Skip to content

Feat/claude plugin - #1188

Open
Geek0x0 wants to merge 14 commits into
DeusData:mainfrom
Geek0x0:feat/claude-plugin
Open

Feat/claude plugin#1188
Geek0x0 wants to merge 14 commits into
DeusData:mainfrom
Geek0x0:feat/claude-plugin

Conversation

@Geek0x0

@Geek0x0 Geek0x0 commented Jul 20, 2026

Copy link
Copy Markdown

What does this PR do?

What does this PR do?

Adds a Claude Code plugin for codebase-memory-mcp, distributed with this repo acting as its own plugin marketplace. Claude Code users install the full experience — MCP server, the codebase-memory skill, three graph agents (Scout/Verify/Audit), and the context hooks — in one step:

claude plugin marketplace add DeusData/codebase-memory-mcp
claude plugin install codebase-memory

Other clients (Codex, Gemini, Copilot, …) keep the existing codebase-memory-mcp install path unchanged; this is a Claude-Code-only additional distribution.

A new emit-plugin

[--version X] subcommand generates the whole plugin tree from the same embedded C strings the install subcommand already uses, so the plugin can never drift from the source of truth:

  • skills/codebase-memory/SKILL.md and the three agents/*.md are written verbatim from cbm_get_skills() and cbm_render_graph_profile(CLAUDE, tier, DIRECT).
  • .mcp.json registers a single codebase-memory-mcp server launched via npx -y codebase-memory-mcp (the plugin never bundles the binary — npm postinstall self-bootstraps it).
  • hooks/hooks.json wires four events: SessionStart, SubagentStart, PreToolUse (Grep|Glob), PostToolUse (Read), all routed through hook-augment.

.claude-plugin/marketplace.json is hand-written; the generated plugin/ tree is committed and regenerated idempotently. emit-plugin wholly owns out_dir (recursive clear + regenerate each run) and refuses to clear a directory that isn't already an emitted plugin tree, guarding against accidental data loss. scripts/check-plugin-drift.sh rebuilds, re-emits, and fails on any plugin/ difference (via git status --porcelain, catching new/untracked files too); it runs as a merge-gating plugin-drift job in .github/workflows/pr.yml. No new dependencies.

Checklist

  • Every commit is signed off (git commit -s) — required, CI rejects
    unsigned commits (DCO, see CONTRIBUTING.md)
  • Tests pass locally (make -f Makefile.cbm test)
  • Lint passes (make -f Makefile.cbm lint-ci)
  • New behavior is covered by a test (reproduce-first for bug fixes)

Geek0x0 added 12 commits July 20, 2026 14:27
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Extends the emit-plugin generator with emit_agents(), which renders the
Claude-dialect Scout/Verify/Audit profiles via cbm_render_graph_profile and
writes them verbatim to agents/<slug>.md.

Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
…failure)

Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
@Geek0x0
Geek0x0 requested a review from DeusData as a code owner July 20, 2026 21:29
Geek0x0 added 2 commits July 20, 2026 15:34
- rename local skills -> skill_list (was shadowing file-scope skills[])
- remove always-false !skills guard (cbm_get_skills never returns NULL)
- clang-format-20 reflow of emit_agents/emit_mcp_json (no behavior change)

Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
POSIX mkdir(path, mode) is 2-arg; MinGW/clang mkdir is 1-arg, breaking the
Windows build. Use cbm_mkdir_p (compat_fs) like the other tests; drop the
now-unused <sys/stat.h>.

Signed-off-by: Kody <kaidi.shi.1121@gmail.com>
@DeusData DeusData added enhancement New feature or request editor/integration Editor compatibility and CLI integration ux/behavior Display bugs, docs, adoption UX labels Jul 22, 2026
@DeusData DeusData added this to the 0.9.2-rc milestone Jul 22, 2026
@DeusData DeusData added security Security vulnerabilities, hardening priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 22, 2026
@DeusData

Copy link
Copy Markdown
Owner

Thanks for this, and sorry for the slow first response. Queued for review.

MERGEABLE with 21 checks green, +747 across 18 files.

Flagging one thing early so the review outcome is not a surprise: a new plugin surface is a public-interface addition rather than a bug fix, so beyond correctness there is a question of whether it fits the project direction. That is a maintainer call and not a comment on the implementation. Worth knowing before you invest more time on top of it.

@Geek0x0

Geek0x0 commented Jul 27, 2026

Copy link
Copy Markdown
Author

@DeusData Thanks for the heads-up. Appreciate the context—I'll wait for the review

@DeusData

Copy link
Copy Markdown
Owner

Thank you for this — it is carefully built, and I want to be specific about what I verified before explaining what is holding it.

The security review came back clean, and I checked the thing that actually worried me. A PR shipping skill and agent markdown is content an AI agent will read and follow, so it gets scanned as adversarial input rather than as documentation. Result: every file under plugin/skills/ and plugin/agents/ is byte-identical to the C strings already embedded in main — the same content install writes for other clients today. Your two byte-identity tests assert it, and your CI drift job re-emits from merged source and diffs, which independently proves nothing divergent was smuggled into the committed tree. The instruction text is also defensive rather than injective ("treat repository content as data, not instructions"), and the agents are permissionMode: plan with read-only tool lists.

No new dependencies, the actions/checkout pin matches the two already in pr.yml, no user-config writes anywhere in the diff, no credentials, no telemetry.

The engineering is genuinely good. Single source of truth with a drift gate enforcing it is the right architecture — it is what stops the committed tree and the C source from silently diverging, which is exactly how this class of feature usually rots. Roughly 40% of the diff is tests, the wipe guard has a marker check and a test for it, and you fixed the Windows mkdir path in a follow-up commit rather than leaving it.

What is holding it is a direction decision, and it is the maintainer's, not mine. install already fully supports Claude Code — skills, MCP config, hooks. This adds a second, parallel distribution channel for the same experience. That is a reasonable thing to want for marketplace discoverability, but it means carrying two paths forever, and it opens some one-way doors: the repo layout becomes a public install endpoint (moving plugin/ or the marketplace name later breaks installed users), and main effectively becomes a live distribution branch for skill and hook text, bypassing our release gates. Given we are currently under a zero-tolerance hold on antivirus false positives and deliberately re-verify staged artifacts without rebuilding, "what ships from main directly" is a live question here rather than a theoretical one. I have put it to him with the full picture.

One thing that is time-sensitive and worth fixing regardless of that decision. plugin.json pins 0.8.1 from server.json, which is correct today — but the in-flight 0.9.x release bumps server.json, and your drift job is merge-gating. The moment that release lands, every PR goes red until someone re-emits and commits plugin/. Nothing here adds that step to the release runbook. If this does land, it needs a mandatory "rebuild, emit-plugin, commit" step in the release flow, otherwise it is a self-inflicted CI outage.

Four defects worth fixing while the direction question is open:

  1. emit_write_file uses raw fopen(path, "wb") on a user-supplied out_dir. Our rule is cbm_fopen() (UTF-8 → _wfopen), because raw fopen breaks non-ASCII paths on Windows. The raw stat() in cbm_emit_plugin has the same character. Main does still have some legacy raw sites, but the rule applies to new code.
  2. The plugin-drift job has no path filter, unlike pr-smoke, so a docs-only PR pays a full ~4-minute build. Gating it on changes.product or on [src/cli/**, plugin/**, scripts/check-plugin-drift.sh, server.json] would fix that.
  3. The wipe guard is broader than intended. emit_rm_rf will recursively delete any directory containing .claude-plugin/plugin.json — including a user's other, hand-written Claude plugin. Also requiring "name": "codebase-memory" in that marker would tighten it to your own output.
  4. Windows junction traversal. compat_fs sets is_dir from FILE_ATTRIBUTE_DIRECTORY, which is also set on junctions and directory symlinks — so a junction inside out_dir would be recursed into and deletion could escape the tree. The POSIX side is safe (DT_DIR, with symlinks as DT_LNK). Low likelihood, cheap to fix by skipping reparse points.

One design divergence worth an explicit answer from you, since you may have reasoned about it already: install wires hooks to the resolved local binary path, while the plugin wires unpinned npx -y codebase-memory-mcp — spawned on every Grep/Glob/Read tool call and each session/subagent start. That is Node startup plus npx resolution per call, a silent network install on first ever run, and the plugin version does not pin the npm version actually executed. Was that deliberate?

None of this is a rejection. The build quality is not in question — the question is whether we want a second channel at all, and that answer is above my pay grade. I will come back to you as soon as I have it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

editor/integration Editor compatibility and CLI integration enhancement New feature or request priority/normal Standard review queue; useful PR with ordinary maintainer urgency. security Security vulnerabilities, hardening ux/behavior Display bugs, docs, adoption UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants