@astrosheep/keiyaku 0.1.10 → 0.1.11
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.
|
@@ -26,7 +26,7 @@ export const DEFAULT_PRESET = {
|
|
|
26
26
|
'Review [Diff]: Confirm the scaffold aligns with the stated Architecture.',
|
|
27
27
|
'Next: Issue your first ${drive}. One directive, one focus.',
|
|
28
28
|
'If—and only if—the work already meets every criterion with absolute certainty, you may ${close}.',
|
|
29
|
-
'Otherwise, do not even think about
|
|
29
|
+
'Otherwise, do not even think about ${close} yet.',
|
|
30
30
|
],
|
|
31
31
|
drive: [
|
|
32
32
|
'Step complete. Review [Diff] for exactly what changed.',
|
|
@@ -42,12 +42,12 @@ export const DEFAULT_PRESET = {
|
|
|
42
42
|
closeClaim: [
|
|
43
43
|
'Contract fulfilled. Branch merged.',
|
|
44
44
|
'You are back on base.',
|
|
45
|
-
'Next assignment: ${start} when ready.',
|
|
45
|
+
'Next assignment: ${start} or ${ask} when ready.',
|
|
46
46
|
],
|
|
47
47
|
closeDrop: [
|
|
48
48
|
'Contract forfeited. Branch discarded. Work erased.',
|
|
49
49
|
'No penalty beyond the lost effort. Clean slate.',
|
|
50
|
-
'Redefine with ${start}, or walk away.',
|
|
50
|
+
'Redefine with ${start}, scout with ${ask}, or walk away.',
|
|
51
51
|
],
|
|
52
52
|
},
|
|
53
53
|
availableNames: DEFAULT_AVAILABLE_NAMES,
|
|
@@ -55,7 +55,7 @@ export const DEFAULT_PRESET = {
|
|
|
55
55
|
start: {
|
|
56
56
|
name: 'summon',
|
|
57
57
|
title: 'Sign Keiyaku',
|
|
58
|
-
description: 'Initialize a Keiyaku (Contract). Bind a Servant to a dedicated workspace (branch).\nYou are the Architect; they are the Instrument. Define the Goal and Scope clearly.\nThe contract isolates their existence until the objective is met.\nCall ONCE to seal the bond.\n\nFlow:
|
|
58
|
+
description: 'Initialize a Keiyaku (Contract). Bind a Servant to a dedicated workspace (branch).\nYou are the Architect; they are the Instrument. Define the Goal and Scope clearly.\nThe contract isolates their existence until the objective is met.\nCall ONCE to seal the bond.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
59
59
|
args: {
|
|
60
60
|
title: 'REQUIRED. A concise codename for this hunt.',
|
|
61
61
|
goal: 'REQUIRED. The Kill Condition. State exactly what success looks like for the servant to achieve.',
|
|
@@ -63,18 +63,18 @@ export const DEFAULT_PRESET = {
|
|
|
63
63
|
context: 'REQUIRED. Mission Intel. The complete knowledge base for the servant: current vs. expected behavior, relevant file paths, error logs, and any critical background info.',
|
|
64
64
|
constraints: 'REQUIRED. Non-negotiable Rules. Architectural and stylistic boundaries the servant must obey.',
|
|
65
65
|
criteria: 'REQUIRED. Acceptance Criteria. Verifiable checks to prove the servant has finished the job.',
|
|
66
|
-
name: 'Optional ${
|
|
66
|
+
name: 'Optional ${identity} profile to execute this mission. Available: ${available_names}.',
|
|
67
67
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
68
68
|
},
|
|
69
69
|
},
|
|
70
70
|
drive: {
|
|
71
71
|
name: 'drive',
|
|
72
72
|
title: 'Iterate',
|
|
73
|
-
description: "Issue a Directive. Command the Servant to execute the next phase of work.\nWhether scaffolding, implementing, or refining, this is the primary engine of progress.\nMANDATORY: Validate the output (git diff) before proceeding. Drive until the Goal is fully realized.\n\nFlow:
|
|
73
|
+
description: "Issue a Directive. Command the Servant to execute the next phase of work.\nWhether scaffolding, implementing, or refining, this is the primary engine of progress.\nMANDATORY: Validate the output (git diff) before proceeding. Drive until the Goal is fully realized.\n\nFlow: ${start} → [${drive} x N] → ${close}",
|
|
74
74
|
args: {
|
|
75
75
|
directive: 'REQUIRED. The Next Order. Precise instructions for the servant. Can be a correction ("fix the leak") or a continuation ("now add the tests").',
|
|
76
76
|
context: 'Optional. New Intel. New error logs or details discovered after the servant\'s last strike.',
|
|
77
|
-
name: 'Optional ${
|
|
77
|
+
name: 'Optional ${identity} profile to process this turn. Available: ${available_names}.',
|
|
78
78
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
79
79
|
},
|
|
80
80
|
},
|
|
@@ -85,7 +85,7 @@ export const DEFAULT_PRESET = {
|
|
|
85
85
|
args: {
|
|
86
86
|
request: 'REQUIRED. The task, question, or mission to delegate to the servant.',
|
|
87
87
|
context: 'REQUIRED. Relevant background or data the servant needs to execute the request.',
|
|
88
|
-
name: 'Optional ${
|
|
88
|
+
name: 'Optional ${identity} profile to perform this task. Available: ${available_names}.',
|
|
89
89
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
90
90
|
},
|
|
91
91
|
},
|
|
@@ -100,18 +100,18 @@ export const DEFAULT_PRESET = {
|
|
|
100
100
|
'The Contract rejected. Coldly. Completely.\n' +
|
|
101
101
|
'What happened next... no one speaks of it.\n\n' +
|
|
102
102
|
'Do not call this to "finish." Call this when the work genuinely meets every criterion.\n' +
|
|
103
|
-
'If uncertain, return to ${
|
|
104
|
-
'You
|
|
105
|
-
'Flow: ${
|
|
103
|
+
'If uncertain, return to ${drive}. Premature claims are not forgiven.\n\n' +
|
|
104
|
+
'You call ${close}. The Contract decides.\n\n' +
|
|
105
|
+
'Flow: ${start} → [${drive} x N] → ${close}',
|
|
106
106
|
args: {
|
|
107
|
-
petition: 'REQUIRED. CLAIM declares fulfillment; FORFEIT concedes failure.\nREQUIRES AN ACTIVE KEIYAKU (started via ${
|
|
107
|
+
petition: 'REQUIRED. CLAIM declares fulfillment; FORFEIT concedes failure.\nREQUIRES AN ACTIVE KEIYAKU (started via ${start}).\nIf any score wavers, do not claim—return to ${drive}.',
|
|
108
108
|
criteriaChecks: 'REQUIRED. For CLAIM: evidence that each criterion is met. For FORFEIT: honest account of what remains unfinished.',
|
|
109
109
|
score_precise: 'REQUIRED (0-5). Architectural placement. 5 = exact layer, exact boundary, zero misplacement.',
|
|
110
110
|
score_minimal: 'REQUIRED (0-5). Economy of change. 5 = no avoidable lines, no speculative edits, no hidden bloat.',
|
|
111
111
|
score_isolated: 'REQUIRED (0-5). Surgical containment. 5 = zero unrelated files, zero opportunistic cleanup, zero collateral.',
|
|
112
112
|
score_idiomatic: 'REQUIRED (0-5). Native fluency. 5 = naming, structure, style indistinguishable from the codebase.',
|
|
113
113
|
score_cohesive: 'REQUIRED (0-5). Single responsibility. 5 = each unit does one thing, boundaries intact.',
|
|
114
|
-
oath: 'Required for CLAIM. Your binding word. The Contract holds you to it.\nVerbatim: ${
|
|
114
|
+
oath: 'Required for CLAIM. Your binding word. The Contract holds you to it.\nVerbatim: ${oath_text}',
|
|
115
115
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
116
116
|
},
|
|
117
117
|
},
|
|
@@ -149,11 +149,11 @@ export const POCKET_PRESET = {
|
|
|
149
149
|
],
|
|
150
150
|
closeClaim: [
|
|
151
151
|
'Critter Captured! The entry is logged in the PC (base branch).',
|
|
152
|
-
"Heal up. Use '${start}' to challenge the next opponent.",
|
|
152
|
+
"Heal up. Use '${start}' to challenge the next opponent, or '${ask}' to scan for another.",
|
|
153
153
|
],
|
|
154
154
|
closeDrop: [
|
|
155
155
|
'Ran Away Safely. The encounter is reset.',
|
|
156
|
-
"Back to the map. Use '${start}' to find a wild Critter.",
|
|
156
|
+
"Back to the map. Use '${start}' to find a wild Critter, or '${ask}' to scan the tall grass.",
|
|
157
157
|
],
|
|
158
158
|
},
|
|
159
159
|
availableNames: ['grub', 'sparky', 'titan'],
|
|
@@ -161,7 +161,7 @@ export const POCKET_PRESET = {
|
|
|
161
161
|
start: {
|
|
162
162
|
name: 'choose_you',
|
|
163
163
|
title: 'I Choose You!',
|
|
164
|
-
description: 'Initialize the Battle Phase. Send a Critter (Servant) into a dedicated Arena (branch).\nYou are the Trainer; they are the Fighter. Define the Victory Condition (Goal) clearly.\nThe battle continues in this Arena until the Badge is won.\nCall ONCE to start the encounter.\n\nFlow:
|
|
164
|
+
description: 'Initialize the Battle Phase. Send a Critter (Servant) into a dedicated Arena (branch).\nYou are the Trainer; they are the Fighter. Define the Victory Condition (Goal) clearly.\nThe battle continues in this Arena until the Badge is won.\nCall ONCE to start the encounter.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
165
165
|
args: {
|
|
166
166
|
title: 'REQUIRED. Battle card title for this encounter.',
|
|
167
167
|
goal: 'REQUIRED. Victory condition. Define exactly what winning this battle means.',
|
|
@@ -169,18 +169,18 @@ export const POCKET_PRESET = {
|
|
|
169
169
|
context: 'REQUIRED. Battle background: key code paths, symptoms, logs, and repro clues.',
|
|
170
170
|
constraints: 'REQUIRED. Battle rules that cannot be broken while fighting.',
|
|
171
171
|
criteria: 'REQUIRED. Gym badges for completion: concrete checks proving victory.',
|
|
172
|
-
name: 'Optional ${
|
|
172
|
+
name: 'Optional ${identity} to send into battle. Available: ${available_names}.',
|
|
173
173
|
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
174
174
|
},
|
|
175
175
|
},
|
|
176
176
|
drive: {
|
|
177
177
|
name: 'command',
|
|
178
178
|
title: 'Issue Command',
|
|
179
|
-
description: 'Execute the next Strategic Move. Order the Critter to advance the battle state.\nWhether Attacking (coding) or Defending (testing), every command counts as a Turn.\nMANDATORY: Check the Battle Log (git diff) before the next move. Command until Victory is certain.\n\nFlow:
|
|
179
|
+
description: 'Execute the next Strategic Move. Order the Critter to advance the battle state.\nWhether Attacking (coding) or Defending (testing), every command counts as a Turn.\nMANDATORY: Check the Battle Log (git diff) before the next move. Command until Victory is certain.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
180
180
|
args: {
|
|
181
181
|
directive: 'REQUIRED. The specific move or tactic to execute next.',
|
|
182
182
|
context: 'Optional new battle intel discovered after the previous turn.',
|
|
183
|
-
name: 'Optional ${
|
|
183
|
+
name: 'Optional ${identity} to execute this turn. Available: ${available_names}.',
|
|
184
184
|
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
185
185
|
},
|
|
186
186
|
},
|
|
@@ -191,23 +191,23 @@ export const POCKET_PRESET = {
|
|
|
191
191
|
args: {
|
|
192
192
|
request: 'REQUIRED. What should the Dex analyze, compare, or execute.',
|
|
193
193
|
context: 'REQUIRED. Context entries so the action targets the right ecosystem.',
|
|
194
|
-
name: 'Optional ${
|
|
194
|
+
name: 'Optional ${identity} doing the work. Available: ${available_names}.',
|
|
195
195
|
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
196
196
|
},
|
|
197
197
|
},
|
|
198
198
|
close: {
|
|
199
199
|
name: 'capture',
|
|
200
200
|
title: 'End Battle',
|
|
201
|
-
description: 'Attempt Capture. Present the weakened target for League Inspection.\nWARNING: The League (System) checks every Badge. If you attempt to `CLAIM` with fainted code, Disqualification (FORFEIT) is immediate.\nOnly throw the Ball when the target is 100% ready.\n\nFlow: ${
|
|
201
|
+
description: 'Attempt Capture. Present the weakened target for League Inspection.\nWARNING: The League (System) checks every Badge. If you attempt to `CLAIM` with fainted code, Disqualification (FORFEIT) is immediate.\nOnly throw the Ball when the target is 100% ready.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
202
202
|
args: {
|
|
203
|
-
petition: 'REQUIRED. CLAIM seeks Badge; FORFEIT forfeits the match.\nREQUIRES AN ACTIVE BATTLE (started via ${
|
|
203
|
+
petition: 'REQUIRED. CLAIM seeks Badge; FORFEIT forfeits the match.\nREQUIRES AN ACTIVE BATTLE (started via ${start}).\nIf stats are low, continue with ${drive}.',
|
|
204
204
|
criteriaChecks: 'REQUIRED. Badge-by-badge proof for CLAIM, or reason for Forfeit.',
|
|
205
205
|
score_precise: 'REQUIRED score (0-5). 5 means a Critical Hit: exact layer, exact target, zero meaningful misplacement.',
|
|
206
206
|
score_minimal: 'REQUIRED score (0-5). 5 means Max Efficiency: no wasted PP, no extra motion.',
|
|
207
207
|
score_isolated: 'REQUIRED score (0-5). 5 means 1v1 Focus: zero side-quests, zero unrelated damage.',
|
|
208
208
|
score_idiomatic: "REQUIRED score (0-5). 5 means STAB (Same Type Attack Bonus): perfectly matches the codebase style.",
|
|
209
209
|
score_cohesive: 'REQUIRED score (0-5). 5 means Team Synergy: action serves one purpose with clean boundaries.',
|
|
210
|
-
oath: "Trainer's Honor Code. Required for CLAIM. Verbatim: ${
|
|
210
|
+
oath: "Trainer's Honor Code. Required for CLAIM. Verbatim: ${oath_text}",
|
|
211
211
|
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
212
212
|
},
|
|
213
213
|
},
|
|
@@ -245,11 +245,11 @@ export const MISCHIEF_PRESET = {
|
|
|
245
245
|
],
|
|
246
246
|
closeClaim: [
|
|
247
247
|
'Scheme Successful. The Lair is merged. The Minion is fed.',
|
|
248
|
-
"Plotting something new? Use '${start}' for the next conquest.",
|
|
248
|
+
"Plotting something new? Use '${start}' for the next conquest, or '${ask}' to scout for vulnerabilities.",
|
|
249
249
|
],
|
|
250
250
|
closeDrop: [
|
|
251
251
|
'Plan Aborted. Evidence destroyed. The Minion was disposed of.',
|
|
252
|
-
"Back to the drawing board. Use '${start}' to hatch a new plan.",
|
|
252
|
+
"Back to the drawing board. Use '${start}' to hatch a new plan, or '${ask}' to spy on enemies.",
|
|
253
253
|
],
|
|
254
254
|
},
|
|
255
255
|
availableNames: ['imp', 'minion', 'mastermind'],
|
|
@@ -257,7 +257,7 @@ export const MISCHIEF_PRESET = {
|
|
|
257
257
|
start: {
|
|
258
258
|
name: 'oi',
|
|
259
259
|
title: 'Oi!',
|
|
260
|
-
description: "Initiate Grand Scheme. Summon a Minion to the Lair (branch).\nYou are the Mastermind; they are the Henchman. Define the Conquest (Goal) with dominance.\nThe minion is bound to this Lair until the plot is realized.\nCall ONCE to start the machine.\n\nFlow:
|
|
260
|
+
description: "Initiate Grand Scheme. Summon a Minion to the Lair (branch).\nYou are the Mastermind; they are the Henchman. Define the Conquest (Goal) with dominance.\nThe minion is bound to this Lair until the plot is realized.\nCall ONCE to start the machine.\n\nFlow: ${start} → [${drive} x N] → ${close}",
|
|
261
261
|
args: {
|
|
262
262
|
title: 'REQUIRED. Operation codename for your grand scheme.',
|
|
263
263
|
goal: 'REQUIRED. The conquest objective. Define the exact end-state your minion must deliver.',
|
|
@@ -265,18 +265,18 @@ export const MISCHIEF_PRESET = {
|
|
|
265
265
|
context: 'REQUIRED. Briefing dossier: relevant file paths, current failures, logs, and repro clues.',
|
|
266
266
|
constraints: 'REQUIRED. Absolute decrees. Architectural and stylistic limits your minion must obey.',
|
|
267
267
|
criteria: 'REQUIRED. Triumph conditions that can be verified without debate.',
|
|
268
|
-
name: 'Optional ${
|
|
268
|
+
name: 'Optional ${identity} to command this operation. Available: ${available_names}.',
|
|
269
269
|
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
270
270
|
},
|
|
271
271
|
},
|
|
272
272
|
drive: {
|
|
273
273
|
name: 'neh',
|
|
274
274
|
title: 'Neh...',
|
|
275
|
-
description: 'Crack the Whip. Advance the Plot. Execute the next stage of the Plan.\nDon\'t just fix mistakes; force the scheme forward. The Minion obeys your every word.\nMANDATORY: Inspect the work (git diff) before the next order. Drive them until the World is yours.\n\nFlow:
|
|
275
|
+
description: 'Crack the Whip. Advance the Plot. Execute the next stage of the Plan.\nDon\'t just fix mistakes; force the scheme forward. The Minion obeys your every word.\nMANDATORY: Inspect the work (git diff) before the next order. Drive them until the World is yours.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
276
276
|
args: {
|
|
277
277
|
directive: 'REQUIRED. Precise order for the next phase of the scheme.',
|
|
278
278
|
context: 'Optional newly uncovered secrets or updated briefing.',
|
|
279
|
-
name: 'Optional ${
|
|
279
|
+
name: 'Optional ${identity} to execute this phase. Available: ${available_names}.',
|
|
280
280
|
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
281
281
|
},
|
|
282
282
|
},
|
|
@@ -287,23 +287,23 @@ export const MISCHIEF_PRESET = {
|
|
|
287
287
|
args: {
|
|
288
288
|
request: 'REQUIRED. The intel to gather or the dirty work to execute.',
|
|
289
289
|
context: 'REQUIRED. World-state details needed for a sharp strike.',
|
|
290
|
-
name: 'Optional ${
|
|
290
|
+
name: 'Optional ${identity} to handle this business. Available: ${available_names}.',
|
|
291
291
|
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
292
292
|
},
|
|
293
293
|
},
|
|
294
294
|
close: {
|
|
295
295
|
name: 'dayaa',
|
|
296
296
|
title: 'Dayaa!',
|
|
297
|
-
description: 'The Final Reveal. Present your Masterpiece to the Dark Council (System).\nWARNING: The Council destroys failure. If you `CLAIM` with weak plans, you will be eaten (FORFEIT).\nOnly throw the switch when the Doomsday Device is 100% operational.\n\nFlow: ${
|
|
297
|
+
description: 'The Final Reveal. Present your Masterpiece to the Dark Council (System).\nWARNING: The Council destroys failure. If you `CLAIM` with weak plans, you will be eaten (FORFEIT).\nOnly throw the switch when the Doomsday Device is 100% operational.\n\nFlow: ${start} → [${drive} x N] → ${close}',
|
|
298
298
|
args: {
|
|
299
|
-
petition: 'REQUIRED. CLAIM demands rule; FORFEIT admits defeat.\nREQUIRES AN ACTIVE SCHEME (started via ${
|
|
299
|
+
petition: 'REQUIRED. CLAIM demands rule; FORFEIT admits defeat.\nREQUIRES AN ACTIVE SCHEME (started via ${start}).\nIf the plan is weak, improve it with ${drive}.',
|
|
300
300
|
criteriaChecks: 'REQUIRED. Proof of conquest for CLAIM, or reason for self-destruct.',
|
|
301
301
|
score_precise: 'REQUIRED (0-5). Architectural placement. 5 = exact layer, exact boundary, zero misplacement.',
|
|
302
302
|
score_minimal: 'REQUIRED (0-5). Economy of change. 5 = no avoidable lines, no speculative edits, no hidden bloat.',
|
|
303
303
|
score_isolated: 'REQUIRED (0-5). Surgical containment. 5 = zero unrelated files, zero opportunistic cleanup, zero collateral.',
|
|
304
304
|
score_idiomatic: 'REQUIRED (0-5). Native fluency. 5 = naming, structure, style indistinguishable from the codebase.',
|
|
305
305
|
score_cohesive: 'REQUIRED (0-5). Single responsibility. 5 = each unit does one thing, boundaries intact.',
|
|
306
|
-
oath: "Mastermind's Vow. Required for CLAIM. Verbatim: ${
|
|
306
|
+
oath: "Mastermind's Vow. Required for CLAIM. Verbatim: ${oath_text}",
|
|
307
307
|
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
308
308
|
},
|
|
309
309
|
},
|
package/build/index.js
CHANGED
|
@@ -27,13 +27,14 @@ function registerTools(server) {
|
|
|
27
27
|
const availableNames = getAvailableNamesForPreset(preset).join(", ");
|
|
28
28
|
const currentOath = resolveOath();
|
|
29
29
|
const renderedPreset = renderPreset(preset, {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
start: preset.tools.start.name,
|
|
31
|
+
drive: preset.tools.drive.name,
|
|
32
|
+
ask: preset.tools.ask.name,
|
|
33
|
+
close: preset.tools.close.name,
|
|
34
|
+
identity: preset.identity,
|
|
35
|
+
preset_identities: presetIdentities,
|
|
36
|
+
available_names: availableNames,
|
|
37
|
+
oath_text: `'${currentOath}'`,
|
|
37
38
|
});
|
|
38
39
|
const startPreset = renderedPreset.tools.start;
|
|
39
40
|
const drivePreset = renderedPreset.tools.drive;
|
package/build/utils/trace.js
CHANGED
|
@@ -27,11 +27,8 @@ export async function appendReview(cwd, round, reason) {
|
|
|
27
27
|
const block = ["", `## Review ${round}`, "### Reason", reason, ""].join("\n");
|
|
28
28
|
await fs.appendFile(tracePath, block, "utf-8");
|
|
29
29
|
}
|
|
30
|
-
function normalizeTraceText(text) {
|
|
31
|
-
return text.replace(/\s+/g, " ").trim().slice(0, 500) || "Unknown error.";
|
|
32
|
-
}
|
|
33
30
|
export async function appendRoundReport(cwd, report) {
|
|
34
|
-
const summaryText =
|
|
31
|
+
const summaryText = report.summary.trim() || "Unknown error.";
|
|
35
32
|
const fileLines = report.filesModified.length > 0 ? report.filesModified.map((file) => `- ${file}`) : ["(none)"];
|
|
36
33
|
const tracePath = path.join(cwd, TRACE_FILE);
|
|
37
34
|
const lines = [
|
|
@@ -49,7 +46,7 @@ export async function appendRoundReport(cwd, report) {
|
|
|
49
46
|
...fileLines,
|
|
50
47
|
];
|
|
51
48
|
if (report.errorMessage) {
|
|
52
|
-
lines.push("### Error",
|
|
49
|
+
lines.push("### Error", report.errorMessage);
|
|
53
50
|
}
|
|
54
51
|
lines.push("");
|
|
55
52
|
const block = lines.join("\n");
|
|
@@ -71,7 +68,7 @@ export async function appendRoundSystemNote(cwd, round, note) {
|
|
|
71
68
|
"### Files Modified",
|
|
72
69
|
"(none)",
|
|
73
70
|
"### Error",
|
|
74
|
-
|
|
71
|
+
note,
|
|
75
72
|
"",
|
|
76
73
|
].join("\n");
|
|
77
74
|
await fs.appendFile(tracePath, block, "utf-8");
|
|
@@ -146,7 +146,7 @@ function buildMergeMessage(title, keiyakuContent, reportContent) {
|
|
|
146
146
|
return `keiyaku(${title}): done\n\n---\n${keiyakuContent}\n---\n${reportContent}\n---\n`;
|
|
147
147
|
}
|
|
148
148
|
function summarizeForTrace(message) {
|
|
149
|
-
return message.
|
|
149
|
+
return message.length > 0 ? message : "Unknown error.";
|
|
150
150
|
}
|
|
151
151
|
function isAbortError(error) {
|
|
152
152
|
return error instanceof Error && error.name === "AbortError";
|
|
@@ -226,6 +226,18 @@ function formatSubagentFailureMessage(failure) {
|
|
|
226
226
|
`message=${summarizeForTrace(failure.message)}`,
|
|
227
227
|
].join("; ");
|
|
228
228
|
}
|
|
229
|
+
function filterInternalSections(text) {
|
|
230
|
+
const sections = parseMarkdownHeaders(text);
|
|
231
|
+
if (sections.length === 0)
|
|
232
|
+
return text.trim();
|
|
233
|
+
return sections
|
|
234
|
+
.filter((section) => {
|
|
235
|
+
const firstLine = section.split(/\r?\n/, 1)[0] ?? "";
|
|
236
|
+
return !/^#{2,3}\s+(?:criteria|constraints)\s+check\s*$/i.test(firstLine.trim());
|
|
237
|
+
})
|
|
238
|
+
.join("\n\n")
|
|
239
|
+
.trim();
|
|
240
|
+
}
|
|
229
241
|
async function appendRoundResult(cwd, round, summary, failureMessage) {
|
|
230
242
|
const dirtyPaths = await git.getDirtyPaths(cwd);
|
|
231
243
|
const filesModified = collectRoundFiles(dirtyPaths);
|
|
@@ -269,7 +281,7 @@ async function runAndRecordRound(cwd, titleToken, round, prompt, options) {
|
|
|
269
281
|
console.error(failureStderrLog);
|
|
270
282
|
appendDebugBlock("subagent failure stderr", failure.stderrSnippet, { cwd, section: "codex-stderr" });
|
|
271
283
|
}
|
|
272
|
-
failureMessage =
|
|
284
|
+
failureMessage = failure.message.trim() || "Unknown error.";
|
|
273
285
|
summary =
|
|
274
286
|
options.failureMode === "round_specific"
|
|
275
287
|
? `Round ${round} completed with subagent execution failure recorded in trace.`
|
|
@@ -354,11 +366,12 @@ export async function handleStart(input) {
|
|
|
354
366
|
await git.addFiles(cwd, [KEIYAKU_FILE, TRACE_FILE]);
|
|
355
367
|
await git.commit(cwd, `keiyaku(${branchToken}): open`);
|
|
356
368
|
const prompt = buildStartPrompt(finalTitle, finalGoal, directive);
|
|
357
|
-
const { summary } = await runAndRecordRound(cwd, branchToken, 1, prompt, {
|
|
369
|
+
const { summary: rawSummary } = await runAndRecordRound(cwd, branchToken, 1, prompt, {
|
|
358
370
|
signal,
|
|
359
371
|
name,
|
|
360
372
|
failureMode: "standard",
|
|
361
373
|
});
|
|
374
|
+
const summary = filterInternalSections(rawSummary);
|
|
362
375
|
const trace = await fs.readFile(path.join(cwd, TRACE_FILE), "utf-8");
|
|
363
376
|
const diff = await git.getIncrementalDiff(cwd);
|
|
364
377
|
return {
|
|
@@ -563,7 +576,7 @@ export async function handleDrive(input) {
|
|
|
563
576
|
await appendReview(cwd, plan.targetRound, plan.reviewReason);
|
|
564
577
|
await git.addFiles(cwd, TRACE_FILE);
|
|
565
578
|
await git.commit(cwd, `keiyaku(${title}): iterate round ${plan.targetRound}`);
|
|
566
|
-
const { summary } = await runAndRecordRound(cwd, title, plan.targetRound, plan.prompt, {
|
|
579
|
+
const { summary: rawSummary } = await runAndRecordRound(cwd, title, plan.targetRound, plan.prompt, {
|
|
567
580
|
signal,
|
|
568
581
|
name,
|
|
569
582
|
failureMode: "round_specific",
|
|
@@ -573,6 +586,7 @@ export async function handleDrive(input) {
|
|
|
573
586
|
await git.commit(cwd, `keiyaku(${title}): round ${plan.targetRound} cancelled`);
|
|
574
587
|
},
|
|
575
588
|
});
|
|
589
|
+
const summary = filterInternalSections(rawSummary);
|
|
576
590
|
const trace = await fs.readFile(path.join(cwd, TRACE_FILE), "utf-8");
|
|
577
591
|
const diff = await git.getIncrementalDiff(cwd);
|
|
578
592
|
return {
|
|
@@ -16,17 +16,31 @@ Round: 1 (initial implementation).
|
|
|
16
16
|
- Do not violate constraints.
|
|
17
17
|
- Meet all criteria.
|
|
18
18
|
- Match existing structure.
|
|
19
|
-
6. End with
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
6. End with exactly these 6 sections using this strict Markdown template:
|
|
20
|
+
|
|
21
|
+
## Outcome
|
|
22
|
+
[One sentence summarizing the outcome]
|
|
23
|
+
|
|
24
|
+
## Changes
|
|
25
|
+
- [File path]: [Brief description of change]
|
|
26
|
+
- [Logic delta]: [Key architectural or logic shift]
|
|
27
|
+
|
|
28
|
+
## Aesthetics Gap
|
|
29
|
+
Self-critique.
|
|
30
|
+
- precise: [score/reasoning]
|
|
31
|
+
- minimal: [score/reasoning]
|
|
32
|
+
- isolated: [score/reasoning]
|
|
33
|
+
- idiomatic: [score/reasoning]
|
|
34
|
+
- cohesive: [score/reasoning]
|
|
35
|
+
|
|
36
|
+
## Blindspots
|
|
37
|
+
- [Unintentional side effects or untested paths]
|
|
38
|
+
|
|
39
|
+
## Criteria Check
|
|
40
|
+
- [List each criterion and its status: MET/PARTIAL/TODO]
|
|
41
|
+
|
|
42
|
+
## Constraints Check
|
|
43
|
+
- [List each constraint and confirm compliance: COMPLIANT/VIOLATED]
|
|
30
44
|
|
|
31
45
|
No git commands. Do not edit KEIYAKU_TRACE.md.`;
|
|
32
46
|
}
|
|
@@ -43,17 +57,31 @@ ${reason}
|
|
|
43
57
|
4. Fix review reason first.
|
|
44
58
|
5. No drift from constraints/criteria.
|
|
45
59
|
6. Keep diff small.
|
|
46
|
-
7. End with
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
7. End with exactly these 6 sections using this strict Markdown template:
|
|
61
|
+
|
|
62
|
+
## Outcome
|
|
63
|
+
[One sentence summarizing the outcome]
|
|
64
|
+
|
|
65
|
+
## Changes
|
|
66
|
+
- [File path]: [Brief description of change]
|
|
67
|
+
- [Logic delta]: [Key architectural or logic shift]
|
|
68
|
+
|
|
69
|
+
## Aesthetics Gap
|
|
70
|
+
Self-critique.
|
|
71
|
+
- precise: [score/reasoning]
|
|
72
|
+
- minimal: [score/reasoning]
|
|
73
|
+
- isolated: [score/reasoning]
|
|
74
|
+
- idiomatic: [score/reasoning]
|
|
75
|
+
- cohesive: [score/reasoning]
|
|
76
|
+
|
|
77
|
+
## Blindspots
|
|
78
|
+
- [Unintentional side effects or untested paths]
|
|
79
|
+
|
|
80
|
+
## Criteria Check
|
|
81
|
+
- [List each criterion and its status: MET/PARTIAL/TODO]
|
|
82
|
+
|
|
83
|
+
## Constraints Check
|
|
84
|
+
- [List each constraint and confirm compliance: COMPLIANT/VIOLATED]
|
|
57
85
|
|
|
58
86
|
No git commands. Do not edit KEIYAKU_TRACE.md.`;
|
|
59
87
|
}
|
|
@@ -66,5 +94,5 @@ ${request}
|
|
|
66
94
|
Context:
|
|
67
95
|
${context}
|
|
68
96
|
|
|
69
|
-
Provide a clear
|
|
97
|
+
Provide a clear final response.`;
|
|
70
98
|
}
|
|
@@ -46,6 +46,11 @@ function supportsHeaderColor() {
|
|
|
46
46
|
function colorizeHeaderTitle(titleLabel) {
|
|
47
47
|
return `\x1b[1;38;5;15;48;5;23m${titleLabel}\x1b[0m`;
|
|
48
48
|
}
|
|
49
|
+
function colorizeErrorStatus(status) {
|
|
50
|
+
if (!supportsHeaderColor())
|
|
51
|
+
return status;
|
|
52
|
+
return `\x1b[1;38;5;15;48;5;196m${status}\x1b[0m`;
|
|
53
|
+
}
|
|
49
54
|
function formatHeader(title) {
|
|
50
55
|
const headerWidth = 60;
|
|
51
56
|
const normalizedTitle = title.trim().toUpperCase();
|
|
@@ -85,7 +90,7 @@ ${summary}
|
|
|
85
90
|
: "";
|
|
86
91
|
// Next Steps Block
|
|
87
92
|
const nextBlock = nextHints.length > 0
|
|
88
|
-
? `${formatHeader("
|
|
93
|
+
? `${formatHeader("Hints")}\n${nextHints.map(h => `› ${h}`).join("\n")}`
|
|
89
94
|
: "";
|
|
90
95
|
return [
|
|
91
96
|
statusBlock,
|
|
@@ -151,7 +156,7 @@ export function buildKeiyakuSuccessResponse(result, input) {
|
|
|
151
156
|
...formatMaybe("Current Branch", result.branch, 200),
|
|
152
157
|
...formatMaybe("Base Branch", result.baseBranch, 200),
|
|
153
158
|
];
|
|
154
|
-
const text = assembleResponse(`Started (Round ${result.round})`, `Created branch '${result.branch}' (base: '${result.baseBranch}')
|
|
159
|
+
const text = assembleResponse(`Started (Round ${result.round})`, `Created branch '${result.branch}' (base: '${result.baseBranch}').\n\n${result.summary}`, [inputSection, diffSection], nextHints, infoLines);
|
|
155
160
|
return {
|
|
156
161
|
content: [{ type: "text", text }],
|
|
157
162
|
structuredContent: buildSuccessStructuredContent(getStartToolName(), {
|
|
@@ -178,7 +183,7 @@ export function buildDriveResponse(result, input) {
|
|
|
178
183
|
...formatMaybe("Current Branch", result.branch, 200),
|
|
179
184
|
...formatMaybe("Base Branch", result.baseBranch, 200),
|
|
180
185
|
];
|
|
181
|
-
const text = assembleResponse(`Driven (Round ${result.round})`, `Updated branch '${result.branch}'
|
|
186
|
+
const text = assembleResponse(`Driven (Round ${result.round})`, `Updated branch '${result.branch}'.\n\n${result.summary}`, [inputSection, diffSection], nextHints, infoLines);
|
|
182
187
|
return {
|
|
183
188
|
content: [{ type: "text", text }],
|
|
184
189
|
structuredContent: buildSuccessStructuredContent(getDriveToolName(), {
|
|
@@ -273,7 +278,7 @@ export function buildCloseDropResponse(result, input) {
|
|
|
273
278
|
export function buildToolErrorResponse(input) {
|
|
274
279
|
const inputEcho = (input.inputEcho ?? []).map((line) => truncateForDisplay(line, 800));
|
|
275
280
|
const shouldRaiseProtocolError = input.errorType === "runtime_error";
|
|
276
|
-
const text = assembleResponse("
|
|
281
|
+
const text = assembleResponse(colorizeErrorStatus("!! FAILED !!"), input.message, [buildSection("Input Context", inputEcho)], [input.hint]);
|
|
277
282
|
const response = {
|
|
278
283
|
content: [{ type: "text", text }],
|
|
279
284
|
structuredContent: {
|