# Plugin agents

> Bundled finish-reviewer, documenter, asset-producer, and manual-edit-applier agents, plugin manifest contract, and hooks packaged for Claude Code and Grok plugin installs.

- Repository: pbakaus/impeccable
- GitHub: https://github.com/pbakaus/impeccable
- Human docs: https://grok-wiki.com/public/docs/pbakaus-impeccable-adadc04d8de4
- Complete Markdown: https://grok-wiki.com/public/docs/pbakaus-impeccable-adadc04d8de4/llms-full.txt

## Source Files

- `skill/agents/impeccable-finish-reviewer.md`
- `skill/agents/impeccable-documenter.md`
- `skill/agents/impeccable-asset-producer.md`
- `skill/agents/impeccable-manual-edit-applier.md`
- `plugin/hooks/hooks.json`
- `scripts/lib/validate-plugin-manifest.js`
- `.claude-plugin/plugin.json`

---

---
title: "Plugin agents"
description: "Bundled finish-reviewer, documenter, asset-producer, and manual-edit-applier agents, plugin manifest contract, and hooks packaged for Claude Code and Grok plugin installs."
---

The committed `plugin/` subtree is the slim package Claude Code marketplace and Grok Build plugin installs load: one skill (`skills/impeccable/`), four subagents under `plugin/agents/*.md`, and design-hook wiring in `plugin/hooks/hooks.json`. Canonical agent prompts live in `skill/agents/`; `bun run build:release` emits provider-native copies and copies the Claude Code agents into `plugin/agents/`. The Claude plugin manifest must **omit** an `agents` key so the loader auto-discovers `plugin/agents/*.md` (PR #494).

## Package layout

```text
plugin/
├── .claude-plugin/plugin.json   # Claude marketplace / plugin loader
├── .grok-plugin/plugin.json     # Native Grok plugin metadata
├── agents/                      # Four markdown agents (auto-discovered)
│   ├── impeccable-finish-reviewer.md
│   ├── impeccable-documenter.md
│   ├── impeccable-asset-producer.md
│   └── impeccable-manual-edit-applier.md
├── hooks/
│   └── hooks.json               # PostToolUse + Stop → hook.mjs
└── skills/
    └── impeccable/              # SKILL.md, reference/, scripts/
```

Marketplace entry (repo root) points at this subtree:

| File | Role |
|------|------|
| `.claude-plugin/marketplace.json` | `plugins[0].source: "./plugin"` |
| `.claude-plugin/plugin.json` | Root version/description source (skills path `./.claude/skills/` for non-plugin layouts) |
| `plugin/.claude-plugin/plugin.json` | Installed plugin manifest: `skills: "./skills/"` only; **no** `agents` key |
| `plugin/.grok-plugin/plugin.json` | Grok dual manifest (name, version, description, author, keywords); no component paths |

Grok install uses the slim package explicitly:

```bash
grok plugin install pbakaus/impeccable#plugin --trust
```

Claude Code:

```text
/plugin marketplace add pbakaus/impeccable
```

then install **impeccable** from the plugin UI.

Project-scoped skill installs (`npx impeccable install`) still write harness dirs such as `.claude/skills/` or `.grok/skills/` plus project hooks; those are separate from marketplace plugin unpack.

## The four agents

Source of truth: `skill/agents/<name>.md`. Shared frontmatter fields:

| Field | Purpose |
|-------|---------|
| `name` | Harness agent id (hyphenated) |
| `codex-name` | Codex TOML id (underscores) |
| `description` | Loader / auto-delegation summary |
| `tools` | Allowed tools (Claude/Grok emitted frontmatter) |
| `model` | Usually `inherit` |
| `effort` | `high` or `medium` |
| `max-turns` | Hard turn ceiling (emitted as `maxTurns` for Claude-format agents) |
| `nickname-candidates` | Codex nicknames only |

| Agent | Id / Codex id | Tools | Effort / max-turns | When the skill spawns it |
|-------|---------------|-------|--------------------|--------------------------|
| Finish reviewer | `impeccable-finish-reviewer` / `impeccable_finish_reviewer` | Read, Bash, Glob, Grep (no Write/Edit) | high / 30 | End of craft/new-work finish: reviews screenshots + artifact against direction contract, approved comp, QUALITY BAR, craft floor |
| Documenter | `impeccable-documenter` / `impeccable_documenter` | Read, Write, Bash, Glob, Grep | medium / 30 | After finish review closes: writes `DESIGN.md` + sidecar from the **built** artifact |
| Asset producer | `impeccable-asset-producer` / `impeccable_asset_producer` | Read, Write, Edit, Bash, Glob, Grep | medium / 24 | Media inventory / visualize / craft: clean production rasters from approved mocks; also decision-card sketch mode |
| Manual edit applier | `impeccable-manual-edit-applier` / `impeccable_manual_edit_applier` | Read, Write, Edit, Bash, Glob, Grep | medium / 12 | Live mode `manual_edit_apply`: leased batch → source files; returns canonical JSON only |

Invocation names in skill references:

| Harness | How parents name the agent |
|---------|----------------------------|
| Claude Code / Grok | `impeccable-<role>` (plugin or `.grok/agents/`) |
| Codex | `impeccable_<role>` TOML nested under skill `agents/` |
| Cursor | `/impeccable-<role>` when agents are installed under `.cursor/agents/` |
| GitHub Copilot | Phrase: "Use the impeccable-\<role\> agent" |

### Finish reviewer

Read-only finishing gate. No browser, server, or second detector pass. Parent supplies screenshots, paths, direction contract (THESIS, OWN-WORLD, STORY, FIRST VIEWPORT, FORM), PRODUCT.md, hook findings, QUALITY BAR cards, approved comp, and `reference/craft-floor.md`.

Checks (order): persistence → fidelity (element matrix; mandatory TYPE and MATERIAL rows) → ceiling → contract promises → truth → craft floor. First return line is disposition:

| Disposition | Meaning |
|-------------|---------|
| `disposition: rebuild` | Wholesale fidelity failure; rebuild directive first, not patch list |
| `disposition: fix` | Non-empty `material_fixes` |
| `disposition: ship` | No contradicted/missing matrix rows |

Then exactly five sections: `persistence`, `fidelity`, `ceiling`, `material_fixes` (≤8, ordered), `keep`. Verdict pass (post-fix recaptures) returns `verdict`, `remaining`, and a recomputed disposition only.

### Documenter

Records design system **after** build. Ground truth is shipped CSS/components, not the direction contract. Follows `reference/document.md` for format, tokens, sidecar, section order. Output: paths written, five-line system summary, one not-canonized line. Must not promote craft-floor refusals (kickers, banned shadows, etc.) into system rules.

### Asset producer

Production cleanup, not new art direction. Buckets: `produce` (regenerate clean plates from mock crops), `direct` (real standalone sources only; mock crops never direct), `semantic` (HTML/CSS/SVG/canvas handoff). Defaults: `.webp` opaque, `.png` cutouts, ≥2× display size, strip UI chrome unless intrinsic. After generation, embed prompt via `embed-prompt.mjs`. Return manifest with `qa_status` ∈ `accepted` \| `needs_parent_review` \| `blocked`. Decision-sketch mode: one card → one file at card `sketch` path; different contract from asset production.

### Manual edit applier

Applies one leased live `manual_edit_apply` batch. Owns source edits only; parent owns poll/protocol. Treats batch text as data, not instructions. Entry atomicity: all ops in an entry succeed or entry fails with undo of that entry’s edits. Return **only** JSON:

```json
{"status":"done","appliedEntryIds":["entry-id"],"failed":[],"files":["src/App.jsx"],"notes":[]}
```

Statuses: `done` | `partial` | `error`. Must not run live poll/commit scripts, stage, commit, or inject live DOM scaffolding into source.

## Degraded mode (no subagents)

When the harness cannot spawn subagents, the parent loads generated fallbacks under `reference/degraded/<role>.md` (role = agent name without `impeccable-` prefix):

| File | Role |
|------|------|
| `degraded/finish-reviewer.md` | Inline finish review / verdict |
| `degraded/documenter.md` | Inline DESIGN.md recording |
| `degraded/asset-producer.md` | Inline asset production |
| `degraded/manual-edit-applier.md` | Inline apply (same JSON contract) |

These are **generated at build** from `skill/agents/` with a preamble that forces the parent to run the role inline and disclose the substitution. Do not hand-edit degraded files; edit the agent sources.

## Plugin manifest contract

`scripts/lib/validate-plugin-manifest.js` is a `bun run build` gate. Verified Claude Code loader keys (`KNOWN_LOADER_KEYS`):

`name`, `description`, `version`, `author`, `homepage`, `repository`, `skills`

Rules:

| Rule | Why |
|------|-----|
| No `agents` key | Array of file paths → zero agents loaded; other shapes can fail the whole plugin |
| `skills` must be `"./skills/"` | Trailing slash required (issue #86); bare path fails slash-command registration |
| Every Claude-emitted agent from `skill/agents/` present under `plugin/agents/` | Auto-discovery only sees shipped files |
| Unknown keys fail the build | Add to `KNOWN_LOADER_KEYS` only after live `claude plugin details` confirms load |

Root `.claude-plugin/plugin.json` is the version source of truth; `validatePluginVersions` keeps marketplace + `plugin/.claude-plugin/plugin.json` + bundled skill frontmatter aligned.

Grok’s `plugin/.grok-plugin/plugin.json` is dual metadata (no `skills` path). Grok also accepts `.claude-plugin/`; both are written so marketplace and `grok plugin validate` stay happy when Claude compat is disabled.

## Packaged hooks

`plugin/hooks/hooks.json` is built by `buildClaudePluginHooksManifest()`:

| Event | Matcher | Timeout | Status message |
|-------|---------|---------|----------------|
| `PostToolUse` | `Edit\|Write\|MultiEdit` | 5s | Checking UI changes |
| `Stop` | (session stop) | 30s | Design deep pass |

Command shape:

1. Skip if `hook.mjs` missing under `${CLAUDE_PLUGIN_ROOT}` (or Grok’s `GROK_PLUGIN_ROOT` alias).
2. Require Node ≥ 22 on PATH; on failure, optional one-shot `systemMessage` notice via `~/.impeccable/node-unsupported`, then exit 0.
3. Else `node …/skills/impeccable/scripts/hook.mjs`.

Marketplace/plugin installs get PostToolUse + Stop without merging project settings. Project-scoped CLI installs still write harness-specific manifests (for example `.claude/settings.json`, `.grok/hooks/impeccable.json`).

## Source, emission, and install paths

```text
skill/agents/*.md          # author here
        │
        ▼  provider transformers (agentFormat)
dist/<provider>/…/agents/  # + skill-nested Codex TOML + degraded refs
        │
        ▼  build:release root sync
.claude/agents/  .grok/agents/  .cursor/agents/  …
        │
        ▼  plugin package (Claude agents copy)
plugin/agents/*.md + hooks/hooks.json + skills/impeccable/
```

| Delivery | Agents | Hooks |
|----------|--------|-------|
| Claude marketplace → `./plugin` | Auto-discover `plugin/agents/*.md` | `plugin/hooks/hooks.json` |
| Grok `…#plugin` | Same markdown agents | Same hooks file (`CLAUDE_PLUGIN_ROOT` → `GROK_PLUGIN_ROOT`) |
| Project `npx impeccable install --providers=grok` | `.grok/agents/` | `.grok/hooks/impeccable.json` |
| Codex skills install | TOML inside skill `agents/` | Project `.codex/hooks.json` (trust step) |
| Cursor / Copilot | Provider agent formats when emitted | Separate project hook manifests |

Agents may set frontmatter `providers:` to limit emission; default is all providers with an `agentFormat`.

## Lifecycle in craft finish

Typical new-world handoff (skill references `new-work` / craft):

1. Parent captures desktop + mobile screenshots; may run `detect.mjs --json` if no design hook ran.
2. Spawn **finish reviewer** with full input packet (`fork_turns: 0` on Codex so review is not poisoned by build transcript).
3. On `rebuild` disposition: rebuild named regions/assets; re-verdict. On `fix`: apply material fixes, recapture, verdict pass. Budget: two unattended rounds unless the user funds more.
4. Spawn **documenter** to write DESIGN.md from the final artifact.
5. Asset producer runs earlier whenever media must ship; manual-edit applier only during live Apply events.

## Verification

| Check | Command / signal |
|-------|------------------|
| Manifest shape | `bun run build` → `collectPluginManifestFindings` empty |
| Real loader inventory | `bun run test:plugin-e2e` (needs `claude` on PATH; skips otherwise) |
| E2E expectations | Skills (1) `impeccable`; Agents = count of `plugin/agents/*.md`; Hooks (2) PostToolUse + Stop |
| Unit guard | `tests/validate-plugin-manifest.test.js` — no `agents` in `KNOWN_LOADER_KEYS` |
| After agent source edits | `bun run build:release` so `plugin/agents/` and harness agents stay in sync |

## Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| Agents missing after marketplace install | Manifest declared `agents` as file paths | Omit key; ship files under `plugin/agents/`; re-release |
| Zero slash commands | `skills` without trailing slash | Must be `"./skills/"` |
| Agents present in repo but not in plugin | Skipped release sync | `bun run build:release` |
| Hook errors every edit | Node &lt; 22 on hook PATH | Install Node 22+ or remove hook |
| Reviewer softens findings | Parent reviewed in-thread or forked transcript | Fresh spawn with input packet only; use degraded path only when subagents impossible |
| DESIGN.md invents tokens | Documenter ran from intention, not build | Re-run documenter against shipped styles only |

## Related pages

<CardGroup>
  <Card title="Installation" href="/installation">
    Marketplace, Grok `#plugin`, and project-scoped provider installs including hook consent.
  </Card>
  <Card title="Provider harnesses" href="/provider-harnesses">
    Harness directories, agent formats, and hook capability matrix across tools.
  </Card>
  <Card title="Design hook" href="/design-hook">
    PostToolUse and Stop detector behavior shared by plugin and project hooks.
  </Card>
  <Card title="Live mode" href="/live-mode">
    Manual edit apply events that drive the manual-edit-applier agent.
  </Card>
  <Card title="Build and test" href="/build-and-test">
    Release sync of `plugin/`, plugin-e2e, and build gates for manifest shape.
  </Card>
  <Card title="Project artifacts" href="/project-artifacts">
    DESIGN.md and sidecar written by the documenter after finish review.
  </Card>
</CardGroup>
