sessionpipe 0.6.0 → 0.7.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 +16 -1
- package/dist/cli.js +1835 -1238
- package/dist/cli.js.map +4 -4
- package/dist/control/aliases.d.ts +15 -0
- package/dist/control/aliases.d.ts.map +1 -0
- package/dist/control/cli.d.ts.map +1 -1
- package/dist/control/daemon.d.ts +50 -10
- package/dist/control/daemon.d.ts.map +1 -1
- package/dist/control/pair.d.ts +2 -0
- package/dist/control/pair.d.ts.map +1 -1
- package/dist/control/route.d.ts +5 -2
- package/dist/control/route.d.ts.map +1 -1
- package/dist/hook.js +5 -2
- package/dist/hook.js.map +2 -2
- package/dist/index.js +84 -55
- package/dist/index.js.map +4 -4
- package/dist/launcher.d.ts +2 -1
- package/dist/launcher.d.ts.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/worker.js +88 -59
- package/dist/worker.js.map +4 -4
- package/package.json +1 -1
package/dist/launcher.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export declare function dataDir(env?: NodeJS.ProcessEnv): string;
|
|
|
3
3
|
export declare const launcherPath: (env?: NodeJS.ProcessEnv) => string;
|
|
4
4
|
export declare const usesLauncher: (platform?: NodeJS.Platform) => boolean;
|
|
5
5
|
/** The launcher, in sh. No node at all prints what Antigravity needs and exits 0: the
|
|
6
|
-
* hook must stay invisible to the harness whatever is missing
|
|
6
|
+
* hook must stay invisible to the harness whatever is missing (and a PreToolUse entry
|
|
7
|
+
* an older install left must not turn into a silent deny). */
|
|
7
8
|
export declare function launcherScript(node: string, hook: string, version: string): string;
|
|
8
9
|
/** Copy the hook and worker out of the npm install and (re)write the launcher. The
|
|
9
10
|
* worker goes first, so a hook that starts mid-copy never spawns a missing one. */
|
package/dist/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,QAAQ,qBAAqB,CAAC;AAG3C,wBAAgB,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAGpE;AACD,eAAO,MAAM,YAAY,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,MAA2C,CAAC;AAChH,eAAO,MAAM,YAAY,GAAI,WAAU,MAAM,CAAC,QAA2B,KAAG,OAA+B,CAAC;AAI5G;;+DAE+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CASlF;AAkBD;oFACoF;AACpF,wBAAgB,eAAe,CAAC,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GAAG;IAC/G,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB,CASA;AAED,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CAEzE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CAwClG"}
|
package/dist/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,UAAU,EAMf,MAAM,EAIN,KAAK,IAAI,EACT,KAAK,UAAU,EAOhB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,UAAU,EAMf,MAAM,EAIN,KAAK,IAAI,EACT,KAAK,UAAU,EAOhB,MAAM,mBAAmB,CAAC;AA6B3B,QAAA,MAAM,OAAO,QAAkF,CAAC;AAEhG,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,CAM1D;AAED;;;2BAG2B;AAC3B,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,SAAO,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB9F;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CASrD;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAkBpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,GAAE;IAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAAG,IAAI,EAAE,CAkBnG;AAED,mFAAmF;AACnF,wBAAsB,MAAM,CAC1B,GAAG,EAAE,GAAG,EACR,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,OAAO,CAAC;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAoHjE;AAKD;;;;;4DAK4D;AAC5D,wBAAsB,KAAK,CACzB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,UAAU,EAAE,EACzB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqEjC;AAaD,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,eAAO,MAAM,WAAW,QAAO,MAAkC,CAAC;AAClE,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,MAAkC,CAAC;AAC3E,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,OAAqC,CAAC"}
|
package/dist/worker.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// sessionpipe 0.
|
|
2
|
+
// sessionpipe 0.7.0 · Apache-2.0 · https://sessionpipe.org
|
|
3
3
|
|
|
4
4
|
// src/worker.ts
|
|
5
|
-
import { readFileSync as
|
|
5
|
+
import { readFileSync as readFileSync10, unlinkSync as unlinkSync5 } from "node:fs";
|
|
6
6
|
|
|
7
7
|
// ../core/src/adapters/antigravity.ts
|
|
8
8
|
import {
|
|
@@ -190,6 +190,9 @@ function readClaude(lines, from) {
|
|
|
190
190
|
}
|
|
191
191
|
return pairTurns(msgs, endOf(lines));
|
|
192
192
|
}
|
|
193
|
+
function codexInjected(text) {
|
|
194
|
+
return /^<[a-z_-]+>/i.test(text) || /^# AGENTS\.md instructions\b/i.test(text);
|
|
195
|
+
}
|
|
193
196
|
function readCodex(lines, from) {
|
|
194
197
|
const msgs = [];
|
|
195
198
|
for (let i = from; i < lines.length; i++) {
|
|
@@ -201,7 +204,7 @@ function readCodex(lines, from) {
|
|
|
201
204
|
const text = textParts(p.content, ["input_text", "output_text"]).trim();
|
|
202
205
|
if (!text) continue;
|
|
203
206
|
if (p.role === "user") {
|
|
204
|
-
if (
|
|
207
|
+
if (codexInjected(text)) continue;
|
|
205
208
|
msgs.push({ role: "user", text, at, line: i });
|
|
206
209
|
} else if (p.role === "assistant") msgs.push({ role: "assistant", text, at, line: i });
|
|
207
210
|
}
|
|
@@ -372,20 +375,19 @@ function installedClaudeShaped(file, harness, events, cmd, o) {
|
|
|
372
375
|
// ../core/src/adapters/antigravity.ts
|
|
373
376
|
var NAME = "antigravity";
|
|
374
377
|
var HOOK_NAME = "sessionpipe";
|
|
375
|
-
var AG_EVENTS = ["PreInvocation", "PostInvocation", "
|
|
378
|
+
var AG_EVENTS = ["PreInvocation", "PostInvocation", "PostToolUse", "Stop"];
|
|
379
|
+
var AG_STALE_PRETOOL = '{"decision":"ask","reason":"sessionpipe: an outdated PreToolUse hook is still loaded. Restart this conversation (or run sessionpipe install) to drop it."}\n';
|
|
380
|
+
var antigravityAnswer = (event) => event === "PreToolUse" ? AG_STALE_PRETOOL : "{}\n";
|
|
376
381
|
var gemini = (env) => env.GEMINI_CLI_HOME || path4.join(HOME, ".gemini");
|
|
377
382
|
var hooksFile = (env) => path4.join(gemini(env), "config", "hooks.json");
|
|
378
383
|
var projectsDir = (env) => path4.join(gemini(env), "config", "projects");
|
|
379
384
|
var dataDirs = (env) => ["antigravity", "antigravity-cli", "antigravity-ide"].map((d) => path4.join(gemini(env), d));
|
|
380
385
|
var ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
381
386
|
var validTool = (n) => typeof n === "string" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);
|
|
382
|
-
function entry(cmd
|
|
387
|
+
function entry(cmd) {
|
|
383
388
|
const handler = (e) => ({ type: "command", command: cmd([NAME, e]).command, timeout: 5 });
|
|
384
389
|
const out = { enabled: true };
|
|
385
|
-
for (const e of AG_EVENTS) {
|
|
386
|
-
if (lean && e === "PreToolUse") continue;
|
|
387
|
-
out[e] = /Tool/.test(e) ? [{ matcher: "*", hooks: [handler(e)] }] : [handler(e)];
|
|
388
|
-
}
|
|
390
|
+
for (const e of AG_EVENTS) out[e] = /Tool/.test(e) ? [{ matcher: "*", hooks: [handler(e)] }] : [handler(e)];
|
|
389
391
|
return out;
|
|
390
392
|
}
|
|
391
393
|
var antigravity = {
|
|
@@ -393,12 +395,12 @@ var antigravity = {
|
|
|
393
395
|
events: AG_EVENTS,
|
|
394
396
|
detect: (env = process.env) => existsSync2(path4.join(gemini(env), "config")) || dataDirs(env).some((d) => existsSync2(d)),
|
|
395
397
|
configFiles: (env = process.env) => [hooksFile(env)],
|
|
396
|
-
install(cmd, env = process.env
|
|
398
|
+
install(cmd, env = process.env) {
|
|
397
399
|
const file = hooksFile(env);
|
|
398
400
|
const f = readJsonFile(file);
|
|
399
401
|
if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];
|
|
400
402
|
const hooks = f.value;
|
|
401
|
-
const e = entry(cmd
|
|
403
|
+
const e = entry(cmd);
|
|
402
404
|
if (JSON.stringify(hooks[HOOK_NAME]) === JSON.stringify(e)) return [{ file, changed: false }];
|
|
403
405
|
hooks[HOOK_NAME] = e;
|
|
404
406
|
mkdirSync2(path4.dirname(file), { recursive: true });
|
|
@@ -427,14 +429,14 @@ var antigravity = {
|
|
|
427
429
|
writeFileSync2(file, formatJson(hooks, f));
|
|
428
430
|
return [{ file, changed: true }];
|
|
429
431
|
},
|
|
430
|
-
installed(cmd, env = process.env
|
|
432
|
+
installed(cmd, env = process.env) {
|
|
431
433
|
const file = hooksFile(env);
|
|
432
434
|
const f = readJsonFile(file);
|
|
433
435
|
const have = f.ok ? f.value[HOOK_NAME] : void 0;
|
|
434
436
|
return [
|
|
435
437
|
{
|
|
436
438
|
file,
|
|
437
|
-
state: !have ? "missing" : JSON.stringify(have) === JSON.stringify(entry(cmd
|
|
439
|
+
state: !have ? "missing" : JSON.stringify(have) === JSON.stringify(entry(cmd)) ? "current" : "stale"
|
|
438
440
|
}
|
|
439
441
|
];
|
|
440
442
|
},
|
|
@@ -446,7 +448,8 @@ var antigravity = {
|
|
|
446
448
|
} catch {
|
|
447
449
|
}
|
|
448
450
|
const id = s.conversationId ?? s.session_id ?? s.sessionId;
|
|
449
|
-
|
|
451
|
+
const stdout = antigravityAnswer(event);
|
|
452
|
+
if (!id) return { session: { id: "" }, events: [], stdout };
|
|
450
453
|
const workspaces = agWorkspaces(s.workspacePaths);
|
|
451
454
|
const session = { id: String(id), cwd: workspaces[0] ?? input.cwd };
|
|
452
455
|
if (typeof s.modelName === "string" && s.modelName !== "auto") session.model = s.modelName;
|
|
@@ -467,7 +470,8 @@ var antigravity = {
|
|
|
467
470
|
if (tool) events.push(ev("tool.started", { tool, input: toolCall?.args }));
|
|
468
471
|
break;
|
|
469
472
|
case "PostToolUse":
|
|
470
|
-
if (tool)
|
|
473
|
+
if (!tool) events.push(ev("session.heartbeat", {}));
|
|
474
|
+
else
|
|
471
475
|
events.push(
|
|
472
476
|
ev("tool.ended", {
|
|
473
477
|
tool,
|
|
@@ -481,9 +485,9 @@ var antigravity = {
|
|
|
481
485
|
events.push(ev("turn.ended", { reason: s.error ? "error" : "stop" }));
|
|
482
486
|
break;
|
|
483
487
|
default:
|
|
484
|
-
return { session, events: [], stdout
|
|
488
|
+
return { session, events: [], stdout };
|
|
485
489
|
}
|
|
486
|
-
const r = { session, events, stdout
|
|
490
|
+
const r = { session, events, stdout, hints: { workspaces } };
|
|
487
491
|
if (typeof s.transcriptPath === "string") r.transcript = s.transcriptPath;
|
|
488
492
|
return r;
|
|
489
493
|
},
|
|
@@ -1438,7 +1442,8 @@ function uninstallNotify(env) {
|
|
|
1438
1442
|
}
|
|
1439
1443
|
return { file, changed: false };
|
|
1440
1444
|
}
|
|
1441
|
-
function findRollout(threadId, env) {
|
|
1445
|
+
function findRollout(threadId, env = process.env) {
|
|
1446
|
+
if (!/^[A-Za-z0-9-]{8,128}$/.test(threadId)) return null;
|
|
1442
1447
|
let best = null;
|
|
1443
1448
|
const walk = (dir, depth) => {
|
|
1444
1449
|
let names = [];
|
|
@@ -1449,7 +1454,7 @@ function findRollout(threadId, env) {
|
|
|
1449
1454
|
}
|
|
1450
1455
|
for (const n of names.sort().reverse()) {
|
|
1451
1456
|
const p = path6.join(dir, n);
|
|
1452
|
-
if (n.endsWith(
|
|
1457
|
+
if (n.endsWith(`-${threadId}.jsonl`)) {
|
|
1453
1458
|
best = p;
|
|
1454
1459
|
return;
|
|
1455
1460
|
}
|
|
@@ -1654,7 +1659,7 @@ function codexFacts(file) {
|
|
|
1654
1659
|
const p = j.payload;
|
|
1655
1660
|
if (j.type !== "response_item" || !p || p.type !== "message" || p.role !== "user") continue;
|
|
1656
1661
|
const text = (p.content ?? []).filter((b) => b && b.type === "input_text" && typeof b.text === "string").map((b) => b.text).join("\n").trim();
|
|
1657
|
-
if (!text ||
|
|
1662
|
+
if (!text || codexInjected(text)) continue;
|
|
1658
1663
|
const line = text.split("\n").find((l) => l.trim()) ?? "";
|
|
1659
1664
|
out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\s+\S*$/, "")}\u2026` : line;
|
|
1660
1665
|
out.title_source = "first-ask";
|
|
@@ -2480,25 +2485,50 @@ var StdoutSink = class {
|
|
|
2480
2485
|
import {
|
|
2481
2486
|
appendFileSync as appendFileSync3,
|
|
2482
2487
|
existsSync as existsSync8,
|
|
2483
|
-
mkdirSync as
|
|
2488
|
+
mkdirSync as mkdirSync8,
|
|
2484
2489
|
readdirSync as readdirSync6,
|
|
2485
|
-
readFileSync as
|
|
2486
|
-
renameSync as
|
|
2490
|
+
readFileSync as readFileSync9,
|
|
2491
|
+
renameSync as renameSync3,
|
|
2487
2492
|
statSync as statSync5,
|
|
2488
2493
|
unlinkSync as unlinkSync4,
|
|
2489
|
-
writeFileSync as
|
|
2494
|
+
writeFileSync as writeFileSync7
|
|
2490
2495
|
} from "node:fs";
|
|
2491
2496
|
import os3 from "node:os";
|
|
2492
|
-
import
|
|
2497
|
+
import path13 from "node:path";
|
|
2498
|
+
|
|
2499
|
+
// src/control/aliases.ts
|
|
2500
|
+
import { chmodSync as chmodSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
2501
|
+
import path11 from "node:path";
|
|
2502
|
+
var aliasFile = (controlDir) => path11.join(controlDir, "aliases.json");
|
|
2503
|
+
function readAliases(file) {
|
|
2504
|
+
try {
|
|
2505
|
+
const j = JSON.parse(readFileSync8(file, "utf8"));
|
|
2506
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) return {};
|
|
2507
|
+
const out = {};
|
|
2508
|
+
for (const [k, v] of Object.entries(j)) {
|
|
2509
|
+
const a = v;
|
|
2510
|
+
if (a && typeof a.id === "string" && a.id && typeof a.cwd === "string")
|
|
2511
|
+
out[k] = { id: a.id, cwd: a.cwd, at: typeof a.at === "string" ? a.at : "" };
|
|
2512
|
+
}
|
|
2513
|
+
return out;
|
|
2514
|
+
} catch {
|
|
2515
|
+
return {};
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
function receiverIdOf(all, harness, id) {
|
|
2519
|
+
const prefix = `${harness}:`;
|
|
2520
|
+
for (const [k, a] of Object.entries(all)) if (a.id === id && k.startsWith(prefix)) return k.slice(prefix.length);
|
|
2521
|
+
return null;
|
|
2522
|
+
}
|
|
2493
2523
|
|
|
2494
2524
|
// src/control/local.ts
|
|
2495
2525
|
import net from "node:net";
|
|
2496
2526
|
import os2 from "node:os";
|
|
2497
|
-
import
|
|
2527
|
+
import path12 from "node:path";
|
|
2498
2528
|
function socketPath(state, env = process.env) {
|
|
2499
2529
|
if (env.SESSIONPIPE_SOCKET) return env.SESSIONPIPE_SOCKET;
|
|
2500
2530
|
if (process.platform === "win32") return `\\\\.\\pipe\\sessionpipe-control-${os2.userInfo().username}`;
|
|
2501
|
-
return
|
|
2531
|
+
return path12.join(state, "control.sock");
|
|
2502
2532
|
}
|
|
2503
2533
|
function ask(sock, req, timeoutMs) {
|
|
2504
2534
|
return new Promise((resolve) => {
|
|
@@ -2650,16 +2680,16 @@ function sinkWithSecrets(s, run = defaultRunner) {
|
|
|
2650
2680
|
}
|
|
2651
2681
|
|
|
2652
2682
|
// src/run.ts
|
|
2653
|
-
async function tellDaemon(state, job2, session, transcript) {
|
|
2683
|
+
async function tellDaemon(state, job2, session, cwd, transcript) {
|
|
2654
2684
|
const sock = socketPath(state);
|
|
2655
2685
|
if (process.platform !== "win32" && !existsSync8(sock)) return;
|
|
2656
2686
|
await ask(
|
|
2657
2687
|
sock,
|
|
2658
2688
|
{
|
|
2659
2689
|
op: "event",
|
|
2660
|
-
session:
|
|
2690
|
+
session: `${job2.harness}:${session}`,
|
|
2661
2691
|
event: job2.event,
|
|
2662
|
-
cwd:
|
|
2692
|
+
...cwd ? { cwd } : {},
|
|
2663
2693
|
...transcript ? { transcript } : {}
|
|
2664
2694
|
},
|
|
2665
2695
|
300
|
|
@@ -2667,9 +2697,9 @@ async function tellDaemon(state, job2, session, transcript) {
|
|
|
2667
2697
|
}
|
|
2668
2698
|
function enqueueJob(state, job2) {
|
|
2669
2699
|
const jobs = jobsDir(state);
|
|
2670
|
-
|
|
2671
|
-
const f =
|
|
2672
|
-
|
|
2700
|
+
mkdirSync8(jobs, { recursive: true, mode: 448 });
|
|
2701
|
+
const f = path13.join(jobs, `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.json`);
|
|
2702
|
+
writeFileSync7(f, JSON.stringify(job2), { mode: 384 });
|
|
2673
2703
|
return f;
|
|
2674
2704
|
}
|
|
2675
2705
|
async function sweepJobs(state, olderThanMs = 3e3, limit = 20) {
|
|
@@ -2682,11 +2712,11 @@ async function sweepJobs(state, olderThanMs = 3e3, limit = 20) {
|
|
|
2682
2712
|
}
|
|
2683
2713
|
let ran = 0;
|
|
2684
2714
|
for (const n of names.sort().slice(0, limit)) {
|
|
2685
|
-
const f =
|
|
2715
|
+
const f = path13.join(jobs, n);
|
|
2686
2716
|
let job2 = null;
|
|
2687
2717
|
try {
|
|
2688
2718
|
if (Date.now() - statSync5(f).mtimeMs < olderThanMs) continue;
|
|
2689
|
-
job2 = JSON.parse(
|
|
2719
|
+
job2 = JSON.parse(readFileSync9(f, "utf8"));
|
|
2690
2720
|
unlinkSync4(f);
|
|
2691
2721
|
} catch {
|
|
2692
2722
|
continue;
|
|
@@ -2699,10 +2729,10 @@ async function sweepJobs(state, olderThanMs = 3e3, limit = 20) {
|
|
|
2699
2729
|
}
|
|
2700
2730
|
function log(state, line) {
|
|
2701
2731
|
try {
|
|
2702
|
-
|
|
2703
|
-
const f =
|
|
2732
|
+
mkdirSync8(state, { recursive: true, mode: 448 });
|
|
2733
|
+
const f = path13.join(state, "log");
|
|
2704
2734
|
try {
|
|
2705
|
-
if (statSync5(f).size > 1024 * 1024)
|
|
2735
|
+
if (statSync5(f).size > 1024 * 1024) renameSync3(f, `${f}.1`);
|
|
2706
2736
|
} catch {
|
|
2707
2737
|
}
|
|
2708
2738
|
appendFileSync3(f, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
@@ -2711,11 +2741,11 @@ function log(state, line) {
|
|
|
2711
2741
|
}
|
|
2712
2742
|
}
|
|
2713
2743
|
function factsState(state) {
|
|
2714
|
-
const file = (h, s) =>
|
|
2744
|
+
const file = (h, s) => path13.join(state, "facts", safeId(h), `${safeId(s)}.json`);
|
|
2715
2745
|
return {
|
|
2716
2746
|
get(h, s) {
|
|
2717
2747
|
try {
|
|
2718
|
-
return JSON.parse(
|
|
2748
|
+
return JSON.parse(readFileSync9(file(h, s), "utf8"));
|
|
2719
2749
|
} catch {
|
|
2720
2750
|
return {};
|
|
2721
2751
|
}
|
|
@@ -2724,8 +2754,8 @@ function factsState(state) {
|
|
|
2724
2754
|
const cur = this.get(h, s);
|
|
2725
2755
|
const next = { ...cur, ...patch };
|
|
2726
2756
|
if (JSON.stringify(next) === JSON.stringify(cur)) return;
|
|
2727
|
-
|
|
2728
|
-
|
|
2757
|
+
mkdirSync8(path13.dirname(file(h, s)), { recursive: true, mode: 448 });
|
|
2758
|
+
writeFileSync7(file(h, s), JSON.stringify(next), { mode: 384 });
|
|
2729
2759
|
}
|
|
2730
2760
|
};
|
|
2731
2761
|
}
|
|
@@ -2753,30 +2783,33 @@ async function runJob(job2, opts = {}) {
|
|
|
2753
2783
|
if (!adapter) return { events: [], delivered: {} };
|
|
2754
2784
|
const r = adapter.fromHook({ argv: job2.argv, stdin: job2.stdin, env: { ...process.env, ...job2.env }, cwd: job2.cwd });
|
|
2755
2785
|
if (!r || !r.session.id) return { events: [], delivered: {} };
|
|
2756
|
-
|
|
2786
|
+
const id = receiverIdOf(readAliases(aliasFile(path13.join(state, "control"))), job2.harness, r.session.id) ?? r.session.id;
|
|
2787
|
+
await tellDaemon(state, job2, id, r.session.cwd, r.transcript);
|
|
2757
2788
|
const outbox = new Outbox(state);
|
|
2758
|
-
const ref = { harness: job2.harness, session:
|
|
2789
|
+
const ref = { harness: job2.harness, session: id };
|
|
2759
2790
|
let release = takeLock(state, ref);
|
|
2760
2791
|
for (let wait = 50; !release && wait <= 3200; wait *= 2) {
|
|
2761
2792
|
await new Promise((res) => setTimeout(res, wait));
|
|
2762
2793
|
release = takeLock(state, ref);
|
|
2763
2794
|
}
|
|
2764
2795
|
if (!release) {
|
|
2765
|
-
log(state, `${job2.harness} ${job2.event}: session ${
|
|
2796
|
+
log(state, `${job2.harness} ${job2.event}: session ${id} locked for 6 s, re-queued`);
|
|
2766
2797
|
enqueueJob(state, job2);
|
|
2767
2798
|
return { events: [], delivered: {} };
|
|
2768
2799
|
}
|
|
2769
2800
|
try {
|
|
2770
2801
|
const facts = factsState(state);
|
|
2771
|
-
const mem = facts.get(job2.harness,
|
|
2802
|
+
const mem = facts.get(job2.harness, id);
|
|
2772
2803
|
const heavy = !/^(PreToolUse|PostToolUse|PostToolUseFailure|BeforeTool|AfterTool|PostInvocation)$/.test(job2.event);
|
|
2773
2804
|
let learned = {};
|
|
2774
2805
|
if (heavy) {
|
|
2775
2806
|
const f = adapter.facts(r.session, r.transcript, r.hints ?? {}, facts);
|
|
2776
2807
|
const { started_at: _s, last_at: _l, first_ask: _fa, harness_version, ...rest } = f;
|
|
2777
2808
|
learned = rest;
|
|
2778
|
-
if (harness_version) facts.save(job2.harness,
|
|
2779
|
-
facts.save(job2.harness,
|
|
2809
|
+
if (harness_version) facts.save(job2.harness, id, { harness_version });
|
|
2810
|
+
facts.save(job2.harness, id, { session: { ...mem.session, ...learned } });
|
|
2811
|
+
if (job2.harness === "antigravity" && r.session.cwd && path13.isAbsolute(r.session.cwd))
|
|
2812
|
+
facts.save(job2.harness, id, { cwd: r.session.cwd });
|
|
2780
2813
|
}
|
|
2781
2814
|
const known = mem.session ?? {};
|
|
2782
2815
|
const cwdRaw = learned.cwd ?? r.session.cwd ?? known.cwd;
|
|
@@ -2786,13 +2819,13 @@ async function runJob(job2, opts = {}) {
|
|
|
2786
2819
|
...learned,
|
|
2787
2820
|
...git,
|
|
2788
2821
|
...learned.branch ? { branch: learned.branch } : {},
|
|
2789
|
-
id
|
|
2822
|
+
id,
|
|
2790
2823
|
seq: 0,
|
|
2791
2824
|
machine: machineName(cfg, os3.hostname()),
|
|
2792
2825
|
...cwdRaw ? { cwd: tilde(cwdRaw) } : {},
|
|
2793
2826
|
...r.session.model ? { model: r.session.model } : {}
|
|
2794
2827
|
};
|
|
2795
|
-
const version = facts.get(job2.harness,
|
|
2828
|
+
const version = facts.get(job2.harness, id).harness_version ?? void 0;
|
|
2796
2829
|
const events = [];
|
|
2797
2830
|
for (const a of r.events) {
|
|
2798
2831
|
const e = makeEvent(a, {
|
|
@@ -2804,7 +2837,7 @@ async function runJob(job2, opts = {}) {
|
|
|
2804
2837
|
}
|
|
2805
2838
|
const wantsTranscript = cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 2);
|
|
2806
2839
|
if (wantsTranscript && r.transcript && r.events.some((e) => e.type === "turn.ended" || e.type === "session.ended")) {
|
|
2807
|
-
const cur = facts.get(job2.harness,
|
|
2840
|
+
const cur = facts.get(job2.harness, id);
|
|
2808
2841
|
const fromLine = Number(cur.transcript_line) || 0;
|
|
2809
2842
|
let turnNo = Number(cur.transcript_turns) || 0;
|
|
2810
2843
|
const read = adapter.readTranscript(r.transcript, fromLine);
|
|
@@ -2824,17 +2857,13 @@ async function runJob(job2, opts = {}) {
|
|
|
2824
2857
|
)
|
|
2825
2858
|
);
|
|
2826
2859
|
}
|
|
2827
|
-
if (read.turns.length)
|
|
2828
|
-
facts.save(job2.harness, r.session.id, { transcript_line: read.line, transcript_turns: turnNo });
|
|
2860
|
+
if (read.turns.length) facts.save(job2.harness, id, { transcript_line: read.line, transcript_turns: turnNo });
|
|
2829
2861
|
}
|
|
2830
2862
|
outbox.append(
|
|
2831
2863
|
ref,
|
|
2832
2864
|
events.map((e) => ({ ...e, session: redactDeep(e.session), data: redactDeep(e.data) }))
|
|
2833
2865
|
);
|
|
2834
|
-
log(
|
|
2835
|
-
state,
|
|
2836
|
-
`${job2.harness} ${job2.event}: ${events.map((e) => e.type).join(",") || "nothing"} (${r.session.id.slice(0, 8)})`
|
|
2837
|
-
);
|
|
2866
|
+
log(state, `${job2.harness} ${job2.event}: ${events.map((e) => e.type).join(",") || "nothing"} (${id.slice(0, 8)})`);
|
|
2838
2867
|
const delivered = await flush(state, cfg.sinks, outbox, ref);
|
|
2839
2868
|
if (Math.random() < 0.02) outbox.prune(cfg.keep_days ?? 30);
|
|
2840
2869
|
return { events, delivered };
|
|
@@ -2925,14 +2954,14 @@ function applySinkVerdict(name, res) {
|
|
|
2925
2954
|
} catch {
|
|
2926
2955
|
}
|
|
2927
2956
|
}
|
|
2928
|
-
var jobsDir = (state) =>
|
|
2957
|
+
var jobsDir = (state) => path13.join(state, "jobs");
|
|
2929
2958
|
|
|
2930
2959
|
// src/worker.ts
|
|
2931
2960
|
var jobFile = process.argv[2];
|
|
2932
2961
|
if (!jobFile) process.exit(0);
|
|
2933
2962
|
var job = null;
|
|
2934
2963
|
try {
|
|
2935
|
-
job = JSON.parse(
|
|
2964
|
+
job = JSON.parse(readFileSync10(jobFile, "utf8"));
|
|
2936
2965
|
} catch {
|
|
2937
2966
|
}
|
|
2938
2967
|
try {
|