Skip to content

CS-10900: Add Claude Code plugin for boxel-cli#4632

Open
FadhlanR wants to merge 4 commits intomainfrom
cs-10900-add-claude-code-plugin-for-boxel-cli
Open

CS-10900: Add Claude Code plugin for boxel-cli#4632
FadhlanR wants to merge 4 commits intomainfrom
cs-10900-add-claude-code-plugin-for-boxel-cli

Conversation

@FadhlanR
Copy link
Copy Markdown
Contributor

@FadhlanR FadhlanR commented May 4, 2026

Summary

Ships a first-class Claude Code plugin for @cardstack/boxel-cli, packaging the kind of guidance the standalone cardstack/boxel-cli repo carries in its .claude/CLAUDE.md so it's distributable via marketplace.

  • Plugin lives at packages/boxel-cli/plugin/ with manifest .claude-plugin/plugin.json.
  • Repo-root .claude-plugin/marketplace.json lists the plugin via relative path; external users /plugin marketplace add cardstack/boxel then /plugin install boxel-cli.
  • Cardstack engineers: claude --plugin-dir packages/boxel-cli/plugin.
  • 7 skills under the /boxel-cli: namespace:
    • boxel-development.gts authoring (ported from standalone, ~90KB of evergreen Boxel patterns)
    • boxel-file-structure — file/directory naming + adoptsFrom rules (ported from standalone)
    • realm-sync, realm-history, file-ops, search, profile — new wrappers around the monorepo CLI's namespaced commands (incl. CS-10627 file touch)

How "generated from the code" works

scripts/build-plugin.ts walks the Commander tree and rewrites the <!-- generated:commands --> block inside each SKILL.md. The Commander tree is extracted into src/build-program.ts so both the runtime entry point (src/index.ts) and the generator share one source of truth. Curated narrative outside the markers is hand-authored.

Two CI gates in ci-lint.yaml:

  1. Synopsis freshnesspnpm build:plugin && git diff --exit-code. Fails if commands changed without regenerating skills.
  2. Synopsis-bump coupling — if any generated block is in the diff, plugin.json version must also be in the diff. Without a version bump, Claude's marketplace cache won't surface the update.

Versioning

Plugin and CLI version independently:

  • Prose-only update → bump plugin.json only.
  • CLI command added/changed → bump both (synopsis must regenerate; CI enforces).
  • CLI internal refactor → bump package.json only.

The plugin is not npm-published. The marketplace clones it from cardstack/boxel directly. npm install -g @cardstack/boxel-cli remains the prerequisite for users — Pattern A in plugins-reference (matches how pyright-lsp and other npm-backed plugins work).

Test plan

  • cd packages/boxel-cli && pnpm build:plugin → no diff (idempotent)
  • pnpm lint in packages/boxel-cli passes (eslint + tsc)
  • pnpm test:unit in packages/boxel-cli passes (158 tests)
  • pnpm build in packages/boxel-cli produces a working dist/index.js
  • claude --plugin-dir packages/boxel-cli/plugin from repo root: /help lists /boxel-cli:* skills
  • Smoke-test one skill end-to-end (e.g., /boxel-cli:realm-sync against a local realm-server)
  • Pin a fake CLI command change locally, re-run pnpm build:plugin, confirm git diff shows the synopsis update
  • CI: synopsis-freshness gate fails on a PR that changes a Commander option without regenerating
  • CI: version-bump-coupling gate fails on a PR that changes a generated block without bumping plugin.json

🤖 Generated with Claude Code

FadhlanR and others added 2 commits May 4, 2026 18:48
Ships a first-class Claude Code plugin for @cardstack/boxel-cli, taking
inspiration from the standalone repo's .claude/CLAUDE.md and packaging
it per https://code.claude.com/docs/en/plugins.

Plugin lives at packages/boxel-cli/plugin/ with a repo-root
.claude-plugin/marketplace.json so external users can `/plugin
marketplace add cardstack/boxel` and Cardstack engineers can `claude
--plugin-dir packages/boxel-cli/plugin`.

Seven skills under the /boxel-cli: namespace:
- boxel-development, boxel-file-structure (ported from standalone)
- realm-sync, realm-history, file-ops, search, profile (new wrappers)

Hybrid generation: scripts/build-plugin.ts walks the Commander tree
(extracted into src/build-program.ts so both the runtime entry point and
the generator share one source of truth) and rewrites the
<!-- generated:commands --> blocks in each SKILL.md. Curated narrative
outside those markers is hand-authored.

CI gates added in ci-lint.yaml:
1. Synopsis freshness — `pnpm build:plugin && git diff --exit-code`.
2. Synopsis-bump coupling — if any generated block changed, plugin.json
   version must also change in the same PR (otherwise marketplace
   consumers won't see the update; Claude caches by version string).

Plugin and CLI version independently — prose-only updates bump only
plugin.json; CLI bug fixes bump only package.json. Plugin distribution
stays git-based via the marketplace, no separate npm publish.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the release model from the (now-removed) ticket plan doc into
packages/boxel-cli/plugin/README.md so future maintainers can ship a new
plugin version without digging through Linear: bump-decision table, the
4-step release flow, how users pick up updates, and how to add another
plugin to the marketplace catalog.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@FadhlanR FadhlanR marked this pull request as ready for review May 5, 2026 05:45
@FadhlanR FadhlanR requested a review from a team May 5, 2026 05:46
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e935183029

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci-lint.yaml Outdated
Comment thread .github/workflows/ci-lint.yaml Outdated
@habdelra habdelra requested a review from Copilot May 5, 2026 13:21
@habdelra
Copy link
Copy Markdown
Contributor

habdelra commented May 5, 2026

are you just duplicating the skills that we already have? if so can you use sym links--otherwise we maintain 2 sources of truth and they will ultimately start to diverge

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a distributable Claude Code plugin for @cardstack/boxel-cli, including curated Boxel authoring guidance plus generated command synopses sourced from the CLI’s Commander program tree.

Changes:

  • Refactors CLI program construction into a shared buildBoxelProgram() builder used by both runtime entrypoint and plugin synopsis generator.
  • Introduces pnpm build:plugin generator to rewrite <!-- generated:commands --> blocks for selected skills from the Commander command tree.
  • Adds plugin packaging/metadata (plugin manifest, marketplace entry) and CI checks to enforce synopsis freshness + version bump coupling.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/boxel-cli/src/index.ts Switches runtime entrypoint to build and parse the shared Commander program tree.
packages/boxel-cli/src/build-program.ts New shared builder for the full CLI Commander tree (single source of truth).
packages/boxel-cli/scripts/build-plugin.ts New generator that derives skill command synopses from Commander and rewrites SKILL.md generated blocks.
packages/boxel-cli/plugin/skills/search/SKILL.md New skill doc for federated search, including generated command synopsis block.
packages/boxel-cli/plugin/skills/realm-sync/SKILL.md New realm sync skill doc with generated synopses for sync/push/pull/create/list.
packages/boxel-cli/plugin/skills/realm-history/SKILL.md New realm history/indexing control skill doc with generated synopses.
packages/boxel-cli/plugin/skills/profile/SKILL.md New profile management skill doc with generated synopsis for boxel profile.
packages/boxel-cli/plugin/skills/file-ops/SKILL.md New single-file operations skill doc with generated synopses for boxel file *.
packages/boxel-cli/plugin/skills/boxel-file-structure/SKILL.md New file layout/naming guidance skill doc (hand-authored prose).
packages/boxel-cli/plugin/skills/boxel-development/SKILL.md New large Boxel authoring guide skill doc (hand-authored content).
packages/boxel-cli/plugin/README.md Plugin install/usage/versioning/release documentation.
packages/boxel-cli/plugin/.claude-plugin/plugin.json Plugin manifest for Claude Code marketplace distribution.
packages/boxel-cli/package.json Adds build:plugin script to run the synopsis generator.
.github/workflows/ci-lint.yaml Adds CI gates for synopsis freshness and plugin version bump coupling.
.claude-plugin/marketplace.json Adds repository-level marketplace catalog pointing to the plugin directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci-lint.yaml
Comment thread .github/workflows/ci-lint.yaml Outdated
Comment thread packages/boxel-cli/plugin/skills/boxel-file-structure/SKILL.md Outdated
Replaces the hand-copied 90KB monolithic boxel-development SKILL.md with
a generator (`pnpm build:skills` in packages/boxel-cli/) that pulls from
cardstack/boxel-skills at a pinned tag (v0.0.22), splits aggregator
SkillSets into a lean SKILL.md + references/, and emits standalone
SkillPlusMarkdown leaves as single-file plugin skills. Allowlist:
boxel-development, boxel-design.

Wires two CI checks into ci-lint.yaml that mirror the existing
build-plugin synopsis pattern: drift detection (rebuild → diff) and
version-bump coupling (changed boxel-skills content → plugin.json bump).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@FadhlanR
Copy link
Copy Markdown
Contributor Author

FadhlanR commented May 6, 2026

Good catch — fixed in db73171. We weren't going to symlink because boxel-skills lives in its own repo (cardstack/boxel-skills) and isn't checked out in this monorepo, plus the plugin needs the content physically present for marketplace distribution.

Instead, boxel-skills is now the single source of truth and the plugin mirrors it at build time:

  • New pnpm build:skills (in packages/boxel-cli/scripts/build-skills.ts) shallow-clones cardstack/boxel-skills at a pinned tag (BOXEL_SKILLS_VERSION = 'v0.0.22') and regenerates plugin/skills/boxel-development/ (lean SKILL.md + 18 references/) and plugin/skills/boxel-design/ (single-file leaf).
  • Two new CI gates in ci-lint.yaml mirror the existing build-plugin synopsis pattern:
    1. boxel-skills sync freshness — re-runs pnpm build:skills and fails if git diff shows hand edits to generated content.
    2. boxel-skills bump coupling — fails if generated content changed in the PR but plugin.json version didn't bump.

To pick up upstream changes: bump BOXEL_SKILLS_VERSION in scripts/build-skills.ts, run pnpm build:skills from packages/boxel-cli/, bump plugin.json. CI enforces no drift.

- build-skills.ts now runs generated markdown through Prettier before
  writing, so CI's clean regen matches the committed copy. Fixes the
  failing `Verify boxel-skills sync` lint step (Prettier had been
  applied locally — via on-save / pre-commit format — but not by the
  generator, so freshness drifted).
- Harden the two `Verify plugin version bumped …` CI gates: fetch
  base/head SHAs explicitly (default-depth checkout meant `git diff`
  against the PR base SHA was non-deterministic) and drop the trailing
  `|| true` so a real diff failure surfaces instead of silently
  passing as "no change".
- Replace the synopsis-change grep with a per-file extract-and-compare
  across the `<!-- generated:commands:start -->` / `:end -->` markers,
  so description-only edits inside the generated block don't slip past
  the version-bump check.
- Remove a stray ``` in `boxel-file-structure/SKILL.md` that was
  breaking the rendered `### JSON Structure Rules` table.
- Bump plugin.json to 0.1.1 to satisfy the boxel-skills-content gate
  (Prettier-canonicalised regen produced real text diffs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants