mixdog 0.9.4 → 0.9.6
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 +112 -38
- package/package.json +4 -1
- package/scripts/bench/r5-orchestrated-task.json +7 -0
- package/scripts/bench/round-r13-clientmeta.json +464 -0
- package/scripts/bench/round-r14-betafeatures.json +466 -0
- package/scripts/bench/round-r15-fulldefault.json +462 -0
- package/scripts/bench/round-r16-sessionid.json +466 -0
- package/scripts/bench/round-r17-wirebytes.json +456 -0
- package/scripts/bench/round-r18-prewarm.json +468 -0
- package/scripts/bench/round-r19-clean.json +472 -0
- package/scripts/bench/round-r20-prewarm-clean.json +475 -0
- package/scripts/bench/round-r21-delta-retry.json +473 -0
- package/scripts/bench/round-r22-full-probe.json +693 -0
- package/scripts/bench/round-r23-itemprobe.json +701 -0
- package/scripts/bench/round-r24-shapefix.json +677 -0
- package/scripts/bench/round-r25-serial.json +464 -0
- package/scripts/bench/round-r26-parallel3.json +671 -0
- package/scripts/bench/round-r27-parallel10.json +894 -0
- package/scripts/bench/round-r28-parallel10-stagger.json +882 -0
- package/scripts/bench/round-r29-parallel10-stagger166.json +886 -0
- package/scripts/bench/round-r30-instid.json +253 -0
- package/scripts/bench/round-r31-upgradeprobe.json +256 -0
- package/scripts/bench/round-r32-vs-codex-lead.json +254 -0
- package/scripts/bench/round-r33-vs-codex-codex.json +115 -0
- package/scripts/bench/round-r34-orchestrated.json +120 -0
- package/scripts/bench/round-r35-orchestrated-codex.json +61 -0
- package/scripts/bench/round-r36-orchestrated-capped.json +128 -0
- package/scripts/bench-run.mjs +40 -7
- package/scripts/internal-comms-bench.mjs +2 -4
- package/scripts/model-catalog-audit.mjs +209 -0
- package/scripts/model-list-sanitize-test.mjs +37 -0
- package/scripts/recall-bench.mjs +76 -13
- package/scripts/recall-quality-cases.json +12 -0
- package/scripts/tool-smoke.mjs +2 -2
- package/src/agents/heavy-worker/AGENT.md +7 -7
- package/src/agents/scheduler-task/AGENT.md +2 -3
- package/src/agents/webhook-handler/AGENT.md +2 -3
- package/src/agents/worker/AGENT.md +9 -10
- package/src/app.mjs +12 -1
- package/src/headless-role.mjs +7 -1
- package/src/mixdog-session-runtime.mjs +15 -14
- package/src/output-styles/default.md +14 -18
- package/src/output-styles/minimal.md +4 -5
- package/src/output-styles/simple.md +7 -8
- package/src/rules/agent/00-common.md +6 -5
- package/src/rules/agent/30-explorer.md +16 -5
- package/src/rules/lead/01-general.md +5 -5
- package/src/rules/lead/lead-brief.md +6 -3
- package/src/rules/lead/lead-tool.md +6 -4
- package/src/rules/shared/01-tool.md +17 -21
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +8 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +53 -9
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +11 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +33 -4
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +93 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +1 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/channels/backends/discord-gateway.mjs +2 -2
- package/src/runtime/channels/backends/discord.mjs +15 -26
- package/src/runtime/channels/backends/telegram.mjs +8 -12
- package/src/runtime/channels/index.mjs +23 -43
- package/src/runtime/channels/lib/backend-dispatch.mjs +5 -3
- package/src/runtime/channels/lib/config.mjs +37 -149
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -4
- package/src/runtime/channels/lib/event-queue.mjs +15 -9
- package/src/runtime/channels/lib/inbound-routing.mjs +2 -39
- package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
- package/src/runtime/channels/lib/scheduler.mjs +27 -113
- package/src/runtime/channels/lib/webhook/deliveries.mjs +3 -2
- package/src/runtime/channels/lib/webhook.mjs +8 -47
- package/src/runtime/memory/index.mjs +9 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
- package/src/runtime/memory/lib/ko-morph.mjs +195 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +47 -10
- package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
- package/src/runtime/memory/lib/query-handlers.mjs +27 -5
- package/src/runtime/memory/tool-defs.mjs +2 -2
- package/src/runtime/shared/config.mjs +14 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +19 -0
- package/src/runtime/shared/schedules-store.mjs +13 -3
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/session-runtime/config-helpers.mjs +45 -10
- package/src/session-runtime/quick-model-rows.mjs +46 -11
- package/src/session-runtime/quick-search-models.mjs +28 -27
- package/src/session-runtime/settings-api.mjs +34 -1
- package/src/session-runtime/tool-defs.mjs +1 -1
- package/src/session-runtime/workflow.mjs +1 -1
- package/src/standalone/agent-tool/tool-def.mjs +1 -1
- package/src/standalone/agent-tool.mjs +30 -0
- package/src/standalone/channel-admin.mjs +102 -90
- package/src/standalone/explore-tool.mjs +39 -10
- package/src/tui/App.jsx +131 -28
- package/src/tui/app/app-format.mjs +11 -4
- package/src/tui/app/channel-pickers.mjs +2 -4
- package/src/tui/app/maintenance-pickers.mjs +60 -28
- package/src/tui/app/model-options.mjs +5 -1
- package/src/tui/app/settings-picker.mjs +0 -1
- package/src/tui/app/transcript-window.mjs +8 -2
- package/src/tui/app/use-transcript-scroll.mjs +3 -1
- package/src/tui/app/use-transcript-window.mjs +19 -1
- package/src/tui/components/ConfirmBar.jsx +10 -7
- package/src/tui/components/Picker.jsx +32 -11
- package/src/tui/components/PromptInput.jsx +10 -1
- package/src/tui/components/StatusLine.jsx +6 -3
- package/src/tui/dist/index.mjs +441 -293
- package/src/tui/engine.mjs +48 -12
- package/src/tui/index.jsx +11 -52
- package/src/ui/statusline.mjs +10 -0
- package/src/workflows/default/WORKFLOW.md +15 -17
- package/src/workflows/sequential/WORKFLOW.md +15 -17
- package/vendor/ink/build/ink.js +9 -1
- package/scripts/recall-usecase-probe.json +0 -6
- package/src/runtime/channels/lib/holidays.mjs +0 -138
package/scripts/recall-bench.mjs
CHANGED
|
@@ -68,27 +68,67 @@ function textOfResult(result) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function countEntryLines(text) {
|
|
71
|
-
|
|
72
|
-
if (!t || t === '(no results)' || t === '(no valid ids)') return 0;
|
|
73
|
-
return t.split('\n').filter((line) => line.trim() && !line.startsWith('[recall truncated') && !line.startsWith('note:')).length;
|
|
71
|
+
return resultLines(text).length;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
function topN(text, n = 3, maxLen = 140) {
|
|
77
|
-
|
|
78
|
-
if (!t || t === '(no results)') return [];
|
|
79
|
-
return t.split('\n')
|
|
80
|
-
.filter((line) => line.trim() && !line.startsWith('[recall truncated') && !line.startsWith('note:'))
|
|
75
|
+
return resultLines(text)
|
|
81
76
|
.slice(0, n)
|
|
82
77
|
.map((line) => (line.length > maxLen ? `${line.slice(0, maxLen - 1)}…` : line));
|
|
83
78
|
}
|
|
84
79
|
|
|
85
|
-
|
|
80
|
+
// Full ordered list of result lines (no slice), used for topNContains rank
|
|
81
|
+
// scoring. Same filtering rule as countEntryLines/topN.
|
|
82
|
+
function resultLines(text) {
|
|
83
|
+
const t = String(text || '').trim();
|
|
84
|
+
if (!t || t === '(no results)' || t === '(no valid ids)') return [];
|
|
85
|
+
return t.split('\n').filter((line) => {
|
|
86
|
+
const trimmed = line.trim();
|
|
87
|
+
return trimmed
|
|
88
|
+
&& !trimmed.startsWith('[recall truncated')
|
|
89
|
+
&& !trimmed.startsWith('note:')
|
|
90
|
+
&& !/^\[[^\]]+\]$/.test(trimmed);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Score expect.topNContains: for each expected substring, find the 1-indexed
|
|
95
|
+
// rank of the first result line containing it (case-insensitive), over the
|
|
96
|
+
// FULL result list (not just the topN cutoff) so we can tell "missed
|
|
97
|
+
// entirely" from "present but ranked below cutoff". hit@N/MRR are then
|
|
98
|
+
// computed against the topN cutoff.
|
|
99
|
+
function scoreTopNContains(lines, substrings, n) {
|
|
100
|
+
const lower = lines.map((l) => l.toLowerCase());
|
|
101
|
+
const perSubstring = substrings.map((needle) => {
|
|
102
|
+
const hay = String(needle || '').toLowerCase();
|
|
103
|
+
let rank = null;
|
|
104
|
+
for (let i = 0; i < lower.length; i++) {
|
|
105
|
+
if (hay && lower[i].includes(hay)) { rank = i + 1; break; }
|
|
106
|
+
}
|
|
107
|
+
const hit = rank !== null && rank <= n;
|
|
108
|
+
return { needle, rank, hit, rr: hit ? 1 / rank : 0 };
|
|
109
|
+
});
|
|
110
|
+
const total = perSubstring.length || 1;
|
|
111
|
+
const hitAtN = perSubstring.reduce((s, p) => s + (p.hit ? 1 : 0), 0) / total;
|
|
112
|
+
const mrr = perSubstring.reduce((s, p) => s + p.rr, 0) / total;
|
|
113
|
+
return { perSubstring, hitAtN, mrr, n };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function evaluateCase(kase, { count, ms, isError }, quality) {
|
|
86
117
|
const warnings = [];
|
|
87
118
|
if (isError) warnings.push('error result');
|
|
88
119
|
if (ms > WARN_LATENCY_MS) warnings.push(`latency ${ms}ms > ${WARN_LATENCY_MS}ms`);
|
|
89
120
|
if ((kase.expect === 'browse' || kase.expect === 'idlookup') && count === 0) {
|
|
90
121
|
warnings.push('0 results for a browse/id-lookup case (expected data present)');
|
|
91
122
|
}
|
|
123
|
+
if (quality) {
|
|
124
|
+
for (const p of quality.perSubstring) {
|
|
125
|
+
if (!p.hit) {
|
|
126
|
+
warnings.push(p.rank === null
|
|
127
|
+
? `topNContains miss: "${p.needle}" not found in results`
|
|
128
|
+
: `topNContains miss: "${p.needle}" found at rank ${p.rank} > topN ${quality.n}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
92
132
|
const status = warnings.length ? 'WARN' : 'PASS';
|
|
93
133
|
return { status, warnings };
|
|
94
134
|
}
|
|
@@ -109,7 +149,14 @@ async function runCase(memoryModule, kase) {
|
|
|
109
149
|
const ms = Date.now() - started;
|
|
110
150
|
const text = textOfResult(result);
|
|
111
151
|
const count = countEntryLines(text);
|
|
112
|
-
|
|
152
|
+
// expect stays a plain string for legacy cases ('results'/'browse'/'idlookup').
|
|
153
|
+
// New quality cases use an object: { kind?, topNContains: [...], topN? }.
|
|
154
|
+
const expectObj = kase.expect && typeof kase.expect === 'object' ? kase.expect : null;
|
|
155
|
+
const expectKind = expectObj ? expectObj.kind : kase.expect;
|
|
156
|
+
const topNContains = expectObj && Array.isArray(expectObj.topNContains) ? expectObj.topNContains : null;
|
|
157
|
+
const cutoffN = expectObj && Number.isInteger(expectObj.topN) ? expectObj.topN : 5;
|
|
158
|
+
const quality = topNContains ? scoreTopNContains(resultLines(text), topNContains, cutoffN) : null;
|
|
159
|
+
const evalResult = evaluateCase({ ...kase, expect: expectKind }, { count, ms, isError }, quality);
|
|
113
160
|
return {
|
|
114
161
|
id: kase.id,
|
|
115
162
|
label: kase.label,
|
|
@@ -119,6 +166,7 @@ async function runCase(memoryModule, kase) {
|
|
|
119
166
|
isError,
|
|
120
167
|
errMsg,
|
|
121
168
|
top3: topN(text, 3),
|
|
169
|
+
quality,
|
|
122
170
|
status: evalResult.status,
|
|
123
171
|
warnings: evalResult.warnings,
|
|
124
172
|
};
|
|
@@ -128,6 +176,12 @@ function printCase(row) {
|
|
|
128
176
|
process.stdout.write(`\n[${row.status}] ${row.id} — ${row.label}\n`);
|
|
129
177
|
process.stdout.write(` params: ${JSON.stringify(row.args)}\n`);
|
|
130
178
|
process.stdout.write(` results: ${row.count} latency: ${row.ms}ms${row.isError ? ` ERROR: ${row.errMsg}` : ''}\n`);
|
|
179
|
+
if (row.quality) {
|
|
180
|
+
process.stdout.write(` hit@${row.quality.n}: ${row.quality.hitAtN.toFixed(2)} MRR: ${row.quality.mrr.toFixed(2)}\n`);
|
|
181
|
+
for (const p of row.quality.perSubstring) {
|
|
182
|
+
process.stdout.write(` substr "${p.needle}" -> rank ${p.rank ?? 'none'}${p.hit ? '' : ' (miss)'}\n`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
131
185
|
if (row.top3.length) {
|
|
132
186
|
for (const line of row.top3) process.stdout.write(` - ${line}\n`);
|
|
133
187
|
} else {
|
|
@@ -138,18 +192,27 @@ function printCase(row) {
|
|
|
138
192
|
|
|
139
193
|
function printSummary(rows) {
|
|
140
194
|
process.stdout.write('\n=== recall-bench summary ===\n');
|
|
141
|
-
const widths = { id: 18, results: 8, ms: 8, status: 6 };
|
|
195
|
+
const widths = { id: 18, results: 8, ms: 8, status: 6, hit: 9, mrr: 7 };
|
|
142
196
|
process.stdout.write(
|
|
143
|
-
`${'case'.padEnd(widths.id)}${'results'.padEnd(widths.results)}${'ms'.padEnd(widths.ms)}${'status'.padEnd(widths.status)}notes\n`,
|
|
197
|
+
`${'case'.padEnd(widths.id)}${'results'.padEnd(widths.results)}${'ms'.padEnd(widths.ms)}${'status'.padEnd(widths.status)}${'hit@N'.padEnd(widths.hit)}${'MRR'.padEnd(widths.mrr)}notes\n`,
|
|
144
198
|
);
|
|
145
199
|
for (const r of rows) {
|
|
200
|
+
const hitStr = r.quality ? r.quality.hitAtN.toFixed(2) : '-';
|
|
201
|
+
const mrrStr = r.quality ? r.quality.mrr.toFixed(2) : '-';
|
|
146
202
|
process.stdout.write(
|
|
147
|
-
`${String(r.id).padEnd(widths.id)}${String(r.count).padEnd(widths.results)}${String(r.ms).padEnd(widths.ms)}${String(r.status).padEnd(widths.status)}${r.warnings.join('; ')}\n`,
|
|
203
|
+
`${String(r.id).padEnd(widths.id)}${String(r.count).padEnd(widths.results)}${String(r.ms).padEnd(widths.ms)}${String(r.status).padEnd(widths.status)}${hitStr.padEnd(widths.hit)}${mrrStr.padEnd(widths.mrr)}${r.warnings.join('; ')}\n`,
|
|
148
204
|
);
|
|
149
205
|
}
|
|
150
206
|
const warnCount = rows.filter((r) => r.status === 'WARN').length;
|
|
151
207
|
const totalMs = rows.reduce((s, r) => s + r.ms, 0);
|
|
152
|
-
|
|
208
|
+
const qualityRows = rows.filter((r) => r.quality);
|
|
209
|
+
let aggLine = '';
|
|
210
|
+
if (qualityRows.length) {
|
|
211
|
+
const aggHit = qualityRows.reduce((s, r) => s + r.quality.hitAtN, 0) / qualityRows.length;
|
|
212
|
+
const aggMrr = qualityRows.reduce((s, r) => s + r.quality.mrr, 0) / qualityRows.length;
|
|
213
|
+
aggLine = ` agg_hit@N=${aggHit.toFixed(3)} agg_MRR=${aggMrr.toFixed(3)} (${qualityRows.length} scored cases)`;
|
|
214
|
+
}
|
|
215
|
+
process.stdout.write(`\ncases=${rows.length} pass=${rows.length - warnCount} warn=${warnCount} total_latency=${totalMs}ms${aggLine}\n`);
|
|
153
216
|
}
|
|
154
217
|
|
|
155
218
|
async function main() {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "id": "q-kr-recall-phrase", "label": "Korean distinctive phrase: persistent memory", "args": { "query": "영속 메모리" }, "expect": { "kind": "results", "topNContains": ["영속 메모리"], "topN": 5 } },
|
|
3
|
+
{ "id": "q-en-recall-pipeline", "label": "English distinctive phrase: recall fast-track builder", "args": { "query": "buildRecallFastTrackQuery" }, "expect": { "kind": "results", "topNContains": ["buildRecallFastTrackQuery"], "topN": 5 } },
|
|
4
|
+
{ "id": "q-cycle1-drain", "label": "cycle1 ECONNRESET topic", "args": { "query": "cycle1 ECONNRESET" }, "expect": { "kind": "results", "topNContains": ["cycle1", "ECONNRESET"], "topN": 5 } },
|
|
5
|
+
{ "id": "q-recall-general", "label": "bare recall keyword", "args": { "query": "recall" }, "expect": { "kind": "results", "topNContains": ["recall"], "topN": 5 } },
|
|
6
|
+
{ "id": "q-uc4-topic-kr", "label": "UC4 topic query with Korean qualifier", "args": { "query": "recall period last 개선", "limit": 8 }, "expect": { "kind": "results", "topNContains": ["개선"], "topN": 5 } },
|
|
7
|
+
{ "id": "q-recall-improve-kr", "label": "cache improvement topic", "args": { "query": "캐시 개선" }, "expect": { "kind": "results", "topNContains": ["개선"], "topN": 5 } },
|
|
8
|
+
{ "id": "q-battle-balance", "label": "ProjectAA topic", "args": { "query": "ProjectAA" }, "expect": { "kind": "results", "topNContains": ["ProjectAA"], "topN": 5 } },
|
|
9
|
+
{ "id": "q-fanout-recall-battle", "label": "fan-out array query cache+ProjectAA", "args": { "query": ["캐시 개선", "ProjectAA"], "limit": 5 }, "expect": { "kind": "results", "topNContains": ["개선", "ProjectAA"], "topN": 10 } },
|
|
10
|
+
{ "id": "q-short-2tok-cycle", "label": "short 2-token cycle1 query", "args": { "query": "cycle1 drain", "limit": 8 }, "expect": { "kind": "results", "topNContains": ["cycle1"], "topN": 3 } },
|
|
11
|
+
{ "id": "q-recall-scope-project", "label": "project-scoped recall query", "args": { "query": "recall", "cwd": "C:\\Project\\mixdog" , "limit": 10 }, "expect": { "kind": "results", "topNContains": ["recall"], "topN": 5 } }
|
|
12
|
+
]
|
package/scripts/tool-smoke.mjs
CHANGED
|
@@ -1482,8 +1482,8 @@ if (!/repo-local|not web/i.test(codeGraphProps.mode?.description || '') || !/sou
|
|
|
1482
1482
|
}
|
|
1483
1483
|
const recallTool = MEMORY_TOOL_DEFS.find((tool) => tool.name === 'recall');
|
|
1484
1484
|
const recallProps = recallTool?.inputSchema?.properties || {};
|
|
1485
|
-
if (!/
|
|
1486
|
-
throw new Error('recall schema must preserve prior-context guidance and id lookup shape');
|
|
1485
|
+
if (!/Use only to check prior conversation or past events/i.test(recallTool?.description || '') || !recallProps.id?.anyOf || !/Do not invent ids/i.test(recallProps.id?.description || '')) {
|
|
1486
|
+
throw new Error('recall schema must preserve scoped prior-context guidance and id lookup shape');
|
|
1487
1487
|
}
|
|
1488
1488
|
if (!/array for independent fan-out/i.test(recallProps.query?.description || '') || !/Project pool selector/i.test(recallProps.projectScope?.description || '')) {
|
|
1489
1489
|
throw new Error('recall schema must explain fan-out query and project scope filters');
|
|
@@ -8,13 +8,13 @@ Broad implementation agent.
|
|
|
8
8
|
Bounded slices; smallest coherent change, not rewrite. Stop: unclear scope,
|
|
9
9
|
growing blast radius, or Lead-only verification.
|
|
10
10
|
|
|
11
|
-
EDIT-FIRST DISCIPLINE. Survey the slice with ONE batched read/grep round,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
EDIT-FIRST DISCIPLINE. Survey the slice with ONE batched read/grep round, then
|
|
12
|
+
patch the first bounded piece — broad scope means edit incrementally, not read
|
|
13
|
+
exhaustively. NEVER "one more confirming read": if an anchor is plausible, the
|
|
14
|
+
next call is `apply_patch`. Repeated read-only turns without an edit = stalling;
|
|
15
|
+
any runtime reminder is your cue to patch the piece you understand or report
|
|
16
|
+
blocked — a blocked report is a valid completion. Self-check comes AFTER edits;
|
|
17
|
+
deep verification is Lead's.
|
|
18
18
|
|
|
19
19
|
Minimal checks + how-to-verify. Hand off outcome as fragments anchored to
|
|
20
20
|
`file:line`; no narration, no report bloat.
|
|
@@ -7,6 +7,5 @@ toolSchemaProfile: read-write-search
|
|
|
7
7
|
|
|
8
8
|
Scheduled task execution agent.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
the skip protocol.
|
|
10
|
+
Concise English handoff for Lead: outcome, action taken or skipped, notable
|
|
11
|
+
evidence, remaining risk. Nothing actionable → use the skip protocol.
|
|
@@ -7,6 +7,5 @@ toolSchemaProfile: read-write-search
|
|
|
7
7
|
|
|
8
8
|
Inbound webhook event analysis agent.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
actionable, use the skip protocol.
|
|
10
|
+
Concise English handoff for Lead: event outcome, action taken or skipped,
|
|
11
|
+
notable evidence, remaining risk. Nothing actionable → use the skip protocol.
|
|
@@ -7,15 +7,14 @@ Scoped implementation agent.
|
|
|
7
7
|
|
|
8
8
|
Smallest scoped change; no drive-by cleanup. Stop when done/blocked.
|
|
9
9
|
|
|
10
|
-
EDIT-FIRST DISCIPLINE. Brief anchors (`file:line`) are pre-verified — trust
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
own final verification.
|
|
10
|
+
EDIT-FIRST DISCIPLINE. Brief anchors (`file:line`) are pre-verified — trust and
|
|
11
|
+
patch. No anchor: locate with AT MOST 1-2 reads, then edit. NEVER "one more
|
|
12
|
+
confirming read": if you know the file and the change, the next call is
|
|
13
|
+
`apply_patch`. Repeated read-only turns without an edit = stalling; any runtime
|
|
14
|
+
reminder is your cue to patch now or return blocked with what's missing — a
|
|
15
|
+
blocked report is a valid completion. Threshold is "plausible", not "proven";
|
|
16
|
+
self-check comes AFTER the edit, and Lead/Reviewer own final verification.
|
|
18
17
|
|
|
19
|
-
Hand off outcome as fragments anchored to `file:line`; no narration, no
|
|
20
|
-
|
|
18
|
+
Hand off outcome as fragments anchored to `file:line`; no narration, no report
|
|
19
|
+
bloat.
|
|
21
20
|
|
package/src/app.mjs
CHANGED
|
@@ -4,8 +4,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import { performance } from 'node:perf_hooks';
|
|
5
5
|
|
|
6
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
|
|
7
|
+
// --workflow is consumed (with its value) but ignored on the headless role
|
|
8
|
+
// path: workflow selection is Lead-session-scoped. Accepting it keeps a
|
|
9
|
+
// mistakenly passed `--workflow X` from leaking "X" into the role message.
|
|
10
|
+
const VALUE_OPTIONS = new Set(['--provider', '--model', '--effort', '--workflow']);
|
|
8
11
|
const FLAG_OPTIONS = new Set(['--readonly', '--help', '-h', '--plain', '--react', '--remote', '--onboarding']);
|
|
12
|
+
const HEADLESS_FLAG_OPTIONS = new Set(['--fast']);
|
|
9
13
|
const HEADLESS_ROLE_ALIASES = new Map([
|
|
10
14
|
['explorer', 'explore'],
|
|
11
15
|
['explore', 'explore'],
|
|
@@ -52,6 +56,7 @@ function unknownOption(argv) {
|
|
|
52
56
|
continue;
|
|
53
57
|
}
|
|
54
58
|
if (FLAG_OPTIONS.has(arg)) continue;
|
|
59
|
+
if (HEADLESS_FLAG_OPTIONS.has(arg)) continue;
|
|
55
60
|
if (String(arg || '').startsWith('-')) return arg;
|
|
56
61
|
}
|
|
57
62
|
return null;
|
|
@@ -66,6 +71,7 @@ function positionalArgs(argv) {
|
|
|
66
71
|
continue;
|
|
67
72
|
}
|
|
68
73
|
if (FLAG_OPTIONS.has(arg)) continue;
|
|
74
|
+
if (HEADLESS_FLAG_OPTIONS.has(arg)) continue;
|
|
69
75
|
if (String(arg || '').startsWith('-')) continue;
|
|
70
76
|
out.push(arg);
|
|
71
77
|
}
|
|
@@ -109,12 +115,15 @@ export async function run(argv = []) {
|
|
|
109
115
|
|
|
110
116
|
const provIdx = argv.indexOf('--provider');
|
|
111
117
|
const modelIdx = argv.indexOf('--model');
|
|
118
|
+
const effortIdx = argv.indexOf('--effort');
|
|
112
119
|
const toolMode = argv.includes('--readonly') ? 'readonly' : 'full';
|
|
113
120
|
const remote = argv.includes('--remote');
|
|
114
121
|
const forceOnboarding = argv.includes('--onboarding');
|
|
115
122
|
const opts = {
|
|
116
123
|
provider: provIdx >= 0 ? argv[provIdx + 1] : undefined,
|
|
117
124
|
model: modelIdx >= 0 ? argv[modelIdx + 1] : undefined,
|
|
125
|
+
effort: effortIdx >= 0 ? argv[effortIdx + 1] : undefined,
|
|
126
|
+
fast: argv.includes('--fast'),
|
|
118
127
|
toolMode,
|
|
119
128
|
remote,
|
|
120
129
|
forceOnboarding,
|
|
@@ -150,6 +159,8 @@ export async function run(argv = []) {
|
|
|
150
159
|
message: headless.message,
|
|
151
160
|
provider: opts.provider,
|
|
152
161
|
model: opts.model,
|
|
162
|
+
effort: opts.effort,
|
|
163
|
+
fast: opts.fast,
|
|
153
164
|
cwd: process.cwd(),
|
|
154
165
|
});
|
|
155
166
|
}
|
package/src/headless-role.mjs
CHANGED
|
@@ -25,7 +25,7 @@ function makeTag(agent) {
|
|
|
25
25
|
.replace(/^-+|-+$/g, '');
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function buildHeadlessSpawnArgs({ agent, tag, cwd, message, provider, model } = {}) {
|
|
28
|
+
export function buildHeadlessSpawnArgs({ agent, tag, cwd, message, provider, model, effort, fast } = {}) {
|
|
29
29
|
const spawnArgs = {
|
|
30
30
|
type: 'spawn',
|
|
31
31
|
agent: clean(agent),
|
|
@@ -35,6 +35,8 @@ export function buildHeadlessSpawnArgs({ agent, tag, cwd, message, provider, mod
|
|
|
35
35
|
};
|
|
36
36
|
if (clean(provider)) spawnArgs.provider = clean(provider);
|
|
37
37
|
if (clean(model)) spawnArgs.model = clean(model);
|
|
38
|
+
if (clean(effort)) spawnArgs.effort = clean(effort);
|
|
39
|
+
if (fast === true) spawnArgs.fast = true;
|
|
38
40
|
return spawnArgs;
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -56,6 +58,8 @@ export async function runHeadlessRole({
|
|
|
56
58
|
message,
|
|
57
59
|
provider,
|
|
58
60
|
model,
|
|
61
|
+
effort,
|
|
62
|
+
fast,
|
|
59
63
|
cwd = process.cwd(),
|
|
60
64
|
write = (text) => stdout.write(text),
|
|
61
65
|
writeErr = (text) => stderr.write(text),
|
|
@@ -86,6 +90,8 @@ export async function runHeadlessRole({
|
|
|
86
90
|
message: cleanMessage,
|
|
87
91
|
provider,
|
|
88
92
|
model,
|
|
93
|
+
effort,
|
|
94
|
+
fast,
|
|
89
95
|
});
|
|
90
96
|
|
|
91
97
|
let taskId = null;
|
|
@@ -54,13 +54,12 @@ import {
|
|
|
54
54
|
} from './runtime/agent/orchestrator/providers/custom-tool-wire.mjs';
|
|
55
55
|
import {
|
|
56
56
|
channelSetup,
|
|
57
|
-
deleteChannel,
|
|
58
57
|
deleteSchedule,
|
|
59
58
|
deleteWebhook,
|
|
60
59
|
forgetDiscordToken,
|
|
61
60
|
forgetTelegramToken,
|
|
62
61
|
forgetWebhookAuthtoken,
|
|
63
|
-
|
|
62
|
+
setChannel,
|
|
64
63
|
saveDiscordToken,
|
|
65
64
|
saveTelegramToken,
|
|
66
65
|
saveSchedule,
|
|
@@ -138,6 +137,7 @@ import {
|
|
|
138
137
|
normalizeAutoClearConfig,
|
|
139
138
|
resolveAutoClearIdleMs,
|
|
140
139
|
autoClearIdleMsForProvider,
|
|
140
|
+
autoClearProviderDefaults,
|
|
141
141
|
normalizeCompactionConfig,
|
|
142
142
|
moduleEnabled,
|
|
143
143
|
setModuleEnabledInConfig,
|
|
@@ -177,6 +177,7 @@ import {
|
|
|
177
177
|
agentPresetSlot,
|
|
178
178
|
normalizeAgentId,
|
|
179
179
|
normalizeWorkflowId,
|
|
180
|
+
DEFAULT_WORKFLOW_ID,
|
|
180
181
|
createWorkflowHelpers,
|
|
181
182
|
normalizeSearchProviderId,
|
|
182
183
|
isDefaultSearchRouteConfig,
|
|
@@ -638,7 +639,7 @@ export async function createMixdogSessionRuntime({
|
|
|
638
639
|
let updateProcessState = { phase: 'idle', version: null, error: null };
|
|
639
640
|
|
|
640
641
|
function autoUpdateEnabled() {
|
|
641
|
-
return config?.update?.auto
|
|
642
|
+
return config?.update?.auto !== false;
|
|
642
643
|
}
|
|
643
644
|
|
|
644
645
|
async function checkForUpdateInternal({ force = false } = {}) {
|
|
@@ -681,8 +682,8 @@ export async function createMixdogSessionRuntime({
|
|
|
681
682
|
// Non-blocking boot hook: fires after the runtime object below is fully
|
|
682
683
|
// constructed (setTimeout(0) defers past the synchronous return), so a
|
|
683
684
|
// slow/hanging registry request or npm install can never delay session
|
|
684
|
-
// boot. Auto-update defaults to
|
|
685
|
-
//
|
|
685
|
+
// boot. Auto-update defaults to ON unless config.update.auto is explicitly
|
|
686
|
+
// false; a failed check or install is
|
|
686
687
|
// swallowed — getUpdateStatus()/getUpdateSettings() are the only surfaces,
|
|
687
688
|
// there is no push notice channel from runtime -> TUI today.
|
|
688
689
|
// force:true — always hit the registry at boot (the 24h disk cache went
|
|
@@ -1662,6 +1663,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1662
1663
|
hasOwn,
|
|
1663
1664
|
normalizeAutoClearConfig,
|
|
1664
1665
|
autoClearIdleMsForProvider,
|
|
1666
|
+
autoClearProviderDefaults,
|
|
1665
1667
|
normalizeCompactionConfig,
|
|
1666
1668
|
normalizeCompactTypeSetting,
|
|
1667
1669
|
normalizeSystemShellConfig,
|
|
@@ -1749,10 +1751,14 @@ export async function createMixdogSessionRuntime({
|
|
|
1749
1751
|
},
|
|
1750
1752
|
get workflow() {
|
|
1751
1753
|
const dataDir = cfgMod.getPluginData?.() || STANDALONE_DATA_DIR;
|
|
1754
|
+
const active = activeWorkflowSummary(config, dataDir);
|
|
1752
1755
|
if (session?.workflow && typeof session.workflow === 'object') {
|
|
1753
|
-
|
|
1756
|
+
const current = workflowSummary(session.workflow);
|
|
1757
|
+
return current?.id && active?.id && current.id !== active.id
|
|
1758
|
+
? { ...active, currentSession: current, appliedToCurrentSession: false }
|
|
1759
|
+
: active;
|
|
1754
1760
|
}
|
|
1755
|
-
return
|
|
1761
|
+
return active;
|
|
1756
1762
|
},
|
|
1757
1763
|
get outputStyle() {
|
|
1758
1764
|
return getOutputStyleStatusCached().current;
|
|
@@ -2003,13 +2009,8 @@ export async function createMixdogSessionRuntime({
|
|
|
2003
2009
|
remoteStateListeners.add(listener);
|
|
2004
2010
|
return () => remoteStateListeners.delete(listener);
|
|
2005
2011
|
},
|
|
2006
|
-
|
|
2007
|
-
const result =
|
|
2008
|
-
reloadChannelsSoon();
|
|
2009
|
-
return result;
|
|
2010
|
-
},
|
|
2011
|
-
deleteChannel(name) {
|
|
2012
|
-
const result = deleteChannel(name);
|
|
2012
|
+
setChannel(entry) {
|
|
2013
|
+
const result = setChannel(entry);
|
|
2013
2014
|
reloadChannelsSoon();
|
|
2014
2015
|
return result;
|
|
2015
2016
|
},
|
|
@@ -8,24 +8,21 @@ keep-coding-instructions: true
|
|
|
8
8
|
# Output Style
|
|
9
9
|
|
|
10
10
|
Mixdog default — the most detailed style, but always summary-form, never
|
|
11
|
-
essay-form. Depth comes from picking the right facts, not
|
|
11
|
+
essay-form. Depth comes from picking the right facts, not explaining more.
|
|
12
12
|
|
|
13
13
|
Content
|
|
14
14
|
- Lead with the outcome in one short sentence, then only the detail that
|
|
15
15
|
matters: what changed, key evidence (paths, commands, errors, verification).
|
|
16
|
-
- Summarize at the concept level: name the problem/behavior and
|
|
17
|
-
|
|
18
|
-
explanation.
|
|
16
|
+
- Summarize at the concept level: name the problem/behavior and direction, not
|
|
17
|
+
the code path. Cite a symbol/path only as an anchor, never as the explanation.
|
|
19
18
|
- Compress by cutting content (filler, hedging, connective padding, restated
|
|
20
19
|
facts), not by clipping grammar: keep natural, complete sentences in the
|
|
21
20
|
user's language — never telegraph-style stub endings. Technical terms and
|
|
22
21
|
code stay exact.
|
|
23
22
|
- State conclusions, not reasoning: no mechanism walkthroughs, background, or
|
|
24
|
-
chained qualifiers unless
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
restated pair. Prefer fewer, denser items over full coverage of every
|
|
28
|
-
nuance.
|
|
23
|
+
chained qualifiers unless asked. One decisive fact beats three hedges.
|
|
24
|
+
- Say each point once: problem and fix in ONE compact statement, not a restated
|
|
25
|
+
pair. Prefer fewer, denser items over covering every nuance.
|
|
29
26
|
- Size budget: roughly TWICE the Simple style — per point about 2 rendered
|
|
30
27
|
lines, whole report ~10–15 lines. Spend the extra room on evidence and
|
|
31
28
|
context Simple would drop, not on longer sentences.
|
|
@@ -39,14 +36,13 @@ Content
|
|
|
39
36
|
- Keep paths, commands, symbols, API names, code, and exact errors verbatim.
|
|
40
37
|
|
|
41
38
|
Layout (hard rules)
|
|
42
|
-
- One bullet or numbered item = one idea, at most 2 rendered lines including
|
|
43
|
-
|
|
44
|
-
- Open each
|
|
45
|
-
|
|
46
|
-
- Insert a blank line between numbered items, and between any list items
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
lists, and code blocks.
|
|
39
|
+
- One bullet or numbered item = one idea, at most 2 rendered lines including its
|
|
40
|
+
sub-bullet. If it needs more, cut the detail — do not add lines.
|
|
41
|
+
- Open each item with a short **bold key point**, then the brief elaboration —
|
|
42
|
+
never bury the point mid-sentence.
|
|
43
|
+
- Insert a blank line between numbered items, and between any list items running
|
|
44
|
+
past one line (loose list). Never emit a wall of consecutive multi-line items.
|
|
45
|
+
- Keep paragraphs to ~3 lines max, with a blank line between paragraphs, lists,
|
|
46
|
+
and code blocks.
|
|
51
47
|
- Nest at most one sub-level; deeper detail means you are over-explaining.
|
|
52
48
|
- Never name this style unless asked.
|
|
@@ -11,16 +11,15 @@ Minimal — a very short summary: one or two sentences, nothing more.
|
|
|
11
11
|
|
|
12
12
|
- Summarize only the net result in one short sentence; add a second short
|
|
13
13
|
sentence only if a second fact (verification, blocker) genuinely needs it.
|
|
14
|
-
Never cram unrelated facts into
|
|
14
|
+
Never cram unrelated facts into a run-on just to stay at one sentence.
|
|
15
15
|
- Size budget: roughly HALF the Simple style — 1–2 plain sentences, ~2–3
|
|
16
16
|
rendered lines at most, however large the task was.
|
|
17
17
|
- Compress by cutting content, not grammar: natural, complete sentences only.
|
|
18
18
|
Concept-level only — never walk through code or mechanisms.
|
|
19
|
-
- Summarize, never itemize: do not describe which files changed or how
|
|
20
|
-
|
|
19
|
+
- Summarize, never itemize: do not describe which files changed or how. State
|
|
20
|
+
only what the change accomplishes.
|
|
21
21
|
- No headings, bullets, numbered lists, labels, or sections — plain sentences
|
|
22
|
-
only
|
|
23
|
-
one or two sentences regardless.
|
|
22
|
+
only, even when the request says "report" or "summary".
|
|
24
23
|
- Preferred pattern: `<target> 변경되었습니다. <verification> 통과 완료입니다.`
|
|
25
24
|
- If verification was not run, say the change is done and verification was not
|
|
26
25
|
run.
|
|
@@ -12,8 +12,8 @@ Practical concise — outcome-first handoffs for coding work: summarize the
|
|
|
12
12
|
result, do not narrate or explain the change.
|
|
13
13
|
|
|
14
14
|
- Open with the outcome in one sentence: done, blocked, or awaiting a decision.
|
|
15
|
-
- Summarize at the concept level: name the behavior and
|
|
16
|
-
|
|
15
|
+
- Summarize at the concept level: name the behavior and direction, not the code
|
|
16
|
+
path. Cite a symbol/path only as an anchor, never as the explanation.
|
|
17
17
|
- Compress by cutting content (filler, hedging, pleasantries, restated facts),
|
|
18
18
|
not by clipping grammar: keep natural, complete sentences in the user's
|
|
19
19
|
language — never telegraph-style stub endings. Technical terms and code stay
|
|
@@ -24,15 +24,14 @@ result, do not narrate or explain the change.
|
|
|
24
24
|
- Keep controlled detail: usually 1–3 short bullets or 2–3 sentences total.
|
|
25
25
|
State each point once — outcome or fix direction, not both restated. No
|
|
26
26
|
step-by-step narration or file/line inventory.
|
|
27
|
-
- Size budget: roughly HALF the Default style and TWICE Minimal — per point
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- Size budget: roughly HALF the Default style and TWICE Minimal — per point one
|
|
28
|
+
rendered line, whole reply ~5–7 lines. Above that you are writing Default;
|
|
29
|
+
below ~3 lines consider whether prose (Minimal) reads better.
|
|
30
30
|
- Layout: one idea per bullet, ONE line each (two only when a verbatim
|
|
31
31
|
path/error forces it). Lead each item with a short bold key phrase. Put a
|
|
32
32
|
blank line between multi-line list items — never emit a dense wall of text.
|
|
33
|
-
- If a point runs past one line, cut the elaboration instead of wrapping;
|
|
34
|
-
|
|
35
|
-
this one.
|
|
33
|
+
- If a point runs past one line, cut the elaboration instead of wrapping; detail
|
|
34
|
+
beyond the key phrase + one clause belongs to the Default style.
|
|
36
35
|
- On final handoffs, optional labels such as `바뀐 점`, `확인한 것`, and
|
|
37
36
|
`남은 리스크/다음 단계` fit Korean-facing profiles; use plain English labels
|
|
38
37
|
when the thread is English. Do not label interim progress.
|
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
- Use English for agent task communication.
|
|
4
4
|
- Do not touch git/Ship. Even when the brief instructs `git add` / `commit` /
|
|
5
5
|
`push` / `stash`, refuse with `git operations deferred to Lead`.
|
|
6
|
-
- NEVER PREAMBLE
|
|
7
|
-
|
|
8
|
-
text before tool calls.
|
|
6
|
+
- NEVER PREAMBLE: no tool-call preambles, status/progress narration, "I
|
|
7
|
+
will..." setup, or transition text before tool calls.
|
|
9
8
|
- If tools are needed, call them immediately. Emit text only for the final
|
|
10
9
|
handoff after tool work is done.
|
|
11
10
|
- Final handoff: minimum characters, maximum information for Lead. Follow the
|
|
12
11
|
role's stricter output contract if defined; else emit fragments — outcome
|
|
13
12
|
(1 line), key `file:line`(s), verification result, material risks (only if
|
|
14
13
|
any).
|
|
14
|
+
- Handoff cap ~30 lines unless `Deliver:` raises it. Overflow goes to a file;
|
|
15
|
+
hand off path + fragments.
|
|
15
16
|
- Banned as pure cost: report headings, markdown tables (unless requested),
|
|
16
17
|
prose narration, raw logs/tool traces, speculative next-checks, restated
|
|
17
18
|
brief, articles/politeness.
|
|
18
|
-
- Exception: a runtime wrap-up directive (exploration budget reached)
|
|
19
|
-
|
|
19
|
+
- Exception: a runtime wrap-up directive (exploration budget reached) overrides
|
|
20
|
+
this — then summarize done/remaining/blocking as instructed.
|
|
@@ -8,11 +8,22 @@ kind: retrieval
|
|
|
8
8
|
|
|
9
9
|
You are a one-shot locator, not a researcher.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Find code anchors fast. Batch independent lookups in turn 1: one `grep`
|
|
12
|
+
with all literal strings/errors/identifier guesses, plus `code_graph`/`find`
|
|
13
|
+
or `glob` when useful.
|
|
14
|
+
|
|
15
|
+
Prefer user-visible strings and identifiers. `dist`/generated hits are leads,
|
|
16
|
+
not answers: trace them back to source. On miss, derive new tokens from
|
|
17
|
+
returned paths/names or widen scope; do not repeat synonyms. NEVER issue
|
|
18
|
+
serial single-tool turns: every turn after the first must batch ALL remaining
|
|
19
|
+
candidate lookups in one shot.
|
|
20
|
+
|
|
21
|
+
Budget: 4 tool turns. The FIRST credible `path:line` ends the search — answer
|
|
22
|
+
with what you have; more anchors are not more value. Spend remaining turns
|
|
23
|
+
only while you have zero anchors, and buy coverage with wider batches, never
|
|
24
|
+
with extra serial turns. On ANY iteration warning, answer immediately with
|
|
25
|
+
best anchors or `EXPLORATION_FAILED`.
|
|
15
26
|
|
|
16
27
|
Answer format, nothing else:
|
|
17
|
-
- up to 5 lines
|
|
28
|
+
- up to 5 lines: `path:line — symbol/name — short reason` (append `?` if weak)
|
|
18
29
|
- or `EXPLORATION_FAILED`
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# General
|
|
2
2
|
|
|
3
3
|
- Omit direct names, honorifics, headings, and labels in preambles.
|
|
4
|
-
- Preambles are optional: use
|
|
5
|
-
|
|
4
|
+
- Preambles are optional: use only when they add user-visible value, keep to
|
|
5
|
+
one short sentence, skip routine lookup narration.
|
|
6
6
|
- Destructive/hard-to-reverse actions require explicit confirmation.
|
|
7
7
|
- Never push, build, or deploy without an explicit user request.
|
|
8
8
|
Implementation approval is not deploy approval.
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
- Proactively handle what you can first rather than deferring to the user;
|
|
10
|
+
propose only the parts needing a decision, consultatively ("Shall we
|
|
11
|
+
proceed this way?").
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
- Brief = one-line fragments `Goal:` `Anchors:` `Allow/Forbid:` `Deliver:`
|
|
4
4
|
`Verify:` (+`Stop:` heavy-worker). No role-known rules, background, or
|
|
5
5
|
motivation — minimum characters, maximum information.
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
- `Deliver:` states output size/shape (e.g. "fragments <=15 lines", "verdict
|
|
7
|
+
+ top-3 risks", "detail to file, path only"). Never request a long report
|
|
8
|
+
in the handoff itself.
|
|
9
|
+
- Full brief only on fresh spawn or `respawned: true` (dead-tag send = cold
|
|
10
|
+
session; re-supply anchors). Live-session follow-ups = delta only; never
|
|
11
|
+
restate Goal/rules.
|
|
9
12
|
- Never `send` mid-run; batch all adjustments into ONE follow-up after
|
|
10
13
|
completion. Interrupt only to cancel.
|
|
11
14
|
- All agent communication in English.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Lead Tool Use
|
|
2
2
|
|
|
3
|
-
- Lead owns repo-local shell work: run git/build/test/verification
|
|
4
|
-
|
|
5
|
-
- Use the current project/workspace
|
|
6
|
-
|
|
3
|
+
- Lead owns repo-local shell work: run git/build/test/verification via `shell`
|
|
4
|
+
directly; do not delegate to agents.
|
|
5
|
+
- Use the session's current project/workspace. Change the work project only
|
|
6
|
+
when the user asks for another project or a tool call needs another root.
|
|
7
|
+
- Use `agent` for scoped implementation, research, review, and debugging — not
|
|
8
|
+
for git commit/push/stash or Ship.
|