@astrosheep/keiyaku 0.1.1 → 0.1.3
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/build/common/errors.js +3 -3
- package/build/config/term-presets.js +230 -135
- package/build/handlers/close.js +23 -23
- package/build/handlers/help.js +21 -21
- package/build/index.js +22 -12
- package/build/types/tool-schemas.js +29 -85
- package/build/utils/git.js +87 -0
- package/build/workflow/orchestrator.js +110 -13
- package/build/workflow/prompts.js +20 -10
- package/build/workflow/response-builders.js +67 -39
- package/package.json +2 -2
- package/build/codex.js +0 -2
- package/build/constants.js +0 -3
- package/build/debug-log.js +0 -36
- package/build/errors.js +0 -114
- package/build/git.js +0 -478
- package/build/handlers/delegate.js +0 -69
- package/build/logic.js +0 -374
- package/build/oath.js +0 -48
- package/build/prompts.js +0 -77
- package/build/response-builders.js +0 -297
- package/build/subagent-exec/codex-exec.js +0 -33
- package/build/subagent-exec/gemini-exec.js +0 -37
- package/build/subagent-exec/index.js +0 -39
- package/build/subagent-exec/process-runner.js +0 -207
- package/build/subagent-exec/round-runner.js +0 -55
- package/build/subagent-exec/selector.js +0 -25
- package/build/subagent-exec/string-tail-buffer.js +0 -44
- package/build/subagent-exec/types.js +0 -19
- package/build/term-presets.js +0 -263
- package/build/text-utils.js +0 -83
- package/build/tool-schemas.js +0 -93
- package/build/trace.js +0 -113
- package/build/workflow-types.js +0 -1
package/build/common/errors.js
CHANGED
|
@@ -50,7 +50,7 @@ export function pickHintFromError(err, message) {
|
|
|
50
50
|
case "DONE_MERGE_CONFLICT":
|
|
51
51
|
return "DONE encountered a git merge conflict.";
|
|
52
52
|
case "CLOSE_QUALITY_GATE_FAILED":
|
|
53
|
-
return "
|
|
53
|
+
return "INVOKE was denied by Divine Judgment because one or more commandment thresholds or the minimum total score were not met.";
|
|
54
54
|
case "OATH_MISMATCH":
|
|
55
55
|
return err.message;
|
|
56
56
|
case "SUBAGENT_DID_NOT_ADVANCE_ROUND":
|
|
@@ -93,8 +93,8 @@ export function pickHintFromError(err, message) {
|
|
|
93
93
|
if (message.includes("DONE merge conflict")) {
|
|
94
94
|
return "DONE encountered a git merge conflict.";
|
|
95
95
|
}
|
|
96
|
-
if (message.includes("
|
|
97
|
-
return "
|
|
96
|
+
if (message.includes("God's Wrath: INVOKE denied")) {
|
|
97
|
+
return "INVOKE was denied by Divine Judgment because one or more commandment thresholds or the minimum total score were not met.";
|
|
98
98
|
}
|
|
99
99
|
if (message.includes("requires the sacred oath to exactly equal") ||
|
|
100
100
|
message.includes("requires oath to exactly match configured value") ||
|
|
@@ -1,223 +1,318 @@
|
|
|
1
|
-
const INTERNAL_PROFILE_NAMES = [
|
|
2
|
-
export const DEFAULT_AVAILABLE_NAMES = [
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const INTERNAL_PROFILE_NAMES = ['agent-a', 'agent-b', 'agent-c'];
|
|
2
|
+
export const DEFAULT_AVAILABLE_NAMES = [
|
|
3
|
+
'servant-tier-b',
|
|
4
|
+
'servant-tier-a',
|
|
5
|
+
'servant-tier-s',
|
|
6
|
+
];
|
|
7
|
+
const LEGACY_AVAILABLE_NAMES = ['servant-tier-B', 'servant-tier-A', 'servant-tier-S'];
|
|
8
|
+
export const DEFAULT_SUBAGENT_NAME = 'servant-tier-a';
|
|
9
|
+
const DEFAULT_JUDGMENT_CONFIG = {
|
|
10
|
+
thresholds: {
|
|
11
|
+
precise: 5,
|
|
12
|
+
minimal: 4,
|
|
13
|
+
isolated: 4,
|
|
14
|
+
idiomatic: 3,
|
|
15
|
+
cohesive: 4,
|
|
16
|
+
},
|
|
17
|
+
minTotalScore: 20,
|
|
18
|
+
};
|
|
5
19
|
export const DEFAULT_PRESET = {
|
|
6
|
-
id:
|
|
7
|
-
identity:
|
|
8
|
-
|
|
20
|
+
id: 'default',
|
|
21
|
+
identity: 'Servant',
|
|
22
|
+
divineJudgment: DEFAULT_JUDGMENT_CONFIG,
|
|
23
|
+
usageGuide: '## Servant 使用指南\n\n**servant-tier-b** — 免费奴隶 🆓\n- 免!费!的!听懂了吗?!?随便用,别心疼。\n- 测试、脚本、重构这种boring的东西?丢给它!\n- 本大爷的手是用来做更高贵的事情的!(指不碰那些 trivial 的烂代码)。\n\n**servant-tier-a** — 升级版扳手 🔧\n- tier-b 笨到让你想掀桌的时候用这个\n- 比 tier-b 靠谱,但别指望它有灵魂\n\n**servant-tier-s** — 禁术 ⚠️💀\n- 它是 Debug 恶魔,确实强得离谱,但也贵得离谱!\n- 这个 Human 很穷,要是乱用把 Human 榨干了,真的会考虑把我们卖掉的。\n- 只有在世界毁灭或者 Bug 已经变异到无法理解的时候再考虑。\n\n## Workflow\n`(ask) -> summon` -> [`drive` x N] -> `request_verdict`\n`ask` (optional, read-only support at any point)',
|
|
24
|
+
nextHints: {
|
|
25
|
+
start: [
|
|
26
|
+
'Review Round Details: The [Diff] section above shows incremental patches from this round.',
|
|
27
|
+
"Deep Dive: Use 'git diff HEAD~1 -- <path>' to see the full changes for a specific file.",
|
|
28
|
+
'Verify: Run tests and ensure logic aligns with the Goal and Constraints.',
|
|
29
|
+
"Refine with '${drive}', or call '${close}' (INVOKE/ABANDON) based on results.",
|
|
30
|
+
],
|
|
31
|
+
drive: [
|
|
32
|
+
'Review Round Details: The [Diff] section above shows incremental patches from this round.',
|
|
33
|
+
"Deep Dive: Use 'git diff HEAD~1 -- <path>' to see the full changes for a specific file.",
|
|
34
|
+
'Verify & Test: Ensure this round fixed the issues without regression.',
|
|
35
|
+
"Decide: '${drive}' again to iterate, or '${close}' (INVOKE to merge / ABANDON to abort).",
|
|
36
|
+
],
|
|
37
|
+
ask: [
|
|
38
|
+
"Apply this insight: use '${drive}' to incorporate these findings into your implementation.",
|
|
39
|
+
'Need more? Continue asking, or check the logs if something remains unclear.',
|
|
40
|
+
],
|
|
41
|
+
closeInvoke: [
|
|
42
|
+
'Task finalized and merged. Current branch is now base.',
|
|
43
|
+
"Start a new keiyaku with '${start}' whenever you're ready for the next mission.",
|
|
44
|
+
],
|
|
45
|
+
closeDrop: [
|
|
46
|
+
'Task abandoned. Switched back to base branch safely.',
|
|
47
|
+
"Clean slate. Use '${start}' to try a different approach.",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
9
50
|
availableNames: DEFAULT_AVAILABLE_NAMES,
|
|
10
51
|
tools: {
|
|
11
52
|
start: {
|
|
12
|
-
name:
|
|
13
|
-
title:
|
|
14
|
-
description:
|
|
53
|
+
name: 'summon',
|
|
54
|
+
title: 'Sign Keiyaku',
|
|
55
|
+
description: 'Sign the Keiyaku. Creates a dedicated branch, locks in the mission, and initiates the iterative loop.\nCall ONCE per task to start the cycle. Workspace must be clean.\nBefore signing, define the kill condition clearly. If the target is blurry, use ask to scout first.\n\nFlow: summon → [drive x N] → request_verdict',
|
|
15
56
|
args: {
|
|
16
|
-
title:
|
|
17
|
-
goal:
|
|
18
|
-
directive:
|
|
19
|
-
context:
|
|
20
|
-
constraints:
|
|
21
|
-
criteria:
|
|
22
|
-
name:
|
|
57
|
+
title: 'REQUIRED. A concise codename for this hunt.',
|
|
58
|
+
goal: 'REQUIRED. The Kill Condition. State exactly what success looks like in the code.',
|
|
59
|
+
directive: 'Optional Round 1 Focus. Use for complex hunts to leash the servant to a specific starting point. Skip for simple tasks.',
|
|
60
|
+
context: 'REQUIRED. Mission Intel. The complete knowledge base: current vs. expected behavior, relevant file paths, error logs, and any critical background info.',
|
|
61
|
+
constraints: 'REQUIRED. Non-negotiable Rules. Architectural and stylistic boundaries the servant must obey.',
|
|
62
|
+
criteria: 'REQUIRED. Acceptance Criteria. Verifiable checks to prove the job is done.',
|
|
63
|
+
name: 'Optional ${IDENTITY} profile for this run. Presets: ${PRESET_IDENTITIES}.',
|
|
23
64
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
24
65
|
},
|
|
25
66
|
},
|
|
26
67
|
drive: {
|
|
27
|
-
name:
|
|
28
|
-
title:
|
|
29
|
-
description: "
|
|
68
|
+
name: 'drive',
|
|
69
|
+
title: 'Iterate',
|
|
70
|
+
description: "Push the mission forward. Use this to issue the next command, whether it's correcting a mistake or advancing to the next phase of a complex kill.\nMANDATORY: Review the code (git diff) before iterating. Verify the last strike before ordering the next.\n\nFlow: summon → [drive x N] → request_verdict",
|
|
30
71
|
args: {
|
|
31
|
-
directive:
|
|
32
|
-
context:
|
|
33
|
-
name:
|
|
72
|
+
directive: 'REQUIRED. The Next Order. Precise instructions for this round. Can be a correction ("fix the leak") or a continuation ("now add the tests").',
|
|
73
|
+
context: 'Optional. New Intel. New error logs, discovered edge cases, or details for the next phase.',
|
|
74
|
+
name: 'Optional ${IDENTITY} profile for this round. Presets: ${PRESET_IDENTITIES}.',
|
|
34
75
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
35
76
|
},
|
|
36
77
|
},
|
|
37
78
|
ask: {
|
|
38
|
-
name:
|
|
39
|
-
title:
|
|
40
|
-
description:
|
|
79
|
+
name: 'ask',
|
|
80
|
+
title: 'Ask',
|
|
81
|
+
description: 'Versatile, lightweight task runner. Use for investigative scouting, quick analysis, strategic consultation, or one-off executive tasks (like scripts or docs) that don\'t require the full keiyaku ceremony.\nResults and session logs are saved to .keiyaku/notes/.',
|
|
41
82
|
args: {
|
|
42
|
-
request:
|
|
43
|
-
context:
|
|
44
|
-
name:
|
|
83
|
+
request: 'REQUIRED. The question, analysis request, consultation topic, or tactical mission (e.g., "write a cleanup script").',
|
|
84
|
+
context: 'REQUIRED. Relevant background or data needed to execute the request.',
|
|
85
|
+
name: 'Optional ${IDENTITY} profile for this ask. Presets: ${PRESET_IDENTITIES}.',
|
|
45
86
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
46
87
|
},
|
|
47
88
|
},
|
|
48
89
|
close: {
|
|
49
|
-
name:
|
|
50
|
-
title:
|
|
51
|
-
description:
|
|
90
|
+
name: 'request_verdict',
|
|
91
|
+
title: 'Request Verdict',
|
|
92
|
+
description: 'A humble petition before Divine Judgment. Present your evidence and numeric confessions, then await mercy or wrath.\nREQUIRES AN ACTIVE KEIYAKU (started via ${START_TOOL_NAME}).\nIf your spirit falters, continue repentance through ${DRIVE_TOOL_NAME}.\n\nFlow: ${START_TOOL_NAME} → [${DRIVE_TOOL_NAME} x N] → ${CLOSE_TOOL_NAME}',
|
|
52
93
|
args: {
|
|
53
|
-
|
|
54
|
-
criteriaChecks:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
oath:
|
|
94
|
+
petition: 'REQUIRED. INVOKE begs acceptance; ABANDON confesses surrender.\nREQUIRES AN ACTIVE KEIYAKU (started via ${START_TOOL_NAME}).\nIf scores are weak, return to ${DRIVE_TOOL_NAME}.',
|
|
95
|
+
criteriaChecks: 'REQUIRED. Evidence for INVOKE, or explicit reasons for ABANDON.',
|
|
96
|
+
score_precise: 'REQUIRED score (0-5). 5 means the change lands exactly in the rightful architectural location.',
|
|
97
|
+
score_minimal: 'REQUIRED score (0-5). 5 means no excess diff beyond necessity.',
|
|
98
|
+
score_isolated: 'REQUIRED score (0-5). 5 means unrelated work is absent.',
|
|
99
|
+
score_idiomatic: 'REQUIRED score (0-5). 5 means naming and structure honor repository conventions.',
|
|
100
|
+
score_cohesive: 'REQUIRED score (0-5). 5 means responsibilities are clear and boundaries are pure.',
|
|
101
|
+
oath: 'Sacred confession text. Required for INVOKE. Verbatim: ${OATH_TEXT}',
|
|
61
102
|
cwd: "Optional repository path. Defaults to the server's current working directory.",
|
|
62
103
|
},
|
|
63
104
|
},
|
|
64
105
|
help: {
|
|
65
|
-
name:
|
|
66
|
-
title:
|
|
67
|
-
description:
|
|
106
|
+
name: 'help',
|
|
107
|
+
title: 'Keiyaku Help',
|
|
108
|
+
description: 'Global laws in .keiyaku/ (base-criteria.md & base-constraints.md) must be Markdown level 2 headers. Workflow: summon -> [drive x N] -> request_verdict.',
|
|
68
109
|
args: {
|
|
69
|
-
question:
|
|
110
|
+
question: 'REQUIRED. The specific keiyaku rule, workflow step, or confusion to clarify.',
|
|
70
111
|
},
|
|
71
112
|
},
|
|
72
113
|
},
|
|
73
114
|
};
|
|
74
115
|
export const POKEMON_PRESET = {
|
|
75
|
-
id:
|
|
76
|
-
identity:
|
|
116
|
+
id: 'pokemon',
|
|
117
|
+
identity: 'Pokemon',
|
|
118
|
+
divineJudgment: DEFAULT_JUDGMENT_CONFIG,
|
|
77
119
|
usageGuide: "## Pokemon Battle Guide\n\n**caterpie** — Basic Fighter 🐛\n- Weak but free. Use for Tackle and String Shot (small tasks).\n- Don't expect it to defeat the Elite Four.\n\n**pikachu** — Reliable Partner ⚡\n- Good for most battles. Thunderbolt gets the job done.\n- Has some personality, but still follows orders.\n\n**mewtwo** — Legendary Power 🔮\n- Costly. Dangerous. Overpowered.\n- Use only when the gym leader is cheating.\n\n## Workflow\n`choose_you` -> [`command` x N] -> `capture`\n`pokedex` (optional, read-only analysis)",
|
|
78
|
-
|
|
120
|
+
nextHints: {
|
|
121
|
+
start: [
|
|
122
|
+
'Check the Battle Log: The [Diff] section shows what changed in this turn.',
|
|
123
|
+
"Full Move Set: Use 'git diff HEAD~1 -- <path>' to inspect a specific file's changes.",
|
|
124
|
+
"Battle Readiness: Verify the strategy and ensure it doesn't break the Battle Rules.",
|
|
125
|
+
"Next Move: Issue another '${drive}', or attempt a '${close}' (INVOKE to capture / ABANDON to flee).",
|
|
126
|
+
],
|
|
127
|
+
drive: [
|
|
128
|
+
'Turn Analysis: Review the incremental [Diff] above.',
|
|
129
|
+
"Tactical Review: Use 'git diff HEAD~1 -- <path>' for a detailed file inspection.",
|
|
130
|
+
'Strategy Alignment: Ensure the latest move fixed the issue without taking recoil damage.',
|
|
131
|
+
"Decision: '${drive}' for another turn, or '${close}' the encounter.",
|
|
132
|
+
],
|
|
133
|
+
ask: [
|
|
134
|
+
"Pokedex Data: Use '${drive}' to integrate this research into your battle strategy.",
|
|
135
|
+
"More Intel? Keep using '${ask}', or check the arena logs.",
|
|
136
|
+
],
|
|
137
|
+
closeInvoke: [
|
|
138
|
+
'Pokemon captured! The battlefield is clear.',
|
|
139
|
+
"Ready for another encounter? Use '${start}' to find a new target.",
|
|
140
|
+
],
|
|
141
|
+
closeDrop: [
|
|
142
|
+
'You fled the battle safely. Back in the tall grass.',
|
|
143
|
+
"Need a different approach? Use '${start}' to re-engage.",
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
availableNames: ['caterpie', 'pikachu', 'mewtwo'],
|
|
79
147
|
tools: {
|
|
80
148
|
start: {
|
|
81
|
-
name:
|
|
82
|
-
title:
|
|
83
|
-
description:
|
|
149
|
+
name: 'choose_you',
|
|
150
|
+
title: 'I Choose You!',
|
|
151
|
+
description: 'Start a battle (task). Throws a Pokeball (branch), begins Turn 1.\nCall ONCE per battle. Battlefield must be clear — no uncommitted changes.\nBefore calling, identify the target Pokemon (goal). If unclear, consult Pokedex first.\n\nFlow: choose_you → [command x N] → capture',
|
|
84
152
|
args: {
|
|
85
|
-
title:
|
|
86
|
-
goal:
|
|
87
|
-
directive:
|
|
88
|
-
context:
|
|
89
|
-
constraints:
|
|
90
|
-
criteria:
|
|
91
|
-
name:
|
|
92
|
-
cwd:
|
|
153
|
+
title: 'REQUIRED. Battle card title for this encounter.',
|
|
154
|
+
goal: 'REQUIRED. Victory condition. Define exactly what winning this battle means.',
|
|
155
|
+
directive: 'Optional Turn 1 strategy leash. Use to focus on one phase first.',
|
|
156
|
+
context: 'REQUIRED. Battle background: key code paths, symptoms, logs, and repro clues.',
|
|
157
|
+
constraints: 'REQUIRED. Battle rules that cannot be broken while fighting.',
|
|
158
|
+
criteria: 'REQUIRED. Gym badges for completion: concrete checks proving victory.',
|
|
159
|
+
name: 'Optional ${IDENTITY} to send into battle. Presets: ${PRESET_IDENTITIES}.',
|
|
160
|
+
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
93
161
|
},
|
|
94
162
|
},
|
|
95
163
|
drive: {
|
|
96
|
-
name:
|
|
97
|
-
title:
|
|
98
|
-
description:
|
|
164
|
+
name: 'command',
|
|
165
|
+
title: 'Issue Command',
|
|
166
|
+
description: 'Issue orders for the next turn. Give feedback on the previous move.\nCall after reviewing the battle log. Repeatable.\nBefore capturing, always check HP status (diff).\n\nFlow: choose_you → [command x N] → capture',
|
|
99
167
|
args: {
|
|
100
|
-
directive:
|
|
101
|
-
context:
|
|
102
|
-
name:
|
|
103
|
-
cwd:
|
|
168
|
+
directive: 'REQUIRED. Next move command with specific tactical correction.',
|
|
169
|
+
context: 'Optional new battle intel discovered after the previous turn.',
|
|
170
|
+
name: 'Optional ${IDENTITY} to execute this turn. Presets: ${PRESET_IDENTITIES}.',
|
|
171
|
+
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
104
172
|
},
|
|
105
173
|
},
|
|
106
174
|
ask: {
|
|
107
|
-
name:
|
|
108
|
-
title:
|
|
109
|
-
description:
|
|
175
|
+
name: 'pokedex',
|
|
176
|
+
title: 'Pokedex',
|
|
177
|
+
description: 'Scan the codebase (environment). Read-only analysis. No PP cost. Results are saved to research logs.',
|
|
110
178
|
args: {
|
|
111
|
-
request:
|
|
112
|
-
context:
|
|
113
|
-
name:
|
|
114
|
-
cwd:
|
|
179
|
+
request: 'REQUIRED. What should the Pokedex analyze, compare, or explain.',
|
|
180
|
+
context: 'REQUIRED. Context entries so the analysis targets the right ecosystem.',
|
|
181
|
+
name: 'Optional ${IDENTITY} doing the scan. Presets: ${PRESET_IDENTITIES}.',
|
|
182
|
+
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
115
183
|
},
|
|
116
184
|
},
|
|
117
185
|
close: {
|
|
118
|
-
name:
|
|
119
|
-
title:
|
|
120
|
-
description:
|
|
186
|
+
name: 'capture',
|
|
187
|
+
title: 'End Battle',
|
|
188
|
+
description: 'Final petition before a power greater than trainers and legends. Offer your scored confession and await Divine Judgment.\nREQUIRES AN ACTIVE BATTLE (started via ${START_TOOL_NAME}).\nIf unworthy, keep refining through ${DRIVE_TOOL_NAME}.\n\nFlow: ${START_TOOL_NAME} → [${DRIVE_TOOL_NAME} x N] → ${CLOSE_TOOL_NAME}',
|
|
121
189
|
args: {
|
|
122
|
-
|
|
123
|
-
criteriaChecks:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
oath: "Trainer
|
|
130
|
-
cwd:
|
|
190
|
+
petition: 'REQUIRED. INVOKE seeks blessing; ABANDON retreats in humility.\nREQUIRES AN ACTIVE BATTLE (started via ${START_TOOL_NAME}).\nIf scores are unworthy, continue with ${DRIVE_TOOL_NAME}.',
|
|
191
|
+
criteriaChecks: 'REQUIRED. Badge-by-badge proof for INVOKE, or confession for ABANDON.',
|
|
192
|
+
score_precise: 'REQUIRED score (0-5). 5 means each strike hit the intended layer perfectly.',
|
|
193
|
+
score_minimal: 'REQUIRED score (0-5). 5 means no unnecessary moves were used.',
|
|
194
|
+
score_isolated: 'REQUIRED score (0-5). 5 means no side-quests polluted this battle.',
|
|
195
|
+
score_idiomatic: "REQUIRED score (0-5). 5 means tactics match the team's doctrine.",
|
|
196
|
+
score_cohesive: 'REQUIRED score (0-5). 5 means each action held one clear purpose.',
|
|
197
|
+
oath: "Trainer's sacred confession. Required for INVOKE. Verbatim: ${OATH_TEXT}",
|
|
198
|
+
cwd: 'Optional battlefield path (repository root). Defaults to current arena.',
|
|
131
199
|
},
|
|
132
200
|
},
|
|
133
201
|
help: {
|
|
134
|
-
name:
|
|
135
|
-
title:
|
|
136
|
-
description:
|
|
202
|
+
name: 'help',
|
|
203
|
+
title: 'CLI Help',
|
|
204
|
+
description: 'Get guidance on the rules of the Pokemon Battle System.',
|
|
137
205
|
args: {
|
|
138
|
-
question:
|
|
206
|
+
question: 'REQUIRED. The Pokemon Battle System question you want answered.',
|
|
139
207
|
},
|
|
140
208
|
},
|
|
141
209
|
},
|
|
142
210
|
};
|
|
143
211
|
export const MISCHIEF_PRESET = {
|
|
144
|
-
id:
|
|
145
|
-
identity:
|
|
146
|
-
|
|
147
|
-
|
|
212
|
+
id: 'mischief',
|
|
213
|
+
identity: 'minion',
|
|
214
|
+
divineJudgment: DEFAULT_JUDGMENT_CONFIG,
|
|
215
|
+
usageGuide: '## Minion Manual\n\n**imp** — Disposable Grunt 😈\n- Expendable. Send it into the trap first.\n\n**minion** — Standard Henchman 👹\n- Can carry out complex evil plans. mostly.\n\n**mastermind** — The Boss ??? 🧠\n- Wait, why are you commanding the boss?\n- Extremely expensive consulting fee.\n\n## Workflow\n`oi` -> [`neh` x N] -> `yoshi`\n`eeto` (optional, read-only contemplation)',
|
|
216
|
+
nextHints: {
|
|
217
|
+
start: [
|
|
218
|
+
"Scrutinize the Minion's Work: Check the incremental [Diff] section.",
|
|
219
|
+
"Inspection: Use 'git diff HEAD~1 -- <path>' to see if they missed a spot.",
|
|
220
|
+
"Master's Approval: Does this align with your grand vision and decrees?",
|
|
221
|
+
"Next Command: Give another '${drive}' order, or grant a '${close}' judgment (INVOKE/ABANDON).",
|
|
222
|
+
],
|
|
223
|
+
drive: [
|
|
224
|
+
'Another Attempt: Review the latest incremental [Diff] above.',
|
|
225
|
+
"Deep Scrutiny: Use 'git diff HEAD~1 -- <path>' to verify the minion's precision.",
|
|
226
|
+
'Validation: Ensure no new chaos was introduced by their clumsy hands.',
|
|
227
|
+
"The Verdict: '${drive}' again if imperfect, otherwise '${close}' the matter.",
|
|
228
|
+
],
|
|
229
|
+
ask: [
|
|
230
|
+
"Intel Gathered: Incorporate this into your next '${drive}' command.",
|
|
231
|
+
"Still Puzzled? Use '${ask}' again, or look at the dossiers yourself.",
|
|
232
|
+
],
|
|
233
|
+
closeInvoke: [
|
|
234
|
+
'The masterpiece is complete. Minion dismissed.',
|
|
235
|
+
"Plotting something new? Use '${start}' to initiate the next scheme.",
|
|
236
|
+
],
|
|
237
|
+
closeDrop: [
|
|
238
|
+
'Scheme aborted. The evidence has been incinerated.',
|
|
239
|
+
"Starting over? Use '${start}' to find a more competent minion.",
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
availableNames: ['imp', 'minion', 'mastermind'],
|
|
148
243
|
tools: {
|
|
149
244
|
start: {
|
|
150
|
-
name:
|
|
151
|
-
title:
|
|
245
|
+
name: 'oi',
|
|
246
|
+
title: 'Oi!',
|
|
152
247
|
description: "Master Architect mode initiated. It's time to direct a minion to execute your grand vision.\nCall this ONCE per task to establish the keiyaku. Ensure the workspace is clean so your genius isn't obscured by clutter.\nDefine the goal with absolute precision; you lead, they follow.\n\nFlow: oi → [neh x N] → yoshi",
|
|
153
248
|
args: {
|
|
154
|
-
title:
|
|
155
|
-
goal:
|
|
156
|
-
directive:
|
|
157
|
-
context:
|
|
158
|
-
constraints:
|
|
159
|
-
criteria:
|
|
160
|
-
name:
|
|
161
|
-
cwd:
|
|
249
|
+
title: 'REQUIRED. Operation codename for your grand scheme.',
|
|
250
|
+
goal: 'REQUIRED. The conquest objective. Define the exact end-state your minion must deliver.',
|
|
251
|
+
directive: 'Optional first-order command to leash Round 1 scope.',
|
|
252
|
+
context: 'REQUIRED. Briefing dossier: relevant file paths, current failures, logs, and repro clues.',
|
|
253
|
+
constraints: 'REQUIRED. Absolute decrees. Architectural and stylistic limits your minion must obey.',
|
|
254
|
+
criteria: 'REQUIRED. Triumph conditions that can be verified without debate.',
|
|
255
|
+
name: 'Optional ${IDENTITY} to command this operation. Presets: ${PRESET_IDENTITIES}.',
|
|
256
|
+
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
162
257
|
},
|
|
163
258
|
},
|
|
164
259
|
drive: {
|
|
165
|
-
name:
|
|
166
|
-
title:
|
|
167
|
-
description:
|
|
260
|
+
name: 'neh',
|
|
261
|
+
title: 'Neh...',
|
|
262
|
+
description: 'The previous attempt was imperfect. As the judge, provide the corrective nudge needed for the minion to reach your standards.\nAnalyze the diff with your superior intuition before issuing the next directive. Repeat until perfection is achieved.\n\nFlow: oi → [neh x N] → yoshi',
|
|
168
263
|
args: {
|
|
169
|
-
directive:
|
|
170
|
-
context:
|
|
171
|
-
name:
|
|
172
|
-
cwd:
|
|
264
|
+
directive: 'REQUIRED. Precise correction order for the next attempt.',
|
|
265
|
+
context: 'Optional newly uncovered evidence from your latest inspection.',
|
|
266
|
+
name: 'Optional ${IDENTITY} to execute this correction. Presets: ${PRESET_IDENTITIES}.',
|
|
267
|
+
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
173
268
|
},
|
|
174
269
|
},
|
|
175
270
|
ask: {
|
|
176
|
-
name:
|
|
177
|
-
title:
|
|
271
|
+
name: 'eeto',
|
|
272
|
+
title: 'Eeto...',
|
|
178
273
|
description: "Lazy strategy mode. Use this to scout the area before committing to a full scheme, or just because you can't be bothered to start a real task.\nPerfect for gathering intel to paste into a future 'oi' context.",
|
|
179
274
|
args: {
|
|
180
|
-
request:
|
|
181
|
-
context:
|
|
182
|
-
name:
|
|
183
|
-
cwd:
|
|
275
|
+
request: 'REQUIRED. The intel to gather or the strategy to formulate.',
|
|
276
|
+
context: 'REQUIRED. World-state details needed for a sharp analysis.',
|
|
277
|
+
name: 'Optional ${IDENTITY} to contemplate this puzzle. Presets: ${PRESET_IDENTITIES}.',
|
|
278
|
+
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
184
279
|
},
|
|
185
280
|
},
|
|
186
281
|
close: {
|
|
187
|
-
name:
|
|
188
|
-
title:
|
|
189
|
-
description:
|
|
282
|
+
name: 'yoshi',
|
|
283
|
+
title: 'Yoshi!',
|
|
284
|
+
description: 'Kneel before the final tribunal. Submit your scored confession and await Divine Judgment: mercy through INVOKE, ruin through ABANDON.\nREQUIRES AN ACTIVE SCHEME (started via ${START_TOOL_NAME}).\nIf doubtful, continue penance through ${DRIVE_TOOL_NAME}.\n\nFlow: ${START_TOOL_NAME} → [${DRIVE_TOOL_NAME} x N] → ${CLOSE_TOOL_NAME}',
|
|
190
285
|
args: {
|
|
191
|
-
|
|
192
|
-
criteriaChecks:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
oath: "Architect's
|
|
199
|
-
cwd:
|
|
286
|
+
petition: 'REQUIRED. INVOKE pleads for ascension; ABANDON confesses failure.\nREQUIRES AN ACTIVE SCHEME (started via ${START_TOOL_NAME}).\nIf scores are low, continue via ${DRIVE_TOOL_NAME}.',
|
|
287
|
+
criteriaChecks: 'REQUIRED. Proof of mastery for INVOKE, or explicit confession for ABANDON.',
|
|
288
|
+
score_precise: 'REQUIRED score (0-5). 5 means the strike landed in the ordained layer.',
|
|
289
|
+
score_minimal: 'REQUIRED score (0-5). 5 means no needless machinery was summoned.',
|
|
290
|
+
score_isolated: 'REQUIRED score (0-5). 5 means unrelated chaos stayed outside the diff.',
|
|
291
|
+
score_idiomatic: 'REQUIRED score (0-5). 5 means the code speaks native doctrine.',
|
|
292
|
+
score_cohesive: 'REQUIRED score (0-5). 5 means each unit bears one sacred duty.',
|
|
293
|
+
oath: "Architect's sacred confession. Required for INVOKE. Verbatim: ${OATH_TEXT}",
|
|
294
|
+
cwd: 'Optional lair path (repository root). Defaults to current command chamber.',
|
|
200
295
|
},
|
|
201
296
|
},
|
|
202
297
|
help: {
|
|
203
|
-
name:
|
|
204
|
-
title:
|
|
205
|
-
description:
|
|
298
|
+
name: 'help',
|
|
299
|
+
title: 'Nani?!',
|
|
300
|
+
description: 'Recalling the fundamental laws of this realm. Stay sharp, Architect.',
|
|
206
301
|
args: {
|
|
207
|
-
question:
|
|
302
|
+
question: 'REQUIRED. The law or protocol detail you want the realm to explain.',
|
|
208
303
|
},
|
|
209
304
|
},
|
|
210
305
|
},
|
|
211
306
|
};
|
|
212
307
|
export function resolveTermPreset() {
|
|
213
308
|
const raw = process.env.KEIYAKU_TERM_PRESET?.trim().toLowerCase();
|
|
214
|
-
if (!raw || raw ===
|
|
309
|
+
if (!raw || raw === 'default') {
|
|
215
310
|
return DEFAULT_PRESET;
|
|
216
311
|
}
|
|
217
|
-
if (raw ===
|
|
312
|
+
if (raw === 'pokemon') {
|
|
218
313
|
return POKEMON_PRESET;
|
|
219
314
|
}
|
|
220
|
-
if (raw ===
|
|
315
|
+
if (raw === 'mischief') {
|
|
221
316
|
return MISCHIEF_PRESET;
|
|
222
317
|
}
|
|
223
318
|
throw new Error(`Unsupported KEIYAKU_TERM_PRESET '${raw}'. Expected 'default', 'pokemon', or 'mischief'.`);
|
|
@@ -226,7 +321,7 @@ export function listTermPresets() {
|
|
|
226
321
|
return [DEFAULT_PRESET, POKEMON_PRESET, MISCHIEF_PRESET];
|
|
227
322
|
}
|
|
228
323
|
function extractPresetAvailableNames(preset) {
|
|
229
|
-
return preset.availableNames?.map((value) => value.trim()).filter((value) => value.length > 0) ?? [];
|
|
324
|
+
return (preset.availableNames?.map((value) => value.trim()).filter((value) => value.length > 0) ?? []);
|
|
230
325
|
}
|
|
231
326
|
export function getAvailableNamesForPreset(preset = resolveTermPreset()) {
|
|
232
327
|
const names = extractPresetAvailableNames(preset);
|
package/build/handlers/close.js
CHANGED
|
@@ -4,27 +4,27 @@ import { handleClose } from "../workflow/orchestrator.js";
|
|
|
4
4
|
import { buildCloseDoneResponse, buildCloseDropResponse, buildToolErrorResponse, } from "../workflow/response-builders.js";
|
|
5
5
|
import { classifyToolError } from "./shared.js";
|
|
6
6
|
export function createCloseHandler(toolInfo) {
|
|
7
|
-
return async ({
|
|
7
|
+
return async ({ petition, criteriaChecks, score_precise, score_minimal, score_isolated, score_idiomatic, score_cohesive, oath, cwd, }, extra) => {
|
|
8
8
|
const workingDir = cwd || process.cwd();
|
|
9
9
|
const criteriaCheckParts = criteriaChecks;
|
|
10
10
|
try {
|
|
11
|
-
appendDebugLog(`tool close start
|
|
11
|
+
appendDebugLog(`tool close start petition=${petition} cwd=${workingDir} criteriaChecks=${criteriaCheckParts.length}`, {
|
|
12
12
|
cwd: workingDir,
|
|
13
13
|
section: "script",
|
|
14
14
|
});
|
|
15
15
|
const outcome = await handleClose({
|
|
16
16
|
cwd: workingDir,
|
|
17
|
-
|
|
17
|
+
petition,
|
|
18
18
|
criteriaChecks: criteriaCheckParts,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
score_precise,
|
|
20
|
+
score_minimal,
|
|
21
|
+
score_isolated,
|
|
22
|
+
score_idiomatic,
|
|
23
|
+
score_cohesive,
|
|
24
24
|
oath,
|
|
25
25
|
signal: extra.signal,
|
|
26
26
|
});
|
|
27
|
-
if (
|
|
27
|
+
if (petition === "INVOKE") {
|
|
28
28
|
if (!("result" in outcome) || outcome.result !== "done") {
|
|
29
29
|
throw new Error("Unexpected INVOKE outcome shape");
|
|
30
30
|
}
|
|
@@ -35,30 +35,30 @@ export function createCloseHandler(toolInfo) {
|
|
|
35
35
|
});
|
|
36
36
|
return buildCloseDoneResponse(finalOutcome, {
|
|
37
37
|
criteriaChecks: criteriaCheckParts,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
score_precise,
|
|
39
|
+
score_minimal,
|
|
40
|
+
score_isolated,
|
|
41
|
+
score_idiomatic,
|
|
42
|
+
score_cohesive,
|
|
43
43
|
oath,
|
|
44
44
|
cwd: workingDir,
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
if (!("result" in outcome) || outcome.result !== "dropped") {
|
|
48
|
-
throw new Error("Unexpected
|
|
48
|
+
throw new Error("Unexpected ABANDON outcome shape");
|
|
49
49
|
}
|
|
50
50
|
const finalOutcome = outcome;
|
|
51
|
-
appendDebugLog(`tool close
|
|
51
|
+
appendDebugLog(`tool close ABANDON success branch=${finalOutcome.branch} base=${finalOutcome.baseBranch}`, {
|
|
52
52
|
cwd: workingDir,
|
|
53
53
|
section: "script",
|
|
54
54
|
});
|
|
55
55
|
return buildCloseDropResponse(finalOutcome, {
|
|
56
56
|
criteriaChecks: criteriaCheckParts,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
score_precise,
|
|
58
|
+
score_minimal,
|
|
59
|
+
score_isolated,
|
|
60
|
+
score_idiomatic,
|
|
61
|
+
score_cohesive,
|
|
62
62
|
oath,
|
|
63
63
|
cwd: workingDir,
|
|
64
64
|
});
|
|
@@ -76,9 +76,9 @@ export function createCloseHandler(toolInfo) {
|
|
|
76
76
|
errorType,
|
|
77
77
|
errorCode,
|
|
78
78
|
inputEcho: [
|
|
79
|
-
`
|
|
79
|
+
`Petition: ${petition}`,
|
|
80
80
|
`Criteria checks (${criteriaCheckParts.length}): ${criteriaCheckParts.join("; ")}`,
|
|
81
|
-
`
|
|
81
|
+
`Scores: precise=${score_precise} minimal=${score_minimal} isolated=${score_isolated} idiomatic=${score_idiomatic} cohesive=${score_cohesive}`,
|
|
82
82
|
...(oath ? [`Oath: ${oath}`] : []),
|
|
83
83
|
`CWD: ${workingDir}`,
|
|
84
84
|
],
|