本文へ移動
cccskills
無料GitHub で公開

rembric-plugin-development

Apply when creating, modifying, or reviewing any Rembric agent plugin. Triggers on changes under `apps/plugin/`, on new clients added alongside Claude Code / Codex CLI / Hermes Agent / opencode / Pi, on edits to `apps/plugin/mcp-bridge/`, `apps/plugin/bin/rembric-plugin-core.mjs`, per-client manifest changes, or plugin install/uninstall scripts. End-to-end validation against a local dev server (`pnpm run dev`, host Next.js on :3000) is mandatory whenever local testing is feasible.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md12.6 KB
  • references/e2e-walkthrough.md18.4 KB
  • references/per-client-gotchas.md14.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Rembric plugin development

Authoritative specs: openspec/specs/{claude-code-plugin,codex-distribution,hermes-agent-plugin,opencode-plugin,pi-plugin,plugin-session-protocol}/. Archived decisions: openspec/changes/archive/.

Mandatory workflow

  1. OpenSpec change first. Run /opsx:propose (or amend an existing change). Plugin work always touches ≥2 specs and ≥3 files. Skipping the change is the failure mode that produces drift.
  2. Two release tracks: server + unified plugin (no cascade). release-please runs exactly two components, no node-workspace/linked-versions/grouping. server (apps/web, package @rembric/web, tag server-v*) builds the Docker image. plugin (apps/plugin — the WHOLE tree, no exclude-paths, package @rembric/plugin, tag plugin-v*) carries one unified version for all five clients; its extra-files update every client carrier in lock-step (.claude-plugin/{package,plugin}.json, .codex-plugin/{package,plugin}.json, .hermes-plugin/plugin.yaml, .opencode-plugin/plugin.ts comment, .pi-plugin/package.json). A change to ANY plugin file bumps the single plugin version — claude/codex/opencode/hermes/pi never diverge; the CHANGELOG (scoped by conventional commit) records what actually changed. A plugin release NEVER rebuilds the server image (publish-docker gates on server_release_created), but it IS what publishes @rembric/pi to npm (trusted-publishing OIDC, provenance, no long-lived token). .pi-plugin/ has to live inside apps/plugin/ for that: release-please attributes a release by the paths of the commits under the component's path, so a client outside it would never cause a release and its carrier would only move when something unrelated did. release-please.yml carries a concurrency guard (cancel-in-progress: false) so a rapid second merge can't cancel tag-minting. The former six-component + node-workspace cascade was retired (change unify-plugin-release-track) after its anchor-tag fragility produced phantom release PRs. Legacy per-client tags (claude-code-plugin-v*, …) stay in history, inert.
  3. End-to-end against a local dev server (pnpm run dev, host Next.js on :3000) before reporting done — see E2E discipline below.
  4. Docs sweep: README.md, docs/agents.md, apps/plugin/README.md, the in-plugin README.md, apps/plugin/CHANGELOG.md.

No tool watches the per-client manifest dirs for you. eslint.config.js ignores apps/plugin/*/**, which matches the dot-directories, and none of them match pnpm-workspace.yaml::packages (apps/*, packages/*) — so pnpm -r does not reach them, ESLint does not lint their TypeScript, and any dependencies they declare are not installed by the repo's own install (.claude-plugin/package.json's workspace:* dep is dead letter today). Their tests run only because apps/web/vitest.config.ts::include lists a literal glob per client; a new client without its glob leaves a test file written and never executed, and the suite is green on nothing.

The three single-source-of-truth rules

  • .rembric is the only per-repo slug source. Dotenv file with PROJECT_SLUG=<lowercase-hyphen>. Regex ^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$.
  • apps/plugin/mcp-bridge/rembric-dotenv.mjs is the only JS/TS implementation of parseDotenv + readRembricSlug + SLUG_RE. The bridge, opencode plugin, and Pi extension import it (the installer rewrites the opencode import to the installed absolute path). Inlining any of those in another .mjs/.ts file fails the build (invariant test).
  • apps/plugin/bin/rembric-plugin-core.mjs is the only JS/TS implementation of the nudge strings, stripPrivateTags, truncate, diag, the session HTTP client, the transcript accumulator and the flush helpers. Both JS/TS clients (opencode, Pi) import it, which is what makes the nudge strings byte-identical and the <private> redaction identical by construction rather than by review. Its agent parameter is required with no default: sessions.agent is written once per session into append-only rows with no repair verb, so a default misfiles sessions permanently. rembric-plugin-core.d.mts is hand-written (apps/plugin has no build step and no typecheck) and is the only thing that makes the omission a compile error.

Bash (apps/plugin/scripts/_api.sh) and Python (apps/plugin/.hermes-plugin/__init__.py) keep their own implementations — cross-language wrappers cost more than the duplication. They MUST agree on the regex value.

Per-client gotchas (read on touch)

Each client has 3–5 non-obvious behaviors that bit us. Before modifying that client's files, skim its section in references/per-client-gotchas.md. Sample of what's there:

  • Claude Code: ${user_config.*} works in both mcp.json::env AND hook commands; keychain is the SoT for credentials.
  • Codex CLI: ${user_config.*} is NOT substituted; subprocess env is cleared before MCP spawn → MUST list every needed var in env_vars: [...]; ${CLAUDE_PLUGIN_ROOT} doesn't work in MCP args.
  • Hermes Agent: plugin.yaml::hooks: [...] array gates lifecycle invocation — overriding a method without listing the hook is a silent no-op.
  • opencode: every named export of a plugin file is invoked as a Plugin function — export ONLY RembricPlugin. The bridge MUST live outside ~/.config/opencode/plugins/. Sub-agent filtering (parentID || title.endsWith(" subagent)")) is mandatory.
  • Pi: no built-in MCP (its own docs say so, deliberately) → this is the one client whose plugin holds the MCP client, discovering tools with tools/list; tools register under provider-safe names (.→_) because a real provider rejects the whole payload on a dot; shutdown is awaited and two Ctrl-C presses within 500 ms fire it in the interactive TUI (a single press does not, and print mode registers no SIGINT); nothing is injected from its settings file, so credentials come from the shell.

Shared-vs-divergent discipline

Per memory 01KRNZM2VFCME5HNT8N78HZW18: shared logic lives in shared paths. Divergence is allowed ONLY when the platform forces it.

  • MUST be shared: apps/plugin/mcp-bridge/rembric-dotenv.mjs, apps/plugin/bin/rembric-plugin-core.mjs, apps/plugin/scripts/*.sh (Claude+Codex hooks), apps/plugin/commands/*.md (Pi consumes them verbatim as prompt templates — reference them, never copy). The published @rembric/mcp-bridge package is the shared stdio transport; there is no repository launcher to copy.
  • Legitimately divergent today: hooks/hooks.json vs hooks/hooks.codex.json (env-substitution rules differ); .claude-plugin/mcp.json vs .codex-plugin/mcp.json (Claude keychain substitution differs from Codex's curated env_vars); Python in-process provider for Hermes; JS/TS in-process for opencode; the MCP transport in .pi-plugin/index.ts, because that host has no MCP client for the published bridge to plug into.

Sanity check: git ls-files apps/plugin/ should show ONE copy of each shared resource. Two paths with near-identical content is a sync bug.

Install / uninstall script invariants

  • Never edit the user's agent config file (settings.json, config.toml, opencode.json, ~/.hermes/config.yaml). Print the snippet with <PLACEHOLDERS>; the user pastes.
  • Idempotent: a second run produces an empty diff.
  • chmod 644 for files invoked as node <path> (the +x bit isn't needed for node x.mjs).
  • Fail loudly on missing source files.

Don't overcommit the spec to behavior the server doesn't support

Before adding a handler that POSTs to an endpoint, verify the endpoint exists:

grep -rnE "export (async )?function (GET|POST)" apps/web/src/app/api/

If it doesn't exist: either add the endpoint first (separate OpenSpec change) OR drop the handler from this scope (tasks.md says DEFERRED, change CHANGELOG documents it). Don't ship a handler that 404s.

This bit us in add-opencode-plugin — first iteration speced chat.message POSTing to /prompts/passive, which didn't exist. Cost: spec rework + scope reduction post-merge.

Adding a brand-new client

Always start with a Phase 0 spike in tasks.md that validates platform assumptions BEFORE any plugin code — the platform assumption you can't cheaply prove is the one that sinks the change. Spike the cwd/PWD propagation chain and the hook/lifecycle delivery shape for the new host before writing any plugin code.

The spike's outcome MUST be recorded as a comment in BOTH tasks.md (<!-- spike result: plan-a -->) and the plugin's source file (// cwd-spike-result: plan-a).

End-to-end validation discipline

You MUST exercise the change against a real Rembric dev stack before reporting work as done, unless local e2e is genuinely impossible. Spec validation and unit tests are necessary but not sufficient for plugin work — the multi-process flow (agent → bridge → MCP → HTTP → SQLite → dashboard) breaks in non-obvious places.

Minimum required steps:

  1. REMBRIC_DATA_DIR=./data-dev REMBRIC_ADMIN_TOKEN=<16+-char-token> pnpm run dev (host Next.js dev, http://127.0.0.1:3000). Wait for the server to answer /healthz, then capture the seeded demo-writer token from seed-dev's output (see references/e2e-walkthrough.md §1-2).
  2. Install the plugin (bash apps/plugin/.<X>-plugin/install.sh), configure the client end-to-end with real URL + real token, drop .rembric with PROJECT_SLUG=demo in the working directory.
  3. Exercise the lifecycle path your change affects. The exact commands per client (opencode mcp list, tsx-driven handler invocation, dashboard SQLite verification, etc.) are in references/e2e-walkthrough.md.
  4. Tear down: stop the dev server, uninstall, restore user's config file to its prior state (placeholders if it didn't exist before).

Prefer the isolated variant of steps 2-4 when the client's CLI supports it — scratch HOME, per-run extension load instead of install, deliberately invalid API key. It touches none of the operator's config, so there is nothing to restore and no half-restored state to leave behind, and it costs no LLM calls. Six rails plus the paired-control method: references/e2e-walkthrough.md § 5b.

If you still cannot drive the agent TUI (a client with no per-run load, or keychain integration you can't script):

  • Direct handler invocation via pnpm exec tsx covers ~95% of the handler logic. Pattern from add-opencode-plugin: import the installed plugin module, set env vars, call handlers with mock inputs that mirror the platform's event shape.
  • Tell the user explicitly what you DID verify vs what you DID NOT. Don't say "verified e2e" when you only ran unit tests. List the manual smoke steps the user should run.

If local e2e is genuinely impossible (Codex /hooks interactive trust gate, Claude Code keychain integration, tool you don't have installed): say so out loud. Tell the user:

"I can't drive <specific path> from this environment. Unit tests cover <list>. Manual verification needed for <list>. Want the steps?"

Honest > glossing-over.

Self-check before commit

If any answer is "no" or "I don't know", stop and resolve it.

  • OpenSpec change open or amended for this work
  • Two-track release respected (server + unified plugin; no node-workspace/cascade; all five clients share the one plugin version via extra-files; plugin release never rebuilds Docker)
  • No duplication of parseDotenv / SLUG_RE / the rembric-plugin-core helpers / endpoint strings without justification
  • pnpm vitest run + pnpm run typecheck + pnpm run lint + openspec validate <change> --strict all clean
  • Exercised against a local dev server (pnpm run dev, :3000) (or explicitly told the user what isn't verified)
  • Docs sweep done (README, docs/agents.md, apps/plugin/README.md, in-plugin README, CHANGELOG)
  • Install/uninstall idempotent (verified by running twice)
  • User's local state restored (dev stack down, plugin uninstalled, config placeholders)

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

diagnose

無料

Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Find deepening opportunities in a codebase, informed by the project's own domain language and prior design decisions. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Resolve a verified cluster of Rembric issues from causal root to evidence-gated closure. Use after systemic triage identifies a shared root, or when the user asks to attack issues at the root, create a mechanism map, plan a deletion-first fix, or close a fixed/stale issue cluster. Use `diagnose` for a single defect whose reproduction is not yet established.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert radix primitives, or switch a shadcn project's base library. Handles single components ("migrate accordion") and whole projects.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

susomejias のスキルをすべて見る

このスキルの問題を報告する