@tekmidian/pai 0.64.0 → 0.65.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/README.md +19 -5
- package/dist/{aibroker-client-BpfuGPe5.mjs → aibroker-client-B8c42Lh8.mjs} +1 -1
- package/dist/{aibroker-client-DRld7g6z.mjs → aibroker-client-C5Fw7DNz.mjs} +10 -4
- package/dist/{aibroker-client-DRld7g6z.mjs.map → aibroker-client-C5Fw7DNz.mjs.map} +1 -1
- package/dist/{async-CY_cd_8j.mjs → async-CNn36gm4.mjs} +2 -2
- package/dist/{async-CY_cd_8j.mjs.map → async-CNn36gm4.mjs.map} +1 -1
- package/dist/{auto-route-CPlam4iv.mjs → auto-route-sLMU-NnM.mjs} +2 -2
- package/dist/{auto-route-CPlam4iv.mjs.map → auto-route-sLMU-NnM.mjs.map} +1 -1
- package/dist/{chain-o-g8AgE3.mjs → chain-C8QO8gwj.mjs} +4 -4
- package/dist/{chain-o-g8AgE3.mjs.map → chain-C8QO8gwj.mjs.map} +1 -1
- package/dist/cli/index.mjs +19 -19
- package/dist/cli/program.d.mts.map +1 -1
- package/dist/cli/program.mjs +19 -19
- package/dist/{clusters-DsMf20PP.mjs → clusters-PgIUYT_v.mjs} +1 -1
- package/dist/{clusters-DsMf20PP.mjs.map → clusters-PgIUYT_v.mjs.map} +1 -1
- package/dist/{config-2wkz744W.mjs → config-BbLFD7Uf.mjs} +3 -3
- package/dist/{config-2wkz744W.mjs.map → config-BbLFD7Uf.mjs.map} +1 -1
- package/dist/{config-CUTg6VDq.mjs → config-YinjgXEJ.mjs} +1 -1
- package/dist/{context-handover-cache-BOpjLsKe.mjs → context-handover-cache-mGxq2-8f.mjs} +11 -29
- package/dist/context-handover-cache-mGxq2-8f.mjs.map +1 -0
- package/dist/daemon/index.mjs +16 -16
- package/dist/daemon-CX9JomIJ.mjs +19 -0
- package/dist/{daemon-BYieXduQ.mjs → daemon-D2r1AQqE.mjs} +30 -30
- package/dist/{daemon-BYieXduQ.mjs.map → daemon-D2r1AQqE.mjs.map} +1 -1
- package/dist/daemon-mcp/index.mjs +17 -17
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/detector-C3Q7mxQU.mjs +3 -0
- package/dist/{detector-BAlmrLQ0.mjs → detector-CIHEXKsV.mjs} +1 -1
- package/dist/{detector-BAlmrLQ0.mjs.map → detector-CIHEXKsV.mjs.map} +1 -1
- package/dist/{embeddings-DK9XfQic.mjs → embeddings-BbNVXa_0.mjs} +1 -1
- package/dist/{embeddings-DK9XfQic.mjs.map → embeddings-BbNVXa_0.mjs.map} +1 -1
- package/dist/{embeddings-Xg8XLf2K.mjs → embeddings-CDfM63uC.mjs} +1 -1
- package/dist/{factory-BMK0tC1b.mjs → factory-CaswxuJ0.mjs} +1 -1
- package/dist/{factory-C4We3xR_.mjs → factory-y36qGegI.mjs} +13 -13
- package/dist/{factory-C4We3xR_.mjs.map → factory-y36qGegI.mjs.map} +1 -1
- package/dist/{fallback-ECiqCuh6.mjs → fallback-CWDQYmJi.mjs} +1205 -1204
- package/dist/fallback-CWDQYmJi.mjs.map +1 -0
- package/dist/{federation-db-CUgy0WYs.mjs → federation-db-BTyoufBh.mjs} +2 -2
- package/dist/{federation-db-CUgy0WYs.mjs.map → federation-db-BTyoufBh.mjs.map} +1 -1
- package/dist/federation-db-HfIFc7FG.mjs +3 -0
- package/dist/hooks/block-sleep-poll.mjs +36 -11
- package/dist/hooks/block-sleep-poll.mjs.map +2 -2
- package/dist/hooks/capture-all-events.mjs +3 -17
- package/dist/hooks/capture-all-events.mjs.map +3 -3
- package/dist/hooks/capture-session-summary.mjs +3 -17
- package/dist/hooks/capture-session-summary.mjs.map +3 -3
- package/dist/hooks/capture-tool-output.mjs +3 -17
- package/dist/hooks/capture-tool-output.mjs.map +3 -3
- package/dist/hooks/cleanup-session-files.mjs +3 -17
- package/dist/hooks/cleanup-session-files.mjs.map +2 -2
- package/dist/hooks/context-compression-hook.mjs +3 -17
- package/dist/hooks/context-compression-hook.mjs.map +3 -3
- package/dist/hooks/initialize-session.mjs +3 -17
- package/dist/hooks/initialize-session.mjs.map +2 -2
- package/dist/hooks/inject-observations.mjs +3 -17
- package/dist/hooks/inject-observations.mjs.map +2 -2
- package/dist/hooks/load-core-context.mjs +4 -22
- package/dist/hooks/load-core-context.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs +3 -17
- package/dist/hooks/load-project-context.mjs.map +3 -3
- package/dist/hooks/mcp-deferred-gate.mjs +3 -17
- package/dist/hooks/mcp-deferred-gate.mjs.map +2 -2
- package/dist/hooks/observe.mjs +3 -17
- package/dist/hooks/observe.mjs.map +2 -2
- package/dist/hooks/security-validator.mjs +3 -17
- package/dist/hooks/security-validator.mjs.map +3 -3
- package/dist/hooks/stop-hook.mjs +3 -17
- package/dist/hooks/stop-hook.mjs.map +3 -3
- package/dist/hooks/sync-todo-to-md.mjs +3 -17
- package/dist/hooks/sync-todo-to-md.mjs.map +2 -2
- package/dist/hooks/worker-guard.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +4 -4
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/{indexer-backend-CJ0RGgMz.mjs → indexer-backend-Cnc7Tf5C.mjs} +2 -2
- package/dist/{ipc-client-EhWY8XL0.mjs → ipc-client-D16Xw6Uo.mjs} +2 -2
- package/dist/{ipc-client-EhWY8XL0.mjs.map → ipc-client-D16Xw6Uo.mjs.map} +1 -1
- package/dist/{kg-entity-1uqCnk4u.mjs → kg-entity-COTUj1ZC.mjs} +1 -1
- package/dist/{kg-entity-1uqCnk4u.mjs.map → kg-entity-COTUj1ZC.mjs.map} +1 -1
- package/dist/{latent-ideas-CSuKfiq3.mjs → latent-ideas-ByvMjVcb.mjs} +3 -3
- package/dist/{latent-ideas-CSuKfiq3.mjs.map → latent-ideas-ByvMjVcb.mjs.map} +1 -1
- package/dist/{link-boost-BtjzfE3c.mjs → link-boost-UiE-uooT.mjs} +1 -1
- package/dist/{link-boost-BtjzfE3c.mjs.map → link-boost-UiE-uooT.mjs.map} +1 -1
- package/dist/{main-resolver-DyOrwNYw.mjs → main-resolver-CDe7DCso.mjs} +6 -6
- package/dist/{main-resolver-DyOrwNYw.mjs.map → main-resolver-CDe7DCso.mjs.map} +1 -1
- package/dist/main-resolver-DI-A7lSO.mjs +7 -0
- package/dist/merge-2gqRPFu2.mjs +3 -0
- package/dist/{merge-D58n_-LZ.mjs → merge-DgU9OgZy.mjs} +1 -1
- package/dist/{merge-D58n_-LZ.mjs.map → merge-DgU9OgZy.mjs.map} +1 -1
- package/dist/module-paths-DdRzbkUI.mjs +44 -0
- package/dist/module-paths-DdRzbkUI.mjs.map +1 -0
- package/dist/{neighborhood-DNuRelRB.mjs → neighborhood-CvRHlqdR.mjs} +2 -2
- package/dist/{neighborhood-DNuRelRB.mjs.map → neighborhood-CvRHlqdR.mjs.map} +1 -1
- package/dist/{note-context-D9JZ4-7o.mjs → note-context-BrbfUIoP.mjs} +1 -1
- package/dist/{note-context-D9JZ4-7o.mjs.map → note-context-BrbfUIoP.mjs.map} +1 -1
- package/dist/{pai-home-UncxWxlX.mjs → pai-home-Cm9rcJgX.mjs} +1 -1
- package/dist/{pai-home-UncxWxlX.mjs.map → pai-home-Cm9rcJgX.mjs.map} +1 -1
- package/dist/{planner-DgC3oSvb.mjs → planner-8-shIa8t.mjs} +7 -7
- package/dist/{planner-DgC3oSvb.mjs.map → planner-8-shIa8t.mjs.map} +1 -1
- package/dist/{postgres-CcsRKir-.mjs → postgres-DYtZg7J7.mjs} +5 -13
- package/dist/{postgres-CcsRKir-.mjs.map → postgres-DYtZg7J7.mjs.map} +1 -1
- package/dist/{program-JhF2GgJY.mjs → program-DiktbiWa.mjs} +225 -245
- package/dist/program-DiktbiWa.mjs.map +1 -0
- package/dist/{query-feedback-BPa0dISE.mjs → query-feedback-BIaZTTFO.mjs} +2 -2
- package/dist/{query-feedback-BPa0dISE.mjs.map → query-feedback-BIaZTTFO.mjs.map} +1 -1
- package/dist/query-feedback-B_iigYj-.mjs +3 -0
- package/dist/{registry-db-DCzdI4sC.mjs → registry-db-C7voqML9.mjs} +2 -2
- package/dist/{registry-db-DCzdI4sC.mjs.map → registry-db-C7voqML9.mjs.map} +1 -1
- package/dist/registry-db-JHPhA8vF.mjs +3 -0
- package/dist/{registry-postgres-BUnkHKYs.mjs → registry-postgres-DSrkxqfF.mjs} +2 -2
- package/dist/{registry-postgres-BUnkHKYs.mjs.map → registry-postgres-DSrkxqfF.mjs.map} +1 -1
- package/dist/{registry-sqlite-CKYNwkUv.mjs → registry-sqlite-B2436JgX.mjs} +2 -2
- package/dist/{registry-sqlite-CKYNwkUv.mjs.map → registry-sqlite-B2436JgX.mjs.map} +1 -1
- package/dist/router-S6C5BxzZ.mjs +3 -0
- package/dist/{router-CGZATlvm.mjs → router-aqLMvNMg.mjs} +1 -1
- package/dist/{router-CGZATlvm.mjs.map → router-aqLMvNMg.mjs.map} +1 -1
- package/dist/{run-W2rV_9j0.mjs → run-DUZRSnIT.mjs} +120 -42
- package/dist/run-DUZRSnIT.mjs.map +1 -0
- package/dist/{run-env-Br4Bc7Vz.mjs → run-env-BHWnXqle.mjs} +3 -3
- package/dist/{run-env-Br4Bc7Vz.mjs.map → run-env-BHWnXqle.mjs.map} +1 -1
- package/dist/{runtime-paths-QGQJAekd.mjs → runtime-paths-CHTg3ywb.mjs} +1 -1
- package/dist/{runtime-paths-QGQJAekd.mjs.map → runtime-paths-CHTg3ywb.mjs.map} +1 -1
- package/dist/{server-B71rem4q.mjs → server-DlL1QI2k.mjs} +4 -5
- package/dist/server-DlL1QI2k.mjs.map +1 -0
- package/dist/{session-keepalive-Dgil9hjw.mjs → session-keepalive-CZUwp5IQ.mjs} +7 -7
- package/dist/{session-keepalive-Dgil9hjw.mjs.map → session-keepalive-CZUwp5IQ.mjs.map} +1 -1
- package/dist/skills/Art/SKILL.md +1 -1
- package/dist/skills/Observability/SKILL.md +4 -4
- package/dist/skills/Research/SKILL.md +1 -1
- package/dist/{sources-LcGptLA-.mjs → sources-DX4ElmrE.mjs} +1 -1
- package/dist/{sources-LcGptLA-.mjs.map → sources-DX4ElmrE.mjs.map} +1 -1
- package/dist/{sqlite-CAJcw2zL.mjs → sqlite-BrEu3avy.mjs} +3 -3
- package/dist/{sqlite-CAJcw2zL.mjs.map → sqlite-BrEu3avy.mjs.map} +1 -1
- package/dist/{state-S9wlKarB.mjs → state-DW8zdweW.mjs} +1 -1
- package/dist/{state-CHltNjXI.mjs → state-HyjqTihC.mjs} +1 -1
- package/dist/{state-CHltNjXI.mjs.map → state-HyjqTihC.mjs.map} +1 -1
- package/dist/{themes-D1FQFthd.mjs → themes-BgqahYVM.mjs} +2 -2
- package/dist/{themes-D1FQFthd.mjs.map → themes-BgqahYVM.mjs.map} +1 -1
- package/dist/{tools-BW7OXf-N.mjs → tools-BbqQIHPe.mjs} +4 -4
- package/dist/{tools-BFC-113F.mjs → tools-gMGDIpJ9.mjs} +18 -18
- package/dist/{tools-BFC-113F.mjs.map → tools-gMGDIpJ9.mjs.map} +1 -1
- package/dist/{trace-IDKK1VFs.mjs → trace-CmAB7iJZ.mjs} +1 -1
- package/dist/{trace-IDKK1VFs.mjs.map → trace-CmAB7iJZ.mjs.map} +1 -1
- package/dist/{vault-indexer-y6YC2-mh.mjs → vault-indexer-Ddq51X20.mjs} +1 -1
- package/dist/{vault-indexer-y6YC2-mh.mjs.map → vault-indexer-Ddq51X20.mjs.map} +1 -1
- package/dist/{wakeup-CNZQZzsY.mjs → wakeup-CZw88uXf.mjs} +3 -3
- package/dist/{wakeup-CNZQZzsY.mjs.map → wakeup-CZw88uXf.mjs.map} +1 -1
- package/dist/{work-queue-worker-Dy5FT2ak.mjs → work-queue-worker-DCzfH0d1.mjs} +4 -4
- package/dist/{work-queue-worker-Dy5FT2ak.mjs.map → work-queue-worker-DCzfH0d1.mjs.map} +1 -1
- package/dist/work-queue-worker-Taba_vcA.mjs +11 -0
- package/dist/{zettelkasten-Dx-63BEk.mjs → zettelkasten-Dwj67e4p.mjs} +4 -4
- package/dist/{zettelkasten-Dx-63BEk.mjs.map → zettelkasten-Dwj67e4p.mjs.map} +1 -1
- package/docker/docker-compose.yml +39 -0
- package/docs/commands/README.md +3 -3
- package/docs/commands/config.md +3 -3
- package/docs/commands/setup.md +9 -2
- package/docs/commands/worker.md +2 -2
- package/package.json +3 -2
- package/scripts/build-hooks.mjs +6 -6
- package/src/hooks/ts/lib/pai-paths-case.test.ts +12 -0
- package/src/hooks/ts/lib/pai-paths-import.test.ts +25 -0
- package/src/hooks/ts/lib/pai-paths.ts +5 -28
- package/src/hooks/ts/lib/sleep-poll-gate.test.ts +17 -1
- package/src/hooks/ts/lib/sleep-poll-gate.ts +21 -9
- package/src/hooks/ts/session-start/load-core-context.ts +2 -6
- package/src/hooks/ts/session-start/session-start-worker-guard.test.ts +24 -1
- package/dist/context-handover-cache-BOpjLsKe.mjs.map +0 -1
- package/dist/daemon-q3xjHwa4.mjs +0 -19
- package/dist/detector-C-YmZsOi.mjs +0 -3
- package/dist/fallback-ECiqCuh6.mjs.map +0 -1
- package/dist/federation-db-BZ8PyxFe.mjs +0 -3
- package/dist/main-resolver-vN09bkXv.mjs +0 -7
- package/dist/merge-CXGz5wXz.mjs +0 -3
- package/dist/program-JhF2GgJY.mjs.map +0 -1
- package/dist/query-feedback-BPHFFSu1.mjs +0 -3
- package/dist/registry-db-Hphlj3H4.mjs +0 -3
- package/dist/router-CoA8Uy1m.mjs +0 -3
- package/dist/run-W2rV_9j0.mjs.map +0 -1
- package/dist/server-B71rem4q.mjs.map +0 -1
- package/dist/work-queue-worker-CkShUa0z.mjs +0 -11
- /package/dist/{indexer-backend-DotpxHJd.mjs → indexer-backend-isSLg6yE.mjs} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as getRegistryBackend } from "./factory-
|
|
2
|
-
import { E as readWorkersSection, O as resolveModelCapability, T as providerKeyPath, b as isModelCapability, d as NATIVE_ANTHROPIC_MODELS, g as classModelCapability, h as assertProviderRunnable, k as resolveProviderKey, m as WorkersConfigError, n as claudeCommand, t as buildRunEnv } from "./run-env-
|
|
3
|
-
import { _ as statusPath, d as resolveTarget, f as setCooldown, g as panesDir, h as ledgerPath, i as capabilityForRun, m as eventsPath, n as ensureProxyRunning, o as isQuotaFailure, p as ensureNoMcpConfig, s as nextAutoProvider, t as DEFAULT_PROXY_PORT, u as resolveCapabilityRun, v as workersLogDir } from "./server-
|
|
1
|
+
import { i as getRegistryBackend } from "./factory-y36qGegI.mjs";
|
|
2
|
+
import { E as readWorkersSection, O as resolveModelCapability, T as providerKeyPath, b as isModelCapability, d as NATIVE_ANTHROPIC_MODELS, g as classModelCapability, h as assertProviderRunnable, k as resolveProviderKey, m as WorkersConfigError, n as claudeCommand, t as buildRunEnv } from "./run-env-BHWnXqle.mjs";
|
|
3
|
+
import { _ as statusPath, d as resolveTarget, f as setCooldown, g as panesDir, h as ledgerPath, i as capabilityForRun, m as eventsPath, n as ensureProxyRunning, o as isQuotaFailure, p as ensureNoMcpConfig, s as nextAutoProvider, t as DEFAULT_PROXY_PORT, u as resolveCapabilityRun, v as workersLogDir } from "./server-DlL1QI2k.mjs";
|
|
4
4
|
import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
5
5
|
import { homedir, platform, tmpdir } from "node:os";
|
|
6
6
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
@@ -233,6 +233,7 @@ function parseRunnerArgs(argv) {
|
|
|
233
233
|
let callerModel = false;
|
|
234
234
|
let callerMcpConfig = false;
|
|
235
235
|
let callerSystemPrompt = false;
|
|
236
|
+
const callerSystemPrompts = [];
|
|
236
237
|
let callerTools = false;
|
|
237
238
|
const mcp = [];
|
|
238
239
|
const allowedTools = [];
|
|
@@ -254,7 +255,13 @@ function parseRunnerArgs(argv) {
|
|
|
254
255
|
} else if (a.startsWith("--output-format=")) {
|
|
255
256
|
const v = a.slice(16);
|
|
256
257
|
if (v === "json" || v === "stream-json") outputFormat = v;
|
|
257
|
-
} else if (a === "--verbose") {} else if (a === "--
|
|
258
|
+
} else if (a === "--verbose") {} else if (a === "--append-system-prompt") {
|
|
259
|
+
callerSystemPrompt = true;
|
|
260
|
+
if (i + 1 < argv.length) callerSystemPrompts.push(argv[++i]);
|
|
261
|
+
} else if (a.startsWith("--append-system-prompt=")) {
|
|
262
|
+
callerSystemPrompt = true;
|
|
263
|
+
callerSystemPrompts.push(a.slice(23));
|
|
264
|
+
} else if (a === "--mcp") {
|
|
258
265
|
const v = argv[i + 1];
|
|
259
266
|
if (v !== void 0 && !v.startsWith("-")) {
|
|
260
267
|
mcp.push(v);
|
|
@@ -277,8 +284,6 @@ function parseRunnerArgs(argv) {
|
|
|
277
284
|
if (a.startsWith("--model=")) callerModel = true;
|
|
278
285
|
if (a === "--mcp-config") callerMcpConfig = true;
|
|
279
286
|
if (a.startsWith("--mcp-config=")) callerMcpConfig = true;
|
|
280
|
-
if (a === "--append-system-prompt") callerSystemPrompt = true;
|
|
281
|
-
if (a.startsWith("--append-system-prompt=")) callerSystemPrompt = true;
|
|
282
287
|
if (a === "--tools") callerTools = true;
|
|
283
288
|
if (a.startsWith("--tools=")) callerTools = true;
|
|
284
289
|
if (prompt === null && !a.startsWith("-") && rest.length > 0 && (rest[rest.length - 1] === "-p" || rest[rest.length - 1] === "--print")) prompt = a;
|
|
@@ -294,12 +299,22 @@ function parseRunnerArgs(argv) {
|
|
|
294
299
|
callerModel,
|
|
295
300
|
callerMcpConfig,
|
|
296
301
|
callerSystemPrompt,
|
|
302
|
+
callerSystemPrompts,
|
|
297
303
|
callerTools,
|
|
298
304
|
mcp,
|
|
299
305
|
allowedTools
|
|
300
306
|
};
|
|
301
307
|
}
|
|
302
308
|
/**
|
|
309
|
+
* The one --append-system-prompt flag for a spawn: claude keeps only the LAST
|
|
310
|
+
* occurrence, so every piece is joined (blank line between) into a single flag.
|
|
311
|
+
* Empty parts are dropped; no parts, no flag.
|
|
312
|
+
*/
|
|
313
|
+
function appendSystemPromptArgs(parts) {
|
|
314
|
+
const text = parts.filter((p) => p.trim()).join("\n\n");
|
|
315
|
+
return text ? ["--append-system-prompt", text] : [];
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
303
318
|
* Turn `-p "<prompt>"` into bare `-p` (same for --print): for stream-json
|
|
304
319
|
* stdin runs the prompt moves to the first user message on stdin, so the
|
|
305
320
|
* value must not stay on the command line. Only prompt values directly
|
|
@@ -1338,14 +1353,20 @@ function gcWorktrees(logDir, olderThanHours = 24, dryRun = false, now = Date.now
|
|
|
1338
1353
|
const out = [];
|
|
1339
1354
|
const root = worktreesDir(logDir);
|
|
1340
1355
|
const known = /* @__PURE__ */ new Set();
|
|
1341
|
-
const archive = (id, dir,
|
|
1356
|
+
const archive = (id, dir, st) => {
|
|
1342
1357
|
const target = `refs/pai-archive/${id}`;
|
|
1343
1358
|
if (dryRun) return void out.push({
|
|
1344
1359
|
id,
|
|
1345
1360
|
archive: target
|
|
1346
1361
|
});
|
|
1347
1362
|
try {
|
|
1348
|
-
|
|
1363
|
+
let repo;
|
|
1364
|
+
try {
|
|
1365
|
+
const raw = git(dir, ["rev-parse", "--git-common-dir"]);
|
|
1366
|
+
repo = isAbsolute(raw) ? raw : resolve(dir, raw);
|
|
1367
|
+
} catch {
|
|
1368
|
+
throw new Error("not a git worktree");
|
|
1369
|
+
}
|
|
1349
1370
|
const label = `archive: leftover state of worker ${id}`;
|
|
1350
1371
|
if (uncommittedPaths(dir).length) {
|
|
1351
1372
|
const res = salvageUncommitted(dir, label);
|
|
@@ -1424,7 +1445,7 @@ function gcWorktrees(logDir, olderThanHours = 24, dryRun = false, now = Date.now
|
|
|
1424
1445
|
continue;
|
|
1425
1446
|
}
|
|
1426
1447
|
if (end > cutoff) continue;
|
|
1427
|
-
archive(st.id, st.worktreeDir, st
|
|
1448
|
+
archive(st.id, st.worktreeDir, st);
|
|
1428
1449
|
}
|
|
1429
1450
|
if (existsSync(root)) for (const ent of readdirSync(root, { withFileTypes: true })) {
|
|
1430
1451
|
if (!ent.isDirectory() || known.has(ent.name) || existsSync(statusPath(logDir, ent.name))) continue;
|
|
@@ -1434,14 +1455,7 @@ function gcWorktrees(logDir, olderThanHours = 24, dryRun = false, now = Date.now
|
|
|
1434
1455
|
} catch {
|
|
1435
1456
|
continue;
|
|
1436
1457
|
}
|
|
1437
|
-
|
|
1438
|
-
try {
|
|
1439
|
-
const raw = git(dir, ["rev-parse", "--git-common-dir"]);
|
|
1440
|
-
repo = isAbsolute(raw) ? raw : resolve(dir, raw);
|
|
1441
|
-
} catch {
|
|
1442
|
-
repo = null;
|
|
1443
|
-
}
|
|
1444
|
-
archive(ent.name, dir, repo, null);
|
|
1458
|
+
archive(ent.name, dir, null);
|
|
1445
1459
|
}
|
|
1446
1460
|
if (!dryRun) for (const repo of new Set(loadStatuses(logDir).map((s) => s.cwd))) try {
|
|
1447
1461
|
git(repo, ["worktree", "prune"]);
|
|
@@ -2200,12 +2214,51 @@ function absoluteCliPath() {
|
|
|
2200
2214
|
if (argv1.endsWith("pai")) return argv1;
|
|
2201
2215
|
return "pai";
|
|
2202
2216
|
}
|
|
2217
|
+
/** The one place that decides where a follow pane opens: tmux (any OS) > iTerm2 (macOS) > nowhere. */
|
|
2218
|
+
function paneBackend(env = process.env, platform = process.platform) {
|
|
2219
|
+
if (env.TMUX) return "tmux";
|
|
2220
|
+
if (platform === "darwin" && env.ITERM_SESSION_ID) return "iterm";
|
|
2221
|
+
return "none";
|
|
2222
|
+
}
|
|
2223
|
+
function noPaneMessage(wid) {
|
|
2224
|
+
return `no pane support here, use: pai worker follow${wid ? ` ${wid}` : ""}`;
|
|
2225
|
+
}
|
|
2226
|
+
/** Split the current tmux window horizontally (right-hand column) and run cmd in it, focus stays put. */
|
|
2227
|
+
function tmuxSplit(cmd) {
|
|
2228
|
+
const target = process.env.TMUX_PANE ? ["-t", process.env.TMUX_PANE] : [];
|
|
2229
|
+
try {
|
|
2230
|
+
execFileSync("tmux", [
|
|
2231
|
+
"split-window",
|
|
2232
|
+
"-h",
|
|
2233
|
+
"-d",
|
|
2234
|
+
"-l",
|
|
2235
|
+
"40%",
|
|
2236
|
+
...target,
|
|
2237
|
+
cmd
|
|
2238
|
+
], { stdio: "pipe" });
|
|
2239
|
+
} catch (e) {
|
|
2240
|
+
const err = e;
|
|
2241
|
+
throw new Error(`pai worker pane: tmux split-window failed: ${(err.stderr?.toString() || err.message || "").trim().slice(0, 200)}`);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2203
2244
|
/** Open (or only report on) the stacked follow pane of one worker. */
|
|
2204
2245
|
async function openPaneForWorker(logDir, config, wid, term) {
|
|
2205
2246
|
if (workerPaneOpen(wid)) return {
|
|
2206
2247
|
message: `pane for ${wid} already open`,
|
|
2207
2248
|
session: null
|
|
2208
2249
|
};
|
|
2250
|
+
const backend = paneBackend();
|
|
2251
|
+
if (backend === "none") return {
|
|
2252
|
+
message: noPaneMessage(wid),
|
|
2253
|
+
session: null
|
|
2254
|
+
};
|
|
2255
|
+
if (backend === "tmux") {
|
|
2256
|
+
tmuxSplit(followCommand(wid, config.pane.autoExitSecs));
|
|
2257
|
+
return {
|
|
2258
|
+
message: `pane opened for ${wid}`,
|
|
2259
|
+
session: null
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2209
2262
|
const uid = itermUuid(term);
|
|
2210
2263
|
const regPath = join(panesDir(logDir), `${scopeKey(term)}.json`);
|
|
2211
2264
|
const reg = loadRegistry(regPath);
|
|
@@ -2259,6 +2312,7 @@ async function windowBoundsLine(term) {
|
|
|
2259
2312
|
*/
|
|
2260
2313
|
async function checkPaneForWorker(wid, fontSize, term) {
|
|
2261
2314
|
const lines = [workerPaneOpen(wid) ? `pane for ${wid} open` : `no pane for ${wid}`];
|
|
2315
|
+
if (paneBackend() !== "iterm") return lines.join("\n");
|
|
2262
2316
|
lines.push(await windowBoundsLine(term));
|
|
2263
2317
|
const path = dynamicProfilePath();
|
|
2264
2318
|
if (existsSync(path)) {
|
|
@@ -2281,6 +2335,13 @@ async function checkPaneForWorker(wid, fontSize, term) {
|
|
|
2281
2335
|
* with the running command, so names cannot serve as idempotence).
|
|
2282
2336
|
*/
|
|
2283
2337
|
async function openFollowPane(logDir, _config, term, checkOnly) {
|
|
2338
|
+
const backend = paneBackend();
|
|
2339
|
+
if (backend === "none") return noPaneMessage();
|
|
2340
|
+
if (backend === "tmux") {
|
|
2341
|
+
if (checkOnly) return "no follow pane";
|
|
2342
|
+
tmuxSplit(`${process.execPath} ${absoluteCliPath()} worker follow`);
|
|
2343
|
+
return "follow pane opened";
|
|
2344
|
+
}
|
|
2284
2345
|
const uid = itermUuid(term);
|
|
2285
2346
|
const out = (await osascript(TAB_TTYS_SCRIPT, [uid])).stdout.trim();
|
|
2286
2347
|
if (out === "notfound") throw new Error("pai worker pane: no open iTerm2 session matches ITERM_SESSION_ID");
|
|
@@ -2399,7 +2460,9 @@ function operatorSocketPath(logDir, id) {
|
|
|
2399
2460
|
}
|
|
2400
2461
|
/**
|
|
2401
2462
|
* The runner's side: listen on the worker socket, hand every received line to
|
|
2402
|
-
* `onLine`.
|
|
2463
|
+
* `onLine`. It acknowledges with "ok" only when `onLine` returns without a
|
|
2464
|
+
* string; a returned string (or a throw) is the failure reason, sent back as
|
|
2465
|
+
* `err <reason>` so `say` never reports ok for a message nobody received. Returns the server (close it when the run ends; the socket file is
|
|
2403
2466
|
* unlinked on close, best effort).
|
|
2404
2467
|
*/
|
|
2405
2468
|
function createOperatorServer(logDir, id, onLine) {
|
|
@@ -2409,14 +2472,20 @@ function createOperatorServer(logDir, id, onLine) {
|
|
|
2409
2472
|
} catch {}
|
|
2410
2473
|
const server = createServer((socket) => {
|
|
2411
2474
|
let buf = "";
|
|
2412
|
-
socket.on("
|
|
2475
|
+
socket.on("error", () => {});
|
|
2476
|
+
socket.on("data", async (chunk) => {
|
|
2413
2477
|
buf += chunk.toString("utf8");
|
|
2414
2478
|
let nl;
|
|
2415
2479
|
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
2416
2480
|
const line = buf.slice(0, nl).replace(/\r$/, "");
|
|
2417
2481
|
buf = buf.slice(nl + 1);
|
|
2418
|
-
|
|
2419
|
-
|
|
2482
|
+
let failure;
|
|
2483
|
+
if (line.trim()) try {
|
|
2484
|
+
failure = await onLine(line);
|
|
2485
|
+
} catch (e) {
|
|
2486
|
+
failure = e.message;
|
|
2487
|
+
}
|
|
2488
|
+
if (!socket.destroyed) socket.write(typeof failure === "string" && failure ? `err ${failure.replace(/\n/g, " ")}\n` : "ok\n");
|
|
2420
2489
|
}
|
|
2421
2490
|
});
|
|
2422
2491
|
});
|
|
@@ -2430,7 +2499,7 @@ function createOperatorServer(logDir, id, onLine) {
|
|
|
2430
2499
|
}
|
|
2431
2500
|
/**
|
|
2432
2501
|
* `pai worker say <id> "<text>"`: forward one line to a running worker.
|
|
2433
|
-
* Resolves "ok"
|
|
2502
|
+
* Resolves "ok" only once the worker acknowledged delivery; rejects with the reason otherwise.
|
|
2434
2503
|
*/
|
|
2435
2504
|
function sayToWorker(logDir, id, text, timeoutMs = 4e3) {
|
|
2436
2505
|
const status = loadStatus(logDir, id);
|
|
@@ -2449,10 +2518,13 @@ function sayToWorker(logDir, id, text, timeoutMs = 4e3) {
|
|
|
2449
2518
|
sock.once("connect", () => {
|
|
2450
2519
|
sock.write(text.replace(/\n/g, " ") + "\n");
|
|
2451
2520
|
});
|
|
2452
|
-
sock.once("data", () => {
|
|
2521
|
+
sock.once("data", (d) => {
|
|
2453
2522
|
sock.end();
|
|
2454
|
-
|
|
2523
|
+
const reply = d.toString("utf8").trim();
|
|
2524
|
+
if (reply === "ok") resolve("ok");
|
|
2525
|
+
else reject(/* @__PURE__ */ new Error(`worker ${id} did not take the message: ${reply.replace(/^err /, "") || "no acknowledgement"}`));
|
|
2455
2526
|
});
|
|
2527
|
+
sock.once("close", () => fail(/* @__PURE__ */ new Error("connection closed before the worker acknowledged")));
|
|
2456
2528
|
});
|
|
2457
2529
|
}
|
|
2458
2530
|
|
|
@@ -2857,10 +2929,10 @@ function fullContractPrompt(format) {
|
|
|
2857
2929
|
"report.",
|
|
2858
2930
|
"No narration, no timestamps, no greetings, no summaries of what you read; act, verify, then stop.",
|
|
2859
2931
|
"Never sleep-poll: no `sleep N` over 60 seconds, anywhere in a command — standalone, after `&&`/`||`/",
|
|
2860
|
-
"`;`/`|`, or inside a loop or subshell
|
|
2861
|
-
"
|
|
2862
|
-
"
|
|
2863
|
-
"
|
|
2932
|
+
"`;`/`|`, or inside a loop or subshell — and the sleeps of one command add up (`sleep 58; sleep 58` is",
|
|
2933
|
+
"116 s). Ending your turn ends this process, so a background job gets no later wake-up here:",
|
|
2934
|
+
"run_in_background is denied. Run the long command in the FOREGROUND with a Bash timeout up to 600000 ms",
|
|
2935
|
+
"and split longer jobs into steps that each fit it.",
|
|
2864
2936
|
...fileNotInlineBlock(),
|
|
2865
2937
|
"",
|
|
2866
2938
|
`Operator messages: a user turn starting with ${OPERATOR_MARK} was typed by the operator while you`,
|
|
@@ -2903,7 +2975,7 @@ function promptTrailer(format) {
|
|
|
2903
2975
|
return format === "ag2" ? "\n\nFinal message: one AG2 R message only, no prose (format in system prompt)." : "\n\nFinal message: a JSON object only, no prose before or after, no code fence (format in system prompt).";
|
|
2904
2976
|
}
|
|
2905
2977
|
/** The exact text sent to resend a final message that failed AG2 validation. */
|
|
2906
|
-
const AG2_REASK_TEXT = "Your final message was not a valid AG2 R message. Resend it now as a single AG2 R message only
|
|
2978
|
+
const AG2_REASK_TEXT = "Your final message was not a valid AG2 R message. Resend it now as a single AG2 R message only, no prose, no code fence. Minimal example (one key=value per line, first line R):\nR\ni=task-id\nr=+\nG=+\nc=path summary\nt=Name+\np=proof command\nz=the answer, one line\n(r is + - ~ ? !; r=+ needs G=+ and p; when r is not +, add y=why.)";
|
|
2907
2979
|
/** The full-contract AG2 prompt — the keepalive path's identical-construction baseline. */
|
|
2908
2980
|
const WORKER_CONTRACT_PROMPT = fullContractPrompt("ag2");
|
|
2909
2981
|
/**
|
|
@@ -3433,7 +3505,7 @@ async function runWorker(opts) {
|
|
|
3433
3505
|
if (gc?.length) process.stderr.write(`pai worker: archived ${gc.length} leftover worktree(s) (pai worker gc)\n`);
|
|
3434
3506
|
} catch {}
|
|
3435
3507
|
if (opts.className === "plan" && !opts._planner) {
|
|
3436
|
-
const { runPlanner } = await import("./planner-
|
|
3508
|
+
const { runPlanner } = await import("./planner-8-shIa8t.mjs");
|
|
3437
3509
|
return runPlanner(opts);
|
|
3438
3510
|
}
|
|
3439
3511
|
const parent = launchParent(opts.parent);
|
|
@@ -3809,7 +3881,7 @@ async function executeImageRun(a) {
|
|
|
3809
3881
|
* ledger line). Fire-and-forget, never blocks the worker.
|
|
3810
3882
|
*/
|
|
3811
3883
|
async function announcePane(logDir, config, wid, term, noPane, ledger) {
|
|
3812
|
-
const skip = !noPane ? !config.pane.enabled ? "workers.pane.enabled is false" : process.env.PAI_WORKER_AUTOPANE === "0" ? "PAI_WORKER_AUTOPANE=0" :
|
|
3884
|
+
const skip = !noPane ? !config.pane.enabled ? "workers.pane.enabled is false" : process.env.PAI_WORKER_AUTOPANE === "0" ? "PAI_WORKER_AUTOPANE=0" : paneBackend() === "none" ? "no tmux ($TMUX) or iTerm2 (ITERM_SESSION_ID) here" : null : "--no-pane";
|
|
3813
3885
|
if (skip) {
|
|
3814
3886
|
process.stderr.write(`[pai worker] no pane for ${wid}: ${skip}\n`);
|
|
3815
3887
|
return;
|
|
@@ -3902,12 +3974,12 @@ async function executeRun(a) {
|
|
|
3902
3974
|
let cmd = [...claudeCmd];
|
|
3903
3975
|
cmd.push(...modelFlagArgs(headless, model, Boolean(parsed.callerModel)));
|
|
3904
3976
|
cmd.push(...chromeArgs, ...mcpArgs, ...toolArgs, ...toolsFlag, ...restArgs);
|
|
3905
|
-
if (headless)
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3977
|
+
if (headless) cmd.push("--output-format", "stream-json", "--verbose", "--input-format", "stream-json");
|
|
3978
|
+
cmd.push(...appendSystemPromptArgs([
|
|
3979
|
+
...headless && !parsed.callerSystemPrompt ? [workerContractPrompt(a.className, a.reportFormat)] : [],
|
|
3980
|
+
...headless ? [worktree ? worktreeSystemPrompt(wid, worktree.branch, worktree.dir, worktree.snapshot) : inPlaceSystemPrompt()] : [],
|
|
3981
|
+
...parsed.callerSystemPrompts
|
|
3982
|
+
]));
|
|
3911
3983
|
cmd = ensureToolSearch(cmd);
|
|
3912
3984
|
if (a.printCmd) {
|
|
3913
3985
|
console.log(JSON.stringify({
|
|
@@ -3994,7 +4066,9 @@ async function executeRun(a) {
|
|
|
3994
4066
|
}) + "\n");
|
|
3995
4067
|
} catch {}
|
|
3996
4068
|
};
|
|
3997
|
-
const operatorServer = headless ? createOperatorServer(logDir, wid, (text) => {
|
|
4069
|
+
const operatorServer = headless ? createOperatorServer(logDir, wid, async (text) => {
|
|
4070
|
+
const stdin = proc.stdin;
|
|
4071
|
+
if (!stdin || !stdin.writable || stdin.writableEnded) return "the worker's stdin is already closed (its turn ended) — use: pai worker resume";
|
|
3998
4072
|
operatorInFlight += 1;
|
|
3999
4073
|
if (closeTimer) {
|
|
4000
4074
|
clearTimeout(closeTimer);
|
|
@@ -4005,9 +4079,13 @@ async function executeRun(a) {
|
|
|
4005
4079
|
text,
|
|
4006
4080
|
handoff: isHandoffMessage(text)
|
|
4007
4081
|
});
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4082
|
+
return new Promise((resolve) => {
|
|
4083
|
+
try {
|
|
4084
|
+
stdin.write(stdinUserMessage(operatorUserText(text)) + "\n", (e) => resolve(e ? `write to the worker failed: ${e.message}` : void 0));
|
|
4085
|
+
} catch (e) {
|
|
4086
|
+
resolve(`write to the worker failed: ${e.message}`);
|
|
4087
|
+
}
|
|
4088
|
+
});
|
|
4011
4089
|
}) : null;
|
|
4012
4090
|
let killed = false;
|
|
4013
4091
|
const cleanup = () => {
|
|
@@ -4595,4 +4673,4 @@ function resultFromOutput(out) {
|
|
|
4595
4673
|
|
|
4596
4674
|
//#endregion
|
|
4597
4675
|
export { expandMcpNames as $, ledgerSummary as A, loadStatuses as B, discardWorker as C, uncommittedPaths as D, mergeWorker as E, contextPercent as F, setWorkerLabel as G, nowStamp as H, elapsedOf as I, parseRunnerArgs as J, waitForTerminalStatus as K, isChatPane as L, ageOf as M, alive as N, worktreesDir as O, contextLabel as P, describeMcp as Q, isLive as R, workerInScope as S, git as T, ownsPid as U, newWorkerId as V, saveStatus as W, pinNotices as X, shortText as Y, projectLaunchConfig as Z, itermForClaudeSession as _, parseWorkerReport as a, sessionMapPath as b, readInbox as c, checkPaneForWorker as d, openFollowPane as f, currentTabKey as g, markControlsHeld as h, usageContextTokens as i, UNLABELED as j, appendLedger as k, sayToWorker as l, clickrControlsArgv as m, runWorker as n, renderReport as o, openPaneForWorker as p, longInlinePromptHint as q, testProvider as r, handoffFromInside as s, printResult as t, workerDepth as u, itermUuid as v, gcWorktrees as w, sessionTag as x, resolveSession as y, loadStatus as z };
|
|
4598
|
-
//# sourceMappingURL=run-
|
|
4676
|
+
//# sourceMappingURL=run-DUZRSnIT.mjs.map
|