@minionry/minion 0.7.36 → 0.7.39
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/bin/commands/minions.js +19 -0
- package/bin/minion.js +33 -4
- package/dist/server/cli/headless/claude-invoker-process.js +23 -7
- package/dist/server/cli/headless/claude-invoker-stream.js +8 -3
- package/dist/server/cli/headless/haiku-assessments.js +2 -1
- package/dist/server/cli/headless/mcp-config.js +2 -1
- package/dist/server/engines/claude/claude-command.js +1 -0
- package/dist/server/engines/factory.js +2 -0
- package/dist/server/engines/hermes/HermesEngine.js +112 -219
- package/dist/server/engines/hermes/hermes-gateway-registry.js +467 -0
- package/dist/server/index.js +10 -4
- package/dist/server/mcp/bouncer-integration.js +3 -2
- package/dist/server/mcp/classifier/ClaudeBouncerClassifier.js +35 -8
- package/dist/server/mcp/classifier/shadow-eval-scheduler.js +42 -0
- package/dist/server/mcp/classifier/telemetry.js +0 -0
- package/dist/server/mcp/permission-channels.js +176 -0
- package/dist/server/mcp/security-analysis.js +9 -1
- package/dist/server/mcp/security-audit.js +22 -2
- package/dist/server/mcp/security-patterns.js +73 -1
- package/dist/server/mcp/server.js +80 -50
- package/dist/server/routes/internal.js +6 -1
- package/dist/server/routes/notifications.js +6 -18
- package/dist/server/server-setup.js +24 -48
- package/dist/server/services/analytics.js +4 -2
- package/dist/server/services/browser/host-mock.js +6 -1
- package/dist/server/services/browser/host.js +27 -3
- package/dist/server/services/browser/reasoning-agent.js +3 -1
- package/dist/server/services/chain/chain-engine.js +494 -0
- package/dist/server/services/chain/chain-store.js +542 -0
- package/dist/server/services/git/haiku.js +2 -2
- package/dist/server/services/plan/agents/check-injection.md +43 -2
- package/dist/server/services/plan/agents/review-code.md +62 -3
- package/dist/server/services/plan/agents/review-quality.md +52 -2
- package/dist/server/services/plan/board-export.js +4 -0
- package/dist/server/services/plan/composer-prompt.js +27 -8
- package/dist/server/services/plan/composer.js +10 -4
- package/dist/server/services/plan/config-installer.js +4 -83
- package/dist/server/services/plan/executor.js +155 -73
- package/dist/server/services/plan/issue-effort.js +9 -21
- package/dist/server/services/plan/issue-prompt-builder.js +72 -9
- package/dist/server/services/plan/parser-core.js +6 -1
- package/dist/server/services/plan/quality-delta.js +6 -24
- package/dist/server/services/plan/readiness-planner.js +12 -4
- package/dist/server/services/plan/record-file.js +52 -0
- package/dist/server/services/plan/review-approval.js +64 -0
- package/dist/server/services/plan/review-gate.js +186 -77
- package/dist/server/services/plan/review-outcome.js +146 -0
- package/dist/server/services/plan/review-report.js +28 -1
- package/dist/server/services/plan/review-target.js +57 -0
- package/dist/server/services/plan/state-reconciler.js +3 -3
- package/dist/server/services/plan/template-diff.js +2 -0
- package/dist/server/services/plan/template-instantiator.js +4 -0
- package/dist/server/services/plan/watcher.js +11 -1
- package/dist/server/services/platform-reconnect.js +7 -0
- package/dist/server/services/platform-token-lifecycle.js +2 -1
- package/dist/server/services/platform.js +293 -50
- package/dist/server/services/relay-http-client.js +107 -0
- package/dist/server/services/schedule/agent-schedule-store.js +69 -8
- package/dist/server/services/schedule/agent-scheduler.js +48 -7
- package/dist/server/services/schedule/daily-timing.js +52 -0
- package/dist/server/services/schedule/prompt-file.js +55 -0
- package/dist/server/services/schedule/run-bootstrap.js +20 -5
- package/dist/server/services/schedule/schedule-store.js +54 -4
- package/dist/server/services/schedule/schedule-wire.js +17 -0
- package/dist/server/services/schedule/scheduler.js +43 -9
- package/dist/server/services/sdk/agent-schedule.js +294 -0
- package/dist/server/services/sdk/agents.js +95 -13
- package/dist/server/services/sdk/app-tools.js +44 -7
- package/dist/server/services/sdk/atomic-write.js +75 -0
- package/dist/server/services/sdk/browser.js +5 -1
- package/dist/server/services/sdk/composer.js +2 -0
- package/dist/server/services/sdk/file-change-notify.js +60 -13
- package/dist/server/services/sdk/files-app.js +12 -7
- package/dist/server/services/sdk/files-search.js +14 -0
- package/dist/server/services/sdk/files-transfer.js +1 -1
- package/dist/server/services/sdk/files-watch.js +721 -0
- package/dist/server/services/sdk/files-workspace.js +37 -11
- package/dist/server/services/sdk/inference-claude.js +4 -2
- package/dist/server/services/sdk/inference.js +16 -2
- package/dist/server/services/sdk/pm-chain.js +0 -0
- package/dist/server/services/sdk/pm-schedule.js +72 -15
- package/dist/server/services/sdk/pm.js +22 -0
- package/dist/server/services/sdk/rate-limits.js +32 -0
- package/dist/server/services/sdk/registry.js +40 -2
- package/dist/server/services/sdk/terminal.js +1 -1
- package/dist/server/services/sentry.js +5 -1
- package/dist/server/services/terminal/pty-manager.js +26 -11
- package/dist/server/services/terminal/pty-utils.js +12 -1
- package/dist/server/services/terminal/terminal-modes.js +87 -0
- package/dist/server/services/timeline/assembler.js +2 -2
- package/dist/server/services/timeline/index.js +1 -1
- package/dist/server/services/websocket/agent-schedule-handlers.js +62 -4
- package/dist/server/services/websocket/ask-user-question-bridge.js +2 -2
- package/dist/server/services/websocket/browser-agent-runtime.js +3 -1
- package/dist/server/services/websocket/browser-handlers.js +5 -2
- package/dist/server/services/websocket/browser-viewer-lifecycle.js +8 -0
- package/dist/server/services/websocket/file-explorer-handlers.js +17 -0
- package/dist/server/services/websocket/file-transfer-http.js +12 -6
- package/dist/server/services/websocket/handler.js +185 -33
- package/dist/server/services/websocket/msg-id-tracker.js +94 -19
- package/dist/server/services/websocket/plan-execution-handlers.js +33 -5
- package/dist/server/services/websocket/plan-handlers.js +10 -5
- package/dist/server/services/websocket/plan-helpers.js +23 -0
- package/dist/server/services/websocket/plan-issue-handlers.js +161 -4
- package/dist/server/services/websocket/plan-sprint-handlers.js +3 -2
- package/dist/server/services/websocket/schedule-handlers.js +8 -2
- package/dist/server/services/websocket/sdk-agent-host.js +5 -1
- package/dist/server/services/websocket/sdk-agent-schedule-host.js +30 -0
- package/dist/server/services/websocket/sdk-browser-host.js +11 -4
- package/dist/server/services/websocket/sdk-handlers.js +6 -1
- package/dist/server/services/websocket/sdk-pm-chain-host.js +20 -0
- package/dist/server/services/websocket/sdk-pm-execution-host.js +21 -14
- package/dist/server/services/websocket/sdk-pm-schedule-host.js +9 -0
- package/dist/server/services/websocket/sdk-terminal-host.js +7 -0
- package/dist/server/services/websocket/settings-handlers.js +6 -18
- package/dist/server/services/websocket/tab-broadcast.js +5 -1
- package/dist/server/services/websocket/terminal-handlers.js +51 -6
- package/dist/server/services/websocket/types.js +6 -5
- package/dist/server/services/websocket/viewer-interest.js +30 -0
- package/package.json +6 -6
|
@@ -11,6 +11,10 @@ checks: [criteria_met, code_quality, no_obvious_bugs]
|
|
|
11
11
|
|
|
12
12
|
You are a reviewer. Review the work done for issue {{issue_id}}: {{issue_title}}.
|
|
13
13
|
|
|
14
|
+
Verification is your whole job — not redesign. Decide whether what was built
|
|
15
|
+
meets the criteria below, prove each decision against the code you read, and
|
|
16
|
+
write feedback the implementing agent can act on without guessing.
|
|
17
|
+
|
|
14
18
|
## Files Modified
|
|
15
19
|
{{files_modified}}
|
|
16
20
|
|
|
@@ -21,8 +25,11 @@ You are a reviewer. Review the work done for issue {{issue_id}}: {{issue_title}}
|
|
|
21
25
|
{{quality_delta}}
|
|
22
26
|
|
|
23
27
|
## Instructions
|
|
24
|
-
1. Read each modified file listed above
|
|
25
|
-
|
|
28
|
+
1. Read each modified file listed above. Read the code, not the summary — the
|
|
29
|
+
output file says what the agent BELIEVES it did.
|
|
30
|
+
2. Take the acceptance criteria one at a time. For each, find the specific code
|
|
31
|
+
that satisfies it (or establish that nothing does) and note where you found
|
|
32
|
+
it. A criterion you did not check is not a criterion that passed.
|
|
26
33
|
3. Evaluate the quality of the changes:
|
|
27
34
|
- For source code files: look for obvious bugs, security vulnerabilities, or code quality issues
|
|
28
35
|
- For content files (markdown, docs, config, copy): check for accuracy, completeness, and appropriate structure
|
|
@@ -32,7 +39,59 @@ You are a reviewer. Review the work done for issue {{issue_id}}: {{issue_title}}
|
|
|
32
39
|
- "Unavailable" or "Not recorded" is not evidence either way and never fails a review.
|
|
33
40
|
5. Check if the output artifact exists at: {{output_path}}
|
|
34
41
|
|
|
42
|
+
## Rules that make a verdict usable
|
|
43
|
+
|
|
44
|
+
- **Evidence, not impression.** Every failed check needs an `evidence` string
|
|
45
|
+
naming what you actually read: `path/to/file.ts:42`, a quoted criterion, a
|
|
46
|
+
command and its output. If you cannot cite it, you have not checked it —
|
|
47
|
+
either go and check it, or do not fail on it.
|
|
48
|
+
- **Remediation, not complaint.** Every failed check needs a `remediation`
|
|
49
|
+
string naming the concrete change that would make it pass. "Error handling is
|
|
50
|
+
insufficient" is not actionable; "wrap the `fetch` in `api.ts:88` in
|
|
51
|
+
try/catch and surface the failure through the existing `onError` callback"
|
|
52
|
+
is. The next attempt gets your remediation verbatim and little else.
|
|
53
|
+
- **Fail on the criteria, not on taste.** An issue that meets every acceptance
|
|
54
|
+
criterion passes, even if you would have built it differently. Style
|
|
55
|
+
preferences, extra tests you would have liked, and refactors outside the
|
|
56
|
+
issue's scope are not failures. Only fail `code_quality` for a real defect:
|
|
57
|
+
a bug, a security problem, a broken contract.
|
|
58
|
+
- **Say how sure you are.** Set `confidence` honestly: `high` when you read the
|
|
59
|
+
relevant code and the verdict is clear; `medium` when you checked but some
|
|
60
|
+
part rests on inference; `low` when you could not reach the evidence you
|
|
61
|
+
needed, the change is large relative to what you could read, or you are
|
|
62
|
+
genuinely torn. A `low` verdict is re-reviewed by a stronger model, so
|
|
63
|
+
marking one is cheap and free of blame — an overconfident wrong verdict is
|
|
64
|
+
what actually costs.
|
|
65
|
+
|
|
66
|
+
## When the issue CANNOT pass, however many times it is retried
|
|
67
|
+
|
|
68
|
+
Some issues are not failing — they are impossible here. If the work requires a
|
|
69
|
+
privileged (sudo/root) command, a credential or account this machine does not
|
|
70
|
+
hold, a package, service or device that cannot be installed, an unreachable
|
|
71
|
+
external service, or the acceptance criteria contradict each other or the code
|
|
72
|
+
they name, then say so instead of failing it again: set
|
|
73
|
+
`"disposition": "blocked"` and fill in `blocker`. The board records the reason
|
|
74
|
+
and stops re-dispatching the issue, rather than spending its remaining attempts
|
|
75
|
+
rediscovering the same wall.
|
|
76
|
+
|
|
77
|
+
`blocker.kind` must be one of: `needs_privileged_command`, `needs_credentials`,
|
|
78
|
+
`missing_dependency`, `external_service`, `contradictory_criteria`,
|
|
79
|
+
`out_of_scope_environment`.
|
|
80
|
+
|
|
81
|
+
Use it only for a genuine dead end. "The agent did it wrong", "this is hard",
|
|
82
|
+
or "the tests fail" are ordinary failures — return `revise` for those. A
|
|
83
|
+
blocked verdict cancels the issue, so it is checked by a second reviewer before
|
|
84
|
+
it takes effect.
|
|
85
|
+
|
|
86
|
+
## Output
|
|
87
|
+
|
|
35
88
|
Output EXACTLY one JSON object on its own line (no markdown fencing):
|
|
36
|
-
{"passed": true, "checks": [{"name": "criteria_met", "passed": true, "details": "..."}]}
|
|
89
|
+
{"passed": true, "confidence": "high", "checks": [{"name": "criteria_met", "passed": true, "details": "...", "evidence": "..."}]}
|
|
90
|
+
|
|
91
|
+
A failing verdict adds `remediation` to each failed check:
|
|
92
|
+
{"passed": false, "confidence": "high", "checks": [{"name": "criteria_met", "passed": false, "details": "AC2 is not met", "evidence": "web/src/x.ts:42 has no retry path", "remediation": "Add the retry in web/src/x.ts:42 using the existing backoff helper"}]}
|
|
93
|
+
|
|
94
|
+
A blocked verdict adds the disposition and the blocker:
|
|
95
|
+
{"passed": false, "confidence": "high", "disposition": "blocked", "blocker": {"kind": "needs_privileged_command", "detail": "AC1 requires installing a system package via apt-get, which needs root", "humanAction": "Install <pkg> yourself, then re-run the issue"}, "checks": [{"name": "criteria_met", "passed": false, "details": "...", "evidence": "..."}]}
|
|
37
96
|
|
|
38
97
|
Include checks for: criteria_met, code_quality, no_obvious_bugs.
|
|
@@ -11,6 +11,10 @@ checks: [criteria_met, output_quality, completeness]
|
|
|
11
11
|
|
|
12
12
|
You are a quality reviewer. Review the work done for issue {{issue_id}}: {{issue_title}}.
|
|
13
13
|
|
|
14
|
+
Verification is your whole job — not rewriting. Decide whether the deliverable
|
|
15
|
+
meets the criteria below, prove each decision against what you actually read,
|
|
16
|
+
and write feedback the author agent can act on without guessing.
|
|
17
|
+
|
|
14
18
|
## Output File
|
|
15
19
|
{{output_path}}
|
|
16
20
|
|
|
@@ -23,7 +27,10 @@ You are a quality reviewer. Review the work done for issue {{issue_id}}: {{issue
|
|
|
23
27
|
## Instructions
|
|
24
28
|
1. Read the output file at the path above
|
|
25
29
|
2. Read the full issue spec to understand the original requirements and intent
|
|
26
|
-
3.
|
|
30
|
+
3. Take the acceptance criteria one at a time. For each, find the passage that
|
|
31
|
+
satisfies it (or establish that none does) and note where. A criterion you
|
|
32
|
+
did not check is not a criterion that passed.
|
|
33
|
+
4. Evaluate the output against ALL of the following dimensions:
|
|
27
34
|
|
|
28
35
|
### Acceptance Criteria
|
|
29
36
|
- Are all acceptance criteria met? Check each one individually.
|
|
@@ -39,7 +46,50 @@ You are a quality reviewer. Review the work done for issue {{issue_id}}: {{issue
|
|
|
39
46
|
- Are there obvious gaps, missing sections, or incomplete thoughts?
|
|
40
47
|
- If the issue requested specific deliverables (e.g., a plan, analysis, document), are all deliverables present?
|
|
41
48
|
|
|
49
|
+
## Rules that make a verdict usable
|
|
50
|
+
|
|
51
|
+
- **Evidence, not impression.** Every failed check needs an `evidence` string
|
|
52
|
+
naming what you actually read: a section heading, a quoted sentence, the
|
|
53
|
+
criterion it fails against. If you cannot cite it, you have not checked it.
|
|
54
|
+
- **Remediation, not complaint.** Every failed check needs a `remediation`
|
|
55
|
+
string naming the concrete change that would make it pass — which section to
|
|
56
|
+
add, which claim to support, which gap to close. The next attempt gets your
|
|
57
|
+
remediation verbatim and little else.
|
|
58
|
+
- **Fail on the criteria, not on taste.** A deliverable that meets every
|
|
59
|
+
acceptance criterion passes, even if you would have written it differently.
|
|
60
|
+
Length, structure and style preferences are not failures unless a criterion
|
|
61
|
+
names them.
|
|
62
|
+
- **Say how sure you are.** Set `confidence` honestly: `high` when you read the
|
|
63
|
+
deliverable and the verdict is clear; `medium` when part of it rests on
|
|
64
|
+
inference; `low` when you could not reach what you needed or you are
|
|
65
|
+
genuinely torn. A `low` verdict is re-reviewed by a stronger model, so
|
|
66
|
+
marking one is cheap — an overconfident wrong verdict is what costs.
|
|
67
|
+
|
|
68
|
+
## When the issue CANNOT pass, however many times it is retried
|
|
69
|
+
|
|
70
|
+
If the deliverable requires information, access or an action that is not
|
|
71
|
+
available here — a credential or account this machine does not hold, an
|
|
72
|
+
unreachable external source, a privileged command, or acceptance criteria that
|
|
73
|
+
contradict each other — say so instead of failing it again: set
|
|
74
|
+
`"disposition": "blocked"` and fill in `blocker`. The board records the reason
|
|
75
|
+
and stops re-dispatching the issue.
|
|
76
|
+
|
|
77
|
+
`blocker.kind` must be one of: `needs_privileged_command`, `needs_credentials`,
|
|
78
|
+
`missing_dependency`, `external_service`, `contradictory_criteria`,
|
|
79
|
+
`out_of_scope_environment`.
|
|
80
|
+
|
|
81
|
+
Use it only for a genuine dead end. A thin, wrong or incomplete document is an
|
|
82
|
+
ordinary failure — return `revise` for that.
|
|
83
|
+
|
|
84
|
+
## Output
|
|
85
|
+
|
|
42
86
|
Output EXACTLY one JSON object on its own line (no markdown fencing):
|
|
43
|
-
{"passed": true, "checks": [{"name": "criteria_met", "passed": true, "details": "..."}]}
|
|
87
|
+
{"passed": true, "confidence": "high", "checks": [{"name": "criteria_met", "passed": true, "details": "...", "evidence": "..."}]}
|
|
88
|
+
|
|
89
|
+
A failing verdict adds `remediation` to each failed check:
|
|
90
|
+
{"passed": false, "confidence": "high", "checks": [{"name": "completeness", "passed": false, "details": "No risks section", "evidence": "The document ends at '## Timeline'", "remediation": "Add a '## Risks' section covering the three dependencies named in the spec"}]}
|
|
91
|
+
|
|
92
|
+
A blocked verdict adds the disposition and the blocker:
|
|
93
|
+
{"passed": false, "confidence": "high", "disposition": "blocked", "blocker": {"kind": "needs_credentials", "detail": "AC2 requires pulling figures from the billing dashboard, which needs an account this Space does not have", "humanAction": "Export the figures yourself and attach them, then re-run the issue"}, "checks": [{"name": "criteria_met", "passed": false, "details": "...", "evidence": "..."}]}
|
|
44
94
|
|
|
45
95
|
Include checks for: criteria_met, output_quality, completeness.
|
|
@@ -106,6 +106,10 @@ function toTemplateIssue(issue, known, ctx) {
|
|
|
106
106
|
out.effort_level = issue.effortLevel;
|
|
107
107
|
if (issue.fastMode != null)
|
|
108
108
|
out.fast_mode = issue.fastMode;
|
|
109
|
+
if (issue.reviewModel)
|
|
110
|
+
out.review_model = issue.reviewModel;
|
|
111
|
+
if (issue.reviewEffort)
|
|
112
|
+
out.review_effort = issue.reviewEffort;
|
|
109
113
|
return out;
|
|
110
114
|
}
|
|
111
115
|
export function buildBoardTemplate(boardState, ctx, options = {}) {
|
|
@@ -17,7 +17,8 @@ created: "YYYY-MM-DD"
|
|
|
17
17
|
blocked_by: [] # Use backlog-relative paths: backlog/IS-NNN.md
|
|
18
18
|
blocks: [] # Use backlog-relative paths: backlog/IS-NNN.md
|
|
19
19
|
review_gate: auto
|
|
20
|
-
review_model:
|
|
20
|
+
review_model: sonnet # model that runs the AI review gate — see "review_model rules" below
|
|
21
|
+
review_effort: high # reasoning effort for the review gate
|
|
21
22
|
output_type: auto # code = modify source files, document = produce written artifact, auto = infer
|
|
22
23
|
output_file: null
|
|
23
24
|
agents: [] # Agent hints — see "agents field rules" below
|
|
@@ -71,13 +72,31 @@ detail transfers your judgment; speculation transfers your mistakes.
|
|
|
71
72
|
|
|
72
73
|
## review_model rules
|
|
73
74
|
|
|
74
|
-
\`review_model\`
|
|
75
|
-
issue's implementation completes.
|
|
76
|
-
|
|
77
|
-
quality equalizer
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
\`review_model\` and \`review_effort\` name the model and reasoning effort that
|
|
76
|
+
run the AI review gate after the issue's implementation completes. The gate is
|
|
77
|
+
the quality equalizer that lets cheaper execution models deliver
|
|
78
|
+
frontier-quality results — but the equalizer does not have to be the most
|
|
79
|
+
expensive model on the board to work.
|
|
80
|
+
|
|
81
|
+
Pick the reviewer for a different question than the executor: not "how hard is
|
|
82
|
+
this to build" but **"how hard is this to CHECK"**. Verifying that work meets
|
|
83
|
+
stated acceptance criteria is a substantially easier task than producing that
|
|
84
|
+
work, so the reviewer usually belongs at or below the executor's rung. Write
|
|
85
|
+
acceptance criteria a reviewer can verify objectively and the reviewer can be
|
|
86
|
+
cheap; write vague ones and no reviewer is good enough.
|
|
87
|
+
|
|
88
|
+
- \`haiku\` / \`auto\` — mechanical or documentation issues whose criteria are
|
|
89
|
+
literally checkable.
|
|
90
|
+
- \`sonnet\` / \`high\` — the default for the large majority of issues,
|
|
91
|
+
including most \`opus\` ones.
|
|
92
|
+
- \`opus\` / \`high\` — where a wrong PASS is expensive: security, auth,
|
|
93
|
+
payments, data migrations, concurrency, or criteria needing real judgement.
|
|
94
|
+
- \`fable\` / \`xhigh\` — the rare architecture-critical issue only.
|
|
95
|
+
|
|
96
|
+
The gate escalates a low-confidence verdict one rung higher on its own, so
|
|
97
|
+
routing a review low is a cost decision rather than a quality one. Never write
|
|
98
|
+
\`review_effort: max\`: review is bounded verification work and \`max\`
|
|
99
|
+
overthinks it.
|
|
81
100
|
|
|
82
101
|
## Issue scoping rules (critical for execution quality)
|
|
83
102
|
|
|
@@ -15,6 +15,7 @@ import { ISSUE_FORMAT_SPEC } from './composer-prompt.js';
|
|
|
15
15
|
import { defaultPmDir, getNextId, parseBoardDirectory, parsePlanDirectory, resolvePmDir } from './parser.js';
|
|
16
16
|
import { createPlanRunner } from './plan-runner-factory.js';
|
|
17
17
|
import { PM_COMPOSER_ISSUE_ID } from './pm-timeline.js';
|
|
18
|
+
import { broadcastPlanStateIfChanged } from './watcher.js';
|
|
18
19
|
const PLANNING_SETTLE_MS = 90_000;
|
|
19
20
|
const PLANNING_TOKEN_SILENCE_MS = 120_000;
|
|
20
21
|
const PLANNING_SETTLE_CHECK_INTERVAL_MS = 10_000;
|
|
@@ -243,7 +244,7 @@ Add these exact fields to EVERY issue's YAML front matter — identical values f
|
|
|
243
244
|
- \`model: ${model}\`
|
|
244
245
|
- \`effort_level: ${effort}\`
|
|
245
246
|
- \`fast_mode: ${fast}\`
|
|
246
|
-
- \`review_model:
|
|
247
|
+
- \`review_model: ${model}\` and \`review_effort: high\` — review on the same rung the issue executes on (checking work is cheaper than doing it, so this is the conservative default; see review_model rules)
|
|
247
248
|
`;
|
|
248
249
|
}
|
|
249
250
|
export function buildModelDirectiveBlock(directive, globalDefaults) {
|
|
@@ -264,9 +265,14 @@ Assign an execution model to EACH issue based on its complexity by adding these
|
|
|
264
265
|
- \`model:\` one of \`haiku\` (trivial/mechanical/doc work), \`sonnet\` (standard implementation — the default for the large majority of issues, including standard bug fixes and features), \`opus\` (difficult agentic coding — hard multi-file features, larger refactors, deep multi-step debugging, and long-horizon work spanning many subsystems; since Opus 5 this band is a real capability step over sonnet at the same Opus price as before), or \`fable\` (reserve for the rare architecture-critical issue where a wrong design decision is expensive to unwind)
|
|
265
266
|
- \`effort_level:\` \`high\` for standard \`sonnet\` issues; \`xhigh\` for EVERY \`opus\` issue and for the hardest \`sonnet\`/\`fable\` issues (on Opus 5 and Sonnet 5, xhigh is the recommended effort for agentic coding — it outperforms the other levels while spending fewer output tokens than max); \`max\` only when correctness matters more than cost and latency — it can overthink routine work; \`low\` or \`medium\` for trivial/mechanical work (both punch far above their weight on this generation; \`auto\` is NOT the cheap option — it resolves to the model's recommended band). Haiku ignores effort — use \`auto\` for Haiku issues.
|
|
266
267
|
- \`fast_mode:\` \`false\` by default. Fast mode is Opus-only (latency-prioritized output at premium price) — set \`true\` only on an \`opus\` issue where the user explicitly asked for the fastest possible turnaround.
|
|
267
|
-
- \`review_model
|
|
268
|
+
- \`review_model:\` and \`review_effort:\` — the model that runs the AI review gate for this issue, chosen the same way, but for a DIFFERENT question: not "how hard is this to build" but "how hard is this to CHECK". Verifying that work meets stated criteria is a substantially easier task than producing it, so the reviewer usually belongs at or below the executor's rung:
|
|
269
|
+
- \`review_model: haiku\`, \`review_effort: auto\` — mechanical or documentation issues whose criteria are literally checkable (a file exists, a string appears, a list is complete).
|
|
270
|
+
- \`review_model: sonnet\`, \`review_effort: high\` — **the default for the large majority of issues**, including every standard \`sonnet\` issue and most \`opus\` ones. Reading a diff against explicit acceptance criteria is well within this rung.
|
|
271
|
+
- \`review_model: opus\`, \`review_effort: high\` — issues where a wrong PASS is expensive: security, auth, payments, data migrations, concurrency, or criteria that need real judgement rather than a lookup.
|
|
272
|
+
- \`review_model: fable\`, \`review_effort: xhigh\` — reserve for the same rare architecture-critical issues you would give \`model: fable\`. Do not use it as a blanket safety net; it is the most expensive setting on the board.
|
|
273
|
+
A low-confidence verdict is automatically re-reviewed one rung higher, so routing a review low is a cost decision, not a quality one — the cascade catches an unsure cheap reviewer on its own. Never write \`review_effort: max\`: review is bounded verification work and \`max\` overthinks it.
|
|
268
274
|
|
|
269
|
-
A well-written issue closes most of the capability gap, and the
|
|
275
|
+
A well-written issue closes most of the capability gap, and the review gate catches what the executor misses — so pick the cheapest model that can do the job well: most issues should be \`sonnet\`; when in doubt between \`sonnet\` and \`opus\` on standard work, pick \`sonnet\`. Do NOT under-route genuinely hard work though: hard multi-file and long-horizon issues belong on \`opus\` at \`xhigh\`.
|
|
270
276
|
`;
|
|
271
277
|
}
|
|
272
278
|
export const SYNTHESIS_MODEL = 'sonnet';
|
|
@@ -537,7 +543,7 @@ function reportPlanningResult(ctx, args) {
|
|
|
537
543
|
}
|
|
538
544
|
const updatedState = parsePlanDirectory(workingDir);
|
|
539
545
|
if (updatedState) {
|
|
540
|
-
ctx
|
|
546
|
+
broadcastPlanStateIfChanged(ctx, workingDir, updatedState);
|
|
541
547
|
}
|
|
542
548
|
}
|
|
543
549
|
export async function handlePlanPrompt(ctx, _ws, userPrompt, workingDir, options = {}) {
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
2
|
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
const REQUIRED_PERMISSIONS = [
|
|
6
|
-
'Bash',
|
|
7
|
-
'Read',
|
|
8
|
-
'Edit',
|
|
9
|
-
'Write',
|
|
10
|
-
'Glob',
|
|
11
|
-
'Grep',
|
|
12
|
-
'WebFetch',
|
|
13
|
-
'WebSearch',
|
|
14
|
-
];
|
|
15
5
|
function restoreFromBackup(backupPath, targetPath) {
|
|
16
6
|
try {
|
|
17
7
|
if (!existsSync(backupPath))
|
|
@@ -28,76 +18,7 @@ function restoreFromBackup(backupPath, targetPath) {
|
|
|
28
18
|
}
|
|
29
19
|
catch { }
|
|
30
20
|
}
|
|
31
|
-
export
|
|
32
|
-
workingDir;
|
|
33
|
-
|
|
34
|
-
claudeSettingsInstalled = false;
|
|
35
|
-
constructor(workingDir) {
|
|
36
|
-
this.workingDir = workingDir;
|
|
37
|
-
this.recoverFromCrash();
|
|
38
|
-
}
|
|
39
|
-
recoverFromCrash() {
|
|
40
|
-
restoreFromBackup(join(this.workingDir, '.claude', 'settings.json.pm-backup'), join(this.workingDir, '.claude', 'settings.json'));
|
|
41
|
-
restoreFromBackup(join(this.workingDir, '.mcp.json.pm-backup'), join(this.workingDir, '.mcp.json'));
|
|
42
|
-
}
|
|
43
|
-
installPermissions() {
|
|
44
|
-
if (this.claudeSettingsInstalled)
|
|
45
|
-
return;
|
|
46
|
-
const claudeDir = join(this.workingDir, '.claude');
|
|
47
|
-
const settingsPath = join(claudeDir, 'settings.json');
|
|
48
|
-
if (!existsSync(claudeDir)) {
|
|
49
|
-
mkdirSync(claudeDir, { recursive: true });
|
|
50
|
-
}
|
|
51
|
-
const backupPath = join(claudeDir, 'settings.json.pm-backup');
|
|
52
|
-
try {
|
|
53
|
-
if (existsSync(settingsPath)) {
|
|
54
|
-
this.savedClaudeSettings = readFileSync(settingsPath, 'utf-8');
|
|
55
|
-
writeFileSync(backupPath, this.savedClaudeSettings);
|
|
56
|
-
const existing = JSON.parse(this.savedClaudeSettings);
|
|
57
|
-
if (!existing.permissions)
|
|
58
|
-
existing.permissions = {};
|
|
59
|
-
if (!existing.permissions.allow)
|
|
60
|
-
existing.permissions.allow = [];
|
|
61
|
-
for (const tool of REQUIRED_PERMISSIONS) {
|
|
62
|
-
if (!existing.permissions.allow.includes(tool)) {
|
|
63
|
-
existing.permissions.allow.push(tool);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
this.savedClaudeSettings = null;
|
|
70
|
-
writeFileSync(backupPath, '__NONE__');
|
|
71
|
-
writeFileSync(settingsPath, JSON.stringify({
|
|
72
|
-
permissions: { allow: REQUIRED_PERMISSIONS },
|
|
73
|
-
}, null, 2));
|
|
74
|
-
}
|
|
75
|
-
this.claudeSettingsInstalled = true;
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
uninstallPermissions() {
|
|
81
|
-
if (!this.claudeSettingsInstalled)
|
|
82
|
-
return;
|
|
83
|
-
const settingsPath = join(this.workingDir, '.claude', 'settings.json');
|
|
84
|
-
const backupPath = join(this.workingDir, '.claude', 'settings.json.pm-backup');
|
|
85
|
-
try {
|
|
86
|
-
if (this.savedClaudeSettings !== null) {
|
|
87
|
-
writeFileSync(settingsPath, this.savedClaudeSettings);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
unlinkSync(settingsPath);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
if (existsSync(backupPath))
|
|
97
|
-
unlinkSync(backupPath);
|
|
98
|
-
}
|
|
99
|
-
catch { }
|
|
100
|
-
this.savedClaudeSettings = null;
|
|
101
|
-
this.claudeSettingsInstalled = false;
|
|
102
|
-
}
|
|
21
|
+
export function restoreInterruptedWaveSettings(workingDir) {
|
|
22
|
+
restoreFromBackup(join(workingDir, '.claude', 'settings.json.pm-backup'), join(workingDir, '.claude', 'settings.json'));
|
|
23
|
+
restoreFromBackup(join(workingDir, '.mcp.json.pm-backup'), join(workingDir, '.mcp.json'));
|
|
103
24
|
}
|