feat: add boxel realm ingest-card to copy a card with its dependency graph#5166
Conversation
Copies a source card + its same-realm dependency graph (module + transitively-imported same-realm modules incl. type-only imports + sample instances + the card-level Catalog Spec) from a source realm into a local dir, preserving realm-relative paths. Replaces the whole-realm `boxel realm pull` + cat-via-Bash workaround the improve flow's bootstrap step improvised, and excludes component/function Specs so they no longer break the seed baseline (CS-11425 root cause). - packages/boxel-cli/src/commands/realm/ingest-card.ts — the command: static import-graph crawl, alias/served URL-space normalization, instance + card-Spec lookup via search, optional --with-linked-instances, best-effort same-realm asset pull, checkpoint. - wire into the realm command group; unit tests for the pure helpers. - software-factory: bootstrap seed instructions + orchestrator bootstrap skill now call `boxel realm ingest-card "<url>" .` for the seed step. Verified end-to-end against the catalog mortgage-calculator: 6 modules (incl. the type-only dep) + 1 instance + the card Spec only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…wording Removed the `--with-linked-instances` linksTo crawl and the best-effort binary-asset scan — neither was exercised and both added surface area. Reworded the command help so it's clear ingest works across realms (source realm → target dir) and "same-realm" refers only to which deps get bundled (the card's own-realm imports) vs. left as references (base/other realms). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new boxel realm ingest-card CLI command to seed a local workspace with a card’s same-realm dependency graph (plus instances/spec), and updates the software-factory bootstrap/seed guidance to use this targeted ingestion instead of whole-realm pulls.
Changes:
- Introduces
boxel realm ingest-card <source-card-url> <local-dir>and wires it into the realm CLI. - Adds unit tests for the ingestion helper functions (import parsing, class extraction, same-realm resolution).
- Updates software-factory seed/bootstrap instructions to use the new command.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/software-factory/src/factory-seed.ts | Updates improve-seed instructions to call boxel realm ingest-card instead of whole-realm pull/copy steps. |
| packages/software-factory/.agents/skills-orchestrator/software-factory-bootstrap/SKILL.md | Updates bootstrap skill docs to reflect the new ingestion workflow. |
| packages/boxel-cli/tests/commands/ingest-card.test.ts | Adds helper-level unit tests for the ingestion implementation. |
| packages/boxel-cli/src/commands/realm/ingest-card.ts | Implements the new ingest-card command and its ingestion logic. |
| packages/boxel-cli/src/commands/realm/index.ts | Registers the new ingest-card subcommand under boxel realm. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- resolveEntry: probe `<path>.json` so canonical instance URLs (without the `.json` extension, e.g. `.../Person/123`) resolve as instances instead of 404 → falling through to the module path → throwing. - resolveSameRealmFile: handle registered-prefix `@cardstack/<realm>/…` specifiers by mapping them onto this realm via its path tail; npm-scoped packages (`@glimmer/…`) and other realms stay external. - seed instructions + bootstrap skill: drop the `--with-linked-instances` mention — that flag was removed from the command. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boxel realm ingest-card for same-realm card ingestionboxel realm ingest-card to copy a card with its dependency graph
There was a problem hiding this comment.
can we add a higher level test where we can see it doing the things described in teh PR descrioption? so you have a realm with a bunch of locally referenced modules and modules that are not referenced by the module that you are ingensting. as well as isntances that consume the ingested module, and instances that don't consume the ingested module. and we confirm that the graph of the ingested card is moved into the new realm in a similar directory structure (so relative refs still work)--which means invent some ad hoc directory structure between the referenced modules. And also confirm related instances are moved over, confirm that unrelated modules and instances are not moved over as well as confirm that referenced modules from other realms (like the base realm) are not moved over.
Why this exists
When the software factory adjusts an existing card, the first thing it has to do is stand up a working copy of that card in the new realm — the card's module, the other modules it imports, its sample data, and its catalog Spec — so it can confirm a green baseline before changing anything.
There was no way to do that, so the factory agent improvised: it ran
boxel realm pullon the entire source realm into a scratch folder and copied files out by hand. That was slow, pulled far more than needed, and dragged in catalog Specs for components/helpers that aren't cards — which broke the baseline and pushed the agent into deleting source files to recover.This adds a command that does it properly in one step.
What it does
Copies, into
<local-dir>:Imports that resolve to the base realm or other realms are left as references (they resolve at runtime), so it bundles only what's genuinely the card's own. It works across realms (e.g. the catalog → a user realm); the one constraint is that source and target live on the same realm server (cross-server auth is out of scope).
The factory's bootstrap step now calls this instead of the whole-realm-pull workaround.
Notes
base: cs-11424…) — review/merge that first; this PR's diff is just the command + its factory wiring.factory:goimprove runs against the catalog mortgage-calculator seed cleanly (card + 5 component modules + 1 instance + the card Spec), baseline green first try, no deleted Specs.🤖 Generated with Claude Code