Generate boxel-ui component Specs for AI agent discovery (CS-10527)#4809
Draft
jurgenwerk wants to merge 1 commit into
Draft
Generate boxel-ui component Specs for AI agent discovery (CS-10527)#4809jurgenwerk wants to merge 1 commit into
jurgenwerk wants to merge 1 commit into
Conversation
Contributor
Preview deploymentsHost Test Results 1 files ±0 1 suites ±0 1h 45m 23s ⏱️ + 3m 56s Results for commit 2de436c. ± Comparison against earlier commit 61b00ec. Realm Server Test Results 1 files ±0 1 suites ±0 11m 55s ⏱️ + 1m 2s Results for commit 2de436c. ± Comparison against earlier commit 61b00ec. |
ea74310 to
61b00ec
Compare
Publishes one Spec card per @cardstack/boxel-ui component into the
catalog so the software factory agent can discover and reuse UI
primitives by querying the realm instead of hand-rolling HTML.
Generator (packages/boxel-ui/addon/bin/generate-component-specs.mjs):
walks each component's usage.gts, extracts the primary FreestyleUsage
block (args, description, example, CSS vars), and emits one JSON Spec
per component. Wired as `pnpm generate:component-specs`. Writes two
outputs: an in-repo snapshot under test/fixtures/specs/ (52 files) for
the CI drift gate, and the live tree at packages/catalog/contents/Spec/
for local realm-server file-watcher reindex. Normalizes internal Boxel-
prefixed tag names in the example block to the public export name
(`<BoxelInput>` → `<Input>`) and inlines class-field array literals for
`@options` so enum values are listed verbatim.
Resolver: registerCardReferencePrefix('@cardstack/boxel-ui/', …) in
host/app/lib/externals.ts so a Spec ref pointing at
@cardstack/boxel-ui/components resolves via the existing fake-packages
URL scheme.
Agent wiring: new factory skill
`packages/software-factory/.agents/skills/boxel-ui-component-discovery/`
that teaches the discovery recipe and makes the rule mandatory before
any UI is written. Loaded automatically by factory-skill-loader on the
same GTS-keyword trigger as ember-best-practices. The system prompt
gains a corresponding catalog-search exception under "Stay in your
target realm" and surfaces the catalog realm URL (derived from the
target realm origin) so the agent doesn't probe staging/prod hosts.
boxel-development pointers reinforce the rule from the always-loaded
skill.
CI: ci-lint runs `generate:component-specs --check` against the boxel-ui
snapshot to catch missed regenerations. mirror-boxel-ui-specs.yaml
publishes the generated specs to cardstack/boxel-catalog on merge to
main (needs BOXEL_CATALOG_PUSH_TOKEN secret — documented inline).
Test artifacts: two example briefs under packages/software-factory/realm/Wiki/
(delete-confirmable-note, support-ticket-form) exercise the discovery
loop against Modal/Button and Input/Select/Button/Pill respectively.
61b00ec to
2de436c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@cardstack/boxel-uicomponent into the catalog so the software-factory agent can discover and reuse UI primitives via realm search instead of hand-rolling HTML.--enable-boxel-ui-discoveryon the factory CLI. Without the flag, the agent has zero awareness of boxel-ui components (no skill loaded, no system-prompt exception) and the factory runs exactly as it did before this PR. With the flag, the discovery skill + catalog-search exception are added to the system prompt.Pieces
usage.gts, emits Spec JSON with keyword-richcardDescriptionand a structuredreadMe)packages/boxel-ui/addon/bin/generate-component-specs.mjspnpm generate:component-specsscriptpackages/boxel-ui/addon/package.json@cardstack/boxel-ui/→https://packages/@cardstack/boxel-ui/so specref.moduleresolvespackages/host/app/lib/externals.tspackages/software-factory/.agents/skills/boxel-ui-component-discovery/SKILL.md--enable-boxel-ui-discoveryCLI flag, plumbed throughFactoryEntrypointOptions→IssueLoopWiringConfig→DefaultSkillResolverconstructor +ContextBuilder→AgentContext.enableBoxelUiDiscovery→ template variablefactory-entrypoint.ts,factory-issue-loop-wiring.ts,factory-skill-loader.ts,factory-context-builder.ts,factory-agent/{types,claude-code,opencode}.ts{{#if enableBoxelUiDiscovery}}wraps the catalog-search exception andCatalog realm: {{catalogRealm}}line — both disappear cleanly when the flag is offpackages/software-factory/prompts/system.md{{catalogRealm}}template variable (derived from target realm origin) so the agent never guesses staging/prod hostsfactory-target-realm.ts(newderiveCatalogRealmUrl)factory-skill-loader.tscardstack/boxel-catalog, regenerates fromusage.gts, pushes the diff on merge to main.github/workflows/mirror-boxel-ui-specs.yamlBOXEL_CATALOG_PUSH_TOKENsecretdocs/spec.mdSection 3 (drops "no support for examples", documents the generator + dev workflow + cross-repo gotchas)docs/spec.mdpackages/software-factory/realm/Wiki/{delete-confirmable-note,support-ticket-form,product-faq}.jsonArchitecture (briefly)
usage.gtsis the source of truth in this repo.<FreestyleUsage>block per component → markdown readMe with Import / API table / Example / CSS Variables.packages/catalog/contents/Spec/— the working tree of the deployedcardstack/boxel-catalogrepo (gitignored from boxel). No generated specs are committed to the boxel repo.cardstack/boxel-catalog.catalog/contents/exists). Deployed catalog reindexes on next startup via the existingstart-staging.sh→setup:catalog-in-deploymentflow.Feature-flag rationale
Pre-CS-10527 factory runs completed inside their 50-turn budget on most briefs. Adding the discovery skill (~80 lines of always-loaded content) increases prompt bloat and modestly competes for the agent's attention with other always-loaded references like
dev-technical-rules.md. Putting the skill behind a flag means:Verified end-to-end (with the flag)
Ran the factory loop against the
product-faqbrief — a brief that describes "collapsible disclosure", "compact tag-style indicator", and "primary action button" in plain language, never naming any component:All three landed correctly from the catalog. Zero raw
<button>/<input>/<details>in the output. Card passed lint, parse, evaluate, instantiate, and tests.Test plan
BOXEL_CATALOG_PUSH_TOKENrepo secret with write access tocardstack/boxel-catalog.grep -c "boxel-ui-component-discovery\|Catalog realm:" /tmp/factory-run.logshould be 0) and the run completes as before.--enable-boxel-ui-discoveryagainstproduct-faq(or another UI-heavy brief) — verify the agent imports from@cardstack/boxel-ui/components.cardstack/boxel-catalog.Follow-ups (out of scope here)
packages/skills-realm/contents/Skill/for the in-host Matrix code agent (this PR covers the factory only).cardDescriptionquality for the ~14 components whoseusage.gtslacks a top-level@description(the generator falls back to a placeholder for those today).gts-pitfallsreference for known parse traps (@trackedon fields of inline class expressions, generics on class-property initializers) that consume turn budget today.cardstack/boxel-catalogrepo (requires the token + a real PR cycle).🤖 Generated with Claude Code