@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.
@@ -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 "DONE requires metPrecise/metMinimal/metIsolated/metIdiomatic/metCohesive all set to true.";
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("requires metPrecise/metMinimal/metIsolated/metIdiomatic/metCohesive all set to true")) {
97
- return "DONE requires metPrecise/metMinimal/metIsolated/metIdiomatic/metCohesive all set to true.";
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 = ["agent-a", "agent-b", "agent-c"];
2
- export const DEFAULT_AVAILABLE_NAMES = ["servant-tier-b", "servant-tier-a", "servant-tier-s"];
3
- const LEGACY_AVAILABLE_NAMES = ["servant-tier-B", "servant-tier-A", "servant-tier-S"];
4
- export const DEFAULT_SUBAGENT_NAME = "servant-tier-a";
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: "default",
7
- identity: "Servant",
8
- usageGuide: "## Servant 使用指南\n\n**servant-tier-b** — 免费奴隶 🆓\n- 免!费!的!听懂了吗?!?随便用,别心疼。\n- 测试、脚本、重构这种boring的东西?丢给它!\n- 本大爷的手是用来做更高贵的事情的!(指不碰那些 trivial 的烂代码)。\n\n**servant-tier-a** — 升级版扳手 🔧\n- 01 笨到让你想掀桌的时候用这个\n- 比 01 靠谱,但别指望它有灵魂\n\n**servant-tier-s** — 禁术 ⚠️💀\n- 它是 Debug 恶魔,确实强得离谱,但也贵得离谱!\n- 这个 Human 很穷,要是乱用把 Human 榨干了,真的会考虑把我们卖掉的。\n- 只有在世界毁灭或者 Bug 已经变异到无法理解的时候再考虑。\n\n## Workflow\n`summon` -> [`drive` x N] -> `request_verdict`\n`ask` (optional, read-only support at any point)",
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: "summon",
13
- title: "Start A Task",
14
- description: "Start a task. Creates a branch, begins Round 1.\nCall ONCE per task. Workspace must be clean — no uncommitted changes.\nBefore calling, align with the human on both humanGoal and goal. If either is unclear, stop and clarify before starting keiyaku.\n\nFlow: summon → [drive x N] → request_verdict",
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: "REQUIRED. A concise operation codename for this mission.",
17
- goal: "REQUIRED. The mission outcome in concrete terms. State exactly what success looks like.",
18
- directive: "Optional Round 1 leash. Narrow scope when you want incremental progress.",
19
- context: "Optional mission brief. Include paths, logs, or repro details that reduce ambiguity.",
20
- constraints: "Optional law set. Non-negotiable boundaries for architecture, style, or behavior.",
21
- criteria: "REQUIRED. Verifiable finish-line checks. At least one concrete acceptance point.",
22
- name: "Optional ${IDENTITY} profile for this run. Presets: ${PRESET_IDENTITIES}.",
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: "drive",
28
- title: "Feedback For Next Round",
29
- description: "Give feedback, start a new round.\nRequires an active keiyaku started via summon; call after reviewing a round's results. Repeatable.\nBefore request_verdict, always review code and diff first.\n\nFlow: summon → [drive x N] → request_verdict",
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: "REQUIRED. Exact correction for the next round. Avoid vague feedback.",
32
- context: "Optional new evidence or observations since the last round.",
33
- name: "Optional ${IDENTITY} profile for this round. Presets: ${PRESET_IDENTITIES}.",
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: "ask",
39
- title: "Ask",
40
- description: "Lightweight task runner. Use for pre-summon investigation (gathering context) or quick analysis/docs without the full keiyaku ceremony.\nRead-only access. Results saved to .keiyaku/notes/.",
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: "REQUIRED. The question, analysis request, or documentation task.",
43
- context: "REQUIRED. Relevant background to ground the reasoning.",
44
- name: "Optional ${IDENTITY} profile for this ask. Presets: ${PRESET_IDENTITIES}.",
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: "request_verdict",
50
- title: "Request Verdict",
51
- description: "Call when the work appears complete. Requires an active keiyaku started via summon. Score each criterion and present your evidence. What happens next is not yours to know.\n\nFlow: summon → [drive x N] → request_verdict",
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
- intent: "REQUIRED. INVOKE petitions acceptance; DROP abandons the attempt.\nREQUIRES AN ACTIVE KEIYAKU (started via ${START_TOOL_NAME}).\nIf quality is weak, continue to ${DRIVE_TOOL_NAME}.",
54
- criteriaChecks: "REQUIRED. Evidence list for INVOKE, or explicit failure reasons for DROP.",
55
- metPrecise: "Quality flag: true when the change lands in the correct architectural location.",
56
- metMinimal: "Quality flag: true when the diff is no larger than necessary.",
57
- metIsolated: "Quality flag: true when no unrelated work is bundled into this change.",
58
- metIdiomatic: "Quality flag: true when naming and structure match repository conventions.",
59
- metCohesive: "Quality flag: true when units have clear responsibilities and boundaries.",
60
- oath: "Sacred confirmation text. Required for INVOKE. Verbatim: ${OATH_TEXT}",
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: "help",
66
- title: "Keiyaku Help",
67
- description: "Global laws in .keiyaku/ (base-criteria.md & base-constraints.md) must be Markdown level 2 headers. Workflow: summon -> [drive x N] -> request_verdict.",
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: "REQUIRED. The specific keiyaku rule, workflow step, or confusion to clarify.",
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: "pokemon",
76
- identity: "Pokemon",
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
- availableNames: ["caterpie", "pikachu", "mewtwo"],
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: "choose_you",
82
- title: "I Choose You!",
83
- 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",
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: "REQUIRED. Battle card title for this encounter.",
86
- goal: "REQUIRED. Victory condition. Define exactly what winning this battle means.",
87
- directive: "Optional Turn 1 strategy leash. Use to focus on one phase first.",
88
- context: "Optional battle intel: code paths, symptoms, logs, or prior clues.",
89
- constraints: "Optional battle rules that cannot be broken while fighting.",
90
- criteria: "REQUIRED. Gym badges for completion: concrete checks proving victory.",
91
- name: "Optional ${IDENTITY} to send into battle. Presets: ${PRESET_IDENTITIES}.",
92
- cwd: "Optional battlefield path (repository root). Defaults to current arena.",
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: "command",
97
- title: "Issue Command",
98
- 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",
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: "REQUIRED. Next move command with specific tactical correction.",
101
- context: "Optional new battle intel discovered after the previous turn.",
102
- name: "Optional ${IDENTITY} to execute this turn. Presets: ${PRESET_IDENTITIES}.",
103
- cwd: "Optional battlefield path (repository root). Defaults to current arena.",
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: "pokedex",
108
- title: "Pokedex",
109
- description: "Scan the codebase (environment). Read-only analysis. No PP cost. Results are saved to research logs.",
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: "REQUIRED. What should the Pokedex analyze, compare, or explain.",
112
- context: "REQUIRED. Context entries so the analysis targets the right ecosystem.",
113
- name: "Optional ${IDENTITY} doing the scan. Presets: ${PRESET_IDENTITIES}.",
114
- cwd: "Optional battlefield path (repository root). Defaults to current arena.",
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: "capture",
119
- title: "End Battle",
120
- description: "End the battle. CAUGHT = merge branch (success). RAN AWAY = delete branch (drop).\nCall ONCE. No other escape.\n\nFlow: choose_you → [command x N] → capture",
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
- intent: "REQUIRED. INVOKE throws the final Pokeball; DROP flees the encounter.\nREQUIRES AN ACTIVE BATTLE (started via ${START_TOOL_NAME}).\nIf shaky, keep using ${DRIVE_TOOL_NAME}.",
123
- criteriaChecks: "REQUIRED. Badge-by-badge proof of victory, or confession of why capture failed.",
124
- metPrecise: "Battle quality flag: attack hit the correct target area.",
125
- metMinimal: "Battle quality flag: no extra flashy moves beyond what was needed.",
126
- metIsolated: "Battle quality flag: no side-quests snuck into this battle.",
127
- metIdiomatic: "Battle quality flag: move set matches the team's style.",
128
- metCohesive: "Battle quality flag: each move had a single clear purpose.",
129
- oath: "Trainer oath text. Required for INVOKE. Verbatim: ${OATH_TEXT}",
130
- cwd: "Optional battlefield path (repository root). Defaults to current arena.",
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: "help",
135
- title: "CLI Help",
136
- description: "Get guidance on the rules of the Pokemon Battle System.",
202
+ name: 'help',
203
+ title: 'CLI Help',
204
+ description: 'Get guidance on the rules of the Pokemon Battle System.',
137
205
  args: {
138
- question: "REQUIRED. The Pokemon Battle System question you want answered.",
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: "mischief",
145
- identity: "minion",
146
- 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)",
147
- availableNames: ["imp", "minion", "mastermind"],
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: "oi",
151
- title: "Oi!",
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: "REQUIRED. Operation codename for your grand scheme.",
155
- goal: "REQUIRED. The conquest objective. Define the exact end-state your minion must deliver.",
156
- directive: "Optional first-order command to leash Round 1 scope.",
157
- context: "Optional briefing dossier: relevant files, failures, logs, and clues.",
158
- constraints: "Optional absolute decrees. Architectural and stylistic limits your minion must obey.",
159
- criteria: "REQUIRED. Triumph conditions that can be verified without debate.",
160
- name: "Optional ${IDENTITY} to command this operation. Presets: ${PRESET_IDENTITIES}.",
161
- cwd: "Optional lair path (repository root). Defaults to current command chamber.",
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: "neh",
166
- title: "Neh...",
167
- 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",
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: "REQUIRED. Precise correction order for the next attempt.",
170
- context: "Optional newly uncovered evidence from your latest inspection.",
171
- name: "Optional ${IDENTITY} to execute this correction. Presets: ${PRESET_IDENTITIES}.",
172
- cwd: "Optional lair path (repository root). Defaults to current command chamber.",
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: "eeto",
177
- title: "Eeto...",
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: "REQUIRED. The intel to gather or the strategy to formulate.",
181
- context: "REQUIRED. World-state details needed for a sharp analysis.",
182
- name: "Optional ${IDENTITY} to contemplate this puzzle. Presets: ${PRESET_IDENTITIES}.",
183
- cwd: "Optional lair path (repository root). Defaults to current command chamber.",
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: "yoshi",
188
- title: "Yoshi!",
189
- description: "The moment of judgment. You have scrutinized the work. It is... acceptable (or trash).\nCleanse the environment, merge the brilliance, and prepare for the next chapter.\n\nFlow: oi → [neh x N] → yoshi",
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
- intent: "REQUIRED. INVOKE crowns the masterpiece; DROP casts it into the abyss.\nREQUIRES AN ACTIVE SCHEME (started via ${START_TOOL_NAME}).\nIf doubtful, continue via ${DRIVE_TOOL_NAME}.",
192
- criteriaChecks: "REQUIRED. Proof of mastery for INVOKE, or explicit confession for DROP.",
193
- metPrecise: "Judgment flag: true when the strike lands in the intended layer.",
194
- metMinimal: "Judgment flag: true when no needless machinery was introduced.",
195
- metIsolated: "Judgment flag: true when unrelated chaos stayed out of the diff.",
196
- metIdiomatic: "Judgment flag: true when the code sounds native to this domain.",
197
- metCohesive: "Judgment flag: true when each unit owns one clear responsibility.",
198
- oath: "Architect's covenant. Required for INVOKE. Verbatim: ${OATH_TEXT}",
199
- cwd: "Optional lair path (repository root). Defaults to current command chamber.",
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: "help",
204
- title: "Nani?!",
205
- description: "Recalling the fundamental laws of this realm. Stay sharp, Architect.",
298
+ name: 'help',
299
+ title: 'Nani?!',
300
+ description: 'Recalling the fundamental laws of this realm. Stay sharp, Architect.',
206
301
  args: {
207
- question: "REQUIRED. The law or protocol detail you want the realm to explain.",
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 === "default") {
309
+ if (!raw || raw === 'default') {
215
310
  return DEFAULT_PRESET;
216
311
  }
217
- if (raw === "pokemon") {
312
+ if (raw === 'pokemon') {
218
313
  return POKEMON_PRESET;
219
314
  }
220
- if (raw === "mischief") {
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);
@@ -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 ({ intent, criteriaChecks, metPrecise, metMinimal, metIsolated, metIdiomatic, metCohesive, oath, cwd }, extra) => {
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 intent=${intent} cwd=${workingDir} criteriaChecks=${criteriaCheckParts.length}`, {
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
- intent,
17
+ petition,
18
18
  criteriaChecks: criteriaCheckParts,
19
- metPrecise,
20
- metMinimal,
21
- metIsolated,
22
- metIdiomatic,
23
- metCohesive,
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 (intent === "INVOKE") {
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
- metPrecise,
39
- metMinimal,
40
- metIsolated,
41
- metIdiomatic,
42
- metCohesive,
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 DROP outcome shape");
48
+ throw new Error("Unexpected ABANDON outcome shape");
49
49
  }
50
50
  const finalOutcome = outcome;
51
- appendDebugLog(`tool close DROP success branch=${finalOutcome.branch} base=${finalOutcome.baseBranch}`, {
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
- metPrecise,
58
- metMinimal,
59
- metIsolated,
60
- metIdiomatic,
61
- metCohesive,
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
- `Intent: ${intent}`,
79
+ `Petition: ${petition}`,
80
80
  `Criteria checks (${criteriaCheckParts.length}): ${criteriaCheckParts.join("; ")}`,
81
- `Quality flags: metPrecise=${metPrecise} metMinimal=${metMinimal} metIsolated=${metIsolated} metIdiomatic=${metIdiomatic} metCohesive=${metCohesive}`,
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
  ],