Skip to content

fix: register hyperstack as Claude Code plugin during setup#100

Merged
KailasMahavarkar merged 1 commit intomainfrom
fix/claude-plugin-registration
Apr 22, 2026
Merged

fix: register hyperstack as Claude Code plugin during setup#100
KailasMahavarkar merged 1 commit intomainfrom
fix/claude-plugin-registration

Conversation

@KailasMahavarkar
Copy link
Copy Markdown
Collaborator

Summary

  • Register Hyperstack with Claude Code's native plugin loader so hooks/hooks.json (SessionStart bootstrap) actually activates on install
  • Ship .claude-plugin/marketplace.json so the repo self-declares as a 1-plugin marketplace
  • Add registerClaudeCodePlugin() to setup-hyperstack.ts and wire it into scripts/setup.ts

Why

Before this patch, bun run setup only wired the MCP server entry into the user's config. The plugin format (.claude-plugin/plugin.json, hooks/hooks.json, skills/) was on disk but Claude Code never discovered it - no entry in ~/.claude/plugins/installed_plugins.json, no entry in enabledPlugins. Result: users saw MCP tools but no SessionStart bootstrap, no Iron Laws injection, no skill auto-discovery for the hyperstack-prefixed skills (blueprint, forge-plan, ship-gate, etc).

What changes

  • .claude-plugin/marketplace.json (new): declares hyperstack as 1-plugin marketplace using the inline source: \"./\" pattern (matches caveman / other single-plugin marketplaces).
  • src/internal/setup-hyperstack.ts: new exported registerClaudeCodePlugin(pluginRoot) that:
    • symlinks plugin into ~/.claude/plugins/marketplaces/hyperstack and ~/.claude/plugins/cache/hyperstack/hyperstack
    • deep-merges known_marketplaces.json and installed_plugins.json
    • sets \"hyperstack@hyperstack\": true in ~/.claude/settings.json::enabledPlugins (only that key - no hand-written hook block, no MCP mutation)
    • all paths via os.homedir() - portable across users
  • scripts/setup.ts: calls registerClaudeCodePlugin(pluginRoot) after MCP patch when platform === \"claude-code\". Silent no-op on other platforms.

Behaviour

  • Idempotent: re-running setup produces "already enabled" messages, no duplicate entries.
  • Non-destructive: only touches enabledPlugins, installed_plugins.json, known_marketplaces.json, and creates two symlinks. Leaves all other keys alone.
  • Gated: does nothing if ~/.claude/settings.json is absent.

Test plan

  • Typecheck passes (bunx tsc --noEmit)
  • Dry-run registerClaudeCodePlugin(pluginRoot) produces expected registry mutations
  • Re-run is idempotent (confirmed via repeat invocation)
  • Manual verification: hook emits valid hookSpecificOutput via node hooks/session-start.mjs
  • Fresh install test on a clean ~/.claude (reviewer)
  • Restart Claude Code, verify SessionStart bootstrap appears in context (reviewer)
  • Confirm hyperstack-namespaced skills (blueprint, forge-plan, ship-gate, etc) become invocable (reviewer)

Claude Code's SessionStart bootstrap hook (hooks/hooks.json) only
activates when hyperstack is registered as a first-class plugin via the
native plugin loader. Before this change, setup only wrote the MCP
server entry, leaving the hooks dormant - users saw MCP tools but no
bootstrap injection, no Iron Laws, no skill auto-discovery.

Changes:
- Add .claude-plugin/marketplace.json so hyperstack self-declares as a
  1-plugin marketplace (inline source: "./" pattern).
- Add registerClaudeCodePlugin() in setup-hyperstack.ts that:
    * Symlinks plugin into ~/.claude/plugins/marketplaces and cache
    * Deep-merges known_marketplaces.json and installed_plugins.json
    * Enables hyperstack@hyperstack in settings.json::enabledPlugins
  All paths use os.homedir() - portable across users.
- Wire registerClaudeCodePlugin() into scripts/setup.ts after MCP patch,
  gated on platform === "claude-code".

Idempotent. Skips cleanly when Claude Code not detected.
@KailasMahavarkar KailasMahavarkar merged commit ebf8cbc into main Apr 22, 2026
4 checks passed
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.

1 participant