# cc-thingz

[![CI](https://github.com/alexei-led/cc-thingz/actions/workflows/ci.yml/badge.svg)](https://github.com/alexei-led/cc-thingz/actions/workflows/ci.yml)
[![GitHub tag](https://img.shields.io/github/v/tag/alexei-led/cc-thingz?label=version&sort=semver)](https://github.com/alexei-led/cc-thingz/tags)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Claude Code](https://img.shields.io/badge/Claude_Code-plugin_marketplace-blueviolet)](https://docs.anthropic.com/en/docs/claude-code)
[![AGENTS.md](https://img.shields.io/badge/AGENTS.md-standard-000000)](https://agents.md)
[![Codex CLI](https://img.shields.io/badge/Codex_CLI-skill_export-10A37F)](https://developers.openai.com/codex/plugins)
[![Gemini CLI](https://img.shields.io/badge/Gemini_CLI-skill_export-4285F4)](https://geminicli.com/docs/extensions)
[![Plugins](https://img.shields.io/badge/plugins-9-green)](src/plugins/)
[![Skills](https://img.shields.io/badge/skills-43-green)](src/plugins/)

A multi-agent skill suite for **Claude Code**, **Codex CLI**, **Gemini CLI**, and **Pi** — 43 skills, 3 agents, and 9 hooks. One source of truth in `src/`, compiled to platform-optimized output for each tool. Supports [AGENTS.md](https://agents.md)-compatible tools too. Built over 6+ months of daily use and continuous refinement.

## Why This Exists

AI coding tools are powerful out of the box, but specialized workflows need specialized prompts. After months of iterating on skills, agents, and hooks across Go, Python, TypeScript, infrastructure, and planning workflows, these plugins encode hard-won patterns:

- **Code review** with parallel multi-agent review and sequential lint-and-check workflows
- **Smart hooks** that auto-suggest skills, lint after edits, protect secrets, and run tests (Claude Code)
- **Spec-driven development** with structured requirements, tasks, and a CLI for project management
- **Infrastructure ops** with validated K8s, Terraform, and Helm deployments
- **Developer utilities** including worktree isolation, AST-first codebase search, web research, and brainstorming

Every skill has been manually crafted and refined through real-world use — not generated boilerplate.

## Installation

> Each section below assumes the corresponding CLI is already installed and on
> `PATH`. If you don't have the CLI yet, install it first
> ([Claude Code](https://docs.anthropic.com/en/docs/claude-code/quickstart),
> [Codex CLI](https://github.com/openai/codex),
> [Gemini CLI](https://github.com/google-gemini/gemini-cli),
> [Pi](https://pi.dev/docs/latest/quickstart)).
> All targets consume artifacts from `dist/<target>/`, which is regenerated
> from `src/` by `make build`.

### Claude Code

```bash
/plugin marketplace add alexei-led/cc-thingz
# then install any plugin(s) you want:
/plugin install dev-flow@cc-thingz
/plugin install dev-tools@cc-thingz
/plugin install go-dev@cc-thingz
# ... repeat for py-dev, ts-dev, web-dev, infra-ops, spec-dev, test-e2e
```

Use `--scope project` to install into `.claude/settings.json` for team sharing.

`dev-flow` wires five hooks automatically on install:

| Event              | Matcher       | Hook                | Effect                                   |
| ------------------ | ------------- | ------------------- | ---------------------------------------- |
| `SessionStart`     | —             | `session-start.py`  | Prints branch, last commit, project type |
| `UserPromptSubmit` | —             | `skill-enforcer.sh` | Suggests relevant skills from prompt     |
| `PreToolUse`       | `Write\|Edit` | `file-protector.py` | Blocks writes to `.env`, keys, secrets   |
| `PostToolUse`      | `Write\|Edit` | `smart-lint.sh`     | Runs formatter/linter on changed files   |
| `Notification`     | —             | `notify.sh`         | macOS notification (Kitty + tmux focus)  |

### OpenAI Codex CLI

```bash
git clone https://github.com/alexei-led/cc-thingz.git ~/src/cc-thingz
cd ~/src/cc-thingz
make build   # generates dist/codex/plugins/ from src/
codex
# inside Codex: /plugins  → install plugins from this local marketplace
```

The marketplace manifest lives at `.agents/plugins/marketplace.json` and
points each plugin source at `./dist/codex/plugins/<plugin>/`, generated by
`make build`. To use skills without the plugin marketplace, point Codex at a
per-plugin skill directory directly:

```jsonc
// ~/.codex/config.json (excerpt)
{
  "skills": ["~/src/cc-thingz/dist/codex/plugins/dev-flow/skills"],
}
```

`dev-flow` wires five hooks via `dist/codex/plugins/dev-flow/hooks/hooks.json`:

| Event          | Matcher         | Hook                | Effect                                   |
| -------------- | --------------- | ------------------- | ---------------------------------------- |
| `SessionStart` | —               | `session-start.py`  | Prints branch, last commit, project type |
| `PreToolUse`   | `^apply_patch$` | `file-protector.py` | Blocks writes to `.env`, keys, secrets   |
| `PreToolUse`   | `^Bash$`        | `git-guardrails.sh` | Blocks destructive git commands          |
| `PostToolUse`  | `^apply_patch$` | `smart-lint.sh`     | Auto-format and lint edited files        |
| `Stop`         | —               | `test-runner.sh`    | Runs focused tests for edited files      |

Plugin hooks require two feature flags in `~/.codex/config.toml`:

```toml
[features]
hooks = true          # enable user-defined hooks
plugin_hooks = true   # enable plugin-bundled hooks (under development)
```

After enabling and restarting Codex, run `/hooks` to review and approve
the hooks before they execute. Codex fingerprints each hook command;
any change to name or command triggers a re-approval prompt.

### Google Gemini CLI

```bash
gemini extensions install https://github.com/alexei-led/cc-thingz
```

For local development, link the checkout instead of copying it:

```bash
gemini extensions link /path/to/cc-thingz
```

Gemini reads `gemini-extension.json` at the repo root, loads context from
`AGENTS.md` (auto-generated; shared with Codex and other AGENTS.md-aware
tools), and discovers skills, agents, and hooks by scanning extension-root
subdirectories by hard-coded name. Root-level `skills/`, `agents/`, and
`hooks/` symlinks point into `dist/gemini/` so Gemini finds them; the
compiler regenerates these symlinks on every `make build`.

`dist/gemini/hooks/hooks.json` registers:

| Event          | Matcher               | Hook                | Effect                                   |
| -------------- | --------------------- | ------------------- | ---------------------------------------- |
| `SessionStart` | —                     | `session-start.py`  | Prints branch, last commit, project type |
| `BeforeAgent`  | —                     | `skill-enforcer.sh` | Suggests relevant skills from prompt     |
| `BeforeTool`   | `write_file\|replace` | `file-protector.py` | Blocks writes to `.env`, keys, secrets   |
| `BeforeTool`   | `run_shell_command`   | `git-guardrails.sh` | Blocks destructive git commands          |
| `AfterTool`    | `write_file\|replace` | `smart-lint.sh`     | Auto-format and lint edited files        |
| `AfterAgent`   | —                     | `test-runner.sh`    | Runs focused tests for edited files      |
| `Notification` | —                     | `notify.sh`         | macOS notification on agent completion   |

All paths resolve via `${extensionPath}`, Gemini's substitution variable for
the extension root.

### Pi

Pi uses generated skills, agents, **and TypeScript extensions** that mirror
Claude-Code-native features (plan mode, todos, AskUserQuestion, subagents,
file/path protection, post-edit lint, completion notifications).

**Required prerequisite** — install the subagent runtime once:

```bash
pi install npm:@tintinweb/pi-subagents
```

**Install extensions and skills** — one command installs skills and extensions
and clones the repo under `~/.pi/agent/git/`:

```bash
pi install git:github.com/alexei-led/cc-thingz
```

For local development (build first, then install from the checkout):

```bash
git clone https://github.com/alexei-led/cc-thingz.git ~/src/cc-thingz
cd ~/src/cc-thingz && make build
pi install "$(pwd)"
```

**Install agents** — Pi's subagent runtime (`@tintinweb/pi-subagents`) loads
agents from `~/.pi/agent/agents/`. After `pi install`, the repo is already at
`~/.pi/agent/git/github.com/alexei-led/cc-thingz` — symlink the agent tree
from there:

```bash
ln -snf \
  ~/.pi/agent/git/github.com/alexei-led/cc-thingz/dist/pi/agents \
  ~/.pi/agent/agents
```

`ln -snf` replaces an existing symlink but will not overwrite a real directory
— move it aside first (`mv ~/.pi/agent/agents ~/.pi/agent/agents.bak`).
Override the agent dir with `PI_CODING_AGENT_DIR=<DIR>` if you run Pi from a
non-default location. Restart Pi or run `/reload` after installing.

**Advisor subagent (`advisor`)** — follows the standard source layout used by
other Pi agents:

- `src/agents/advisor/AGENT.md`
- `src/agents/advisor/pi/frontmatter.yaml`

Compiled output is `dist/pi/agents/advisor.md`. Behavior: strategic review with
read-only code exploration (no file edits) and output sections `Verdict`,
`Top Risks`, and `Next Actions`.

Background usage (separate context + parent context inherited):

```ts
const run = Agent({
  subagent_type: "advisor",
  description: "Architecture risk review",
  prompt: "Review my plan and propose the safest next steps.",
  inherit_context: true,
  run_in_background: true,
});

get_subagent_result({ agent_id: run.agent_id, wait: true });
```

Foreground usage:

```ts
Agent({
  subagent_type: "advisor",
  description: "Blocking strategy check",
  prompt: "Challenge this implementation plan and suggest corrections.",
  inherit_context: true,
  run_in_background: false,
});
```

**Bundled Pi extensions** (`dist/pi/extensions/`):

| Extension              | Role                                                                                             |
| ---------------------- | ------------------------------------------------------------------------------------------------ |
| `ask-user-question.ts` | `ask_user_question` tool with structured options UI                                              |
| `permission-gate.ts`   | Confirms dangerous bash commands (rm -rf, sudo, chmod 777)                                       |
| `protected-paths.ts`   | Blocks writes to `.env`, `.git/`, `node_modules/`                                                |
| `plan-mode/`           | `/plan` toggle for read-only exploration and step tracking                                       |
| `todo.ts`              | `todo` tool + `/todos` command, branch-aware state                                               |
| `subagent/`            | Spawns isolated `pi` processes (single, parallel, chain)                                         |
| `structured-output.ts` | `structured_output` tool that terminates the agent loop                                          |
| `notify.ts`            | macOS notification via `terminal-notifier` on completion (requires Homebrew `terminal-notifier`) |

**Pi gets**: all 3 agents — `engineer`, `reviewer`, `advisor` (requires
`@tintinweb/pi-subagents`) — all 43 skills, and 8 bundled extensions. Each
agent has a Pi-specific frontmatter overlay tuned for OpenAI Codex models
(`openai-codex/gpt-5.5`), thinking levels, tool restrictions, and turn limits.
`advisor` ships to Codex, Gemini, and Pi; Claude is excluded because it has a
built-in advisor. The old scout→planner→worker→reviewer pipeline is superseded
by the 3-role model.

### Other AGENTS.md-Compatible Tools

The `AGENTS.md` at the repo root provides a skill catalog readable by any tool supporting the [AGENTS.md standard](https://agents.md) (GitHub Copilot, Cursor, Windsurf, Devin, and others).

## Prerequisites

Structural code search uses [ast-grep](https://ast-grep.github.io/) when installed. Skills fall back to `rg`/`fd`, but AST-aware search is the fast path for code shape queries:

```bash
brew install ast-grep
npm install -g @ast-grep/cli
cargo install ast-grep
```

Portable docs lookup uses the [Context7 CLI](https://github.com/upstash/context7):

```bash
npm install -g ctx7@latest
# or with Bun:
bun add -g ctx7@latest

# one-shot (no global install):
npx ctx7@latest docs /facebook/react "React hooks"
# or with Bun:
bunx ctx7@latest docs /facebook/react "React hooks"
```

Claude Code agents can also use optional MCP servers for enhanced capabilities.
These are optional — plugins degrade gracefully without them. Pi exports do not
assume MCP tools.

| MCP Server                                                   | Purpose                                     | Used By                                                             |
| ------------------------------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------- |
| [DeepWiki](https://cognition.ai/blog/deepwiki-mcp-server)    | AI-generated wiki for public GitHub repos   | Claude Code dev-tools                                               |
| [Perplexity](https://github.com/ppl-ai/modelcontextprotocol) | Web research and technical comparisons      | Claude Code dev-flow, dev-tools, infra-ops                          |
| [MorphLLM](https://github.com/morphllm/morph-claude-code)    | Fast codebase search and batch file editing | Claude Code `engineer` role via dev-flow, language, infra, spec-dev |

> Stepwise reasoning previously came from the
> [Sequential Thinking MCP](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking).
> It now ships as the [`sequential-thinking` skill](src/skills/sequential-thinking/SKILL.md) — no MCP install required and portable across Claude Code, Codex, Gemini, and Pi.

### Claude-Mem Integration

All agents and several skills optionally integrate with [claude-mem](https://github.com/thedotmack/claude-mem) for cross-session memory and AST-based code navigation. Install with:

```bash
/plugin marketplace add thedotmack/claude-mem
/plugin install claude-mem@thedotmack
```

**What this enables:**

| Capability                    | Tools Used                                      | Benefit                                            |
| ----------------------------- | ----------------------------------------------- | -------------------------------------------------- |
| AST code navigation           | `smart_search`, `smart_outline`, `smart_unfold` | 10-20x fewer tokens than reading full files        |
| Cross-session memory          | `search`, `get_observations`, `timeline`        | Find past decisions, known gotchas, recurring bugs |
| Historical context in reviews | `search` + `get_observations`                   | Review agents check past findings before starting  |

**Graceful degradation**: All plugins work without claude-mem. When it's not installed, MCP tools are silently absent — agents fall back to local tools. Search skills use ast-grep when installed, then `rg`/`fd`, then platform Read/Grep/Glob where needed. No errors, no configuration needed.

**How it works**: Agent frontmatter lists claude-mem MCP tools alongside standard tools. Claude Code silently omits unavailable tools at runtime, so agents always have their core tools (Read, Grep, Glob, LSP) and gain smart_explore/memory tools when claude-mem is present. Skill instructions use "when available" / "if claude-mem available" phrasing to guide Claude's behavior.

## Plugins

| Plugin                                             | Skills | Agents | Description                                                                       |
| -------------------------------------------------- | ------ | ------ | --------------------------------------------------------------------------------- |
| [**dev-flow**](src/plugins/dev-flow/plugin.yaml)   | 10     | 2      | Fix, refactor, review, document, commit; `engineer` and `reviewer` roles; 7 hooks |
| [**go-dev**](src/plugins/go-dev/plugin.yaml)       | 1      | 1      | Idiomatic Go development with stdlib-first patterns, testing, and CLI tooling     |
| [**py-dev**](src/plugins/py-dev/plugin.yaml)       | 1      | 1      | Python 3.12+ development with uv/ruff/pyright toolchain                           |
| [**ts-dev**](src/plugins/ts-dev/plugin.yaml)       | 1      | 1      | TypeScript with strict typing, React patterns, and modern tooling                 |
| [**web-dev**](src/plugins/web-dev/plugin.yaml)     | 1      | 1      | Web frontend with vanilla HTML, CSS, JavaScript, and HTMX                         |
| [**infra-ops**](src/plugins/infra-ops/plugin.yaml) | 3      | 1      | Kubernetes, Terraform, Helm, GitHub Actions, AWS, GCP                             |
| [**dev-tools**](src/plugins/dev-tools/plugin.yaml) | 17     | 1      | Modern CLI, AST-first search, git worktrees, docs lookup, research, config review |
| [**spec-dev**](src/plugins/spec-dev/plugin.yaml)   | 7      | 2      | Spec-driven development: requirements, tasks, and planning workflows              |
| [**test-e2e**](src/plugins/test-e2e/plugin.yaml)   | 2      | 1      | E2E testing with Playwright: browser automation and test generation               |

**Totals**: 43 skills, 2 plugin-owned role agents (`engineer`, `reviewer`), 9 hooks

## Skills

Skills teach the AI model domain-specific knowledge and workflows. All skills are authored in cc-thingz and exported with platform-optimized instructions for Codex CLI, Gemini CLI, Pi, and [AGENTS.md](https://agents.md)-compatible tools. On Claude Code, the `skill-enforcer` hook auto-suggests relevant skills based on your prompt.

### User-Invocable

Invoke as `/skill-name` or let the skill enforcer suggest them.

| Skill                             | What It Does                                                          | Example Trigger                          |
| --------------------------------- | --------------------------------------------------------------------- | ---------------------------------------- |
| `brainstorming-ideas`             | Brainstorm ideas and stress-test draft plans                          | "brainstorm", "design feature"           |
| `improving-codebase-architecture` | Find deepening opportunities, module/seam vocab                       | "improve architecture", "deepen modules" |
| `committing-code`                 | Smart git commits with logical grouping                               | "commit", "save changes"                 |
| `debating-ideas`                  | Dialectic agents stress-test design decisions                         | "debate", "pros and cons"                |
| `deploying-infra`                 | Validate + deploy K8s/Terraform/Helm                                  | "deploy to staging", "rollout"           |
| `documenting-code`                | Update docs based on recent changes                                   | "update docs", "document"                |
| `evolving-config`                 | Audit config against latest Claude Code features                      | "evolve", "audit config"                 |
| `exploring-repos`                 | Explore public GitHub repos and architecture                          | "explore repo", "how does repo work"     |
| `fixing-code`                     | Parallel agents fix all issues, zero tolerance                        | "fix errors", "make it pass"             |
| `improving-tests`                 | Refactor tests: combine to tabular, fill gaps                         | "improve tests", "coverage"              |
| `context7-cli`                    | Current library docs via ctx7 CLI; docs/API lookup                    | "ctx7", "look up docs", "API ref"        |
| `looking-up-docs`                 | Find current docs via fallback chain: ctx7 → Perplexity → web tools   | "find docs", "latest API", "look up"     |
| `mem-history`                     | Query project history and prior decisions                             | "last session", "what happened"          |
| `researching-web`                 | Web research via Perplexity AI                                        | "research", "X vs Y"                     |
| `reviewing-code`                  | Multi-agent review (security, quality, idioms)                        | "review code", "check this"              |
| `testing-e2e`                     | Playwright browser automation and test gen                            | "e2e test", "playwright"                 |
| `analyzing-usage`                 | Analyze AI agent usage, cost, and efficiency (Claude Code, Codex, Pi) | "usage", "cost", "spending"              |
| `learning-patterns`               | Extract learnings and generate customizations                         | "learn", "extract learnings"             |
| `reviewing-instructions`          | Review and score AI agent/skill instructions (8-dimension quality)    | "lint instructions", "audit prompts"     |
| `reviewing-cc-config`             | Review CC config for context efficiency                               | "review config", "config review"         |
| `using-git-worktrees`             | Isolated git worktrees for parallel development                       | "worktree", "isolate"                    |

### Auto-Activated

These activate silently when relevant patterns are detected — no `/skill-name` needed.

| Skill                | Activates When                                 |
| -------------------- | ---------------------------------------------- |
| `managing-infra`     | K8s resources, Terraform, Helm, GitHub Actions |
| `playwright-skill`   | Runtime library for testing-e2e skill          |
| `refactoring-code`   | Multi-file batch changes, rename everywhere    |
| `searching-code`     | AST-first search, trace flow, find all uses    |
| `smart-explore`      | Token-efficient known-file/symbol extraction   |
| `using-cloud-cli`    | bq queries, gcloud/aws commands                |
| `using-modern-cli`   | ast-grep, rg, fd, bat, eza, sd over legacy CLI |
| `writing-go`         | Go files, go commands, Go-specific terms       |
| `writing-python`     | Python files, pytest, pip, frameworks          |
| `writing-typescript` | TS/TSX files, npm/bun, React, Node.js          |
| `writing-web`        | HTML/CSS/JS/HTMX templates                     |

## Agents

Three role agents: a capability envelope plus a reasoning stance no skill can supply. Consolidated from 39 → 3 — see `docs/agent-audit-2026-05-16.md` and the executed plan in `docs/plans/completed/`. Domain procedure and output format live in skills; language specifics live in each skill's `references/<lang>.md`. Role × skill × references compose — language is not a routing key. Envelope enforcement is per-target: Claude and Gemini grant a hard `tools:` allowlist (Gemini via its subagent frontmatter `tools:` field); Codex blocks writes via `sandbox_mode: read-only`; Pi has no tool-allowlist primitive, so the envelope there is a system-prompt directive. Gemini frontmatter has no read-only sandbox primitive, so `advisor` is granted `run_shell_command` and held read-only by its body directive, the same tradeoff as Pi.

| Role       | Envelope                         | Stance                                                           | Claude model        | Pi model                |
| ---------- | -------------------------------- | ---------------------------------------------------------------- | ------------------- | ----------------------- |
| `engineer` | Read + write + execute           | Sole mutator: applies changes, runs the build/test/lint gate     | sonnet              | gpt-5.4 thinking:high   |
| `reviewer` | Read, Grep, Glob, LS — no writes | Adversarial evaluator: emits findings/proposals, applies nothing | sonnet              | gpt-5.4 thinking:medium |
| `advisor`  | Read + read-only Bash            | Strategic escalation: verdict, ranked risks, next actions        | built-in (Opus 4.7) | gpt-5.5 thinking:xhigh  |

`engineer` is the fork target for `writing-{go,python,typescript,web}` and `managing-infra`. `reviewer` absorbs the review family, code search, and planning (via `spec`). `advisor` ships to Codex, Gemini, and Pi; Claude is excluded because it has a built-in advisor. On Pi, `advisor` is invoked via transcript forwarding; on Gemini and Codex it is spawned as a normal custom subagent under its tool/sandbox envelope.

Model tiers are matched per role across vendors. `engineer`/`reviewer` use Claude `sonnet`; their Pi counterparts pin `gpt-5.4` (not `gpt-5.5`) because GPT-5.5 is a frontier tier above Sonnet 4.6 — using it for the same role would make the Pi agent materially stronger and ~2× costlier for no parity reason. `advisor` is an escalation role: Claude's built-in advisor runs Opus 4.7 (frontier), so the Pi advisor stays at `gpt-5.5 thinking:xhigh` to match that tier. On Codex, the agent inherits the model chosen at `codex` launch, so there is no model to pin without brittleness.

Pi model names use the `openai-codex/` provider prefix (e.g. `openai-codex/gpt-5.4`) to avoid ambiguous fuzzy matching when multiple providers expose the same model ID.

## Hooks

| Hook                 | Event            | What It Does                                |
| -------------------- | ---------------- | ------------------------------------------- |
| `session-start.sh`   | SessionStart     | Shows git branch, last commit, file context |
| `skill-enforcer.sh`  | UserPromptSubmit | Pattern-matches prompt and suggests skills  |
| `file-protector.py`  | PreToolUse       | Blocks edits to settings.json, secrets      |
| `git-guardrails.sh`  | PreToolUse       | Blocks destructive git commands             |
| `smart-lint.sh`      | PostToolUse      | Auto-runs focused lint after file edits     |
| `test-runner.sh`     | Stop             | Auto-runs focused tests after agent turns   |
| `notify.sh`          | Notification     | Desktop notifications for long operations   |
| `worktree-create.sh` | WorktreeCreate   | Sets up isolated git worktree environment   |
| `worktree-remove.sh` | WorktreeRemove   | Cleans up worktree on exit                  |

### Hook Prerequisites

`smart-lint.sh` and `test-runner.sh` auto-detect project type and prefer focused tools. Missing optional tools warn or fall through; tool failures block.

#### Focused path

`smart-lint.sh` runs after edits. It reads hook stdin first, records the edited file set, then formats and lints only matching files. If hook input lacks paths, it falls back to git diff only when the changed-file count is at or below `SMART_LINT_DIFF_FALLBACK_LIMIT` (default: 5).

`test-runner.sh` runs at agent-finish time (`Stop` for Claude/Codex/Pi, `AfterAgent` for Gemini). It uses the edited-file state recorded by `smart-lint.sh`, then falls back to git diff. Full project tests require `TEST_RUNNER_FULL=1`.

Focused checks matter. Project-wide scripts are slower, burn context, and often produce unrelated failures. Keep package and Makefile fallbacks as safety nets, not the normal path. Smart-lint tracks formatting and linting separately: a focused formatter does not suppress a project-level lint fallback.

#### Tool order

| Ecosystem       | Format / lint path                                                   | Test path                                                                      |
| --------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Python          | `ruff` format once, `ruff check --fix`; `black` / `flake8` fallback  | matching `test_*.py` / `*_test.py` via `pytest -q --maxfail=1 --tb=short`      |
| Pyright         | `pyright --outputjson`; `reportMissingImports` filtered structurally | —                                                                              |
| JavaScript / TS | local/global `prettier --write`, local/global `eslint --fix`         | Vitest `related <sources> --run`, Jest `--findRelatedTests`, direct test files |
| Bun             | package-script fallback via `bun run <script>` when selected by lock | `bun test <tests>` or package-script fallback                                  |
| Go              | `gofmt -w`, package-scoped `golangci-lint --fix` / `go vet`          | `go test -failfast ./changed/pkg`                                              |
| Shell / Bash    | `shfmt -w`, `shellcheck`                                             | matching `.bats` files                                                         |
| Package scripts | last fallback for missing side: `fmt` / `format`, then `lint`        | last fallback: `test`, `tests`, `check`, `verify` scripts                      |
| Makefile        | last fallback for missing side: root `fmt`, then `lint`              | last fallback: nearest non-root `test`, `tests`, `check`, `verify` target      |

Package-script selection: `yarn.lock` → `yarn run`, `bun.lock` / `bun.lockb` → `bun run`, otherwise `npm run --silent` when npm is available. npm and Yarn run package scripts and expose local binaries on the script PATH; Bun `run` can run package scripts and local executables.

Fallbacks fill gaps only. If focused formatting ran but no focused linter ran, smart-lint may still run project `lint`. If focused linting ran, it skips project `lint`. `TEST_RUNNER_FULL=1` is the explicit project-level test path: root Makefile target first, then Go/Python project runners, then package scripts by the same yarn/bun/npm selection.

#### Fallback controls

| Control                      | Effect                                                     |
| ---------------------------- | ---------------------------------------------------------- |
| `SKIP_LINT=1` or `.nolint`   | skip smart-lint completely                                 |
| `SKIP_TESTS=1` or `.notests` | skip test-runner completely                                |
| `HOOK_PROJECT_FALLBACK=0`    | disable package-script and Makefile fallbacks              |
| `.nohooks-project`           | repo-local file form of `HOOK_PROJECT_FALLBACK=0`          |
| `TEST_RUNNER_FULL=1`         | run one project-level test target instead of focused tests |

#### Output and exit codes

Hooks write concise diagnostics to stderr for agent consumption.

- Exit `0`: checks passed, skipped, or no relevant focused target found.
- Exit `2`: blocking lint/test failure. Agents should fix the shown issue before retrying.
- Compact output keeps the first relevant lines and truncates long logs. This preserves context budget and makes the failing file, line, and command visible.
- Formatters run once. Post-format “check” passes are avoided in the interactive path to stop formatter/linter ping-pong.

Recommended installs for tools that don't ship with their language runtime:

```bash
# Python
brew install uv           # manages interpreter + venv + lockfile
brew install ruff         # linter + formatter, replaces flake8 + black

# JavaScript / TypeScript
brew install bun          # runtime + test runner + package manager

# Go
go install gotest.tools/gotestsum@latest   # cleaner output than go test
brew install golangci-lint

# Shell
brew install bats-core    # Bash Automated Testing System
brew install shellcheck shfmt

# macOS notifications (used by notify.sh)
brew install terminal-notifier
```

## Skill Export Architecture

One source of truth (`src/`) compiles into per-target trees (`dist/<target>/`).
The compiler is `scripts/build/compile.py`.

| Target      | Output                                               | Notes                                                  |
| ----------- | ---------------------------------------------------- | ------------------------------------------------------ |
| Claude Code | `dist/claude/plugins/<plugin>/`                      | Skills + markdown agents + hooks + commands per plugin |
| Codex CLI   | `dist/codex/plugins/<plugin>/`, `dist/codex/agents/` | Skills + hooks per plugin; standalone TOML agents      |
| Gemini CLI  | `dist/gemini/{skills,agents,hooks}/`                 | Flat per kind; root symlinks for extension loader      |
| Pi          | `dist/pi/{skills,agents,extensions}/`                | Flat layout; symlinked into `~/.pi/agent/`             |

### Structure

```text
src/                                 # ALL hand-edited
├── skills/<skill>/SKILL.md          # vendor-neutral base + optional <target>/ overlay
├── agents/<agent>/AGENT.md          # same pattern as skills
├── hooks/<hook>/HOOK.sh             # + meta.yaml (event, timeout)
└── plugins/<plugin>/plugin.yaml     # plugin composition (skills/agents/hooks lists)

dist/                                # ALL generated; linguist-generated=true
├── claude/plugins/<plugin>/
├── codex/plugins/<plugin>/
├── gemini/{skills,agents,hooks}/
└── pi/{skills,agents,extensions}/

# Root-level files generated by the compiler:
.claude-plugin/marketplace.json      # → ./dist/claude/plugins/*
.agents/plugins/marketplace.json     # → ./dist/codex/plugins/*
gemini-extension.json                # → ${extensionPath}/dist/gemini/
AGENTS.md                            # AGENTS.md catalog
skills      -> dist/gemini/skills    # symlink — Gemini scans extension root by name
agents      -> dist/gemini/agents    # symlink — Gemini scans extension root by name
hooks       -> dist/gemini/hooks     # symlink — Gemini scans extension root by name
```

Regenerate everything with:

```bash
make build
```

Validate with:

```bash
make validate    # frontmatter + vendor-neutrality checks
make check       # build + git diff --exit-code (drift gate)
make test        # pytest
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to add plugins, run validation, and submit PRs.

## License

[MIT](LICENSE)
