@tekmidian/pai 0.55.0 → 0.57.0
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/dist/{chain-DogidBji.mjs → chain-OzYgALdx.mjs} +2 -2
- package/dist/{chain-DogidBji.mjs.map → chain-OzYgALdx.mjs.map} +1 -1
- package/dist/cli/index.mjs +5 -5
- package/dist/cli/program.mjs +5 -5
- package/dist/daemon/index.mjs +3 -3
- package/dist/{daemon-Cgrdvdo6.mjs → daemon-Caxrq2iQ.mjs} +54 -17
- package/dist/daemon-Caxrq2iQ.mjs.map +1 -0
- package/dist/{daemon-B7Y8GQnt.mjs → daemon-D8zXReoA.mjs} +3 -3
- package/dist/daemon-mcp/index.mjs +3 -3
- package/dist/{fallback-DS6AEJsU.mjs → fallback-CiG573uw.mjs} +4 -4
- package/dist/fallback-CiG573uw.mjs.map +1 -0
- package/dist/hooks/worker-status-line.mjs +1 -0
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/{planner-C2wWnZrZ.mjs → planner-s1iQQsjj.mjs} +3 -3
- package/dist/{planner-C2wWnZrZ.mjs.map → planner-s1iQQsjj.mjs.map} +1 -1
- package/dist/{program-Cb-9J5Ie.mjs → program-COHW5ZtV.mjs} +14 -9
- package/dist/program-COHW5ZtV.mjs.map +1 -0
- package/dist/{run-DkTrZejF.mjs → run-9HbO1gTM.mjs} +128 -2
- package/dist/run-9HbO1gTM.mjs.map +1 -0
- package/dist/{session-keepalive-C5_69Av6.mjs → session-keepalive-Dg3wiiFJ.mjs} +2 -2
- package/dist/{session-keepalive-C5_69Av6.mjs.map → session-keepalive-Dg3wiiFJ.mjs.map} +1 -1
- package/package.json +1 -1
- package/src/hooks/ztk-passthrough.mjs +3 -0
- package/statusline-command.sh +3 -1
- package/dist/daemon-Cgrdvdo6.mjs.map +0 -1
- package/dist/fallback-DS6AEJsU.mjs.map +0 -1
- package/dist/program-Cb-9J5Ie.mjs.map +0 -1
- package/dist/run-DkTrZejF.mjs.map +0 -1
|
@@ -466,6 +466,22 @@ function elapsedOf(ts, now = /* @__PURE__ */ new Date()) {
|
|
|
466
466
|
if (mins > 0) return `${mins}m ${String(sec).padStart(2, "0")}s`;
|
|
467
467
|
return `${sec}s`;
|
|
468
468
|
}
|
|
469
|
+
/** Shorter sleeps are legitimate polling — not worth a supervision event. */
|
|
470
|
+
const SLEEP_FLOOR_SECS = 60;
|
|
471
|
+
const SLEEP_RE = /^\s*sleep\s+([0-9]+(?:\.[0-9]+)?)([smhd]?)\s*$/;
|
|
472
|
+
/**
|
|
473
|
+
* Seconds of a standalone `sleep N` (N plain or with an s/m/h/d suffix), or
|
|
474
|
+
* null when the command is not one long sleep: anchored to the whole command,
|
|
475
|
+
* so a filename containing "sleep" or an `echo sleep 500` never trips it, and
|
|
476
|
+
* floored at SLEEP_FLOOR_SECS so ordinary polling stays invisible.
|
|
477
|
+
*/
|
|
478
|
+
function parseSleepSecs(command) {
|
|
479
|
+
const m = command.match(SLEEP_RE);
|
|
480
|
+
if (!m) return null;
|
|
481
|
+
const mult = m[2] === "m" ? 60 : m[2] === "h" ? 3600 : m[2] === "d" ? 86400 : 1;
|
|
482
|
+
const secs = Number(m[1]) * mult;
|
|
483
|
+
return Number.isFinite(secs) && secs >= SLEEP_FLOOR_SECS ? secs : null;
|
|
484
|
+
}
|
|
469
485
|
/** One-line description of a tool call, e.g. "Bash: npm test". */
|
|
470
486
|
function describeTool(name, inp) {
|
|
471
487
|
if (typeof inp !== "object" || inp === null) return name;
|
|
@@ -2410,6 +2426,7 @@ function fullContractPrompt(format) {
|
|
|
2410
2426
|
"will pick something up later, never leave a background command as your final action. Finish, then",
|
|
2411
2427
|
"report.",
|
|
2412
2428
|
"No narration, no timestamps, no greetings, no summaries of what you read; act, verify, then stop.",
|
|
2429
|
+
"Never sleep longer than 60 seconds in one command; wait on a bounded timeout or event instead.",
|
|
2413
2430
|
...fileNotInlineBlock(),
|
|
2414
2431
|
"",
|
|
2415
2432
|
`Operator messages: a user turn starting with ${OPERATOR_MARK} was typed by the operator while you`,
|
|
@@ -2520,6 +2537,53 @@ function renderReport(c, prefix, r, cwd = "") {
|
|
|
2520
2537
|
if (r.notes) out.push(`${prefix}${c("bold", "notes")} ${shortText(r.notes, 120)}`);
|
|
2521
2538
|
return out;
|
|
2522
2539
|
}
|
|
2540
|
+
/** A summary that names its own deletion — the path is expected to be gone. */
|
|
2541
|
+
const DELETED_RE = /\b(delete|deleted|deleting|remove|removed|removing)\b/i;
|
|
2542
|
+
/**
|
|
2543
|
+
* Check every path a report's `changed` list claims against the filesystem:
|
|
2544
|
+
* it must exist (mtime at or after `startMs`, the run's start) unless its
|
|
2545
|
+
* summary says it was deleted, in which case it must be absent. Mechanical
|
|
2546
|
+
* only — counts, row totals and other free-text claims are not checked (a
|
|
2547
|
+
* worker's R report is trusted as written; a 2026-09-23 report claimed "181
|
|
2548
|
+
* rows saved" while it had written 31, and only its listed paths are
|
|
2549
|
+
* something the filesystem can confirm or refute).
|
|
2550
|
+
*/
|
|
2551
|
+
function verifyReportChanges(changed, cwd, startMs) {
|
|
2552
|
+
const failures = [];
|
|
2553
|
+
for (const ch of changed ?? []) {
|
|
2554
|
+
const raw = (ch.path ?? "").trim();
|
|
2555
|
+
if (!raw) continue;
|
|
2556
|
+
const abs = isAbsolute(raw) ? raw : resolve(cwd, raw);
|
|
2557
|
+
let mtimeMs;
|
|
2558
|
+
try {
|
|
2559
|
+
mtimeMs = statSync(abs).mtimeMs;
|
|
2560
|
+
} catch {
|
|
2561
|
+
mtimeMs = null;
|
|
2562
|
+
}
|
|
2563
|
+
if (DELETED_RE.test(ch.summary ?? "")) {
|
|
2564
|
+
if (mtimeMs !== null) failures.push({
|
|
2565
|
+
path: raw,
|
|
2566
|
+
reason: "not-deleted"
|
|
2567
|
+
});
|
|
2568
|
+
} else if (mtimeMs === null) failures.push({
|
|
2569
|
+
path: raw,
|
|
2570
|
+
reason: "missing"
|
|
2571
|
+
});
|
|
2572
|
+
else if (mtimeMs < startMs) failures.push({
|
|
2573
|
+
path: raw,
|
|
2574
|
+
reason: "stale"
|
|
2575
|
+
});
|
|
2576
|
+
}
|
|
2577
|
+
return {
|
|
2578
|
+
ok: failures.length === 0,
|
|
2579
|
+
failures
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
/** The one-line note appended to a report/ledger when verify fails. */
|
|
2583
|
+
function verifyFailNote(v) {
|
|
2584
|
+
const paths = v.failures.map((f) => f.path).slice(0, 5).join(", ");
|
|
2585
|
+
return `verify: ${v.failures.length} claimed change${v.failures.length === 1 ? "" : "s"} not confirmed: ${paths}`;
|
|
2586
|
+
}
|
|
2523
2587
|
/** repo-relative display of a changed path when it lies under cwd. */
|
|
2524
2588
|
function relShort(p, cwd) {
|
|
2525
2589
|
if (!cwd) return p;
|
|
@@ -2848,6 +2912,27 @@ function resetContextTokensOnCompact(status, e) {
|
|
|
2848
2912
|
function isCompactBoundary(e) {
|
|
2849
2913
|
return e.type === "system" && (e.subtype === "compact_boundary" || e.subtype === "compact");
|
|
2850
2914
|
}
|
|
2915
|
+
/** The command string of a Bash tool_use input, "" when there is none. */
|
|
2916
|
+
function bashCommand(input) {
|
|
2917
|
+
if (typeof input === "object" && input !== null && typeof input.command === "string") return input.command;
|
|
2918
|
+
return "";
|
|
2919
|
+
}
|
|
2920
|
+
function toolResultText(content) {
|
|
2921
|
+
if (typeof content === "string") return content;
|
|
2922
|
+
if (Array.isArray(content)) return content.map((c) => typeof c === "object" && c !== null && typeof c.text === "string" ? c.text : "").join("\n");
|
|
2923
|
+
return "";
|
|
2924
|
+
}
|
|
2925
|
+
/**
|
|
2926
|
+
* Whether a tool_result block is a failed execution: the harness's own
|
|
2927
|
+
* is_error flag, or — the older Bash spelling — an "Exit code N" line with a
|
|
2928
|
+
* non-zero N in the result text. Feeds the consecFails counter supervision's
|
|
2929
|
+
* thrashing detector reads.
|
|
2930
|
+
*/
|
|
2931
|
+
function toolResultFailed(block) {
|
|
2932
|
+
if (block.is_error === true) return true;
|
|
2933
|
+
const m = toolResultText(block.content).match(/Exit code (\d+)/);
|
|
2934
|
+
return m !== null && Number(m[1]) !== 0;
|
|
2935
|
+
}
|
|
2851
2936
|
/**
|
|
2852
2937
|
* The model the init event announces, adopted into the status when the spawn
|
|
2853
2938
|
* could not name one (a caller that passed `--model` itself in the claude
|
|
@@ -2952,7 +3037,7 @@ async function runWorker(opts) {
|
|
|
2952
3037
|
const logDir = workersLogDir(config);
|
|
2953
3038
|
mkdirSync(logDir, { recursive: true });
|
|
2954
3039
|
if (opts.className === "plan" && !opts._planner) {
|
|
2955
|
-
const { runPlanner } = await import("./planner-
|
|
3040
|
+
const { runPlanner } = await import("./planner-s1iQQsjj.mjs");
|
|
2956
3041
|
return runPlanner(opts);
|
|
2957
3042
|
}
|
|
2958
3043
|
const parent = launchParent(opts.parent);
|
|
@@ -3495,8 +3580,21 @@ async function executeRun(a) {
|
|
|
3495
3580
|
for (const block of e.message?.content ?? []) if (block.type === "tool_use") {
|
|
3496
3581
|
status.tools += 1;
|
|
3497
3582
|
status.last = describeTool(block.name ?? "?", block.input);
|
|
3583
|
+
if (block.name === "Bash") status.sleepSec = parseSleepSecs(bashCommand(block.input));
|
|
3498
3584
|
} else if (block.type === "text" && (block.text ?? "").trim()) status.last = "says: " + shortText(block.text, 70);
|
|
3499
3585
|
saveStatus(logDir, status);
|
|
3586
|
+
} else if (e.type === "user") {
|
|
3587
|
+
const blocks = e.message?.content;
|
|
3588
|
+
if (Array.isArray(blocks)) {
|
|
3589
|
+
let sawResult = false;
|
|
3590
|
+
for (const block of blocks) {
|
|
3591
|
+
if (block.type !== "tool_result") continue;
|
|
3592
|
+
sawResult = true;
|
|
3593
|
+
status.consecFails = toolResultFailed(block) ? (status.consecFails ?? 0) + 1 : 0;
|
|
3594
|
+
status.sleepSec = null;
|
|
3595
|
+
}
|
|
3596
|
+
if (sawResult) saveStatus(logDir, status);
|
|
3597
|
+
}
|
|
3500
3598
|
} else if (e.type === "result") {
|
|
3501
3599
|
const tokens = usageContextTokens(e.usage);
|
|
3502
3600
|
if (e.is_compact) status.contextTokens = tokens ?? status.contextTokens;
|
|
@@ -3561,6 +3659,20 @@ async function executeRun(a) {
|
|
|
3561
3659
|
} catch {}
|
|
3562
3660
|
}
|
|
3563
3661
|
}
|
|
3662
|
+
if (headless && ctx.resultReport?.changed?.length) {
|
|
3663
|
+
const verify = verifyReportChanges(ctx.resultReport.changed, worktree?.dir ?? cwd, t0);
|
|
3664
|
+
if (!verify.ok) {
|
|
3665
|
+
status.reportValid = false;
|
|
3666
|
+
const note = verifyFailNote(verify);
|
|
3667
|
+
status.last = shortText(note, 90);
|
|
3668
|
+
ctx.resultReport.notes = ctx.resultReport.notes ? `${ctx.resultReport.notes} — ${note}` : note;
|
|
3669
|
+
appendLedger(ledger, "REPORT-UNVERIFIED", {
|
|
3670
|
+
id: wid,
|
|
3671
|
+
failures: verify.failures.length,
|
|
3672
|
+
paths: verify.failures.map((f) => f.path).slice(0, 5).join(",")
|
|
3673
|
+
});
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3564
3676
|
saveStatus(logDir, status);
|
|
3565
3677
|
appendLedger(ledger, "WORKER-END", {
|
|
3566
3678
|
id: wid,
|
|
@@ -3833,6 +3945,20 @@ async function executeCodexRun(a) {
|
|
|
3833
3945
|
status.rc = rc;
|
|
3834
3946
|
status.secs = secs;
|
|
3835
3947
|
status.last = shortText(report?.notes ?? finalText, 90) || (ok ? "done" : "failed");
|
|
3948
|
+
if (report?.changed?.length) {
|
|
3949
|
+
const verify = verifyReportChanges(report.changed, worktree?.dir ?? cwd, t0);
|
|
3950
|
+
if (!verify.ok) {
|
|
3951
|
+
status.reportValid = false;
|
|
3952
|
+
const note = verifyFailNote(verify);
|
|
3953
|
+
status.last = shortText(note, 90);
|
|
3954
|
+
report.notes = report.notes ? `${report.notes} — ${note}` : note;
|
|
3955
|
+
appendLedger(ledger, "REPORT-UNVERIFIED", {
|
|
3956
|
+
id: wid,
|
|
3957
|
+
failures: verify.failures.length,
|
|
3958
|
+
paths: verify.failures.map((f) => f.path).slice(0, 5).join(",")
|
|
3959
|
+
});
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3836
3962
|
saveStatus(logDir, status);
|
|
3837
3963
|
appendLedger(ledger, "WORKER-END", {
|
|
3838
3964
|
id: wid,
|
|
@@ -4000,4 +4126,4 @@ function resultFromOutput(out) {
|
|
|
4000
4126
|
|
|
4001
4127
|
//#endregion
|
|
4002
4128
|
export { contextLabel as A, saveStatus as B, mergeWorker as C, UNLABELED as D, ledgerSummary as E, loadStatus as F, shortText as G, waitForTerminalStatus as H, loadStatuses as I, describeMcp as K, newWorkerId as L, elapsedOf as M, isChatPane as N, ageOf as O, isLive as P, nowStamp as R, discardWorker as S, appendLedger as T, longInlinePromptHint as U, setWorkerLabel as V, parseRunnerArgs as W, itermUuid as _, projectLaunchConfig as a, sessionTag as b, handoffFromInside as c, workerDepth as d, checkPaneForWorker as f, itermForClaudeSession as g, currentTabKey as h, usageContextTokens as i, contextPercent as j, alive as k, readInbox as l, openPaneForWorker as m, runWorker as n, parseWorkerReport as o, openFollowPane as p, expandMcpNames as q, testProvider as r, renderReport as s, printResult as t, sayToWorker as u, resolveSession as v, worktreesDir as w, workerInScope as x, sessionMapPath as y, ownsPid as z };
|
|
4003
|
-
//# sourceMappingURL=run-
|
|
4129
|
+
//# sourceMappingURL=run-9HbO1gTM.mjs.map
|