@astrosheep/keiyaku 0.1.7 → 0.1.9
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
CHANGED
|
@@ -33,7 +33,7 @@ function hintForFlowCode(code, message) {
|
|
|
33
33
|
case "NOT_GIT_REPO":
|
|
34
34
|
return "The provided `cwd` is not a git repository.";
|
|
35
35
|
case "ACTIVE_KEIYAKU_EXISTS":
|
|
36
|
-
return "An active keiyaku branch already exists in this repository. Continue with `drive`, or use `close` + `
|
|
36
|
+
return "An active keiyaku branch already exists in this repository. Continue with `drive`, or use `close` + `FORFEIT` to drop it.";
|
|
37
37
|
case "EXISTING_KEIYAKU_BRANCH_FOUND":
|
|
38
38
|
return "At least one local `keiyaku/*` branch already exists in this repository.";
|
|
39
39
|
case "EMPTY_PARAM":
|
|
@@ -49,7 +49,7 @@ function hintForFlowCode(code, message) {
|
|
|
49
49
|
case "DONE_MERGE_CONFLICT":
|
|
50
50
|
return "DONE encountered a git merge conflict.";
|
|
51
51
|
case "CLOSE_QUALITY_GATE_FAILED":
|
|
52
|
-
return "
|
|
52
|
+
return "CLAIM was denied because one or more verification thresholds were not met (check .keiyaku/settings.json).";
|
|
53
53
|
case "OATH_MISMATCH":
|
|
54
54
|
return message;
|
|
55
55
|
case "SUBAGENT_DID_NOT_ADVANCE_ROUND":
|
|
@@ -72,7 +72,7 @@ const MESSAGE_HINT_PATTERNS = [
|
|
|
72
72
|
{ code: "MISSING_KEIYAKU_BASE", patterns: ["is missing base metadata"] },
|
|
73
73
|
{ code: "MISSING_PROTOCOL_FILES", patterns: ["missing protocol files"] },
|
|
74
74
|
{ code: "DONE_MERGE_CONFLICT", patterns: ["DONE merge conflict"] },
|
|
75
|
-
{ code: "CLOSE_QUALITY_GATE_FAILED", patterns: ["God's Wrath:
|
|
75
|
+
{ code: "CLOSE_QUALITY_GATE_FAILED", patterns: ["God's Wrath: CLAIM denied"] },
|
|
76
76
|
{
|
|
77
77
|
code: "OATH_MISMATCH",
|
|
78
78
|
patterns: [
|
|
@@ -39,7 +39,7 @@ export const DEFAULT_PRESET = {
|
|
|
39
39
|
'Intel acquired. This was stateless—no contract, no branch.',
|
|
40
40
|
'To act on this knowledge: ${start} a Keiyaku, or ${drive} an existing one.',
|
|
41
41
|
],
|
|
42
|
-
|
|
42
|
+
closeClaim: [
|
|
43
43
|
'Contract fulfilled. Branch merged.',
|
|
44
44
|
'You are back on base.',
|
|
45
45
|
'Next assignment: ${start} when ready.',
|
|
@@ -147,7 +147,7 @@ export const POCKET_PRESET = {
|
|
|
147
147
|
"Data Recorded: Use '${start}' to begin the encounter, or '${drive}' to use this intel.",
|
|
148
148
|
"Still Searching? Keep using '${ask}' to fill the Dex.",
|
|
149
149
|
],
|
|
150
|
-
|
|
150
|
+
closeClaim: [
|
|
151
151
|
'Critter Captured! The entry is logged in the PC (base branch).',
|
|
152
152
|
"Heal up. Use '${start}' to challenge the next opponent.",
|
|
153
153
|
],
|
|
@@ -198,16 +198,16 @@ export const POCKET_PRESET = {
|
|
|
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 `
|
|
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_TOOL_NAME} → [${DRIVE_TOOL_NAME} x N] → ${CLOSE_TOOL_NAME}',
|
|
202
202
|
args: {
|
|
203
|
-
petition: 'REQUIRED.
|
|
204
|
-
criteriaChecks: 'REQUIRED. Badge-by-badge proof for
|
|
203
|
+
petition: 'REQUIRED. CLAIM seeks Badge; FORFEIT forfeits the match.\nREQUIRES AN ACTIVE BATTLE (started via ${START_TOOL_NAME}).\nIf stats are low, continue with ${DRIVE_TOOL_NAME}.',
|
|
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
|
|
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
|
},
|
|
@@ -243,7 +243,7 @@ export const MISCHIEF_PRESET = {
|
|
|
243
243
|
"Intel Stolen: Use '${start}' to launch the scheme, or '${drive}' to exploit this weakness.",
|
|
244
244
|
"Still Puzzled? Send the spy ('${ask}') out again.",
|
|
245
245
|
],
|
|
246
|
-
|
|
246
|
+
closeClaim: [
|
|
247
247
|
'Scheme Successful. The Lair is merged. The Minion is fed.',
|
|
248
248
|
"Plotting something new? Use '${start}' for the next conquest.",
|
|
249
249
|
],
|
|
@@ -294,16 +294,16 @@ export const MISCHIEF_PRESET = {
|
|
|
294
294
|
close: {
|
|
295
295
|
name: 'yoshi',
|
|
296
296
|
title: 'Yoshi!',
|
|
297
|
-
description: 'The Final Reveal. Present your Masterpiece to the Dark Council (System).\nWARNING: The Council destroys failure. If you `
|
|
297
|
+
description: 'The Final Reveal. Present your Masterpiece to the Dark Council (System).\nWARNING: The Council destroys failure. If you `CLAIM` with weak plans, the Self-Destruct (FORFEIT) will trigger.\nOnly reveal the Doomsday Device when it is fully operational.\n\nFlow: ${START_TOOL_NAME} → [${DRIVE_TOOL_NAME} x N] → ${CLOSE_TOOL_NAME}',
|
|
298
298
|
args: {
|
|
299
|
-
petition: 'REQUIRED.
|
|
300
|
-
criteriaChecks: 'REQUIRED. Proof of conquest for
|
|
299
|
+
petition: 'REQUIRED. CLAIM demands rule; FORFEIT admits defeat.\nREQUIRES AN ACTIVE SCHEME (started via ${START_TOOL_NAME}).\nIf the plan is weak, improve it with ${DRIVE_TOOL_NAME}.',
|
|
300
|
+
criteriaChecks: 'REQUIRED. Proof of conquest for CLAIM, or reason for self-destruct.',
|
|
301
301
|
score_precise: 'REQUIRED score (0-5). 5 means Laser Focus: exact cut, zero meaningful drift.',
|
|
302
302
|
score_minimal: 'REQUIRED score (0-5). 5 means Ruthless Efficiency: no wasted movement, no excess.',
|
|
303
303
|
score_isolated: 'REQUIRED score (0-5). 5 means Perfect Containment: no collateral damage.',
|
|
304
304
|
score_idiomatic: 'REQUIRED score (0-5). 5 means Native Tongue: matches the lair\'s dialect perfectly.',
|
|
305
305
|
score_cohesive: 'REQUIRED score (0-5). 5 means Absolute Loyalty: each unit serves the master plan.',
|
|
306
|
-
oath: "Mastermind's Vow. Required for
|
|
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/handlers/close.js
CHANGED
|
@@ -24,12 +24,12 @@ export function createCloseHandler() {
|
|
|
24
24
|
oath,
|
|
25
25
|
signal: extra.signal,
|
|
26
26
|
});
|
|
27
|
-
if (petition === "
|
|
27
|
+
if (petition === "CLAIM") {
|
|
28
28
|
if (!("result" in outcome) || outcome.result !== "done") {
|
|
29
|
-
throw new Error("Unexpected
|
|
29
|
+
throw new Error("Unexpected CLAIM outcome shape");
|
|
30
30
|
}
|
|
31
31
|
const finalOutcome = outcome;
|
|
32
|
-
appendDebugLog(`tool close
|
|
32
|
+
appendDebugLog(`tool close CLAIM success branch=${finalOutcome.branch} base=${finalOutcome.baseBranch}`, {
|
|
33
33
|
cwd: workingDir,
|
|
34
34
|
section: "script",
|
|
35
35
|
});
|
|
@@ -45,10 +45,10 @@ export function createCloseHandler() {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
if (!("result" in outcome) || outcome.result !== "dropped") {
|
|
48
|
-
throw new Error("Unexpected
|
|
48
|
+
throw new Error("Unexpected FORFEIT outcome shape");
|
|
49
49
|
}
|
|
50
50
|
const finalOutcome = outcome;
|
|
51
|
-
appendDebugLog(`tool close
|
|
51
|
+
appendDebugLog(`tool close FORFEIT success branch=${finalOutcome.branch} base=${finalOutcome.baseBranch}`, {
|
|
52
52
|
cwd: workingDir,
|
|
53
53
|
section: "script",
|
|
54
54
|
});
|
|
@@ -22,7 +22,7 @@ export const askToolSchema = z.object({
|
|
|
22
22
|
cwd: z.string().optional(),
|
|
23
23
|
});
|
|
24
24
|
export const closeToolSchema = z.object({
|
|
25
|
-
petition: z.enum(["
|
|
25
|
+
petition: z.enum(["CLAIM", "FORFEIT"]),
|
|
26
26
|
criteriaChecks: z.array(z.string().trim().min(1)).min(1),
|
|
27
27
|
score_precise: z.number().min(0).max(5),
|
|
28
28
|
score_minimal: z.number().min(0).max(5),
|
|
@@ -61,9 +61,9 @@ function truncateForMessage(text, maxChars) {
|
|
|
61
61
|
async function buildActiveKeiyakuStartMessage(cwd, branch) {
|
|
62
62
|
const lines = [
|
|
63
63
|
`active keiyaku already exists (${branch})`,
|
|
64
|
-
"This task is still active. Decide whether to continue or
|
|
64
|
+
"This task is still active. Decide whether to continue or forfeit it.",
|
|
65
65
|
"Continue: run drive on the current keiyaku branch.",
|
|
66
|
-
"
|
|
66
|
+
"Forfeit: run close with petition=FORFEIT to drop the branch.",
|
|
67
67
|
];
|
|
68
68
|
try {
|
|
69
69
|
const keiyakuPath = path.join(cwd, KEIYAKU_FILE);
|
|
@@ -417,7 +417,7 @@ export async function handleClose(input) {
|
|
|
417
417
|
}
|
|
418
418
|
const title = keiyakuBranch.slice("keiyaku/".length);
|
|
419
419
|
const petition = input.petition;
|
|
420
|
-
if (petition === "
|
|
420
|
+
if (petition === "FORFEIT") {
|
|
421
421
|
let round = 0;
|
|
422
422
|
try {
|
|
423
423
|
const trace = await fs.readFile(path.join(cwd, TRACE_FILE), "utf-8");
|
|
@@ -433,7 +433,7 @@ export async function handleClose(input) {
|
|
|
433
433
|
await git.clearKeiyakuBase(cwd, keiyakuBranch);
|
|
434
434
|
}
|
|
435
435
|
catch (err) {
|
|
436
|
-
throw wrapFlowError(`execute
|
|
436
|
+
throw wrapFlowError(`execute FORFEIT (${keiyakuBranch} -> ${baseBranch})`, err);
|
|
437
437
|
}
|
|
438
438
|
return {
|
|
439
439
|
status: "success",
|
|
@@ -441,12 +441,12 @@ export async function handleClose(input) {
|
|
|
441
441
|
round,
|
|
442
442
|
branch: keiyakuBranch,
|
|
443
443
|
baseBranch,
|
|
444
|
-
diff: "
|
|
444
|
+
diff: "Forfeited without merge.",
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
await ensureKeiyakuFiles(cwd);
|
|
448
448
|
const traceContent = await readTraceContent(cwd);
|
|
449
|
-
if (petition === "
|
|
449
|
+
if (petition === "CLAIM") {
|
|
450
450
|
const verdict = await resolveVerdictConfig(cwd);
|
|
451
451
|
const failedCommandments = CLOSE_SCORE_FIELDS.flatMap((field) => {
|
|
452
452
|
const score = input[field];
|
|
@@ -476,15 +476,15 @@ export async function handleClose(input) {
|
|
|
476
476
|
}
|
|
477
477
|
await assertCleanWorkingTree(cwd);
|
|
478
478
|
try {
|
|
479
|
-
const invokeDiffLog = `[
|
|
479
|
+
const invokeDiffLog = `[CLAIM] Collecting diff preview against base '${baseBranch}'`;
|
|
480
480
|
console.error(invokeDiffLog);
|
|
481
481
|
appendDebugLog(invokeDiffLog, { cwd, section: "script" });
|
|
482
|
-
const invokeReadLog = "[
|
|
482
|
+
const invokeReadLog = "[CLAIM] Reading keiyaku protocol files";
|
|
483
483
|
console.error(invokeReadLog);
|
|
484
484
|
appendDebugLog(invokeReadLog, { cwd, section: "script" });
|
|
485
485
|
const keiyakuContent = await fs.readFile(path.join(cwd, KEIYAKU_FILE), "utf-8");
|
|
486
486
|
const message = buildMergeMessage(title, keiyakuContent, traceContent);
|
|
487
|
-
const invokeCleanupLog = "[
|
|
487
|
+
const invokeCleanupLog = "[CLAIM] Removing protocol files and creating cleanup commit";
|
|
488
488
|
console.error(invokeCleanupLog);
|
|
489
489
|
appendDebugLog(invokeCleanupLog, { cwd, section: "script" });
|
|
490
490
|
await fs.unlink(path.join(cwd, KEIYAKU_FILE));
|
|
@@ -492,15 +492,15 @@ export async function handleClose(input) {
|
|
|
492
492
|
await git.addFiles(cwd, "-A");
|
|
493
493
|
await git.commit(cwd, `keiyaku(${title}): cleanup`);
|
|
494
494
|
const diff = await git.getDiffPreviewText(cwd, baseBranch);
|
|
495
|
-
const invokeCheckoutLog = `[
|
|
495
|
+
const invokeCheckoutLog = `[CLAIM] Checking out base branch '${baseBranch}'`;
|
|
496
496
|
console.error(invokeCheckoutLog);
|
|
497
497
|
appendDebugLog(invokeCheckoutLog, { cwd, section: "script" });
|
|
498
498
|
await git.checkoutBranch(cwd, baseBranch);
|
|
499
|
-
const invokeMergeLog = `[
|
|
499
|
+
const invokeMergeLog = `[CLAIM] Merging '${keiyakuBranch}' into '${baseBranch}'`;
|
|
500
500
|
console.error(invokeMergeLog);
|
|
501
501
|
appendDebugLog(invokeMergeLog, { cwd, section: "script" });
|
|
502
502
|
await git.merge(cwd, keiyakuBranch, message);
|
|
503
|
-
const invokeFinalizeLog = `[
|
|
503
|
+
const invokeFinalizeLog = `[CLAIM] Deleting merged branch '${keiyakuBranch}' and clearing metadata`;
|
|
504
504
|
console.error(invokeFinalizeLog);
|
|
505
505
|
appendDebugLog(invokeFinalizeLog, { cwd, section: "script" });
|
|
506
506
|
await git.deleteBranch(cwd, keiyakuBranch);
|
|
@@ -518,9 +518,9 @@ export async function handleClose(input) {
|
|
|
518
518
|
catch (err) {
|
|
519
519
|
const conflictFiles = await git.getUnmergedFiles(cwd);
|
|
520
520
|
if (conflictFiles.length > 0) {
|
|
521
|
-
throw new FlowError("DONE_MERGE_CONFLICT", `
|
|
521
|
+
throw new FlowError("DONE_MERGE_CONFLICT", `CLAIM merge conflict between ${keiyakuBranch} and ${baseBranch} (CONFLICTS: ${conflictFiles.join(", ")})`, err);
|
|
522
522
|
}
|
|
523
|
-
throw wrapFlowError(`execute
|
|
523
|
+
throw wrapFlowError(`execute CLAIM (merge ${keiyakuBranch} into ${baseBranch})`, err);
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
throw new Error(`unsupported close petition: ${petition}`);
|
|
@@ -189,13 +189,13 @@ export function buildCloseDoneResponse(result, input) {
|
|
|
189
189
|
const { status: _status, ...resultData } = result;
|
|
190
190
|
const closeToolName = getCloseToolName();
|
|
191
191
|
const inputEcho = [
|
|
192
|
-
`Petition:
|
|
192
|
+
`Petition: CLAIM`,
|
|
193
193
|
...formatList("Criteria Checks", input.criteriaChecks, { maxItems: 10, maxItemChars: 220 }),
|
|
194
194
|
`Scores: precise=${input.score_precise}/5 minimal=${input.score_minimal}/5 isolated=${input.score_isolated}/5 idiomatic=${input.score_idiomatic}/5 cohesive=${input.score_cohesive}/5`,
|
|
195
195
|
...formatMaybe("Oath", input.oath, 220),
|
|
196
196
|
...formatMaybe("CWD", input.cwd, 300),
|
|
197
197
|
];
|
|
198
|
-
const nextHints = renderHints(resolveTermPreset().nextHints.
|
|
198
|
+
const nextHints = renderHints(resolveTermPreset().nextHints.closeClaim);
|
|
199
199
|
const inputSection = buildSection("Input", inputEcho);
|
|
200
200
|
const diffSection = result.diff ? buildSection("Diff", result.diff) : "";
|
|
201
201
|
const infoLines = [
|
|
@@ -203,7 +203,7 @@ export function buildCloseDoneResponse(result, input) {
|
|
|
203
203
|
...formatMaybe("Current Branch", result.branch, 200),
|
|
204
204
|
...formatMaybe("Base Branch", result.baseBranch, 200),
|
|
205
205
|
];
|
|
206
|
-
const text = assembleResponse("Keiyaku Fulfilled (
|
|
206
|
+
const text = assembleResponse("Keiyaku Fulfilled (CLAIM)", `Merged '${result.branch}' into '${result.baseBranch}'. Deleted feature branch.`, [inputSection, diffSection], nextHints, infoLines);
|
|
207
207
|
return {
|
|
208
208
|
content: [{ type: "text", text }],
|
|
209
209
|
structuredContent: buildSuccessStructuredContent(closeToolName, {
|
|
@@ -218,7 +218,7 @@ export function buildCloseDropResponse(result, input) {
|
|
|
218
218
|
const { status: _status, ...resultData } = result;
|
|
219
219
|
const closeToolName = getCloseToolName();
|
|
220
220
|
const inputEcho = [
|
|
221
|
-
`Petition:
|
|
221
|
+
`Petition: FORFEIT`,
|
|
222
222
|
...formatList("Reasons/Checks", input.criteriaChecks, { maxItems: 10, maxItemChars: 220 }),
|
|
223
223
|
`Scores: precise=${input.score_precise}/5 minimal=${input.score_minimal}/5 isolated=${input.score_isolated}/5 idiomatic=${input.score_idiomatic}/5 cohesive=${input.score_cohesive}/5`,
|
|
224
224
|
...formatMaybe("CWD", input.cwd, 300),
|
|
@@ -230,7 +230,7 @@ export function buildCloseDropResponse(result, input) {
|
|
|
230
230
|
...formatMaybe("Current Branch", result.branch, 200),
|
|
231
231
|
...formatMaybe("Base Branch", result.baseBranch, 200),
|
|
232
232
|
];
|
|
233
|
-
const text = assembleResponse("Keiyaku
|
|
233
|
+
const text = assembleResponse("Keiyaku Forfeited (FORFEIT)", `Deleted '${result.branch}'. Switched back to '${result.baseBranch}'.`, [inputSection], nextHints, infoLines);
|
|
234
234
|
return {
|
|
235
235
|
content: [{ type: "text", text }],
|
|
236
236
|
structuredContent: buildSuccessStructuredContent(closeToolName, {
|