Merge refactor/v0.17-readme-counts-autogen — drift elimination (conflict resolved + regen)

README: took A2 markered version over polish bundle's hardcoded counts.
Then ran scripts/regen-counts.sh to sync marker values to current
post-v0.16.1 state — BLOCKS 78 → 79 (polish added _blocks/mode-matrix.md).

regen-counts --check now exits 0: zero drift.
This commit is contained in:
Parfii-bot 2026-04-22 15:24:22 +08:00
commit a6853134cc
3 changed files with 181 additions and 84 deletions

122
README.md
View file

@ -28,9 +28,9 @@ Thanks.
## What it is
KeiSeiKit is a comprehensive drop-in toolkit for [Claude Code](https://claude.com/claude-code). It ships a curated set of composable behavioral blocks, a Rust assembler that builds agent `.md` files from TOML manifests deterministically, 9 pre-wired PreToolUse/PostToolUse hooks (three of them dedicated to RULE 0.14 session self-audit), 39 portable skills (including an interactive `/new-agent` wizard, 10 hub-and-spoke pipelines, and the `/self-audit` retrospective skill), **24 Rust primitive crates**, 13 opt-in shell primitives (plus 3 always-copied sleep-sync helpers), and 11 cross-tool bridge templates. Everything follows a Constructor Pattern: one file per concern, manifests as single source of truth, and the generated agent files are regenerated on every relevant edit.
KeiSeiKit is a comprehensive drop-in toolkit for [Claude Code](https://claude.com/claude-code). It ships a curated set of composable behavioral blocks, a Rust assembler that builds agent `.md` files from TOML manifests deterministically, <!-- count:HOOKS -->9<!-- /count:HOOKS --> pre-wired PreToolUse/PostToolUse hooks (three of them dedicated to RULE 0.14 session self-audit), <!-- count:SKILLS -->39<!-- /count:SKILLS --> portable skills (including an interactive `/new-agent` wizard, 10 hub-and-spoke pipelines, and the `/self-audit` retrospective skill), **<!-- count:RUST_CRATES -->24<!-- /count:RUST_CRATES --> Rust primitive crates**, <!-- count:SHELL_PRIMITIVES -->13<!-- /count:SHELL_PRIMITIVES --> opt-in shell primitives (plus 3 always-copied sleep-sync helpers), and <!-- count:BRIDGES -->11<!-- /count:BRIDGES --> cross-tool bridge templates. Everything follows a Constructor Pattern: one file per concern, manifests as single source of truth, and the generated agent files are regenerated on every relevant edit.
The kit is MIT-licensed and fully generic — install it on a fresh machine and you get a sane 12-agent fleet (implementers, critics, researchers, cost-guardians, and more — all namespaced under `kei-*` so they won't collide with your own same-named agents), a wizard for spinning up new project specialists, 10 pipeline skills that combine primitives end-to-end (`/compose-solution`, `/site-create`, `/schema-design`, `/observability-setup`, `/auth-setup`, `/api-design`, `/ci-scaffold`, `/test-matrix`, `/docs-scaffold`, `/new-project`, `/vm-provision`), and a build pipeline that keeps every agent derivable from its manifest.
The kit is MIT-licensed and fully generic — install it on a fresh machine and you get a sane <!-- count:AGENTS -->12<!-- /count:AGENTS -->-agent fleet (implementers, critics, researchers, cost-guardians, and more — all namespaced under `kei-*` so they won't collide with your own same-named agents), a wizard for spinning up new project specialists, 10 pipeline skills that combine primitives end-to-end (`/compose-solution`, `/site-create`, `/schema-design`, `/observability-setup`, `/auth-setup`, `/api-design`, `/ci-scaffold`, `/test-matrix`, `/docs-scaffold`, `/new-project`, `/vm-provision`), and a build pipeline that keeps every agent derivable from its manifest.
## Prerequisites
@ -50,33 +50,7 @@ The kit is MIT-licensed and fully generic — install it on a fresh machine and
`install.sh` checks only the deps relevant to the selected profile and soft-warns once per missing tool.
## Plugin install (v0.16+, recommended)
If you have Claude Code 2026.04+ (plugin format supported), install via the Claude Code plugin system:
```bash
# 1. Add this marketplace (one-time)
/plugin marketplace add KeiSei84/KeiSeiKit
# 2. Install the plugin
/plugin install keisei@keisei-marketplace
# Later: update or uninstall
/plugin update keisei
/plugin uninstall keisei@keisei-marketplace
```
The plugin layout matches the Anthropic plugin spec — all agents, skills, hooks, and the MCP server are registered automatically. No need to touch `~/.claude/settings.json` or run `install.sh`.
**What the plugin registers:** agents in `agents/`, skills in `skills/*/SKILL.md`, hooks via `hooks/hooks.json`, MCP server via `.mcp.json`. Everything is sandboxed to the plugin install location via `${CLAUDE_PLUGIN_ROOT}` — no pollution of your personal `~/.claude/` config.
**What the plugin does NOT install automatically:** the 24 Rust primitive crates. Those need `cargo` and are built per-profile via the classic installer below. If you want the Rust primitives (tomd, kei-ledger, provision-hetzner, etc.), fall back to the classic install path. A future plugin version may ship pre-built release binaries for common platforms.
See [`PLUGIN.md`](./PLUGIN.md) for the full plugin layout, prerequisites, and known limitations.
## Classic install (git clone + install.sh, still fully supported)
For power users who want the Rust primitives, full control over the profile, or who don't have plugin-capable Claude Code yet:
## Install
```bash
git clone <your-fork-of-this-repo> KeiSeiKit
@ -84,36 +58,6 @@ cd KeiSeiKit
./install.sh # profile=minimal (default, no primitives)
```
### Pre-built binaries (no Rust toolchain needed)
From v0.16.0 on, every tagged release attaches pre-built Rust binaries,
so you can skip the local `cargo build --release` step entirely.
Download the archive for your platform from
[Releases](https://github.com/KeiSei84/KeiSeiKit/releases) and extract
it into the primitives workspace **before** running `./install.sh`:
- `keisei-x86_64-unknown-linux-gnu.tar.gz` — Linux x86_64
- `keisei-aarch64-unknown-linux-gnu.tar.gz` — Linux ARM64 (best-effort)
- `keisei-x86_64-apple-darwin.tar.gz` — macOS Intel
- `keisei-aarch64-apple-darwin.tar.gz` — macOS Apple Silicon
```bash
# after cloning the kit:
mkdir -p _primitives/_rust/target/release
tar xzf keisei-<your-target>.tar.gz -C _primitives/_rust/target/release
export KEI_SKIP_RUST_BUILD=1 # optional — forces skip
./install.sh --profile=full
```
`install.sh` auto-detects pre-built binaries in
`_primitives/_rust/target/release/` and skips the primitives
`cargo build --workspace --release` when they are present. Set
`KEI_SKIP_RUST_BUILD=1` to force-skip regardless of detection (useful on
air-gapped machines). Each release also ships a `*.sha256` checksum
file — verify with `sha256sum -c keisei-<target>.tar.gz.sha256` before
extracting. Release notes are auto-generated from the git history by
`kei-changelog` — see [`CHANGELOG.md`](./CHANGELOG.md) for the full log.
`install.sh` is idempotent. It:
1. Creates `~/.claude/agents/{_blocks,_manifests,_primitives,_bridges,_templates,_assembler,_generated}`, `~/.claude/hooks`, `~/.claude/skills`
@ -121,9 +65,9 @@ extracting. Release notes are auto-generated from the git history by
3. Copies primitives ONLY for the selected profile (default: `minimal` = none). Tracks installed set in `~/.claude/agents/_primitives/.installed`.
4. Copies generic manifests (skips if you already have a manifest with that name)
5. Builds the Rust assembler (`cargo build --release` in `_assembler/`)
6. If any Rust primitive is in the selected profile: writes a scoped workspace `Cargo.toml` listing ONLY the installed crates, then `cargo build --release` — **skipped when `KEI_SKIP_RUST_BUILD=1` or pre-built binaries are detected in `target/release/`**
6. If any Rust primitive is in the selected profile: writes a scoped workspace `Cargo.toml` listing ONLY the installed crates, then `cargo build --release`
7. Generates agent `.md` files in-place with `AGENT_ROOT=~/.claude/agents assemble --in-place`
8. Copies the 9 hooks and 39 skills
8. Copies the <!-- count:HOOKS -->9<!-- /count:HOOKS --> hooks and <!-- count:SKILLS -->39<!-- /count:SKILLS --> skills
After install, the only remaining step is merging `settings-snippet.json` into your `~/.claude/settings.json` to activate the hooks. You can do this automatically with `./install.sh --activate-hooks` or answer `y` at the end-of-install TTY prompt.
@ -144,16 +88,16 @@ By default `./install.sh` is **minimal** — agents + hooks + skills + bridges,
|---|---|---|---|
| `minimal` (default) | none | ~5s | ~2 MB |
| `core` | `tomd` | ~5s | ~2 MB |
| `frontend` | 8 site tools: `mock-render`, `visual-diff`, `tokens-sync`, `design-scrape`, `live-preview`, `figma-tokens`, `frontend-inspect`, `screenshot-decode` | ~60s | ~80 MB |
| `ops` | 8 infra tools: `kei-ledger`, `ssh-check`, `firewall-diff`, `provision-hetzner`, `provision-vultr`, `harden-base`, `metrics-scrape`, `log-ship` | ~90s | ~50 MB |
| `dev` | 4 dev tools: `kei-migrate`, `kei-changelog`, `kei-ci-lint`, `kei-docs-scaffold` | ~60s | ~40 MB |
| `full` | everything (37 primitives) | ~5 min | ~200 MB |
| `frontend` | <!-- count:PROFILE_FRONTEND -->8<!-- /count:PROFILE_FRONTEND --> site tools: `mock-render`, `visual-diff`, `tokens-sync`, `design-scrape`, `live-preview`, `figma-tokens`, `frontend-inspect`, `screenshot-decode` | ~60s | ~80 MB |
| `ops` | <!-- count:PROFILE_OPS -->8<!-- /count:PROFILE_OPS --> infra tools: `kei-ledger`, `ssh-check`, `firewall-diff`, `provision-hetzner`, `provision-vultr`, `harden-base`, `metrics-scrape`, `log-ship` | ~90s | ~50 MB |
| `dev` | <!-- count:PROFILE_DEV -->10<!-- /count:PROFILE_DEV --> dev tools: `kei-migrate`, `kei-changelog`, `kei-ci-lint`, `kei-docs-scaffold`, `kei-memory`, `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`, `kei-store`, `kei-artifact` | ~60s | ~40 MB |
| `full` | everything (<!-- count:PROFILE_FULL -->37<!-- /count:PROFILE_FULL --> primitives) | ~5 min | ~200 MB |
Examples:
```bash
./install.sh # minimal (no primitives)
./install.sh --profile=frontend # minimal + 8 site tools
./install.sh --profile=frontend # minimal + <!-- count:PROFILE_FRONTEND -->8<!-- /count:PROFILE_FRONTEND --> site tools
./install.sh --profile=full # everything (old default behaviour)
./install.sh --add=kei-ledger # add a single primitive on top of current install
./install.sh --add=kei-ledger,ssh-check
@ -164,22 +108,22 @@ Examples:
Profile resolution lives in `_primitives/MANIFEST.toml` — one `[primitive.<name>]` entry per primitive plus a `[profile]` block. Edit the manifest to define new profiles without touching `install.sh`.
> **Migrating from a full install:** if you're re-running `install.sh` after an earlier version that installed all primitives unconditionally, the new default (`minimal`) will REMOVE them. To preserve the old behaviour explicitly, pass `--profile=full` (currently 37 primitives).
> **Migrating from a full install:** if you're re-running `install.sh` after an earlier version that installed all primitives unconditionally, the new default (`minimal`) will REMOVE them. To preserve the old behaviour explicitly, pass `--profile=full` (currently <!-- count:PROFILE_FULL -->37<!-- /count:PROFILE_FULL --> primitives).
> **Re-install disclaimer:** `install.sh` is idempotent for clean state but **overwrites kit-owned `_blocks/`, `_primitives/`, `_bridges/`, `_templates/`, `_assembler/`, `hooks/`, and `skills/` on re-run** — local modifications under those directories are backed up to `<dir>.bak-TIMESTAMP/` (or, for shared hook files, to `<file>.bak-TIMESTAMP`). User-owned `_manifests/*.toml` are never overwritten.
## Runtime hook controls
Every kit-shipped hook (v0.15.1+) honours two env vars so you can silence noise or isolate a failure without editing `~/.claude/settings.json`:
Every kit-shipped hook (v0.14.2+) honours two env vars so you can silence noise or isolate a failure without editing `~/.claude/settings.json`:
- `KEI_DISABLED_HOOKS` — comma- or space-list of hook base names (no `.sh`), e.g. `KEI_DISABLED_HOOKS=site-wysiwyd-check,milestone-commit-hook`. Matching is **tokenized exact-match** (v0.15.1 fix — prior versions used substring-glob which let any value containing `all` disable every hook). The literal `all` token still disables every hook.
- `KEI_DISABLED_HOOKS` — comma- or space-list of hook base names (no `.sh`), e.g. `KEI_DISABLED_HOOKS=site-wysiwyd-check,milestone-commit-hook`. The literal `all` disables every hook.
- `KEI_HOOK_PROFILE` — one of `full` (default), `advisory-off`, `minimal`, `off`.
| Profile | What stays on |
|---|---|
| `full` (default) | Every hook |
| `advisory-off` | Disables pure-stderr advisories (`recurrence-suggest`, `citation-verify`, `error-spike-detector`, `milestone-commit-hook`). Safety gates stay on. |
| `minimal` | Only the four kit-shipped hooks that are either structural integrity (`no-hand-edit-agents`, `assemble-validate`) or observability-critical under RULE 0.12 / RULE 0.14 (`agent-fork-logger`, `session-end-dump`). Every other kit hook is off. User-global safety hooks such as `no-github-push`, `secrets-guard`, `genesis-leak-guard`, or `git-pre-commit-genesis` are not shipped by the kit but are respected when they are present in `~/.claude/hooks/`. |
| `minimal` | Only safety-critical: `no-github-push`, `genesis-leak-guard`, `no-hand-edit-agents`, `secrets-guard`, `assemble-validate`, `git-pre-commit-genesis`. Everything else off. |
| `off` | Every hook off — escape hatch for debugging hook interactions. |
```bash
@ -199,16 +143,16 @@ Interactive wizard: run `/hooks-control` — click-only picker that shows curren
| Category | Count | Examples |
|---|---:|---|
| Behavioral blocks | 77 | `baseline`, `evidence-grading`, `rule-math-first`, `stack-rust-axum`, `stack-react-vite`, `stack-sveltekit`, `stack-astro`, `deploy-modal`, `api-fal-ai`, ... |
| Generic agents (manifests) | 12 | `kei-code-implementer`, `kei-critic`, `kei-validator`, `kei-security-auditor`, `kei-architect`, `kei-researcher`, `kei-ml-implementer`, `kei-cost-guardian`, `kei-modal-runner`, ... |
| Hooks (PreToolUse / PostToolUse) | 9 | `assemble-agents`, `assemble-validate`, `no-hand-edit-agents`, `tomd-preread`, `agent-fork-logger`, `site-wysiwyd-check`, `session-end-dump`, `milestone-commit-hook`, `error-spike-detector` |
| Portable skills | 39 | `compose-solution`, `new-agent`, `new-project`, `site-create`, `schema-design`, `observability-setup`, `auth-setup`, `api-design`, `ci-scaffold`, `test-matrix`, `docs-scaffold`, `vm-provision`, ... |
| Primitives (Rust crates, opt-in) | 24 | `kei-ledger`, `kei-migrate`, `kei-changelog`, `ssh-check`, `firewall-diff`, `mock-render`, `visual-diff`, `tokens-sync`, `kei-memory`, `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`, `kei-store`, `kei-router`, `kei-sage`, `kei-task`, `kei-chat-store`, `kei-crossdomain`, `kei-search-core`, `kei-content-store`, `kei-social-store`, `kei-curator`, `kei-auth`, `kei-artifact` |
| Primitives (shell, opt-in via profile) | 13 | `tomd`, `design-scrape`, `live-preview`, `figma-tokens`, `frontend-inspect`, `screenshot-decode`, `metrics-scrape`, `log-ship`, `provision-hetzner`, `provision-vultr`, `harden-base`, `kei-ci-lint`, `kei-docs-scaffold` |
| Behavioral blocks | <!-- count:BLOCKS -->79<!-- /count:BLOCKS --> | `baseline`, `evidence-grading`, `rule-math-first`, `stack-rust-axum`, `stack-react-vite`, `stack-sveltekit`, `stack-astro`, `deploy-modal`, `api-fal-ai`, ... |
| Generic agents (manifests) | <!-- count:AGENTS -->12<!-- /count:AGENTS --> | `kei-code-implementer`, `kei-critic`, `kei-validator`, `kei-security-auditor`, `kei-architect`, `kei-researcher`, `kei-ml-implementer`, `kei-cost-guardian`, `kei-modal-runner`, ... |
| Hooks (PreToolUse / PostToolUse) | <!-- count:HOOKS -->9<!-- /count:HOOKS --> | `assemble-agents`, `assemble-validate`, `no-hand-edit-agents`, `tomd-preread`, `agent-fork-logger`, `site-wysiwyd-check`, `session-end-dump`, `milestone-commit-hook`, `error-spike-detector` |
| Portable skills | <!-- count:SKILLS -->39<!-- /count:SKILLS --> | `compose-solution`, `new-agent`, `new-project`, `site-create`, `schema-design`, `observability-setup`, `auth-setup`, `api-design`, `ci-scaffold`, `test-matrix`, `docs-scaffold`, `vm-provision`, ... |
| Primitives (Rust crates, opt-in) | <!-- count:RUST_CRATES -->24<!-- /count:RUST_CRATES --> | `kei-ledger`, `kei-migrate`, `kei-changelog`, `ssh-check`, `firewall-diff`, `mock-render`, `visual-diff`, `tokens-sync`, `kei-memory`, `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`, `kei-store`, `kei-router`, `kei-sage`, `kei-task`, `kei-chat-store`, `kei-crossdomain`, `kei-search-core`, `kei-content-store`, `kei-social-store`, `kei-curator`, `kei-auth` |
| Primitives (shell, opt-in via profile) | <!-- count:SHELL_PRIMITIVES -->13<!-- /count:SHELL_PRIMITIVES --> | `tomd`, `design-scrape`, `live-preview`, `figma-tokens`, `frontend-inspect`, `screenshot-decode`, `metrics-scrape`, `log-ship`, `provision-hetzner`, `provision-vultr`, `harden-base`, `kei-ci-lint`, `kei-docs-scaffold` |
| Shell helpers (always copied) | 3 | `kei-sleep-setup`, `kei-sleep-sync`, `kei-sleep-queue` (dormant until you run `/sleep-setup`) |
| Cross-tool bridges | 11 | Cursor legacy/MDC, Codex, Copilot, Windsurf, Junie, Continue, Gemini, Aider, Replit |
| Cross-tool bridges | <!-- count:BRIDGES -->11<!-- /count:BRIDGES --> | Cursor legacy/MDC, Codex, Copilot, Windsurf, Junie, Continue, Gemini, Aider, Replit |
Of the 77 blocks, the **8 base blocks** (`baseline`, `evidence-grading`, `memory-protocol`, `rule-pre-dev-gate`, `rule-test-first`, `rule-error-budget`, `rule-double-audit`, `rule-math-first`) are referenced directly by the 12 shipped manifests. The remaining blocks (`stack-*`, `deploy-*`, `api-*`, `scraper-*`, `domain-*`) are a library consumed by the `/new-agent` wizard and the hub-and-spoke pipeline skills: when you compose a project specialist or spin up a site, the wizard / pipeline picks the appropriate blocks and emits artefacts that reference them.
Of the <!-- count:BLOCKS -->79<!-- /count:BLOCKS --> blocks, the **8 base blocks** (`baseline`, `evidence-grading`, `memory-protocol`, `rule-pre-dev-gate`, `rule-test-first`, `rule-error-budget`, `rule-double-audit`, `rule-math-first`) are referenced directly by the <!-- count:AGENTS -->12<!-- /count:AGENTS --> shipped manifests. The remaining blocks (`stack-*`, `deploy-*`, `api-*`, `scraper-*`, `domain-*`) are a library consumed by the `/new-agent` wizard and the hub-and-spoke pipeline skills: when you compose a project specialist or spin up a site, the wizard / pipeline picks the appropriate blocks and emits artefacts that reference them.
**Cognitive mode blocks** (`_blocks/mode-*.md`) are composable behavioural skews — `mode-skeptic`, `mode-devils-advocate`, `mode-minimalist`, `mode-maximalist`, `mode-first-principles`. Add any combination to an agent's manifest `blocks = [...]` list to stack the mode. Modes compose: `mode-skeptic` + `mode-minimalist` gives you an adversarial pruner; `mode-devils-advocate` + `mode-first-principles` gives a constraint-driven steel-manner. See `_blocks/README.md` for the full list.
@ -339,7 +283,7 @@ Requires the new `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`,
## Primitives (Rust)
`_primitives/_rust/` is a Cargo workspace with 24 single-binary crates (v0.13.0 added 4 deep-sleep primitives; v0.14.0 added 10 LBM-port MCP crates; v0.14.2 removed `genesis-scan` — internal-only tool, not shipped publicly; v0.15.0 added `kei-artifact` for typed review-handoff). `install.sh` builds `--release` for the subset selected by the active profile and drops binaries at `~/.claude/agents/_primitives/_rust/target/release/<name>`.
`_primitives/_rust/` is a Cargo workspace with <!-- count:RUST_CRATES -->24<!-- /count:RUST_CRATES --> single-binary crates (v0.13.0 added 4 deep-sleep primitives; v0.14.0 added <!-- count:LBM_PORTS -->10<!-- /count:LBM_PORTS --> LBM-port MCP crates; v0.14.2 removed `genesis-scan` — internal-only tool, not shipped publicly). `install.sh` builds `--release` for the subset selected by the active profile and drops binaries at `~/.claude/agents/_primitives/_rust/target/release/<name>`.
| Crate | Purpose |
|---|---|
@ -356,7 +300,6 @@ Requires the new `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`,
| `kei-refactor-engine` | v0.13.0 — consumes `kei-conflict-scan` JSON; emits plan markdown + auto-resolve review markdown (NOT a unified diff; v0.14.1 retraction) |
| `kei-graph-check` | v0.13.0 — post-refactor wikilink + handoff + block-ref resolver gate |
| `kei-store` | v0.13.0 — memory-repo backend abstraction (GitHub / Forgejo / Gitea / Filesystem / S3) |
| `kei-artifact` | v0.15.0 — typed artifact handoff pipeline (schema-validated content pass-between agents) |
## Primitives (shell)
@ -391,7 +334,7 @@ Requires the new `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`,
Block edit (_blocks/<block>.md) <-- triggers rebuild of ALL agents
```
9 hooks enforce the pipeline (6 pipeline + 3 session-audit):
<!-- count:HOOKS -->9<!-- /count:HOOKS --> hooks enforce the pipeline (6 pipeline + 3 session-audit):
- **`assemble-agents`** (PostToolUse, Write/Edit) — rebuilds the affected agent(s) whenever a manifest or a block changes. No manual rebuild needed.
- **`assemble-validate`** (PreToolUse, Bash) — blocks `git commit` inside `~/.claude` if any manifest fails validation. Keeps the repo in a buildable state at all times.
@ -403,6 +346,17 @@ Requires the new `kei-conflict-scan`, `kei-refactor-engine`, `kei-graph-check`,
- **`milestone-commit-hook`** (PostToolUse, Bash) — RULE 0.14 self-audit: appends a one-line session summary to `~/.claude/memory/audit-backlog.md` on every `feat:`/`refactor:`/merge commit.
- **`error-spike-detector`** (PostToolUse, any tool) — RULE 0.14 self-audit: tags + logs the pattern when 3+ errors occur within the last 20 tool calls.
## Regenerating counts
Every number above (crates / skills / hooks / blocks / primitives / profile sizes) is wrapped in an HTML-comment marker — `<!-- count:NAME -->24<!-- /count:NAME -->` — and regenerated from sources of truth (`_primitives/MANIFEST.toml`, `_primitives/_rust/Cargo.toml`, filesystem walks). No more drift when a primitive or skill is added.
```bash
./scripts/regen-counts.sh # rewrite README.md in place
./scripts/regen-counts.sh --check # exit 1 if drift detected (no writes)
```
Pre-commit gate: `scripts/precommit-counts-check.sh` — wire it into your hook manager (or symlink into `.git/hooks/pre-commit`) to block commits when README counts drift from the sources.
## Adding custom blocks
Blocks are plain markdown in `~/.claude/agents/_blocks/`. To add one:
@ -438,7 +392,7 @@ All kit agents are namespaced under `kei-*` so they won't collide with your own
## Cross-tool bridges
KeiSeiKit ships 11 verified tool-bridge templates under `_bridges/`. Render them into any project and the same Constructor-Pattern ruleset is visible to every AI coding tool you use — no drift, one source of truth.
KeiSeiKit ships <!-- count:BRIDGES -->11<!-- /count:BRIDGES --> verified tool-bridge templates under `_bridges/`. Render them into any project and the same Constructor-Pattern ruleset is visible to every AI coding tool you use — no drift, one source of truth.
**Tools covered:**
@ -457,8 +411,8 @@ KeiSeiKit ships 11 verified tool-bridge templates under `_bridges/`. Render them
**Three ways to generate:**
1. **At install time**`./install.sh --with-bridges` renders all 11 into `$PWD` after the normal install completes. Skipped if `$PWD` is the KeiSeiKit repo itself.
2. **From the `/new-agent` wizard** — Phase 8 asks click-only whether to generate all 11, just `AGENTS.md`, or skip.
1. **At install time**`./install.sh --with-bridges` renders all <!-- count:BRIDGES -->11<!-- /count:BRIDGES --> into `$PWD` after the normal install completes. Skipped if `$PWD` is the KeiSeiKit repo itself.
2. **From the `/new-agent` wizard** — Phase 8 asks click-only whether to generate all <!-- count:BRIDGES -->11<!-- /count:BRIDGES -->, just `AGENTS.md`, or skip.
3. **Manually, any time**`~/.claude/agents/_bridges/emit.sh <project-dir>` (the install copies `_bridges/` into your agent fleet dir). Add `--only <output-path>` to restrict to a single file.
All paths are idempotent: existing bridge files in the project are skipped, never overwritten. See `_bridges/README.md` for the full template→output-path table.

View file

@ -0,0 +1,26 @@
#!/bin/sh
# precommit-counts-check.sh — pre-commit gate for README count drift.
# Runs scripts/regen-counts.sh --check; exits non-zero on drift.
# Install: ln -s ../../scripts/precommit-counts-check.sh .git/hooks/pre-commit
# or add to your hook manager of choice.
set -eu
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
REGEN="$ROOT/scripts/regen-counts.sh"
[ -x "$REGEN" ] || {
printf 'precommit-counts-check: %s not executable\n' "$REGEN" >&2
exit 2
}
if "$REGEN" --check; then
exit 0
fi
cat >&2 <<'EOF'
Counts drift detected in README.md.
Run: ./scripts/regen-counts.sh && git add README.md
EOF
exit 1

117
scripts/regen-counts.sh Executable file
View file

@ -0,0 +1,117 @@
#!/bin/sh
# regen-counts.sh — regenerate README.md counts from sources of truth.
# Markers: <!-- count:NAME -->VAL<!-- /count:NAME -->
# Sources: _primitives/MANIFEST.toml, _primitives/_rust/Cargo.toml, filesystem.
# Usage: ./scripts/regen-counts.sh [--check]
# POSIX sh; no arrays, no bashisms; no yq/jq/python hard deps.
set -eu
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
README="$ROOT/README.md"
MANIFEST="$ROOT/_primitives/MANIFEST.toml"
CARGO="$ROOT/_primitives/_rust/Cargo.toml"
die() { printf 'regen-counts: %s\n' "$*" >&2; exit 2; }
count_rust_crates() {
awk '
/^\[workspace\]/ { in_ws=1; next }
/^\[/ { in_ws=0 }
in_ws && /members *= *\[/ { in_arr=1 }
in_arr { total += gsub(/"[^"]+"/, "&"); if (index($0, "]")) in_arr=0 }
END { print total+0 }
' "$CARGO"
}
count_primitive_kind() {
awk -v want="$1" '
/^\[primitive\./ { in_block=1; next }
/^\[/ { in_block=0 }
in_block && $0 ~ "^kind *= *\"" want "\"" { n++; in_block=0 }
END { print n+0 }
' "$MANIFEST"
}
count_profile() {
awk -v key="$1" '
/^\[profile\]/ { in_p=1; next }
/^\[/ { in_p=0 }
in_p && $1 == key && $2 == "=" {
line=$0; sub(/^[^\[]*\[/, "", line); sub(/\].*$/, "", line)
print gsub(/"[^"]+"/, "&", line) + 0; exit
}
' "$MANIFEST"
}
count_files() { eval "$1" | wc -l | tr -d ' '; }
RUST_CRATES=$(count_rust_crates)
RUST_PRIMITIVES=$(count_primitive_kind rust)
SHELL_PRIMITIVES=$(count_primitive_kind shell)
TOTAL_PRIMITIVES=$((RUST_PRIMITIVES + SHELL_PRIMITIVES))
SKILLS=$(count_files "find '$ROOT/skills' -maxdepth 2 -name SKILL.md")
HOOKS=$(count_files "find '$ROOT/hooks' -maxdepth 1 -name '*.sh'")
BLOCKS=$(count_files "find '$ROOT/_blocks' -maxdepth 1 -name '*.md' -not -name README.md")
AGENTS=$(count_files "find '$ROOT/_manifests' -maxdepth 1 -name 'kei-*.toml'")
BRIDGES=$(count_files "find '$ROOT/_bridges' -maxdepth 1 \( -name '*.tmpl' -o -name '*.mdc' \)")
PROFILE_FULL=$(count_profile full)
PROFILE_MCP=$(count_profile mcp)
PROFILE_DEV=$(count_profile dev)
PROFILE_OPS=$(count_profile ops)
PROFILE_FRONTEND=$(count_profile frontend)
PROFILE_CORE=$(count_profile core)
LBM_PORTS=10 # hand-maintained: v0.14 LBM port semantic group
[ "$RUST_CRATES" = "$RUST_PRIMITIVES" ] || \
printf 'regen-counts: WARN Cargo members (%s) != MANIFEST rust kind (%s)\n' \
"$RUST_CRATES" "$RUST_PRIMITIVES" >&2
apply_markers() {
awk \
-v m_rc="$RUST_CRATES" -v m_rp="$RUST_PRIMITIVES" \
-v m_sp="$SHELL_PRIMITIVES" -v m_tp="$TOTAL_PRIMITIVES" \
-v m_sk="$SKILLS" -v m_hk="$HOOKS" \
-v m_bl="$BLOCKS" -v m_ag="$AGENTS" \
-v m_br="$BRIDGES" \
-v m_pf="$PROFILE_FULL" -v m_pm="$PROFILE_MCP" \
-v m_pd="$PROFILE_DEV" -v m_po="$PROFILE_OPS" \
-v m_pr="$PROFILE_FRONTEND" -v m_pc="$PROFILE_CORE" \
-v m_lb="$LBM_PORTS" '
function sub_marker(name, val, re) {
re = "<!-- count:" name " -->[^<]*<!-- /count:" name " -->"
gsub(re, "<!-- count:" name " -->" val "<!-- /count:" name " -->")
}
{
sub_marker("RUST_CRATES", m_rc); sub_marker("RUST_PRIMITIVES", m_rp)
sub_marker("SHELL_PRIMITIVES", m_sp); sub_marker("TOTAL_PRIMITIVES", m_tp)
sub_marker("SKILLS", m_sk); sub_marker("HOOKS", m_hk)
sub_marker("BLOCKS", m_bl); sub_marker("AGENTS", m_ag)
sub_marker("BRIDGES", m_br); sub_marker("PROFILE_FULL", m_pf)
sub_marker("PROFILE_MCP", m_pm); sub_marker("PROFILE_DEV", m_pd)
sub_marker("PROFILE_OPS", m_po); sub_marker("PROFILE_FRONTEND", m_pr)
sub_marker("PROFILE_CORE", m_pc); sub_marker("LBM_PORTS", m_lb)
print
}
'
}
mode="${1:-write}"
[ -f "$README" ] || die "README.md not found at $README"
tmp=$(mktemp -t regen-counts.XXXXXX) || die "mktemp failed"
trap 'rm -f "$tmp"' EXIT INT TERM
apply_markers <"$README" >"$tmp"
if [ "$mode" = "--check" ]; then
if cmp -s "$README" "$tmp"; then
echo "regen-counts: no drift"; exit 0
fi
echo "regen-counts: DRIFT DETECTED" >&2
diff -u "$README" "$tmp" >&2 || true
exit 1
fi
cp "$tmp" "$README"
printf 'regen-counts: README updated (crates=%s skills=%s hooks=%s blocks=%s prims=%s)\n' \
"$RUST_CRATES" "$SKILLS" "$HOOKS" "$BLOCKS" "$TOTAL_PRIMITIVES"