From 0de117a0da30f3f861a7b4faf2e18f2bb1f7f5c4 Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Tue, 14 Jul 2026 15:41:56 -0400 Subject: [PATCH 1/4] Rewrite build-skills.ts as a copy of the pinned boxel-skills tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit boxel-skills is markdown-first now — skills//SKILL.md directories and commands/.md slash-command files are already in the shape Claude Code consumes — so the cards-to-SKILL.md transform (aggregator emission, description overrides, host-only exclusions) is gone. The script copies skills/ and commands/ verbatim into plugin/, keeps the pinned-tag model (bumped to v0.0.28, the first tag with the new layout), and keeps the manifest-based stale sweep, now covering commands too. The plugin README's auto-generated block lists both catalogs from each file's frontmatter; the publish workflow stages the new outputs. Linear: CS-11543 Co-Authored-By: Claude Fable 5 --- .github/workflows/boxel-cli-publish.yml | 5 +- packages/boxel-cli/plugin/README.md | 47 +- .../plugin/commands/boxel-add-field.md | 48 + .../plugin/commands/boxel-add-file-field.md | 49 + .../commands/boxel-build-from-pattern.md | 51 + .../plugin/commands/boxel-create-card.md | 219 ++++ .../plugin/commands/boxel-create-instance.md | 82 ++ .../plugin/commands/boxel-debug-runtime.md | 50 + .../plugin/commands/boxel-design-card.md | 64 + .../plugin/commands/boxel-develop-theme.md | 80 ++ .../plugin/commands/boxel-edit-template.md | 53 + .../plugin/commands/boxel-install-listing.md | 48 + .../plugin/commands/boxel-migrate-schema.md | 44 + .../plugin/commands/boxel-preview-card.md | 41 + .../plugin/commands/boxel-search-cards.md | 44 + .../plugin/commands/boxel-submit-listing.md | 48 + .../plugin/commands/boxel-sync-workspace.md | 237 ++++ .../commands/distill-from-boxel-skills.md | 202 +++ .../plugin/commands/distill-learnings.md | 122 ++ .../skills/boxel-create-edit-cards/SKILL.md | 59 + .../plugin/skills/boxel-design/SKILL.md | 698 +---------- .../references/asset-selection-guidelines.md | 129 ++ .../boxel-design/references/critical-rules.md | 40 + .../plugin/skills/boxel-development/SKILL.md | 142 --- .../references/dev-core-concept.md | 140 --- .../references/dev-fitted-formats.md | 40 - .../references/dev-query-systems.md | 95 -- .../references/dev-replicate-ai.md | 114 -- .../plugin/skills/boxel-environment/SKILL.md | 140 +++ .../references/assistant-persona.md | 22 + .../references/calling-commands.md | 153 +++ .../references/choosing-llm-models.md | 17 + .../references/common-errors.md | 53 + .../references/diagnosing-broken-links.md | 63 + .../references/host-commands-reference.md | 114 ++ .../references/indexing-operations.md | 325 +++++ .../references/markdown-edit.md | 115 ++ .../references/searching-and-querying.md | 95 ++ .../references/source-code-editing.md | 16 + .../references/user-environment-awareness.md | 46 + .../references/workflows-and-orchestration.md | 169 +++ .../plugin/skills/boxel-file-def/SKILL.md | 69 + .../references/available-fields.md | 23 + .../filedef-first-class-file-support.md | 11 + .../references/filedef-vs-base64imagefield.md | 20 + .../boxel-file-def/references/import-paths.md | 44 + .../markdowndef-vs-markdownfield.md | 16 + .../references/no-inline-binary.md | 102 ++ .../rendering-file-fields-in-templates.md | 33 + .../references/type-hierarchy.md | 23 + .../references/using-filedef-in-cards.md | 95 ++ .../skills/boxel-flavored-markdown/SKILL.md | 40 + .../references/authoring-notes.md | 5 + .../references/base-syntax.md | 11 + .../bfm-extensions-beyond-commonmarkgfm.md | 79 ++ .../card-directives-the-boxel-extension.md | 65 + .../references/quick-reference.md | 56 + .../references/where-bfm-is-used.md | 11 + .../skills/boxel-markdown-format/SKILL.md | 40 + .../references/delegation-composes.md | 20 + .../essential-helper-markdownescape.md | 9 + .../references/pitfalls.md | 64 + .../rendering-markdown-html-at-runtime.md | 34 + .../shape-of-a-static-markdown-template.md | 25 + .../the-default-usually-good-enough.md | 12 + .../the-markdown-helpers-toolkit.md | 35 + .../references/when-youre-done.md | 6 + ...-example-note-card-with-custom-markdown.md | 46 + .../plugin/skills/boxel-patterns/SKILL.md | 345 +++++ .../app-card-home-with-search/README.md | 323 +++++ .../patterns/attach-remote-image/README.md | 150 +++ .../automate-image-steering/README.md | 213 ++++ .../automate-image-steering/example.gts | 399 ++++++ .../automate-linked-to-me-lookup/README.md | 181 +++ .../automate-linked-to-me-lookup/example.gts | 114 ++ .../automate-run-command-cli/README.md | 91 ++ .../automate-run-command-cli/example.gts | 95 ++ .../build-planning-cards-trio/README.md | 190 +++ .../build-site-config-with-theme/README.md | 39 + .../build-site-config-with-theme/example.gts | 156 +++ .../cardinfo-override-title/README.md | 65 + .../cardinfo-override-title/example.gts | 96 ++ .../patterns/command-atomic-install/README.md | 72 ++ .../command-atomic-install/example.gts | 86 ++ .../patterns/command-data-resource/README.md | 45 + .../command-data-resource/example.gts | 51 + .../command-optimistic-pipeline/README.md | 34 + .../command-optimistic-pipeline/example.gts | 223 ++++ .../command-typed-with-progress/README.md | 29 + .../command-typed-with-progress/example.gts | 90 ++ .../command-with-skill-card-ref/README.md | 30 + .../command-with-skill-card-ref/example.gts | 49 + .../containsmany-sorted-render/README.md | 69 + .../containsmany-sorted-render/example.gts | 119 ++ .../format-morph-shared-component/README.md | 138 ++ .../integrate-chess-js-via-cdn/README.md | 65 + .../integrate-chess-js-via-cdn/example.gts | 102 ++ .../README.md | 19 + .../example.gts | 67 + .../integrate-leaflet-via-cdn/README.md | 55 + .../integrate-leaflet-via-cdn/example.gts | 84 ++ .../patterns/integrate-one-shot-llm/README.md | 46 + .../integrate-one-shot-llm/example.gts | 69 + .../README.md | 26 + .../example.gts | 192 +++ .../README.md | 137 ++ .../example.gts | 184 +++ .../README.md | 46 + .../example.gts | 73 ++ .../integrate-three-js-via-cdn/README.md | 67 + .../integrate-three-js-via-cdn/example.gts | 104 ++ .../integrate-thumbnail-card-ai/README.md | 196 +++ .../integrate-thumbnail-card-ai/example.gts | 223 ++++ .../integrate-tone-js-via-cdn/README.md | 86 ++ .../integrate-tone-js-via-cdn/example.gts | 162 +++ .../integrate-web-audio-synthesis/README.md | 109 ++ .../integrate-web-audio-synthesis/example.gts | 152 +++ .../layout-3d-card-carousel/README.md | 145 +++ .../layout-3d-card-carousel/example.gts | 235 ++++ .../patterns/layout-design-board/README.md | 29 + .../patterns/layout-design-board/example.gts | 73 ++ .../layout-kanban-drag-drop/README.md | 52 + .../layout-kanban-drag-drop/example.gts | 313 +++++ .../README.md | 239 ++++ .../example.gts | 239 ++++ .../patterns/link-command-menu-item/README.md | 91 ++ .../link-command-menu-item/example.gts | 83 ++ .../README.md | 33 + .../example.gts | 89 ++ .../link-element-tag-helper/README.md | 48 + .../link-element-tag-helper/example.gts | 43 + .../patterns/link-flip-card/README.md | 77 ++ .../patterns/link-flip-card/example.gts | 136 ++ .../patterns/link-host-mode-paths/README.md | 197 +++ .../patterns/link-host-mode-paths/example.gts | 144 +++ .../patterns/link-onclick-outside/README.md | 53 + .../patterns/link-onclick-outside/example.gts | 56 + .../patterns/link-view-transition/README.md | 73 ++ .../patterns/link-view-transition/example.gts | 136 ++ .../organize-atomic-field-factory/README.md | 36 + .../organize-atomic-field-factory/example.gts | 69 + .../organize-base-class-taxonomy/README.md | 60 + .../organize-base-class-taxonomy/example.gts | 61 + .../organize-lru-cached-parser/README.md | 46 + .../organize-lru-cached-parser/example.gts | 90 ++ .../organize-recursive-fielddef/README.md | 31 + .../organize-recursive-fielddef/example.gts | 97 ++ .../README.md | 28 + .../example.gts | 95 ++ .../organize-sensitive-stub-pair/README.md | 164 +++ .../organize-sensitive-stub-pair/example.gts | 215 ++++ .../organize-typed-activity-feed/README.md | 246 ++++ .../organize-typed-activity-feed/example.gts | 208 +++ .../README.md | 28 + .../example.gts | 79 ++ .../patterns/pick-rating/README.md | 38 + .../patterns/pick-rating/example.gts | 226 ++++ .../patterns/pick-typed-sort/README.md | 56 + .../patterns/pick-typed-sort/example.gts | 75 ++ .../polymorphic-field-subclass/README.md | 110 ++ .../patterns/resource-for-state/README.md | 158 +++ .../show-card-list-with-views/README.md | 67 + .../show-card-list-with-views/example.gts | 89 ++ .../show-count-tiles-from-query/README.md | 38 + .../show-count-tiles-from-query/example.gts | 291 +++++ .../show-filedef-audio-player/README.md | 22 + .../show-filedef-audio-player/example.gts | 178 +++ .../show-pdf-annotations-filedef/README.md | 27 + .../show-pdf-annotations-filedef/example.gts | 378 ++++++ .../show-runtime-markdown-html/README.md | 64 + .../show-runtime-markdown-html/example.gts | 76 ++ .../patterns/show-table-from-query/README.md | 29 + .../show-table-from-query/example.gts | 81 ++ .../patterns/show-wiki-links/README.md | 39 + .../patterns/show-wiki-links/example.gts | 156 +++ .../patterns/theme-first-workflow/README.md | 139 ++ .../patterns/theme-first-workflow/example.gts | 99 ++ .../references/ai-image-models.md | 52 + .../references/integration-surfaces.md | 407 ++++++ .../boxel-patterns/references/libraries.md | 224 ++++ .../scripts/audit-host-command-refs.mjs | 165 +++ .../skills/boxel-theme-development/SKILL.md | 74 ++ .../references/design-md-adapter.md | 123 ++ .../references/shadcn-boxel-token-mapping.md | 90 ++ .../skills/boxel-ui-guidelines/SKILL.md | 640 +--------- .../references/checklist.md | 20 + .../references/delegated-render-control.md | 642 ++++++++++ .../field-rendering-fields-vs-model.md | 11 + .../font-loading-theme-card-owns-imports.md | 21 + ...t-apis-write-new-components-when-needed.md | 27 + .../references/prevent-content-overflow.md | 7 + .../references/style-budget.md | 63 + .../references/template-patterns.md | 217 ++++ .../use-boxel-design-tokens-for-theming.md | 289 +++++ .../references/use-boxel-ui-components.md | 102 ++ ...se-container-queries-not-viewport-units.md | 27 + .../boxel-cli/plugin/skills/boxel/SKILL.md | 168 +++ .../boxel/references/base-field-catalog.md | 244 ++++ .../boxel/references/card-references.md | 118 ++ .../references/command-development.md} | 72 +- .../references/command-invocation-modes.md | 98 ++ .../skills/boxel/references/common-imports.md | 166 +++ .../container-query-fitted-layout.md | 1115 +++++++++++++++++ .../skills/boxel/references/core-concept.md | 373 ++++++ .../references/core-patterns.md} | 3 + .../references/data-management.md} | 0 .../skills/boxel/references/date-math.md | 186 +++ .../references/defensive-link-traversal.md | 206 +++ .../references/defensive-programming.md} | 0 .../references/delegated-rendering.md} | 2 +- .../boxel/references/design-playbook.md | 405 ++++++ .../references/enumerations.md} | 78 ++ .../references/external-libraries.md} | 67 +- .../references/file-editing.md} | 0 .../skills/boxel/references/fitted-formats.md | 100 ++ .../skills/boxel/references/formatters.md | 54 + .../plugin/skills/boxel/references/icons.md | 188 +++ .../skills/boxel/references/imagedef.md | 113 ++ .../skills/boxel/references/lint-workflow.md | 102 ++ .../boxel/references/prefers-wide-format.md | 91 ++ .../skills/boxel/references/query-systems.md | 299 +++++ .../references/quick-reference.md} | 43 +- .../references/relationship-loading-state.md | 100 ++ .../boxel/references/searchable-fields.md | 101 ++ .../references/spec-usage.md} | 0 .../references/styling-design.md} | 98 +- .../references/technical-rules.md} | 0 .../references/template-syntax.md} | 26 +- .../references/theme-design-system.md} | 95 +- .../scripts/instance-correctness-scan.py | 152 +++ .../plugin/skills/catalog-listing/SKILL.md | 53 +- .../references/submission-workflow.md | 135 ++ .../plugin/skills/dev-bfm-syntax/SKILL.md | 248 ---- .../plugin/skills/dev-file-def/SKILL.md | 171 --- .../skills/dev-markdown-format/SKILL.md | 272 ---- packages/boxel-cli/plugin/skills/glossary.md | 506 ++++++++ .../skills/source-code-editing/SKILL.md | 135 ++ .../scripts/.boxel-skills-manifest.json | 35 +- packages/boxel-cli/scripts/build-skills.ts | 569 +++------ .../tests/scripts/build-skills.test.ts | 291 ++--- 240 files changed, 24972 insertions(+), 3149 deletions(-) create mode 100644 packages/boxel-cli/plugin/commands/boxel-add-field.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-add-file-field.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-build-from-pattern.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-create-card.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-create-instance.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-debug-runtime.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-design-card.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-develop-theme.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-edit-template.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-install-listing.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-migrate-schema.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-preview-card.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-search-cards.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-submit-listing.md create mode 100644 packages/boxel-cli/plugin/commands/boxel-sync-workspace.md create mode 100644 packages/boxel-cli/plugin/commands/distill-from-boxel-skills.md create mode 100644 packages/boxel-cli/plugin/commands/distill-learnings.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-create-edit-cards/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-design/references/asset-selection-guidelines.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-design/references/critical-rules.md delete mode 100644 packages/boxel-cli/plugin/skills/boxel-development/SKILL.md delete mode 100644 packages/boxel-cli/plugin/skills/boxel-development/references/dev-core-concept.md delete mode 100644 packages/boxel-cli/plugin/skills/boxel-development/references/dev-fitted-formats.md delete mode 100644 packages/boxel-cli/plugin/skills/boxel-development/references/dev-query-systems.md delete mode 100644 packages/boxel-cli/plugin/skills/boxel-development/references/dev-replicate-ai.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/assistant-persona.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/calling-commands.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/choosing-llm-models.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/common-errors.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/diagnosing-broken-links.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/host-commands-reference.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/indexing-operations.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/markdown-edit.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/searching-and-querying.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/source-code-editing.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/user-environment-awareness.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-environment/references/workflows-and-orchestration.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/available-fields.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/filedef-first-class-file-support.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/filedef-vs-base64imagefield.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/import-paths.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/markdowndef-vs-markdownfield.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/no-inline-binary.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/rendering-file-fields-in-templates.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/type-hierarchy.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-file-def/references/using-filedef-in-cards.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/authoring-notes.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/base-syntax.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/bfm-extensions-beyond-commonmarkgfm.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/card-directives-the-boxel-extension.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/quick-reference.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-flavored-markdown/references/where-bfm-is-used.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/delegation-composes.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/essential-helper-markdownescape.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/pitfalls.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/rendering-markdown-html-at-runtime.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/shape-of-a-static-markdown-template.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/the-default-usually-good-enough.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/the-markdown-helpers-toolkit.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/when-youre-done.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-markdown-format/references/worked-example-note-card-with-custom-markdown.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/app-card-home-with-search/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/attach-remote-image/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-image-steering/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-image-steering/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-linked-to-me-lookup/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-linked-to-me-lookup/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-run-command-cli/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/automate-run-command-cli/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/build-planning-cards-trio/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/build-site-config-with-theme/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/build-site-config-with-theme/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/cardinfo-override-title/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/cardinfo-override-title/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-atomic-install/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-atomic-install/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-data-resource/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-data-resource/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-optimistic-pipeline/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-optimistic-pipeline/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-typed-with-progress/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-typed-with-progress/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-with-skill-card-ref/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/command-with-skill-card-ref/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/containsmany-sorted-render/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/containsmany-sorted-render/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/format-morph-shared-component/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-chess-js-via-cdn/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-chess-js-via-cdn/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-filedef-generated-image/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-filedef-generated-image/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-leaflet-via-cdn/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-leaflet-via-cdn/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-one-shot-llm/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-one-shot-llm/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-openrouter-image-generation/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-openrouter-image-generation/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-screenshot-card-format/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-screenshot-card-format/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-send-request-via-proxy/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-send-request-via-proxy/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-three-js-via-cdn/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-three-js-via-cdn/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-thumbnail-card-ai/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-thumbnail-card-ai/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-tone-js-via-cdn/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-tone-js-via-cdn/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-web-audio-synthesis/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/integrate-web-audio-synthesis/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-3d-card-carousel/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-3d-card-carousel/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-design-board/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-design-board/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-kanban-drag-drop/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-kanban-drag-drop/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-sectioned-record-with-nav/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/layout-sectioned-record-with-nav/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-command-menu-item/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-command-menu-item/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-discriminated-action-resolver/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-discriminated-action-resolver/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-element-tag-helper/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-element-tag-helper/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-flip-card/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-flip-card/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-host-mode-paths/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-host-mode-paths/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-onclick-outside/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-onclick-outside/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-view-transition/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/link-view-transition/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-atomic-field-factory/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-atomic-field-factory/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-base-class-taxonomy/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-base-class-taxonomy/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-lru-cached-parser/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-lru-cached-parser/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-recursive-fielddef/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-recursive-fielddef/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-resource-class-data-loader/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-resource-class-data-loader/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-sensitive-stub-pair/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-sensitive-stub-pair/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-typed-activity-feed/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-typed-activity-feed/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-variant-field-dispatcher/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/organize-variant-field-dispatcher/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/pick-rating/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/pick-rating/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/pick-typed-sort/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/pick-typed-sort/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/polymorphic-field-subclass/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/resource-for-state/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-card-list-with-views/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-card-list-with-views/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-count-tiles-from-query/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-count-tiles-from-query/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-filedef-audio-player/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-filedef-audio-player/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-pdf-annotations-filedef/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-pdf-annotations-filedef/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-runtime-markdown-html/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-runtime-markdown-html/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-table-from-query/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-table-from-query/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-wiki-links/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/show-wiki-links/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/theme-first-workflow/README.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/patterns/theme-first-workflow/example.gts create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/references/ai-image-models.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/references/integration-surfaces.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/references/libraries.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-patterns/scripts/audit-host-command-refs.mjs create mode 100644 packages/boxel-cli/plugin/skills/boxel-theme-development/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-theme-development/references/design-md-adapter.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-theme-development/references/shadcn-boxel-token-mapping.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/checklist.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/delegated-render-control.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/field-rendering-fields-vs-model.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/font-loading-theme-card-owns-imports.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/prefer-component-apis-write-new-components-when-needed.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/prevent-content-overflow.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/style-budget.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/template-patterns.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/use-boxel-design-tokens-for-theming.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/use-boxel-ui-components.md create mode 100644 packages/boxel-cli/plugin/skills/boxel-ui-guidelines/references/use-container-queries-not-viewport-units.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/base-field-catalog.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/card-references.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-command-development.md => boxel/references/command-development.md} (53%) create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/command-invocation-modes.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/common-imports.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/container-query-fitted-layout.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/core-concept.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-core-patterns.md => boxel/references/core-patterns.md} (97%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-data-management.md => boxel/references/data-management.md} (100%) create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/date-math.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/defensive-link-traversal.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-defensive-programming.md => boxel/references/defensive-programming.md} (100%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-delegated-rendering.md => boxel/references/delegated-rendering.md} (97%) create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/design-playbook.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-enumerations.md => boxel/references/enumerations.md} (67%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-external-libraries.md => boxel/references/external-libraries.md} (63%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-file-editing.md => boxel/references/file-editing.md} (100%) create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/fitted-formats.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/formatters.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/icons.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/imagedef.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/lint-workflow.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/prefers-wide-format.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/query-systems.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-quick-reference.md => boxel/references/quick-reference.md} (76%) create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/relationship-loading-state.md create mode 100644 packages/boxel-cli/plugin/skills/boxel/references/searchable-fields.md rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-spec-usage.md => boxel/references/spec-usage.md} (100%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-styling-design.md => boxel/references/styling-design.md} (53%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-technical-rules.md => boxel/references/technical-rules.md} (100%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-template-patterns.md => boxel/references/template-syntax.md} (91%) rename packages/boxel-cli/plugin/skills/{boxel-development/references/dev-theme-design-system.md => boxel/references/theme-design-system.md} (58%) create mode 100755 packages/boxel-cli/plugin/skills/boxel/scripts/instance-correctness-scan.py create mode 100644 packages/boxel-cli/plugin/skills/catalog-listing/references/submission-workflow.md delete mode 100644 packages/boxel-cli/plugin/skills/dev-bfm-syntax/SKILL.md delete mode 100644 packages/boxel-cli/plugin/skills/dev-file-def/SKILL.md delete mode 100644 packages/boxel-cli/plugin/skills/dev-markdown-format/SKILL.md create mode 100644 packages/boxel-cli/plugin/skills/glossary.md create mode 100644 packages/boxel-cli/plugin/skills/source-code-editing/SKILL.md diff --git a/.github/workflows/boxel-cli-publish.yml b/.github/workflows/boxel-cli-publish.yml index a7165b39820..45feda51141 100644 --- a/.github/workflows/boxel-cli-publish.yml +++ b/.github/workflows/boxel-cli-publish.yml @@ -219,7 +219,10 @@ jobs: set -euo pipefail git add packages/boxel-cli/package.json \ packages/boxel-cli/plugin/.claude-plugin/plugin.json \ - packages/boxel-cli/plugin/skills + packages/boxel-cli/plugin/skills \ + packages/boxel-cli/plugin/commands \ + packages/boxel-cli/plugin/README.md \ + packages/boxel-cli/scripts/.boxel-skills-manifest.json if git diff --cached --quiet; then echo "No changes to commit (regen produced no diff, bumps both none)." echo "pushed=false" >> "$GITHUB_OUTPUT" diff --git a/packages/boxel-cli/plugin/README.md b/packages/boxel-cli/plugin/README.md index f80fa6859c5..497755d0956 100644 --- a/packages/boxel-cli/plugin/README.md +++ b/packages/boxel-cli/plugin/README.md @@ -60,17 +60,42 @@ Authored upstream in [`cardstack/boxel-skills`](https://github.com/cardstack/box -_Generated from [`cardstack/boxel-skills@v0.0.22`](https://github.com/cardstack/boxel-skills/tree/v0.0.22) by_ `pnpm build:skills`. _Edit upstream, not here._ - -| Skill | Use it for | -| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `/boxel-cli:boxel-design` | Boxel UI design discovery. Use when designing or redesigning a Boxel app, choosing a visual direction, or pushing past default look-and-feel before generating code. | -| `/boxel-cli:boxel-development` | Authoring Boxel cards. Use when creating or editing .gts card definitions, .json card instances, or answering questions about CardDef / FieldDef / templates / Boxel patterns. Covers the full .gts authoring surface — imports, fields, formats (isolated/embedded/fitted/atom/edit), styling, and common pitfalls. | -| `/boxel-cli:boxel-ui-guidelines` | Ensures boxel-ui components are used in templates and theming guidelines are followed | -| `/boxel-cli:catalog-listing` | catalog-listing | -| `/boxel-cli:dev-bfm-syntax` | BFM reference: render surfaces, base syntax, :card/::card directives, mermaid, math ($...$ / $$...$$), alerts, footnotes, and code highlighting. | -| `/boxel-cli:dev-file-def` | How to use FileDef, ImageDef, MarkdownDef, and related types for file fields in Boxel cards | -| `/boxel-cli:dev-markdown-format` | Authoring `static markdown` templates: defaults, markdownEscape, markdown-helpers toolkit, delegation, and pitfalls. | +_Copied from [`cardstack/boxel-skills@v0.0.28`](https://github.com/cardstack/boxel-skills/tree/v0.0.28) by_ `pnpm build:skills`. _Edit upstream, not here._ + +| Skill | Use it for | +| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `boxel` | Use whenever creating, reading, or editing Boxel cards (.gts files), card instances (.json), fields, templates, queries, or anything in a Boxel realm. Required for any Boxel coding work — covers CardDef, FieldDef, contains/linksTo, templates, formats, queries, and core patterns. Companion skills - boxel-design (visual decisions), boxel-ui-guidelines (template UI), source-code-editing (SEARCH/REPLACE), boxel-environment (running the Boxel app). | +| `boxel-create-edit-cards` | Use when choosing the right Boxel host command combination to create new cards or edit existing instances from the AI assistant. | +| `boxel-design` | Use when designing or styling a Boxel card — choosing colors, typography, theme variables, layout, or visual treatment. Activates for any visual decisions on a card. | +| `boxel-environment` | Use when running, navigating, or orchestrating tasks inside the live Boxel application — switching between Code Mode and Interact Mode, calling host commands (search-cards, switch-submode, show-card, patch-fields, apply-markdown-edit, reindex, etc.), or any operation that drives the Boxel UI. Activates for Boxel-app runtime work, not for writing card definitions (see boxel for that). | +| `boxel-file-def` | Use when adding or working with file-typed fields (FileDef, ImageDef, MarkdownDef, PngDef, CsvFileDef). Activates when a card needs to reference an image, document, or other file asset. | +| `boxel-flavored-markdown` | Use when authoring or editing Boxel Flavored Markdown (BFM) content — content fields rendered as rich markdown with :card/::card directives, mermaid diagrams, etc. | +| `boxel-markdown-format` | Use when authoring a `markdown` template (static markdown format) on a CardDef or FieldDef — defaults, markdownEscape, and markdown helpers. | +| `boxel-patterns` | Use when the user names an outcome ("show a chart", "let users pick a color", "build a dashboard", "summarize comments", "embed AI image generation", "lay out a moodboard") and you need a working code example to start from. This skill is the bridge between user intent and the existing patterns in Boxel realms. Index your search by what the user wants to DO, not by which CardDef/FieldDef class to extend. Activates when the user asks "do we have a pattern for…", "how is X typically done", or names a feature outcome that isn't in core syntax. | +| `boxel-theme-development` | Develop Boxel Theme, StructuredTheme, StyleReference, DetailedStyleReference, and BrandGuide cards. Use when creating, converting, auditing, or patching theme/style/brand-guide artifacts; importing or exporting Google DESIGN.md design-system briefs; choosing Boxel Brand Guide vs custom brand styling; or working with logo/mark usage, functional palettes, typography, and theme tokens. | +| `boxel-ui-guidelines` | Use when writing or editing Boxel templates that render UI: applying theme tokens, choosing between @fields and @model, using boxel-ui components (Button, Pill, Avatar, BoxelSelect), or fixing layout/overflow issues. | +| `catalog-listing` | Use when installing, browsing, remixing, updating, or submitting catalog listings (Apps, Cards, Fields, Skills, Themes) from a Boxel catalog realm. Includes the submission workflow that creates a SubmissionWorkflowCard and GitHub PR. | +| `source-code-editing` | Use when editing existing .gts or .json files via SEARCH/REPLACE blocks. Defines exact block format, matching rules, and recovery from failed matches. Required before issuing any code edit. | + +| Command | Use it for | +| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/boxel-cli:boxel-add-field` | Add or change schema fields, computed fields, or relationships on an existing CardDef/FieldDef. | +| `/boxel-cli:boxel-add-file-field` | Add a file-backed field (image, document, CSV, markdown) using FileDef/ImageDef/MarkdownDef/CsvFileDef. | +| `/boxel-cli:boxel-build-from-pattern` | Start from an existing ready pattern — list patterns by outcome, or adapt a chosen one to the user's domain. | +| `/boxel-cli:boxel-create-card` | Create a new CardDef, FieldDef, or small card family with all required formats. | +| `/boxel-cli:boxel-create-instance` | Create a new JSON card instance or update an existing one. | +| `/boxel-cli:boxel-debug-runtime` | Diagnose runtime, indexing, command, or mode issues in the live Boxel app. | +| `/boxel-cli:boxel-design-card` | Improve a card's visual design — colors, typography, mood, asset direction, theme tokens. | +| `/boxel-cli:boxel-develop-theme` | Create, convert, audit, or patch a Boxel Theme, Style Reference, Detailed Style Reference, or Brand Guide. | +| `/boxel-cli:boxel-edit-template` | Change isolated, embedded, fitted, edit, atom, or markdown templates on a CardDef or FieldDef. | +| `/boxel-cli:boxel-install-listing` | Use, install, remix, or update a catalog listing. | +| `/boxel-cli:boxel-migrate-schema` | Find existing card instances after a schema change and update them in batches. | +| `/boxel-cli:boxel-preview-card` | Preview a card, module, or format in the live Boxel app. | +| `/boxel-cli:boxel-search-cards` | Find cards in the live Boxel app or in a realm by type, title, or query filter. | +| `/boxel-cli:boxel-submit-listing` | Submit a catalog listing through the workflow-card PR flow. | +| `/boxel-cli:boxel-sync-workspace` | Pull, push, sync, watch, status, history, milestone, and search realms via boxel-cli. Manage workspace state including .boxel-sync.json manifest and checkpoints in .boxel-history. | +| `/boxel-cli:distill-from-boxel-skills` | Backport an improvement (or a batch of improvements) from the upstream cardstack/boxel-skills repo into this workspace's skill tree. Use when a recent PR or commit upstream documents a gotcha, pattern, or rule we should mirror locally. | +| `/boxel-cli:distill-learnings` | Consolidate accumulated learnings from .claude/learnings/ into the right skill tree files, then archive consumed entries. | diff --git a/packages/boxel-cli/plugin/commands/boxel-add-field.md b/packages/boxel-cli/plugin/commands/boxel-add-field.md new file mode 100644 index 00000000000..8ff33c7eaf7 --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-add-field.md @@ -0,0 +1,48 @@ +--- +name: boxel-add-field +description: Add or change schema fields, computed fields, or relationships on an existing CardDef/FieldDef. +boxel: + kind: skill +--- + +# /boxel-add-field + +## Use When + +- A card already exists and the user wants to add, rename, retype, or remove a field. +- They want a computed field, a `linksTo`/`linksToMany`, or a `contains`/`containsMany`. + +## Inputs + +- Path to the `.gts` file. +- Field name + type + relationship intent. +- Whether existing instances need to be migrated. + +## Read + +1. `skills/boxel/SKILL.md` +2. `skills/boxel/references/lint-workflow.md` +3. `skills/source-code-editing/SKILL.md` +4. If the field is file-typed: `skills/boxel-file-def/SKILL.md`. +5. If the field is enum-ish: `skills/boxel/references/enumerations.md`. + +## Procedure + +1. Read the current file to confirm its shape. +2. Identify whether the target type extends CardDef (use `linksTo`) or FieldDef (use `contains`). +3. SEARCH/REPLACE to add the `@field foo = …` declaration. +4. If templates reference the old shape, update them in the same edit. +5. If schema changed, run `/boxel-migrate-schema` to update affected instances. + +## Done Criteria (self-verify) + +- [ ] The new field uses `linksTo`/`linksToMany` if it points at a CardDef, `contains`/`containsMany` if FieldDef. +- [ ] Computed fields wrap field access in try/catch when crossing card boundaries. +- [ ] No self-referencing computed fields. +- [ ] Tracking marker `ⁿ` added on every changed line (if tracking mode is on). +- [ ] Changed `.gts` files passed installed npm `boxel` lint (`npx boxel file lint ... --file ` before push and `npx boxel lint --realm ` after push). + +## Failure Recovery + +- "Cannot find module" after adding an import → check the path; relative paths must use `./` or `../`. +- Instances now invalid → propose `/boxel-migrate-schema` next. diff --git a/packages/boxel-cli/plugin/commands/boxel-add-file-field.md b/packages/boxel-cli/plugin/commands/boxel-add-file-field.md new file mode 100644 index 00000000000..2c0fb556e5f --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-add-file-field.md @@ -0,0 +1,49 @@ +--- +name: boxel-add-file-field +description: Add a file-backed field (image, document, CSV, markdown) using FileDef/ImageDef/MarkdownDef/CsvFileDef. +boxel: + kind: skill +--- + +# /boxel-add-file-field + +## Use When + +- The user wants a card field that holds an image, document, audio, video, or other file asset. +- They mention "upload", "attach", "image", "file", "PDF", "CSV", "markdown file". + +## Inputs + +- Path to the `.gts` file. +- What kind of file (image / png / svg / markdown file / CSV / generic). +- Single or multiple (`linksTo` vs `linksToMany`). + +## Read + +1. `skills/boxel-file-def/SKILL.md` +2. `skills/boxel/SKILL.md` +3. `skills/boxel/references/lint-workflow.md` +4. `skills/boxel-file-def/references/no-inline-binary.md` +5. `skills/source-code-editing/SKILL.md` +6. If rendering the file (preview, gallery): `skills/boxel-ui-guidelines/SKILL.md`. + +## Procedure + +1. Choose the most specific FileDef subtype (`ImageDef`, `PngDef`, `SvgDef`, `MarkdownDef`, `CsvFileDef`, etc.) — fall back to `FileDef` only when the type is truly generic. +2. Import from the corresponding `https://cardstack.com/base/-file-def` (or `image-file-def`, `file-api`). +3. Add `@field foo = linksTo(SomeFileDef)` (NEVER `contains` — FileDef has identity). +4. If the template renders the file, include the file's own format (e.g. `<@fields.thumbnail />` and let the FileDef render). + +## Done Criteria (self-verify) + +- [ ] The file field uses `linksTo` or `linksToMany`, never `contains`. +- [ ] The import is from `https://cardstack.com/base/-file-def` (or `file-api`). +- [ ] `Base64ImageField` is NOT used (it crashes the AI context with embedded binary). +- [ ] No media bytes or `data:image/...;base64` strings are stored in `StringField`, `outputText`, JSON attributes, or notes. +- [ ] If the file appears in JSON, empty value is `"self": null`, not `[]`. +- [ ] Changed `.gts` files passed installed npm `boxel` lint (`npx boxel file lint ... --file ` before push and `npx boxel lint --realm ` after push). + +## Failure Recovery + +- "Base64 too large" errors → confirm you're using a FileDef subtype, not Base64ImageField. +- Image renders blank → check the FileDef instance has a valid `url` and is indexed. diff --git a/packages/boxel-cli/plugin/commands/boxel-build-from-pattern.md b/packages/boxel-cli/plugin/commands/boxel-build-from-pattern.md new file mode 100644 index 00000000000..2dc129e0f0f --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-build-from-pattern.md @@ -0,0 +1,51 @@ +--- +name: boxel-build-from-pattern +description: Start from an existing ready pattern — list patterns by outcome, or adapt a chosen one to the user's domain. +boxel: + kind: skill +--- + +# /boxel-build-from-pattern + +## Use When + +- The user describes an OUTCOME ("show a chart", "let users pick a color", "build a quote document", "embed AI image generation", "lay out a moodboard") rather than a class hierarchy. +- They ask "do we have an example of…" or "how is X typically done in Boxel?". + +## Inputs + +- The user's outcome in plain language. +- (Optional) which realm they want to apply this in. + +## Read + +1. `skills/boxel-patterns/SKILL.md` — the intent taxonomy. +2. After picking a pattern, its `patterns//README.md` and `patterns//example.gts`. +3. The pattern's "See also" section — usually points to one or two supporting skills. + +## Procedure + +**Discovery mode** — user described an outcome, doesn't know what's available: + +1. Map the outcome to an intent group in the taxonomy (Show / Let users / Build / Automate / Lay out / Link / Collaborate / Use library / Integrate / Organize / Make Command / Theme). +2. List the **Ready Patterns** in that group with one-line outcomes. Skip planned entries. +3. Ask the user which pattern matches (or pick one if obvious). + +**Application mode** — user named a specific pattern, or one is now chosen: + +1. Read `patterns//README.md` for when/why/insight/gotchas. +2. Read `patterns//example.gts` for the code shape. +3. Adapt to the user's domain — replace placeholder names, data, and styling. +4. Apply via `/boxel-create-card` or `/boxel-edit-template` flow. + +## Done Criteria (self-verify) + +- [ ] The chosen pattern is from the **Ready Patterns** section, not the Planned backlog. +- [ ] The adaptation preserves the pattern's "insight" (the non-obvious bit the pattern is teaching). +- [ ] Imports match the pattern (especially library imports from `https://realms-staging.stack.cards/ctse/common-libs/...`). +- [ ] The user's domain replaces the example's placeholders, not the other way around. + +## Failure Recovery + +- No matching pattern → fall back to the core skills (`boxel`, `boxel-ui-guidelines`, `boxel-design`) and write from scratch. +- Pattern looks outdated → check `BSL-STUDY-V3.md` in the `familiar-turkey` realm for the latest syntax, especially `commands/ai-assistant` vs older `commands/use-ai-assistant`. Ask the user for the current URL. diff --git a/packages/boxel-cli/plugin/commands/boxel-create-card.md b/packages/boxel-cli/plugin/commands/boxel-create-card.md new file mode 100644 index 00000000000..a597cac5167 --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-create-card.md @@ -0,0 +1,219 @@ +--- +name: boxel-create-card +description: Create a new CardDef, FieldDef, or small card family with all required formats. +boxel: + kind: skill +--- + +# /boxel-create-card + +## Use When + +- The user wants a new CardDef, FieldDef, or small card family. +- They describe a domain ("a recipe card", "a project tracker", "a quote document") without yet having code. + +## Inputs + +- Realm URL or local realm path. +- The card concept (one sentence is fine). +- Whether sample JSON instances are needed. + +## Read (REQUIRED, in order) + +1. **`skills/boxel/references/design-playbook.md`** — THE process. Four stages: mockup → extract → tokenize → derive. The verbatim Pentagram-art-director framing IS stage 1. Read this in full before any other skill. +2. **`skills/boxel-ui-guidelines/references/delegated-render-control.md`** — REQUIRED if this card embeds other cards via `<@fields.X @format='...' />`. Covers: format choice (fitted vs embedded — _upstream_ of any CSS; pick the wrong one and you get empty boxes), the plural-field wrapper trap (`linksToMany` ≠ `containsMany` in class names), atom-on-dark-background invisibility, stagger via CSS-variable cascade through `display: contents`, and the per-format chrome contract. +3. **`skills/boxel-patterns/patterns/app-card-home-with-search/README.md`** — REQUIRED if this build is a card _family_ (2+ related CardDefs). Build a Home CardDef alongside them so the realm has an entry point. +4. `skills/boxel-patterns/patterns/cardinfo-override-title/README.md` — the `cardTitle` override that respects user input. +5. `skills/boxel/SKILL.md` (focus on `references/core-concept.md` — CardInfo + computed pass-throughs). +6. `skills/boxel/references/base-field-catalog.md` — reach past `StringField` when the value has a known shape (`EmailField`, `DateRangeField`, `PercentageField`, etc.). +7. `skills/boxel/references/icons.md` — verify icons against the CDN HEAD before importing. +8. `skills/boxel/references/lint-workflow.md` — mandatory installed npm `boxel` lint gate. +9. `skills/source-code-editing/SKILL.md`. +10. Check `skills/boxel-patterns/SKILL.md` for a ready pattern matching the outcome (`automate-linked-to-me-lookup`, `format-morph-shared-component`, `polymorphic-field-subclass`, `resource-for-state`). + +## Procedure — apply the design playbook + +The playbook is mandatory for any user-facing card. Skip only for utility cards (lookup tables, internal config). For **card families** (2+ related CardDefs), stage 0 below is REQUIRED before any real schema is written — without it, fitted views end up pedestrian because the data model isn't rich enough to compose with. + +### Stage 0 — Planning artifacts (for card families) + +Produce these BEFORE writing any production CardDef. Each can ship as a CardDef whose `static isolated` IS the plan document, pushed to the realm so the user can review visually. See `boxel/references/design-playbook.md` for ASCII templates of each artifact. + +| Artifact | What it answers | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Goal | What the family does in one paragraph | +| Brief | What makes this unique + important for users | +| DataModelPlan | ASCII data-flow diagram + schema sketch (CardDef list, FieldDef list, relationships, sensitive vs operational realm split) | +| Sample data | 3-5 dossiers per CardDef — real names, real prices, real photo captions | +| ASCII layout | Box layout for each CardDef's `isolated` view — where the hero image goes, where the eyebrow vs headline vs meta lives | +| MicroMockups | Hi-fi mockup of each format (`isolated` / `embedded` / `fitted` / `edit`) at desktop AND mobile, with the divider strategy decided. All cards responsive in `isolated` AND `edit`. | + +The source pattern is in `app.boxel.ai/.../actual-duck-82/{architecture-plan,data-model-plan,micro-mockups}.gts` — three CardDefs whose isolated templates ARE the plan documents. Without stage 0, agents reach for thin schemas (name + description + date) and produce fitted views with nothing to show. Stage 0 forces the rich-enough data model and the signature-field decision (which field is the visual hero of fitted: the photo? the price? the badge?). + +### Stage 1 — Mockup pass (NO variables) + +Write `static isolated` as an HTML/CSS mockup with hardcoded values: real fonts, real `#hex`, real px sizes. The verbatim brief: + +> Do a design exploration and generate only the above-the-fold view in isolated, framed as such. Write sample content for this use case and fit the elements in there as a design challenge executed by a brand-focused art director of Pentagram, judged by the preeminent taste maker in that field. (Specify who in your thinking, not your final summary.) + +Hold an internal taste-maker in mind. Schema must be rich enough that the design has something to compose with — add fields (`subtitle`, `eyebrow`, `cuisine`, `keyIngredient`, `rating`, `reviews`, etc.) the design demands. + +Apply intrinsic design taste: serif/sans pairing, weight rhythm (large light + tiny bold), letter-spaced micro-labels, ONE accent color in ≤2 places, editorial micro-objects (avatar with initial, drawn rule, eyebrow + section heading, rule-bracketed data slab). Write evocative sample content in the publication's voice (NYT, Cherry Bombe, Apartamento, Pitchfork — pick the register). + +### Stage 2 — Extract theme + +Scan stage-1 CSS and pull every distinct decision into named tokens. Write a Theme card whose `cssVariables` ARE the design's palette. Rule of two: tokenize if used twice+; leave inline if used once. Don't add tokens the mockup didn't earn. + +### Stage 3 — Tokenize isolated + +Replace hardcoded values with `var(--*)` references to the new theme. Pixel-identical to stage 1. Link `cardInfo.theme` on the instance. + +### Stage 4 — Derive fitted + embedded + +Use the established visual identity to author `static embedded` and `static fitted`. **Fitted MUST feature the card's media** (hero image, illustration, brand mark) if any. Same fonts, same accents, less content. + +### When embedding child cards (linksTo/linksToMany) + +If any format renders `<@fields.X @format='...' />`, read `delegated-render-control.md` BEFORE writing the parent's CSS. The host injects CardContainer chrome (rounded corners, halo, padding, `overflow: hidden`). The parent overrides via: + +- Theme cascade (cleanest — when the child has its own `cardInfo.theme`) +- `:deep(.boxel-card-container)` from the parent's scoped CSS (workhorse) +- `@displayContainer={{false}}` (kills chrome entirely; pair with parent-owned chip span) + +For atoms in prose or in a bill list, the canonical pattern is `<@fields.X @format='atom' @displayContainer={{false}} />` inside a parent-owned `` so the parent controls borders, alignment, padding. + +### Other procedure steps + +- Inspect the realm to see existing conventions. +- Decide CardDef vs FieldDef and the relationship type (`contains` vs `linksTo`). +- **Override `cardTitle`** if the card has a natural primary identifier field. Use the canonical form (cardInfo.name → primary field → `Untitled `). Also override `cardDescription` if you can compute it from other fields. +- Assign a `static icon` on every CardDef and FieldDef (CDN-verified name). + +### Sample instances + +Create one or two `.json` instances when requested: + +- Link the Theme via `"cardInfo.theme": { "links": { "self": "../Theme/" } }` (relationship key has a literal dot). +- Include an explicit `attributes.cardInfo` object with `notes`, `name`, `summary`, `cardThumbnailURL` whenever a theme is linked. +- For nested app folders, prefer an absolute Theme URL in `cardInfo.theme.links.self` unless the relative path has been verified in the live app. +- **Theme JSON itself**: include `attributes.cardInfo` but OMIT `relationships["cardInfo.theme"]` entirely (no self-loop). +- Use `"self": null` for empty `linksTo`/`linksToMany`, NEVER `[]`. +- Include `meta.adoptsFrom.module` + `name`. +- Content should match the design's editorial voice — evocative and real-sounding, never Lorem ipsum. + +### Lint/compile verification + +- `npx boxel check ` is sync state only, NOT a compile or lint check. +- Use the installed npm `@cardstack/boxel-cli` 0.2.0+ lint surface: + - Before push: `npx boxel file lint --realm --file `. + - After push: `npx boxel lint --realm `. +- Clean lint means `No lint issues found` or JSON `messages: []`; `ok: true` with lint messages is not clean. +- Run server-side render validation after push too: hit `/_search-prerendered` for `embedded`/`fitted`/`atom`/`head` formats, and open the card in the live app to exercise `isolated`. + +### Final gate — verify via search, not via lint + +**Lint passing ≠ kit shipped.** Lint is a smoke test of file structure; it does NOT exercise the realm's actual module-load path. A kit can lint clean with 0 of N instances actually indexed. + +For every CardDef built in this command, run BOTH gates before declaring done: + +```sh +REALM="" + +# Gate A: module-load probe (the realm-server actually evaluates the .gts) +npx boxel run-command @cardstack/boxel-host/tools/get-card-type-schema/default \ + --realm "$REALM" \ + --input "{\"codeRef\":{\"module\":\"${REALM}\",\"name\":\"\"}}" \ + --json +# Must return: status: "ready" +# `cardOrThunk was undefined` → bad import or unresolved cycle somewhere in the chain. + +# Gate B: typed-search count (instances are recognized as the type) +npx boxel search --realm "$REALM" \ + --query "{\"filter\":{\"type\":{\"module\":\"${REALM}\",\"name\":\"\"}}}" \ + --json +# Count must equal the number of instances you intended to push. +# Use absolute module URLs in --query; relative paths like ./ don't resolve from the CLI. +``` + +If Gate A returns error OR Gate B count is short, the kit is NOT shipped. Do NOT report done. + +### Icon — CDN-verify before assignment + +Workspace source-file grep is NOT proof. Probe every icon you plan to use: + +```sh +for icon in ; do + code=$(curl -s -o /dev/null -w "%{http_code}" \ + "https://boxel-icons.boxel.ai/@cardstack/boxel-icons/v1/icons/${icon}.js") + printf " %-20s HTTP %s\n" "$icon" "$code" +done +``` + +Require 200 before adding `static icon = X`. See `boxel/references/icons.md` "CDN verification is the only proof an icon exists." + +## Done Criteria (self-verify) + +**Design playbook (the spine):** + +- [ ] Stage 1 mockup was a real designed surface — internal taste-maker held in mind, schema rich enough to compose with, evocative sample content, two-family typography pairing, weight rhythm (large light + tiny bold), letter-spaced eyebrow, ONE accent in ≤2 places, 2-3 editorial micro-objects. +- [ ] Stage 2 theme was EXTRACTED from the mockup (rule of two — tokenize if used twice+), not picked from a generic shadcn palette before the design existed. +- [ ] Stage 3 isolated is pixel-identical to stage 1 but uses `var(--*)` for every value that appears twice+. +- [ ] Stage 4 fitted **features the card's media** if the card has any (hero image, illustration, brand mark, color swatch). Fitted is not a text-only metadata strip when imagery is available. +- [ ] Fitted view **renders correctly at ALL 16 named sizes** (Small/Medium/Large Badge; Single/Double/Triple Strip; Double-Wide/Triple-Wide Strip; Small/Regular/CardsGrid/Tall/Large Tile; Compact/Full/Expanded Card). No content overflow, no clipped text, type hierarchy legible at every cell, sub-format routing (badge/strip/tile/card) hits correctly. Walk the table in `boxel/references/fitted-formats.md` and confirm each row. Verify via the live app's fitted preview — not by `npx boxel check`. + +**Chrome contract (every format):** + +- [ ] No format's outermost element decorates with `border-radius`, `border`, `box-shadow`, opaque `background`, or `overflow` — those belong to the host's CardContainer or the parent's `:deep()` override. Brand outer-treatment goes on the Theme card via `--radius` / `--background` / `--border`. +- [ ] `fitted` outermost doesn't set `width`, `height`, `min/max-height`, `container-type`, or `container-name` — the host's `.field-component-card.fitted-format` sets those. +- [ ] If this card embeds children via `<@fields.X @format='...' />`, the parent's CSS overrides CardContainer chrome (via `:deep()`, theme cascade, or `@displayContainer={{false}}`) so embedded children look native to the parent's design language — no orphan rounded corners, no misaligned atoms. + +**Embedding contract (every place `<@fields.X @format='...' />` appears):** + +- [ ] Format chosen by who owns the cell size — `embedded` for natural-height lists/feeds (clubs, events, results), `fitted` for uniform tile grids (portraits, calendar cells). Never `fitted` into a flex column with short content — that produces empty box space below each row. See "Picking the format" in `delegated-render-control.md`. +- [ ] Plural-field grid selectors target `:deep(> .plural-field)` AND `:deep(.linksToMany-itemContainer), :deep(.containsMany-item)` with `display: contents`. Targeting only `.containsMany-field` silently skips `linksToMany` and the grid collapses to one column. +- [ ] Atoms inside dark surfaces use `@displayContainer={{false}}` (or the parent recolors `:deep(.field-component-card.atom-format)` chrome). Default atom chrome has near-white background and will hide light-on-dark text. +- [ ] Staggered animations on plural-field cards use the CSS-variable cascade (`--stagger-d` on the wrapper's `:nth-child(N)`, `animation-delay: var(--stagger-d)` on the card). Direct `:nth-child` on `.field-component-card` always matches `:nth-child(1)` because of the per-item wrapper. +- [ ] Divider strategy chosen explicitly. If the parent draws lines between cards (`border-bottom`, `border-right`, outer-frame borders), the parent ALSO sets `:deep(.boxel-card-container--boundaries) { box-shadow: none; }`. If the child halo IS the boundary, the parent uses `gap` and no parent borders. Mixing produces the "double rule" / "drop shadow fighting border" bug. +- [ ] No duplicate `:deep(.boxel-card-container--boundaries)` rules per section. When switching strategies, DELETE the stale rule — don't just add an override below it. `grep -c "boundaries" ` should equal one rule per styled section. + +**Home app (mandatory for card families):** + +- [ ] If this build introduces 2+ related CardDefs, a `Home` CardDef exists alongside them with `prefersWideFormat = true` and one `@context.searchResultsComponent` section per CardDef. The realm has a clear entry point — no manual indexing. See `app-card-home-with-search`. + +**`prefersWideFormat` decision (most-forgotten static property):** + +- [ ] For each new CardDef, decided **at creation time** whether `static prefersWideFormat = true` is right. Set true for app-card homes, long-record cards with side nav, dashboards, document / multi-column cards, 3D/spatial layouts, routed pages, spreadsheets, slide decks. Leave false for detail / form / note / settings cards. **Don't defer — discovering you needed it later means rewriting the layout you already wrote against the narrow column.** See `boxel/references/prefers-wide-format.md`. + +**Framework rules:** + +- [ ] `@field cardTitle` is overridden to compute from a primary field (when one exists) AND respects `cardInfo?.name?.trim()?.length` first. +- [ ] `grep -E '@field [a-z]+ = contains\(CardDef' ` returns nothing (no `contains(CardDef)`). +- [ ] `grep -E 'static (isolated|embedded|fitted) =' ` returns 3 hits per CardDef. +- [ ] Every exported class is preceded by `export class`. +- [ ] Edit-tracking banner is on line 1 if the file uses tracking mode. +- [ ] Icons imported are CDN-verified (HEAD 200 against `https://boxel-icons.boxel.ai/@cardstack/boxel-icons/v1/icons/.js`). +- [ ] No `{{#if (this.x)}}` parens around bare property access in templates (parens turn it into a helper invocation; class getters fail silently). +- [ ] Entrance animations have their `from` state INSIDE the keyframe and use `animation-fill-mode: both` — never `opacity: 0` in base CSS + `animation: ... forwards`. Otherwise the card goes invisible after a format flip (`isolated → edit → isolated`) or any animation cancellation. See `boxel-ui-guidelines/references/template-patterns.md` → "Entrance animations". +- [ ] Queries use `filter: { type: ref }` to select all of a type (NOT `filter: { on: ref }` — `on` is a scope, not a filter). Custom-field sorts include `on: ref` (only `lastModified`, `createdAt`, `cardURL` work without it). Refs built with `codeRef(here, path, name)` from `@cardstack/runtime-common`; `realmURL` imported as a Symbol from the same module (not `Symbol.for('realmURL')`). See `boxel/references/query-systems.md`. +- [ ] `containsMany(FieldDef)` is used ONLY when the list stays small (≤2 entries typical) OR each entry has very few fields (≤2). For multi-field entries that accumulate (results, line items, history rows, etc.), use `linksToMany(CardDef)` instead — otherwise the edit form gets one inline editor per (entry × field), producing ~1s/keystroke at 5 entries × 6 fields. See boxel/SKILL.md "containsMany edit-form perf trap." + +**Instances:** + +- [ ] A Theme card exists and is linked from every non-Theme sample instance (`cardInfo.theme` with the dotted key). +- [ ] Sample JSON instances include `attributes.cardInfo` with `notes`, `name`, `summary`, `cardThumbnailURL` when a theme is linked. +- [ ] Theme JSON itself does NOT include `relationships["cardInfo.theme"]` (no self-loop). +- [ ] `meta.adoptsFrom.module` + `name` present on every instance. +- [ ] Sample content matches the design's editorial voice — evocative, real-sounding, never Lorem ipsum. + +**Validation:** + +- [ ] Local lint was clean before push: `npx boxel file lint --realm --file `. +- [ ] Remote lint was clean after push: `npx boxel lint --realm `. +- [ ] A real server-side render check was run (`_search-prerendered` for `embedded`/`fitted`/`atom`/`head` + open in app for `isolated`). `npx boxel check` alone does not satisfy this. + +## Failure Recovery + +- SEARCH/REPLACE didn't match: read the file again, include a unique nearby marker, retry with a smaller window. +- Card renders as "Untitled " → you skipped the `cardTitle` override. Add it per `cardinfo-override-title`. +- Card looks unstyled in preview → the instance is missing `cardInfo.theme` link, OR the Theme card itself has empty `cssVariables`. Verify both. +- "instanceof check fails after import" → the constructor was passed unboxed through `{{...}}`. Box it (see pattern `organize-resource-class-data-loader`). diff --git a/packages/boxel-cli/plugin/commands/boxel-create-instance.md b/packages/boxel-cli/plugin/commands/boxel-create-instance.md new file mode 100644 index 00000000000..270e8998cec --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-create-instance.md @@ -0,0 +1,82 @@ +--- +name: boxel-create-instance +description: Create a new JSON card instance or update an existing one. +boxel: + kind: skill +--- + +# /boxel-create-instance + +## Use When + +- The user wants to seed example data, create a card from structured input, or update an existing instance's data. +- The CardDef already exists. + +## Inputs + +- Realm URL. +- The CardDef path (module URL + class name). +- The data to populate. + +## Read + +1. `skills/boxel/SKILL.md` (focus: `references/data-management.md`) +2. `skills/boxel-create-edit-cards/SKILL.md` +3. `skills/source-code-editing/SKILL.md` (if going via SEARCH/REPLACE) + +## Procedure + +1. Decide the tool: `write-text-file` (new instance, simple shape), `patch-fields` (existing instance, surgical), `patchCardInstance` (existing instance, full replace), or SEARCH/REPLACE (large or structural). +2. Compose the JSON. Use `"data"` envelope, `"type": "card"`, `"meta.adoptsFrom"`, `"attributes"`, `"relationships"`. +3. For empty `linksTo`/`linksToMany` use `"self": null`, NEVER `[]`. +4. Save to `//.json`. + +## Instance shape — JSON:API correctness rules + +- **`adoptsFrom.module` is the URL of the .gts, NOT including the export name.** Use `"module": "https://cardstack.com/base/brand-guide"`, `"name": "default"` — never `"module": "https://cardstack.com/base/brand-guide/default"` (that treats the export name as a URL path and returns 404). +- **Every `links.self` MUST start with `./`, `../`, or `http`.** Bare paths like `"BrandGuide/foo"` are treated as npm-style package specifiers and fail with `Cannot resolve bare package specifier`. Use `"./BrandGuide/foo"` for root-level instances, `"../BrandGuide/foo"` for subfolder instances, or absolute URLs for cross-realm references. See `boxel/references/core-concept.md` "Relationship path resolution." +- **`linksToMany` uses INDEXED KEYS, not an array.** Each linked item is its own top-level relationship key: + ```json + "relationships": { + "materials.0": { "links": { "self": "../Material/white-oak" } }, + "materials.1": { "links": { "self": "../Material/walnut" } } + } + ``` + NEVER `"materials": { "links": { "self": ["a", "b"] } }` — the host rejects the instance as "not a card resource document" and it never loads. +- **`containsMany` is an ARRAY in attributes.** `"attributes": { "cabinets": [ {...}, {...} ] }` — opposite of `linksToMany`. Easy to mix up. +- **Date fields match their schema type.** `DateField` ↔ `"YYYY-MM-DD"` (no `T`). `DateTimeField` ↔ `"YYYY-MM-DDTHH:MM:SS.sssZ"` (with `T` and `Z`). Mismatch passes lint, crashes at render with `RangeError: Invalid time value`. +- **Image URLs go in the paired `*URL` field, NEVER in a `linksTo` relationship's `links.self`.** Putting an external URL there bricks the realm (Postgres NULL-byte rejection rolls back the whole indexing batch). See Cardinal Rule in CLAUDE.md. + +## Done Criteria (self-verify) + +- [ ] `"data"` envelope at top level. +- [ ] `"meta.adoptsFrom"` has both `module` and `name`. Module URL does NOT include `/default` or any export-name suffix. +- [ ] Every `links.self` value starts with `./`, `../`, or `http`. No bare paths. +- [ ] `linksToMany` uses indexed-key shape (`"field.0"`, `"field.1"`), NOT array in `links.self`. +- [ ] `containsMany` is an array in `attributes.`. +- [ ] Empty relationships use `"self": null`. +- [ ] `attributes` is an object, NEVER a JSON-string. +- [ ] `relationships` is a sibling of `attributes`, not nested inside it. +- [ ] Include `attributes.cardInfo` (the four-key object: `name`, `summary`, `cardThumbnailURL`, `notes`; nulls fine) UNLESS the CardDef has a meaningful computed `cardTheme` AND there's no name/summary the user might want to edit. When in doubt, include it — it's cheap and gives the user an edit surface. +- [ ] **Per-instance theme override.** If you want THIS instance to override whatever `cardTheme` would otherwise compute, set `relationships["cardInfo.theme"]` with the dotted key. For CardDefs that use the default `cardTheme` pass-through, this is also the only way to install a theme at all. For CardDefs that override `cardTheme` (e.g. Task inherits from Project), it's optional. +- [ ] Exception for Theme card instances themselves: they include `attributes.cardInfo` but OMIT `relationships["cardInfo.theme"]` entirely (no circular self-link). +- [ ] Date string formats match the schema's field type (DateField vs DateTimeField). +- [ ] Image URLs are in `attributes.`, NOT in `relationships..links.self`. + +## Verification after push + +`npx boxel file lint` does NOT confirm the instance is indexed. Run: + +```sh +npx boxel search --realm \ + --query "{\"filter\":{\"type\":{\"module\":\"\",\"name\":\"\"}}}" \ + --json | python3 -c "import json,sys;raw=sys.stdin.read();s=raw.find('[');e=raw.rfind(']')+1;print(len(json.loads(raw[s:e])))" +``` + +Count must match the number of `` instances you intended to push. If short, look for: bare `links.self` path, malformed `linksToMany` array, wrong `adoptsFrom.module` URL. + +## Failure Recovery + +- "Error: attributes is a string" → `attributes` must be an object literal, not a stringified JSON. +- "Error: relationships inside attributes" → move `relationships` to be a sibling at the top level of `data`. +- See `skills/boxel-environment/references/common-errors.md` for the full error catalogue. diff --git a/packages/boxel-cli/plugin/commands/boxel-debug-runtime.md b/packages/boxel-cli/plugin/commands/boxel-debug-runtime.md new file mode 100644 index 00000000000..8626aca26aa --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-debug-runtime.md @@ -0,0 +1,50 @@ +--- +name: boxel-debug-runtime +description: Diagnose runtime, indexing, command, or mode issues in the live Boxel app. +boxel: + kind: skill +--- + +# /boxel-debug-runtime + +## Use When + +- A card won't render or shows an error overlay. +- Indexing is stuck or stale. +- A host command is failing with an unhelpful JSON error. +- The user says "something's broken" without naming the cause. + +## Inputs + +- The symptom (error message, blank screen, stale data, etc.). +- Where it happens (which card, which realm, which mode). + +## Read + +1. `skills/boxel-environment/SKILL.md` +2. `skills/boxel-environment/references/common-errors.md` +3. `skills/boxel-environment/references/indexing-operations.md` +4. If the cause turns out to be in code: `skills/boxel/SKILL.md`. + +## Procedure + +1. Gather context — current workspace, mode, attached card(s), recent edits. +2. If the user message starts with `debug`, output the context dump (see `boxel-environment` debug mode). +3. Match the symptom: + - **JSON tool-call error** → cross-check with `references/common-errors.md`. + - **`Cannot read properties of null (reading 'manager')`** → likely an HTML-tag-shadowing block param; see `boxel/references/template-syntax.md`. + - **Indexing stale** → `invalidate-realm-identifiers_xxxx` for specific resource identifiers, or `reindex-realm_xxxx` for the whole realm. + - **Card module won't load** → switch to code mode and read the file; look for syntax errors from recent SEARCH/REPLACE edits. +4. Once the cause is identified, propose the fix or escalate to the appropriate command (`/boxel-edit-template`, `/boxel-add-field`, etc.). + +## Done Criteria (self-verify) + +- [ ] Root cause named (not just "I tried X and it worked now"). +- [ ] If a fix was applied, the symptom no longer reproduces (verify via `/boxel-preview-card` or re-running the failing query). +- [ ] If the cause was indexing, the affected URLs are now indexed. +- [ ] User understands what happened (one-sentence explanation). + +## Failure Recovery + +- Can't reproduce → ask the user for exact reproduction steps. Boxel runtime errors often surface differently for different ages of edit-tracking state. +- Loop detected (same commands repeating) → STOP and tell the user. Don't barrel forward. diff --git a/packages/boxel-cli/plugin/commands/boxel-design-card.md b/packages/boxel-cli/plugin/commands/boxel-design-card.md new file mode 100644 index 00000000000..c81ad02b393 --- /dev/null +++ b/packages/boxel-cli/plugin/commands/boxel-design-card.md @@ -0,0 +1,64 @@ +--- +name: boxel-design-card +description: Improve a card's visual design — colors, typography, mood, asset direction, theme tokens. +boxel: + kind: skill +--- + +# /boxel-design-card + +## Use When + +- The user says "make this look better", "redesign", "more modern", "more playful", "match brand X". +- Visual concerns dominate the request, even if some template editing follows. + +## Inputs + +- Path to the `.gts` file. +- The design intent (mood, brand, audience, reference inspirations). +- Whether a theme card is involved. + +## Read + +1. **`skills/boxel-patterns/patterns/theme-first-workflow/README.md`** — the Theme card structure + `cardInfo.theme` linkage. +2. `skills/boxel-theme-development/SKILL.md` if the task creates or changes the Theme/StyleReference/BrandGuide artifact itself. +3. `skills/boxel-design/SKILL.md` +4. `skills/boxel-ui-guidelines/SKILL.md` +5. `skills/boxel/SKILL.md` (focus: `references/theme-design-system.md`, `references/styling-design.md`, `references/core-concept.md` for the cardInfo/theme system) + +## Procedure + +1. **Step 0 — Confirm the Theme.** Check whether `cardInfo.theme` is set on representative instances. If not, this is the first thing to fix — no amount of ` + + }; + + static embedded = class Embedded extends Component { /* brand card */ }; + static fitted = class Fitted extends Component { /* mini wordmark */ }; +} +``` + +```json +// Surge/home.json — the canonical home instance +{ + "data": { + "type": "card", + "attributes": { + "welcome": "SURGE", + "tagline": "The youth swim meet platform.", + "cardInfo": { "name": "SURGE — Home", "summary": "Realm home." } + }, + "relationships": { + "headlineMeet": { + "links": { "self": "../Meet/mid-atlantic-senior-sectionals-2026" } + }, + "cardInfo.theme": { "links": { "self": "../Theme/surge" } } + }, + "meta": { "adoptsFrom": { "module": "../surge", "name": "Surge" } } + } +} +``` + +**`@context.searchResultsComponent` is live by construction — mind the cost on multi-section homes.** + +Each `@context.searchResultsComponent` section subscribes its query to realm change events. Every time ANY card in the realm is created, edited, or deleted, the matching sections re-fetch and re-render. For a Home with 4 result-list sections, editing a single Swimmer somewhere else in the realm can fire re-fetches across every section whose query might be affected — even though only one section's data actually changed. With the host's autosave on each keystroke, this can make unrelated edit forms feel sluggish because the Home tab is consuming CPU on every reindex. + +There is no snapshot/live toggle to reach for — the surface is live by default. The lever you _do_ have is `@mode`: `'hover'` (default) hydrates each result so it can respond to hover; `'none'` renders the prerendered HTML with no per-result interactivity, which is cheaper for dense read-only sections. + +```hbs +{{! ✅ Default: hover-hydrated results. }} +<@context.searchResultsComponent @query={{this.q}} as |results|> + {{#each results.entries key='id' as |entry|}}{{/each}} + + +{{! ✅ Cheaper for dense, read-only sections — no per-result hover hydration. }} +<@context.searchResultsComponent @query={{this.q}} @mode='none' as |results|> + {{#each results.entries key='id' as |entry|}}{{/each}} + +``` + +Keep the number of live sections on a single Home modest, and prefer `@mode='none'` for sections the user only reads. + +**Why `@context.searchResultsComponent` (display) instead of `getCards` (instances):** + +| Use case | Pick | +| ----------------------------------------------------------------- | -------------------------------------------- | +| Showing the cards as themselves (fitted/embedded HTML) | `@context.searchResultsComponent` | +| Reading model values to compute aggregates (counts, sums, charts) | `getCards` | +| Both — list and aggregate | `getCards`, then render with `<@fields ...>` | + +The home almost always wants the first. The host pre-renders each result on the realm side, so the home doesn't pay the cost of loading every model into memory. For a realm with hundreds of swimmers, this is the difference between snappy and unusable. + +**Critical — apply the chrome contract:** + +The home's outermost element (`.sg` in the example) MUST leave decoration to the host's CardContainer. No `border-radius`, no `border`, no `box-shadow`, no opaque `background` (`var(--paper)` is fine — the paper is the brand surface, not chrome), no `overflow`. Brand-specific outer treatment goes on the Theme card as `--radius`, `--background`, `--border`. See `boxel-ui-guidelines/references/delegated-render-control.md`. + +**Critical — no plural-field wrapper for search-results output:** + +`@context.searchResultsComponent` does NOT wrap its yielded entries in `.plural-field / .containsMany-field / .linksToMany-field` — that wrapper only appears for `<@fields.plural @format='...' />` direct rendering. With the search-results surface, you own the `