@jabworks/condux 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -18
- package/agents/explorer.md +1 -0
- package/agents/planner.md +1 -0
- package/agents/researcher.md +1 -0
- package/index.js +34 -3
- package/package.json +6 -4
- package/skills/code-review/SKILL.md +136 -0
- package/skills/code-review/evals/trigger_eval.json +22 -0
- package/skills/discovery/SKILL.md +242 -0
- package/skills/discovery/evals/trigger_eval.json +24 -0
- package/skills/discovery/references/choice-server.js +216 -0
- package/skills/discovery/references/mockup-picker.md +90 -0
- package/skills/discovery/references/package.json +3 -0
- package/skills/draft-plan/SKILL.md +229 -0
- package/skills/draft-plan/evals/trigger_eval.json +22 -0
- package/skills/draft-plan/references/plan-template.md +96 -0
- package/skills/finalize/SKILL.md +123 -0
- package/skills/finalize/evals/trigger_eval.json +22 -0
- package/skills/finalize/references/rationalization-table.md +15 -0
- package/skills/plan-review/SKILL.md +215 -0
- package/skills/plan-review/evals/trigger_eval.json +22 -0
- package/skills/plan-review/references/annotate-server.js +465 -0
- package/skills/plan-review/references/install-codex-hook.sh +112 -0
- package/skills/plan-review/references/package.json +3 -0
- package/skills/plan-review/references/plan-review-template.html +730 -0
- package/skills/preflight/SKILL.md +128 -0
- package/skills/preflight/evals/trigger_eval.json +26 -0
- package/skills/root-cause-analysis/SKILL.md +82 -0
- package/skills/root-cause-analysis/evals/trigger_eval.json +22 -0
- package/skills/subagent-deployment/SKILL.md +105 -0
- package/skills/subagent-deployment/evals/trigger_eval.json +22 -0
- package/skills/subagent-deployment/references/safety-checklist.md +54 -0
- package/skills/subagent-execution/SKILL.md +182 -0
- package/skills/subagent-execution/agents/coder.md +55 -0
- package/skills/subagent-execution/agents/explorer.md +77 -0
- package/skills/subagent-execution/agents/planner.md +101 -0
- package/skills/subagent-execution/agents/researcher.md +78 -0
- package/skills/subagent-execution/evals/trigger_eval.json +22 -0
- package/skills/subagent-execution/references/install-codex-agents.mjs +98 -0
- package/skills/subagent-execution/references/review-package.sh +29 -0
- package/skills/subagent-execution/references/spawn-rules.md +88 -0
- package/skills/subagent-execution/references/task-brief.sh +39 -0
- package/skills/technical-spec/SKILL.md +190 -0
- package/skills/technical-spec/evals/trigger_eval.json +23 -0
- package/skills/technical-spec/references/scaffold.sh +98 -0
- package/skills/technical-spec/references/templates.md +159 -0
- package/skills/test-first-development/SKILL.md +121 -0
- package/skills/test-first-development/evals/trigger_eval.json +22 -0
- package/skills/test-first-development/references/rationalization-table.md +16 -0
- package/skills/workflow/SKILL.md +241 -0
- package/skills/workflow/evals/trigger_eval.json +30 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: finalize
|
|
3
|
+
description: "End-of-task quality gate — typecheck → lint → format → tests. Runs in order, once. Stops on first failure and fixes before continuing. Run after all implementation is complete. Called automatically by /workflow, or standalone. Check AGENTS.md for the project's actual commands. Not for auditing whether requirements and plan steps are complete; use preflight first."
|
|
4
|
+
argument-hint: "[package or path to scope — optional]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /finalize
|
|
8
|
+
|
|
9
|
+
One quality gate at the end. Typecheck → lint → format → test. In that order. Once.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/finalize # full repo
|
|
15
|
+
/finalize apps/web # scoped to package or path
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Before Running
|
|
19
|
+
|
|
20
|
+
Check `AGENTS.md` for the project's finalize commands. If `AGENTS.md` defines a `finalize` script or step sequence, use that. Otherwise fall back to reading `package.json` scripts and infer the right commands. If no `.condux/plans/*<slug>*.md` exists for the inferred feature slug, note it in the output below — don't block. This is informational only, surfacing when a task ran without going through `/workflow` or `/draft-plan`, not a gate.
|
|
21
|
+
|
|
22
|
+
## How It Works
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
26
|
+
│ FINALIZE │
|
|
27
|
+
├──────────────────────────────────────────────────────────────────┤
|
|
28
|
+
│ Step 1: TYPECHECK │
|
|
29
|
+
│ Run: typecheck script from AGENTS.md or package.json │
|
|
30
|
+
│ → Failure: fix type errors, re-run typecheck only │
|
|
31
|
+
│ → Clean: proceed to Step 2 │
|
|
32
|
+
│ │
|
|
33
|
+
│ Step 2: LINT │
|
|
34
|
+
│ Run: lint script from AGENTS.md or package.json │
|
|
35
|
+
│ → Errors: fix, re-run lint only to confirm │
|
|
36
|
+
│ → Warnings: note them, do not block │
|
|
37
|
+
│ → Clean: proceed to Step 3 │
|
|
38
|
+
│ │
|
|
39
|
+
│ Step 3: FORMAT │
|
|
40
|
+
│ Run: format check, then auto-fix if dirty │
|
|
41
|
+
│ → Report which files were changed │
|
|
42
|
+
│ → Continue to Step 4 regardless (format is auto-fixed) │
|
|
43
|
+
│ │
|
|
44
|
+
│ Step 4: TEST │
|
|
45
|
+
│ Run: test script from AGENTS.md or package.json │
|
|
46
|
+
│ → Failure: diagnose, make one targeted fix, re-run │
|
|
47
|
+
│ failing tests only (not full suite) │
|
|
48
|
+
│ → Still failing: stop, report, do not loop │
|
|
49
|
+
│ → Clean: done │
|
|
50
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Failure Handling
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Typecheck fails
|
|
57
|
+
→ Read the error carefully
|
|
58
|
+
→ Fix the type issue
|
|
59
|
+
→ Re-run typecheck only — do not proceed until clean
|
|
60
|
+
|
|
61
|
+
Lint fails (errors, not warnings)
|
|
62
|
+
→ Fix flagged issues (auto-fix with --fix if safe)
|
|
63
|
+
→ Re-run lint only to confirm clean
|
|
64
|
+
→ Do not proceed to tests until clean
|
|
65
|
+
|
|
66
|
+
Format is dirty
|
|
67
|
+
→ Run format --write
|
|
68
|
+
→ Note changed files in output
|
|
69
|
+
→ Continue — format never blocks
|
|
70
|
+
|
|
71
|
+
Tests fail
|
|
72
|
+
→ Read failure output carefully
|
|
73
|
+
→ Make one targeted fix
|
|
74
|
+
→ Re-run the failing test(s) only
|
|
75
|
+
→ If still failing: STOP and report — do not loop
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Output Format
|
|
79
|
+
|
|
80
|
+
The `Plan` line below only appears when no matching plan doc was found for the inferred feature slug — it's omitted entirely otherwise.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
## Finalize: [task or feature name]
|
|
84
|
+
|
|
85
|
+
Typecheck ✓ clean
|
|
86
|
+
Lint ✓ clean (2 warnings — not blocking)
|
|
87
|
+
Format ✓ 2 files auto-fixed (Button.tsx, invoice.router.ts)
|
|
88
|
+
Tests ✓ 18 passed, 0 failed
|
|
89
|
+
Plan (none found for this task — treating as standalone scope)
|
|
90
|
+
|
|
91
|
+
Ready to commit.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
On failure:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
## Finalize: [task or feature name]
|
|
98
|
+
|
|
99
|
+
Typecheck ✗ FAILED
|
|
100
|
+
apps/web/src/components/InvoiceTable.tsx:42
|
|
101
|
+
Property 'onExport' does not exist on type 'InvoiceTableProps'
|
|
102
|
+
Fix: added onExport?: () => void to InvoiceTableProps
|
|
103
|
+
Re-run: ✓ clean
|
|
104
|
+
|
|
105
|
+
Lint ✓ clean
|
|
106
|
+
Format ✓ clean
|
|
107
|
+
Tests ✓ 18 passed
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## What Does NOT Happen
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
✗ Running tests mid-implementation
|
|
114
|
+
✗ Running lint/typecheck after individual file edits
|
|
115
|
+
✗ Looping on test failures — one fix attempt, then stop and report
|
|
116
|
+
✗ Blocking on lint warnings (errors only)
|
|
117
|
+
✗ Running the full test suite multiple times
|
|
118
|
+
✗ Skipping steps because "the change was small"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## See Also
|
|
122
|
+
|
|
123
|
+
- `references/rationalization-table.md` — common rationalizations for skipping finalize and why they're wrong
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "query": "run the quality gate", "should_trigger": true, "expected_skill": "finalize" },
|
|
3
|
+
{ "query": "typecheck lint format test", "should_trigger": true, "expected_skill": "finalize" },
|
|
4
|
+
{ "query": "finalize the task", "should_trigger": true, "expected_skill": "finalize" },
|
|
5
|
+
{ "query": "all done implementing, run the checks", "should_trigger": true, "expected_skill": "finalize" },
|
|
6
|
+
{ "query": "is the build green", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
7
|
+
{ "query": "run tests and lint before I commit", "should_trigger": true, "expected_skill": "finalize" },
|
|
8
|
+
{ "query": "finalize just apps/web", "should_trigger": true, "expected_skill": "finalize" },
|
|
9
|
+
{ "query": "prettier rewrote 3 files during the check, is that ok", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
10
|
+
{ "query": "should I run lint after every file edit", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
11
|
+
{ "query": "whats the projects test command, AGENTS.md has it maybe", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
12
|
+
{ "query": "tests failing, keep looping until green", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
13
|
+
{ "query": "run the full suite twice just to be sure", "should_trigger": true, "expected_skill": "finalize", "kind": "in-context" },
|
|
14
|
+
{ "query": "am I actually done though", "should_trigger": true, "expected_skill": "preflight" },
|
|
15
|
+
{ "query": "commit this with a proper message", "should_trigger": true, "expected_skill": "git-commit" },
|
|
16
|
+
{ "query": "fix this type error in the component", "should_trigger": true, "expected_skill": "workflow" },
|
|
17
|
+
{ "query": "why is this one test failing", "should_trigger": true, "expected_skill": "root-cause-analysis" },
|
|
18
|
+
{ "query": "review the diff before merge", "should_trigger": true, "expected_skill": "code-review" },
|
|
19
|
+
{ "query": "format this sql query nicely for the doc", "should_trigger": false, "expected_skill": null },
|
|
20
|
+
{ "query": "what does the no-unused-vars eslint rule mean", "should_trigger": false, "expected_skill": null },
|
|
21
|
+
{ "query": "release the package to npm", "should_trigger": true, "expected_skill": "release" }
|
|
22
|
+
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Finalize Rationalization Table
|
|
2
|
+
|
|
3
|
+
Common rationalizations agents use to skip or shortcut the finalize gate — and why they're wrong.
|
|
4
|
+
|
|
5
|
+
| Rationalization | Reality | Counter |
|
|
6
|
+
| --------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
7
|
+
| "The change was too small to break types" | Type errors compound. A small change that breaks an import breaks everything downstream. | Run typecheck. It takes seconds. |
|
|
8
|
+
| "I already ran lint during implementation" | Lint state during implementation is stale. You may have added new violations since. | Run lint once at the end, clean. |
|
|
9
|
+
| "Tests were passing before my change" | Your change may have introduced a regression that existing tests catch. | Run tests. That's their purpose. |
|
|
10
|
+
| "I'll skip format — it's just whitespace" | Noisy diffs make code review harder and hide real changes. | Format is auto-fixed and non-blocking. There's no reason to skip it. |
|
|
11
|
+
| "The tests take too long to run" | Check AGENTS.md for a fast/watch mode. Scope the run to the affected package. | Run scoped tests. Don't run the full suite if there's a faster option. |
|
|
12
|
+
| "I fixed the failing test so I can skip re-running" | The fix might have introduced a new failure. | Re-run the affected test(s). One command. |
|
|
13
|
+
| "Typecheck is already run by the build" | The build runs in CI, not locally. You want to catch errors before push, not after. | Run typecheck locally before committing. |
|
|
14
|
+
| "I'll fix the lint errors in a follow-up" | Follow-ups don't happen. The lint errors accumulate and become background noise. | Fix now. It's part of the task. |
|
|
15
|
+
| "There are too many test failures to fix right now" | Stop and report. Don't merge broken tests. | If tests are failing and you can't fix them, surface that — don't hide it. |
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan-review
|
|
3
|
+
description: "Render a plan in a local browser for inline annotation, then return an approve / request-revisions / deny decision to the agent. Auto-captures the plan via a Claude Code ExitPlanMode hook or a Codex Stop hook, or runs manually on any markdown file or spec directory. Self-contained — no network egress, no third-party runtime deps. When the agent finishes planning (Claude Code ExitPlanMode, or a Codex planning turn) and you want to review/annotate before it implements, or when you invoke /plan-review on a markdown plan or spec directory. Also owns its own machinery — steer-mode review loops, the live spec preview, and installing or troubleshooting the ExitPlanMode / Codex Stop hooks. Not for cataloging a whole specs tree; use spec-browser."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /plan-review
|
|
7
|
+
|
|
8
|
+
Interactive plan review. The agent's plan opens in a local browser; you select
|
|
9
|
+
any text to attach an inline comment, chat with the agent, then submit a decision.
|
|
10
|
+
The decision flows back to the agent — **Approve** lets it proceed, **Request
|
|
11
|
+
Revisions** sends your notes back so it revises and re-presents, and **Reject**
|
|
12
|
+
tells it not to implement — reconsider whether the feature should be built.
|
|
13
|
+
|
|
14
|
+
Inspired by [Plannotator](https://github.com/backnotprop/plannotator), rebuilt
|
|
15
|
+
in-house so it carries **no third-party runtime dependency** and makes **no
|
|
16
|
+
network calls** — safe for strict environments.
|
|
17
|
+
|
|
18
|
+
## Ways in
|
|
19
|
+
|
|
20
|
+
### Auto — ExitPlanMode hook (the real workflow)
|
|
21
|
+
|
|
22
|
+
When installed as part of the **condux plugin**, this hook ships in the plugin
|
|
23
|
+
(`hooks/hooks.json`) and is auto-registered — no setup. Every time the agent
|
|
24
|
+
exits plan mode, the plan is captured and the review UI opens automatically. The
|
|
25
|
+
hook blocks until you decide. The plugin entry is:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
// dist/plugins/condux/hooks/hooks.json (shipped — for reference)
|
|
29
|
+
{
|
|
30
|
+
"hooks": {
|
|
31
|
+
"PreToolUse": [
|
|
32
|
+
{
|
|
33
|
+
"matcher": "ExitPlanMode",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{
|
|
36
|
+
"type": "command",
|
|
37
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/skills/condux/plan-review/references/annotate-server.js\" --hook"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Standalone (no plugin)?** Wire the same hook by hand in your
|
|
47
|
+
`settings.json` (project `.claude/settings.json` or `~/.claude/settings.json`),
|
|
48
|
+
swapping `${CLAUDE_PLUGIN_ROOT}/skills/condux/plan-review` for the absolute path:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
find ~/.claude ~/.codex ~/.agents -name annotate-server.js -path '*plan-review*' 2>/dev/null | head -1
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
What the hook returns to the agent:
|
|
55
|
+
|
|
56
|
+
| Your decision | Hook output | Agent behavior |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| **Approve** | `permissionDecision: "allow"` (+ notes as `additionalContext` if any) | proceeds to implement |
|
|
59
|
+
| **Request Revisions** | `permissionDecision: "deny"`, reason = *revise this plan* + feedback | revises the plan, re-enters plan mode (re-triggers the hook) |
|
|
60
|
+
| **Reject** | `permissionDecision: "deny"`, reason = *do not implement, reconsider* + feedback | stops; reconsiders whether the feature should be built, or proposes a different approach |
|
|
61
|
+
|
|
62
|
+
### Auto — Codex Stop hook
|
|
63
|
+
|
|
64
|
+
Codex has **no `ExitPlanMode`** interception point, so plan review runs off
|
|
65
|
+
Codex's experimental **`Stop` hook**. When a planning turn ends
|
|
66
|
+
(`permission_mode === "plan"`), `annotate-server.js --codex-stop` reads the plan
|
|
67
|
+
from the Stop payload (`last_assistant_message`, falling back to
|
|
68
|
+
`transcript_path`) and opens the same review UI. On any other turn it emits `{}`
|
|
69
|
+
and exits, leaving the turn untouched.
|
|
70
|
+
|
|
71
|
+
**Installed via the condux plugin?** The `Stop` hook ships with it. The Codex
|
|
72
|
+
manifest (`.codex-plugin/plugin.json`) sets `"hooks": "./hooks/codex-hooks.json"`,
|
|
73
|
+
which Codex loads **instead of** the default `hooks/hooks.json` (that one is
|
|
74
|
+
Claude's `ExitPlanMode` hook, inert on Codex). Just enable `[features] hooks =
|
|
75
|
+
true` in `$CODEX_HOME/config.toml`, then **restart Codex** and **trust the hook**
|
|
76
|
+
when prompted — no installer needed.
|
|
77
|
+
|
|
78
|
+
**Standalone (no plugin)?** Run the installer once — it writes `~/.codex/hooks.json`
|
|
79
|
+
+ sets the feature flag, then restart Codex and trust the hook:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bash /PATH/TO/plan-review/references/install-codex-hook.sh
|
|
83
|
+
# or, after a plugin install:
|
|
84
|
+
find ~/.codex ~/.claude -name install-codex-hook.sh -path '*plan-review*' 2>/dev/null | head -1 | xargs bash
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Your decision | Hook output | Codex behavior |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| **Approve** (no notes) | `{}` (turn completes) | plan accepted, turn ends |
|
|
90
|
+
| **Approve** (with notes) | `{"decision":"block","reason":<approved + notes>}` | continues the turn; agent implements while addressing the notes |
|
|
91
|
+
| **Request Revisions** | `{"decision":"block","reason":<revise + feedback>}` | revises the plan in the same turn (re-triggers on next stop) |
|
|
92
|
+
| **Reject** | `{"decision":"block","reason":<do not implement, reconsider + feedback>}` | stops; reconsiders whether the feature should be built, or proposes a different approach |
|
|
93
|
+
|
|
94
|
+
Caveats: Codex hooks are **experimental and disabled on Windows**; the review is
|
|
95
|
+
**post-render** (after Codex prints the plan), not a pre-interception like Claude
|
|
96
|
+
Code. The plugin hook invokes bare `node` (resolved via `${PLUGIN_ROOT}`, the
|
|
97
|
+
variable Codex substitutes in plugin hook commands — it does **not** set Claude's
|
|
98
|
+
`${CLAUDE_PLUGIN_ROOT}`, so never use that in `codex-hooks.json`) — if Codex
|
|
99
|
+
Desktop can't find `node` on `PATH`, fall back to the installer, which bakes in
|
|
100
|
+
an **absolute** node path.
|
|
101
|
+
|
|
102
|
+
### Manual — on any file or spec directory
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
node /PATH/TO/plan-review/references/annotate-server.js <plan-or-spec.md>
|
|
106
|
+
node /PATH/TO/plan-review/references/annotate-server.js <spec-dir>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Serves the file, writes your decision to `<file>.feedback.md`, and stays running
|
|
110
|
+
(Ctrl+C to stop). Pass `--no-open` to skip the automatic browser launch (used by
|
|
111
|
+
the test suite; also right for headless/CI runs). Use this for ad-hoc review of a spec or a written plan when you
|
|
112
|
+
are not in plan mode. After submitting, read `<file>.feedback.md` to action it.
|
|
113
|
+
|
|
114
|
+
**Directory mode** reviews a whole spec folder (e.g. `specs/wan-config/` from
|
|
115
|
+
the `technical-spec` skill): every top-level `*.md` is listed in the sidebar,
|
|
116
|
+
notes are tagged with their source file, edits to any file live-reload (with a
|
|
117
|
+
per-file revision diff), and the decision lands in `<dir>/review.feedback.md`
|
|
118
|
+
grouped by file. Works in manual and `--steer` modes; this is also the live
|
|
119
|
+
preview surface for `technical-spec` (its old preview server is retired).
|
|
120
|
+
|
|
121
|
+
### Steer — agent-invoked loop (any agent, no hook needed)
|
|
122
|
+
|
|
123
|
+
When you want the review to actually **drive an agent** outside Claude's
|
|
124
|
+
`ExitPlanMode` / Codex `Stop` hooks — e.g. an agent that wrote a plan to a file
|
|
125
|
+
and wants you to gate it — run the server in `--steer` mode. The server is
|
|
126
|
+
**long-lived**: launch it once, and one browser tab stays open for the whole
|
|
127
|
+
review while the agent loops.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# 1. Launch once, in the background (default port 7777; override with --port).
|
|
131
|
+
node /PATH/TO/plan-review/references/annotate-server.js <plan.md> --steer &
|
|
132
|
+
|
|
133
|
+
# 2. Each round: block until you submit a decision (long-poll).
|
|
134
|
+
curl -s http://127.0.0.1:7777/api/decision
|
|
135
|
+
# → {"decision":"Request Revisions","feedback":"<markdown>","feedbackFile":"<abs>.feedback.md"}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The agent runs the **iterative loop** off that decision:
|
|
139
|
+
|
|
140
|
+
1. Launch the server (step 1) — the review tab opens and stays open.
|
|
141
|
+
2. `GET /api/decision` — blocks until you decide; returns the decision JSON.
|
|
142
|
+
3. Branch on `decision`:
|
|
143
|
+
- **Approve** → stop looping, implement the plan (use `feedback` as notes). The server exits.
|
|
144
|
+
- **Request Revisions** → edit `<plan.md>` **in place**; the open tab live-reloads the new plan over SSE (orphaned notes auto-clear). **Go to 2.**
|
|
145
|
+
- **Reject** → stop; do not implement — reconsider whether to build this, or surface the blocker. The server exits.
|
|
146
|
+
|
|
147
|
+
Same steering the hooks give you, available to any agent that can run a command
|
|
148
|
+
and read a file — at the cost of the agent orchestrating the loop itself rather
|
|
149
|
+
than a hook blocking inline. Because the server is long-lived, **the same tab
|
|
150
|
+
reflects every revision** — no new tab per round. The decision is also written to
|
|
151
|
+
`<plan.md>.feedback.md` as a record each round.
|
|
152
|
+
|
|
153
|
+
## The review surface
|
|
154
|
+
|
|
155
|
+
A three-pane layout over a **decision bar**: a left sidebar with two tabs —
|
|
156
|
+
**Contents** (heading outline with per-section note counts; in directory mode,
|
|
157
|
+
each document is a top-level node with its headings nested, click to switch
|
|
158
|
+
docs) and **Files** (paths the plan touches, parsed from inline code and
|
|
159
|
+
fences, badged **exists**/**new** against the repo; click jumps to the first
|
|
160
|
+
mention, repeat clicks cycle) — the centered rendered plan (middle), and a
|
|
161
|
+
**Review** rail (right) holding your notes and messages. The decisions live in
|
|
162
|
+
a fixed bar along the bottom — `[Reject] ——— [Request revisions] [Approve]` —
|
|
163
|
+
with a live summary of what rides along ("3 notes · 1 message will be sent").
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
167
|
+
│ Step 1 RENDER Plan renders centered in the browser, w/ TOC. │
|
|
168
|
+
│ Step 2 ANNOTATE Select text → a toolbar opens above it. Pick │
|
|
169
|
+
│ a category (Comment / Issue / Question / │
|
|
170
|
+
│ Suggestion / Nitpick) → the note input opens. │
|
|
171
|
+
│ Or message the agent in the Review rail. │
|
|
172
|
+
│ Step 3 DECIDE Bottom bar: Approve / Request Revisions / │
|
|
173
|
+
│ Reject — with a note/message count summary. │
|
|
174
|
+
│ Step 4 RETURN Decision + notes (each tagged with its │
|
|
175
|
+
│ category and quoting its anchor) go back. │
|
|
176
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Selecting text opens a floating **annotation toolbar** anchored above the
|
|
180
|
+
selection (it flips below when there's no room). It starts as a category
|
|
181
|
+
**menubar**; choosing a category expands it to reveal the note input and
|
|
182
|
+
Save/Cancel. Saving highlights the text and anchors the note; clicking a
|
|
183
|
+
highlight or a note cross-links the two. The page live-reloads when the plan
|
|
184
|
+
file changes on disk (SSE + `fs.watch`).
|
|
185
|
+
|
|
186
|
+
When the agent **revises** the plan, the tab doesn't silently swap the text: a
|
|
187
|
+
banner reports the change (`+adds / -dels lines`) with a **View changes** toggle
|
|
188
|
+
that shows a unified line diff (old vs. new, folding long unchanged runs), and
|
|
189
|
+
the now-orphaned notes clear so the next round starts clean. Submitting a
|
|
190
|
+
decision **clears your notes immediately** and replaces the decision bar's
|
|
191
|
+
content with a confirmation that states what the agent does next
|
|
192
|
+
(implement / revise / rework).
|
|
193
|
+
|
|
194
|
+
## Guarantees (why it passes review)
|
|
195
|
+
|
|
196
|
+
- **No egress.** Server binds `127.0.0.1` only; the HTML template embeds its own
|
|
197
|
+
markdown renderer and uses a system monospace font — no CDN, no web fonts, no
|
|
198
|
+
paste/share service. Audit: `grep -rE 'https?://' references/*.html` returns nothing.
|
|
199
|
+
- **No dependencies.** `annotate-server.js` is Node stdlib only.
|
|
200
|
+
- **Auditable.** One stdlib server + one self-contained HTML file. The UI is
|
|
201
|
+
styled after the **Terminus UI** design system (Button, Badge, Card, Textarea,
|
|
202
|
+
Popover) — adapted as vanilla CSS tokens + classes, no React, no bundle.
|
|
203
|
+
|
|
204
|
+
## Files
|
|
205
|
+
|
|
206
|
+
| File | Role |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `references/annotate-server.js` | Local server. `--hook` (Claude ExitPlanMode), `--codex-stop` (Codex Stop), `<file> --steer` (agent-invoked blocking loop), or `<file|dir>` alone for manual mode. A directory argument reviews every top-level `*.md` in it. |
|
|
209
|
+
| `references/install-codex-hook.sh` | Registers the Codex `Stop` hook in `~/.codex` and enables the hooks feature flag. |
|
|
210
|
+
| `references/plan-review-template.html` | Self-contained review UI (renderer + annotation surface). |
|
|
211
|
+
|
|
212
|
+
## Related skills
|
|
213
|
+
|
|
214
|
+
- `draft-plan` — produces the plan this skill reviews.
|
|
215
|
+
- `technical-spec` — persists decisions/API/quirks; this server (directory mode) is its live preview + review surface.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "query": "review the plan in the browser", "should_trigger": true, "expected_skill": "plan-review" },
|
|
3
|
+
{ "query": "open the annotation ui for this plan", "should_trigger": true, "expected_skill": "plan-review" },
|
|
4
|
+
{ "query": "let me annotate before you implement", "should_trigger": true, "expected_skill": "plan-review" },
|
|
5
|
+
{ "query": "plan review on .condux/plans/2026-07-04-git-skills.md", "should_trigger": true, "expected_skill": "plan-review" },
|
|
6
|
+
{ "query": "run the steer mode review loop", "should_trigger": true, "expected_skill": "plan-review" },
|
|
7
|
+
{ "query": "review the spec directory with per-file notes", "should_trigger": true, "expected_skill": "plan-review", "accept": ["spec-browser"] },
|
|
8
|
+
{ "query": "open live preview of specs/wan-config", "should_trigger": true, "expected_skill": "plan-review" },
|
|
9
|
+
{ "query": "approve / request revisions flow for this plan", "should_trigger": true, "expected_skill": "plan-review" },
|
|
10
|
+
{ "query": "the exitplanmode hook isnt opening the browser", "should_trigger": true, "expected_skill": "plan-review" },
|
|
11
|
+
{ "query": "install the codex stop hook for plan review", "should_trigger": true, "expected_skill": "plan-review" },
|
|
12
|
+
{ "query": "reject this plan, dont build it", "should_trigger": true, "expected_skill": "plan-review" },
|
|
13
|
+
{ "query": "send my notes on section 3 back to the agent", "should_trigger": true, "expected_skill": "plan-review" },
|
|
14
|
+
{ "query": "why didnt the review tab reload after the revision", "should_trigger": true, "expected_skill": "plan-review", "kind": "in-context" },
|
|
15
|
+
{ "query": "something like plannotator?", "should_trigger": true, "expected_skill": "plan-review" },
|
|
16
|
+
{ "query": "review this code diff", "should_trigger": true, "expected_skill": "code-review" },
|
|
17
|
+
{ "query": "review pr #42 on github", "should_trigger": true, "expected_skill": "code-review" },
|
|
18
|
+
{ "query": "write the plan first", "should_trigger": true, "expected_skill": "draft-plan", "accept": ["workflow"] },
|
|
19
|
+
{ "query": "browse all our specs as one doc site", "should_trigger": true, "expected_skill": "spec-browser" },
|
|
20
|
+
{ "query": "build the spec index catalog", "should_trigger": true, "expected_skill": "spec-browser" },
|
|
21
|
+
{ "query": "review this google doc proposal", "should_trigger": false, "expected_skill": null }
|
|
22
|
+
]
|