@tekmidian/pai 0.45.0 → 0.47.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-DAEC9AU7.mjs → chain-CNSa0A3G.mjs} +2 -2
- package/dist/{chain-DAEC9AU7.mjs.map → chain-CNSa0A3G.mjs.map} +1 -1
- package/dist/cli/index.mjs +4 -4
- package/dist/cli/program.mjs +4 -4
- package/dist/daemon/index.mjs +2 -2
- package/dist/{daemon-Dq2ZSdex.mjs → daemon-CYpVy_Dw.mjs} +2 -2
- package/dist/{daemon-DNBEFHaj.mjs → daemon-DZ4Q0jrs.mjs} +2 -2
- package/dist/{daemon-DNBEFHaj.mjs.map → daemon-DZ4Q0jrs.mjs.map} +1 -1
- package/dist/daemon-mcp/index.mjs +3 -3
- package/dist/{fallback-CxGDTXWt.mjs → fallback-IeR2FrFn.mjs} +6 -6
- package/dist/fallback-IeR2FrFn.mjs.map +1 -0
- package/dist/hooks/load-core-context.mjs +9 -11
- package/dist/hooks/load-core-context.mjs.map +3 -3
- package/dist/hooks/load-project-context.mjs +59 -6
- package/dist/hooks/load-project-context.mjs.map +3 -3
- package/dist/hooks/worker-status-line.mjs +23 -4
- package/dist/hooks/worker-status-line.mjs.map +3 -3
- package/dist/{planner-B4DvNpXd.mjs → planner-Cn8HmT7l.mjs} +3 -3
- package/dist/{planner-B4DvNpXd.mjs.map → planner-Cn8HmT7l.mjs.map} +1 -1
- package/dist/{program-DvuMelhj.mjs → program-BxpeczCx.mjs} +4123 -4003
- package/dist/program-BxpeczCx.mjs.map +1 -0
- package/dist/{run-BgExF8Xg.mjs → run-Cls0YGgV.mjs} +43 -6
- package/dist/run-Cls0YGgV.mjs.map +1 -0
- package/docs/commands/config.md +1 -1
- package/package.json +1 -1
- package/src/hooks/ts/lib/frontmatter.test.ts +19 -0
- package/src/hooks/ts/lib/frontmatter.ts +10 -0
- package/src/hooks/ts/lib/handover-budget.test.ts +124 -0
- package/src/hooks/ts/lib/handover-budget.ts +94 -0
- package/src/hooks/ts/session-start/load-core-context.ts +6 -15
- package/src/hooks/ts/session-start/load-project-context.ts +9 -6
- package/dist/fallback-CxGDTXWt.mjs.map +0 -1
- package/dist/program-DvuMelhj.mjs.map +0 -1
- package/dist/run-BgExF8Xg.mjs.map +0 -1
|
@@ -410,6 +410,43 @@ function alive(pid) {
|
|
|
410
410
|
return false;
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* Whether `status.pid` still names the process that was started as this
|
|
415
|
+
* worker, not a later, unrelated process the OS handed the same pid to after
|
|
416
|
+
* the worker exited. `alive()` alone can't tell these apart — a pid observed
|
|
417
|
+
* live on 2026-09-19 (worker 20260919-083549-90913) had been reused, and
|
|
418
|
+
* `pai worker kill` signalled the wrong, unrelated process. `ps -o lstart=`
|
|
419
|
+
* reads the running process's actual start time and compares it against the
|
|
420
|
+
* status file's own `started` stamp; a reused pid almost never starts within
|
|
421
|
+
* 120s of the original, so a wider drift means "different process".
|
|
422
|
+
*/
|
|
423
|
+
function ownsPid(status) {
|
|
424
|
+
if (status.pid <= 0 || !alive(status.pid)) return false;
|
|
425
|
+
try {
|
|
426
|
+
const out = execFileSync("ps", [
|
|
427
|
+
"-o",
|
|
428
|
+
"lstart=",
|
|
429
|
+
"-p",
|
|
430
|
+
String(status.pid)
|
|
431
|
+
], {
|
|
432
|
+
encoding: "utf8",
|
|
433
|
+
env: {
|
|
434
|
+
...process.env,
|
|
435
|
+
LC_ALL: "C"
|
|
436
|
+
}
|
|
437
|
+
}).trim();
|
|
438
|
+
const psStart = Date.parse(out);
|
|
439
|
+
const started = Date.parse(status.started.replace(" ", "T"));
|
|
440
|
+
if (Number.isNaN(psStart) || Number.isNaN(started)) return alive(status.pid);
|
|
441
|
+
return Math.abs(psStart - started) <= 12e4;
|
|
442
|
+
} catch {
|
|
443
|
+
return alive(status.pid);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/** Whether a status is both marked "running" and still owns its recorded pid. */
|
|
447
|
+
function isLive(status) {
|
|
448
|
+
return status.state === "running" && ownsPid(status);
|
|
449
|
+
}
|
|
413
450
|
/** "42s" under 90s, "7m" above — the coarse age the table and bar show. */
|
|
414
451
|
function ageOf(ts, now = /* @__PURE__ */ new Date()) {
|
|
415
452
|
const t = Date.parse(ts.replace(" ", "T"));
|
|
@@ -1199,7 +1236,7 @@ function workerDepth(statuses, id, opts) {
|
|
|
1199
1236
|
}
|
|
1200
1237
|
/** Children of `parent` that are still running, oldest first. */
|
|
1201
1238
|
function runningChildren(statuses, parent) {
|
|
1202
|
-
return statuses.filter((s) => s.parent === parent &&
|
|
1239
|
+
return statuses.filter((s) => s.parent === parent && isLive(s));
|
|
1203
1240
|
}
|
|
1204
1241
|
/**
|
|
1205
1242
|
* Would starting a child of `parent` stay within the caps? Throws with a
|
|
@@ -1279,7 +1316,7 @@ function createOperatorServer(logDir, id, onLine) {
|
|
|
1279
1316
|
function sayToWorker(logDir, id, text, timeoutMs = 4e3) {
|
|
1280
1317
|
const status = loadStatus(logDir, id);
|
|
1281
1318
|
if (!status) return Promise.reject(/* @__PURE__ */ new Error(`no worker named "${id}"`));
|
|
1282
|
-
if (
|
|
1319
|
+
if (!isLive(status)) return Promise.reject(/* @__PURE__ */ new Error(`worker ${id} is not running (state: ${status.state}) — continue it instead with: pai worker resume ${id} "<text>"`));
|
|
1283
1320
|
const path = operatorSocketPath(logDir, id);
|
|
1284
1321
|
if (!existsSync(path)) return Promise.reject(/* @__PURE__ */ new Error(`worker ${id} has no operator socket (${path}) — it may predate this PAI version`));
|
|
1285
1322
|
return new Promise((resolve, reject) => {
|
|
@@ -1393,7 +1430,7 @@ async function deliverHandoff(logDir, h, deps = {}, now = /* @__PURE__ */ new Da
|
|
|
1393
1430
|
appendHandoff(logDir, h, now);
|
|
1394
1431
|
const say = deps.say ?? ((id, text) => sayToWorker(logDir, id, text));
|
|
1395
1432
|
const parent = loadStatus(logDir, h.to);
|
|
1396
|
-
if (parent &&
|
|
1433
|
+
if (parent && isLive(parent)) try {
|
|
1397
1434
|
await say(h.to, handoffMessage(h));
|
|
1398
1435
|
} catch {}
|
|
1399
1436
|
return h;
|
|
@@ -2640,7 +2677,7 @@ async function runWorker(opts) {
|
|
|
2640
2677
|
const logDir = workersLogDir(config);
|
|
2641
2678
|
mkdirSync(logDir, { recursive: true });
|
|
2642
2679
|
if (opts.className === "plan" && !opts._planner) {
|
|
2643
|
-
const { runPlanner } = await import("./planner-
|
|
2680
|
+
const { runPlanner } = await import("./planner-Cn8HmT7l.mjs");
|
|
2644
2681
|
return runPlanner(opts);
|
|
2645
2682
|
}
|
|
2646
2683
|
const parent = launchParent(opts.parent);
|
|
@@ -3538,5 +3575,5 @@ function resultFromOutput(out) {
|
|
|
3538
3575
|
}
|
|
3539
3576
|
|
|
3540
3577
|
//#endregion
|
|
3541
|
-
export {
|
|
3542
|
-
//# sourceMappingURL=run-
|
|
3578
|
+
export { isLive as A, parseRunnerArgs as B, ledgerSummary as C, contextLabel as D, alive as E, ownsPid as F, describeMcp as H, saveStatus as I, setWorkerLabel as L, loadStatuses as M, newWorkerId as N, contextPercent as O, nowStamp as P, waitForTerminalStatus as R, appendLedger as S, ageOf as T, expandMcpNames as U, shortText as V, currentTabKey as _, projectLaunchConfig as a, sessionTag as b, discardWorker as c, readInbox as d, sayToWorker as f, openPaneForWorker as g, openFollowPane as h, usageContextTokens as i, loadStatus as j, isChatPane as k, mergeWorker as l, checkPaneForWorker as m, runWorker as n, parseWorkerReport as o, workerDepth as p, testProvider as r, renderReport as s, printResult as t, handoffFromInside as u, itermForClaudeSession as v, UNLABELED as w, workerInScope as x, resolveSession as y, longInlinePromptHint as z };
|
|
3579
|
+
//# sourceMappingURL=run-Cls0YGgV.mjs.map
|