Skip to content

feat: tag artifacts with a semantic kind at registration - #564

Draft
filip131311 wants to merge 1 commit into
mainfrom
filip/artifact-kind
Draft

feat: tag artifacts with a semantic kind at registration#564
filip131311 wants to merge 1 commit into
mainfrom
filip/artifact-kind

Conversation

@filip131311

Copy link
Copy Markdown
Collaborator

Fresh, from-current-main take on the artifact-kind idea from #398 / #466. Knowing what an artifact represents (not just its MIME type) is what a UI needs to group and name artifacts (e.g. in EAS); this PR delivers exactly that — the tagged handle — without the declared-output-map machinery.

Summary

  • Adds a closed ArtifactKind union to the artifact wire contract; kind is carried on ArtifactHandle, ArtifactEntry, and the /artifacts inventory items.
  • ArtifactStore.register now takes a single { hostPath, kind, ... } options object, so the compiler forces every producer — current and future — to declare what it is emitting.
  • Tags all producers on main today, including the ones feat: add artifact kind metadata #398/feat: add declared artifact output kinds #466 predate: screenshot (all four capture paths), screenshot-diff, flow snapshot baselines/diffs (screenshot / screenshot-diff-context), screen recordings (new screen-recording kind), and the native/React profiler exports and reports.
  • Types the native-profiler export keys at their source (IosExportKey from the EXPORTS table, AndroidExportKey) and maps them through a kind table that is total over both unions — a newly added export key fails to compile until classified, replacing the previous stringly-keyed loop (and the ?? "native-profile-trace" silent-default this design would otherwise need).
  • Client-side (@argent/tools-client), the mirrored handle type keeps kind optional and widened (ArtifactKind | (string & {})): an older, already-running tool-server sends no kind, and a newer server may send kinds this client build predates. Consumers treat it as advisory metadata; unknown kinds are opaque, never an error.

Differences from #398 / #466 (deliberate)

  • No @argent/artifacts package, no third ToolDefinition generic, no per-tool output-name registrar, no runtime throw for “undeclared output” — the kind is plain data at the registration call site, checked at compile time where it can be, and a wrong label can never fail a tool at runtime. If a pre-invocation artifacts declaration in tool-listing metadata is ever needed (an actual EAS consumer), it can be layered on later without changing this wire contract.
  • The two ArtifactKind definitions (registry / tools-client) stay deliberately separate — same as the existing ARTIFACT_MARKER must-match convention — because the client-side type is intentionally looser (optional + open) than the server-side one for version skew.
  • Extending the union stays backward-compatible on the wire.

Validation

  • npm run build (full tsc --build)
  • npm run typecheck:tests in registry, tools-client, tool-server, mcp, cli — clean
  • Full suites green: registry 87, tools-client 178, tool-server 2914, mcp 78, cli 276
  • prettier --check and eslint --max-warnings 0 on all touched files

🤖 Generated with Claude Code

Adds a closed ArtifactKind union to the artifact wire contract and requires
every producer to declare it when registering: ArtifactStore.register now
takes a single { hostPath, kind, ... } options object. MIME type tells a
consumer how to read the bytes; kind tells it what the artifact represents
(a screenshot vs. the annotated diff of two screenshots, a raw trace vs.
the report derived from it). The kind travels on the handle, the store
entry, and the /artifacts inventory items.

All current producers are tagged: screenshot (all four capture paths),
screenshot-diff, flow snapshot baselines/diffs, screen recordings, and the
native and React profiler exports and reports.

The native-profiler export keys are now typed at their source
(IosExportKey / AndroidExportKey) and mapped through a kind table that is
total over both unions, so a newly added export key fails to compile until
it is classified — nothing silently defaults.

The client-side mirror in tools-client keeps kind optional and widened
(ArtifactKind | (string & {})): an older tool-server sends no kind and a
newer one may send kinds this client predates, so consumers must treat it
as advisory metadata, never a hard contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant