sessionpipe 0.9.0 → 0.10.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 +25 -2
- package/dist/cli.js +4358 -3288
- package/dist/cli.js.map +4 -4
- package/dist/control/aliases.d.ts +5 -0
- package/dist/control/aliases.d.ts.map +1 -1
- package/dist/control/autoupdate.d.ts +1 -18
- package/dist/control/autoupdate.d.ts.map +1 -1
- package/dist/control/cli.d.ts +1 -1
- package/dist/control/cli.d.ts.map +1 -1
- package/dist/control/daemon.d.ts +83 -12
- package/dist/control/daemon.d.ts.map +1 -1
- package/dist/control/files.d.ts +6 -4
- package/dist/control/files.d.ts.map +1 -1
- package/dist/control/pair.d.ts +15 -23
- package/dist/control/pair.d.ts.map +1 -1
- package/dist/control/route.d.ts +1 -1
- package/dist/control/route.d.ts.map +1 -1
- package/dist/control/sdk.d.ts.map +1 -1
- package/dist/control/store.d.ts +21 -2
- package/dist/control/store.d.ts.map +1 -1
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +7 -1
- package/dist/hook.js.map +2 -2
- package/dist/index.js +150 -44
- package/dist/index.js.map +4 -4
- package/dist/run.d.ts.map +1 -1
- package/dist/update.d.ts +1 -7
- package/dist/update.d.ts.map +1 -1
- package/dist/worker.js +152 -46
- package/dist/worker.js.map +4 -4
- package/package.json +1 -1
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,EAKL,KAAK,KAAK,EACV,KAAK,UAAU,EAOf,MAAM,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/dist/update.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
export declare const REGISTRY_LATEST = "https://registry.npmjs.org/sessionpipe/latest";
|
|
2
|
-
|
|
3
|
-
* its own prereleases; prereleases compare by their tag. */
|
|
4
|
-
export declare function compareVersions(a: string, b: string): number | null;
|
|
5
|
-
/** `a` is a release newer than `b`. A prerelease is never offered as an update: the
|
|
6
|
-
* `latest` dist-tag is a release, and anything else is someone's experiment.
|
|
7
|
-
* Setup opts into prereleases when checking whether an installed build is newer. */
|
|
8
|
-
export declare function isNewer(a: string, b: string, includePrereleases?: boolean): boolean;
|
|
2
|
+
export { compareVersions, isNewer } from "@sessionpipe/core/version";
|
|
9
3
|
/** The registry's `latest` for sessionpipe: one GET, nothing sent but the request. */
|
|
10
4
|
export declare function latestVersion(f?: typeof fetch, timeoutMs?: number): Promise<string>;
|
|
11
5
|
/** The prefix a global npm install of sessionpipe lives under, from the running copy's
|
package/dist/update.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,eAAe,kDAAkD,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,eAAe,kDAAkD,CAAC;AAK/E,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAErE,sFAAsF;AACtF,wBAAsB,aAAa,CAAC,CAAC,GAAE,OAAO,KAAa,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9F;AAED;;iDAEiD;AACjD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,GAAG,IAAI,CAIrG;AAED;;0FAE0F;AAC1F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,GAAG,IAAI,CAMzG;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,GAAG,IAAI,CAQtG;AAED;;2EAE2E;AAC3E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,EAAE,CAa5F;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE7G,gEAAgE;AAChE,eAAO,MAAM,WAAW,EAAE,IAiCtB,CAAC;AAEL,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAA;CAAE,CAAC;AAKjF,0EAA0E;AAC1E,wBAAsB,gBAAgB,CAAC,CAAC,EAAE;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOzB;AAED;;;;yDAIyD;AACzD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CA8C/F"}
|
package/dist/worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// sessionpipe 0.
|
|
2
|
+
// sessionpipe 0.10.0 · Apache-2.0 · https://sessionpipe.org
|
|
3
3
|
|
|
4
4
|
// src/worker.ts
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
@@ -820,14 +820,28 @@ var claudeCode = {
|
|
|
820
820
|
case "SessionStart":
|
|
821
821
|
events.push(ev("session.started", { source: pickSource(s.source ?? s.trigger) }));
|
|
822
822
|
break;
|
|
823
|
-
case "UserPromptSubmit":
|
|
823
|
+
case "UserPromptSubmit": {
|
|
824
|
+
const prompt = typeof s.prompt === "string" ? s.prompt : void 0;
|
|
824
825
|
events.push(
|
|
825
826
|
ev("turn.started", {
|
|
826
827
|
turn_id,
|
|
827
|
-
prompt_chars:
|
|
828
|
+
prompt_chars: prompt === void 0 ? void 0 : [...prompt].length,
|
|
829
|
+
// Claude Code's hook schema documents `source`
|
|
830
|
+
// (user | sdk | system | loop_wakeup | schedule_wakeup | poll_event) and says a
|
|
831
|
+
// payload may omit it while the field rolls out; 2.1.304's payload has no such
|
|
832
|
+
// key at all. Forwarded verbatim, shape-guarded only: the list is the harness's
|
|
833
|
+
// to extend.
|
|
834
|
+
submitted_by: harnessWord(s.source),
|
|
835
|
+
// One of Claude Code's own prompt wrappers: the prompt is a block the harness
|
|
836
|
+
// wrote, so it is not the person's words. Absent is unknown, never "the person" —
|
|
837
|
+
// and `true` is never "no person caused this turn", because a Talk or
|
|
838
|
+
// `sessionpipe wait` delivery hands the person's own message over inside a
|
|
839
|
+
// <task-notification> (PROTOCOL.md §4).
|
|
840
|
+
injected: prompt !== void 0 && injectedBlock(prompt) ? true : void 0
|
|
828
841
|
})
|
|
829
842
|
);
|
|
830
843
|
break;
|
|
844
|
+
}
|
|
831
845
|
case "PreToolUse":
|
|
832
846
|
if (tool) events.push(ev("tool.started", { tool, call_id, turn_id, agent_id, input: s.tool_input }));
|
|
833
847
|
break;
|
|
@@ -882,7 +896,13 @@ var claudeCode = {
|
|
|
882
896
|
);
|
|
883
897
|
break;
|
|
884
898
|
case "Stop":
|
|
885
|
-
events.push(
|
|
899
|
+
events.push(
|
|
900
|
+
ev("turn.ended", {
|
|
901
|
+
turn_id,
|
|
902
|
+
reason: "stop",
|
|
903
|
+
background: Array.isArray(s.background_tasks) ? s.background_tasks.length : void 0
|
|
904
|
+
})
|
|
905
|
+
);
|
|
886
906
|
break;
|
|
887
907
|
case "StopFailure":
|
|
888
908
|
events.push(
|
|
@@ -925,6 +945,8 @@ var claudeCode = {
|
|
|
925
945
|
if (event === "UserPromptSubmit" && typeof s.prompt === "string") hints.prompt = s.prompt;
|
|
926
946
|
const host = input.env.CLAUDE_CODE_HOST_SESSION_ID;
|
|
927
947
|
if (host && DESKTOP_ID.test(host)) hints.desktop_id = host;
|
|
948
|
+
const attended = input.env.CLAUDE_CODE_SESSION_ATTENDED;
|
|
949
|
+
if (attended === "1" || attended === "0") hints.attended = attended === "1" || !!input.env.SESSIONPIPE_CONTROL_JOB;
|
|
928
950
|
if (event !== "PreToolUse" && event !== "PostToolUse") hints.claude_pid = claudePid(input.env);
|
|
929
951
|
const r = { session, events, hints };
|
|
930
952
|
if (typeof s.transcript_path === "string") r.transcript = s.transcript_path;
|
|
@@ -945,6 +967,7 @@ var claudeCode = {
|
|
|
945
967
|
const cwd = out.cwd ?? session.cwd;
|
|
946
968
|
Object.assign(out, gitFacts(cwd), out.branch ? { branch: out.branch } : {});
|
|
947
969
|
if (!out.url && typeof hints.desktop_id === "string") out.url = `claude://code/continue/${hints.desktop_id}`;
|
|
970
|
+
if (typeof hints.attended === "boolean") out.attended = hints.attended || !!out.url;
|
|
948
971
|
return out;
|
|
949
972
|
},
|
|
950
973
|
backfill(sinceMs, env = process.env) {
|
|
@@ -980,6 +1003,9 @@ function notClaudeCode(id, s) {
|
|
|
980
1003
|
function pickSource(v) {
|
|
981
1004
|
return typeof v === "string" && ["startup", "resume", "clear", "compact", "fork"].includes(v) ? v : "unknown";
|
|
982
1005
|
}
|
|
1006
|
+
var harnessWord = (v) => typeof v === "string" && /^[A-Za-z0-9][A-Za-z0-9_.-]{0,39}$/.test(v) ? v : void 0;
|
|
1007
|
+
var WRAPPER = /^<(?:task-notification|cross-session-message|system-reminder|local-command-stdout|command-[a-z-]+)[\s/>]/i;
|
|
1008
|
+
var injectedBlock = (prompt) => WRAPPER.test(prompt.trim());
|
|
983
1009
|
function errText(v) {
|
|
984
1010
|
if (typeof v === "string") return v.slice(0, 2e3);
|
|
985
1011
|
if (v && typeof v === "object") {
|
|
@@ -1096,7 +1122,27 @@ function claudeLogin(dir, home = homeDir()) {
|
|
|
1096
1122
|
} catch {
|
|
1097
1123
|
}
|
|
1098
1124
|
}
|
|
1099
|
-
return
|
|
1125
|
+
return apiAccount(dir);
|
|
1126
|
+
}
|
|
1127
|
+
var ANTHROPIC_HOST = /(^|\.)anthropic\.com$/i;
|
|
1128
|
+
function apiAccount(dir) {
|
|
1129
|
+
let base;
|
|
1130
|
+
try {
|
|
1131
|
+
base = JSON.parse(readFileSync3(settingsIn(dir), "utf8")).env?.ANTHROPIC_BASE_URL;
|
|
1132
|
+
} catch {
|
|
1133
|
+
return null;
|
|
1134
|
+
}
|
|
1135
|
+
if (typeof base !== "string") return null;
|
|
1136
|
+
let u;
|
|
1137
|
+
try {
|
|
1138
|
+
u = new URL(base.trim());
|
|
1139
|
+
} catch {
|
|
1140
|
+
return null;
|
|
1141
|
+
}
|
|
1142
|
+
if (u.protocol !== "https:" && u.protocol !== "http:" || !u.hostname || ANTHROPIC_HOST.test(u.hostname))
|
|
1143
|
+
return null;
|
|
1144
|
+
const origin = `${u.protocol}//${u.host}`;
|
|
1145
|
+
return { id: `api-${createHash("sha256").update(origin).digest("hex").slice(0, 16)}`, name: u.host };
|
|
1100
1146
|
}
|
|
1101
1147
|
var accountCache = /* @__PURE__ */ new Map();
|
|
1102
1148
|
function claudeAccount(dir) {
|
|
@@ -1256,6 +1302,18 @@ function claudeFacts(file, sessionId, hints, state) {
|
|
|
1256
1302
|
return out;
|
|
1257
1303
|
}
|
|
1258
1304
|
|
|
1305
|
+
// ../core/src/control/verify.ts
|
|
1306
|
+
var GRANT_MAX_MS = 24 * 36e5;
|
|
1307
|
+
var SKEW_MS = 5 * 6e4;
|
|
1308
|
+
var MACHINE_MAX_AGE_MS = 24 * 36e5;
|
|
1309
|
+
var RECEIVER_MAX_AGE_MS = 10 * 6e4;
|
|
1310
|
+
var NONCE_TTL_MS = 25 * 36e5;
|
|
1311
|
+
var MODEL_RE = /^[A-Za-z0-9][A-Za-z0-9._:/@[\]-]*$/;
|
|
1312
|
+
var START_PERMISSIONS = ["read", "safe", "edits", "auto"];
|
|
1313
|
+
var levelRank = (l) => START_PERMISSIONS.indexOf(l);
|
|
1314
|
+
var enc = new TextEncoder();
|
|
1315
|
+
var dec = new TextDecoder();
|
|
1316
|
+
|
|
1259
1317
|
// ../core/src/adapters/codex.ts
|
|
1260
1318
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1261
1319
|
import path6 from "node:path";
|
|
@@ -1577,7 +1635,7 @@ var codex = {
|
|
|
1577
1635
|
if (j && typeof j === "object" && !Array.isArray(j)) s = j;
|
|
1578
1636
|
} catch {
|
|
1579
1637
|
}
|
|
1580
|
-
const id = s.session_id;
|
|
1638
|
+
const id = s.session_id ?? s.thread_id ?? s.conversation_id ?? s["thread-id"] ?? s["session-id"];
|
|
1581
1639
|
if (!id) return null;
|
|
1582
1640
|
if (s.transcript_path === null) return null;
|
|
1583
1641
|
const session = { id: String(id), cwd: typeof s.cwd === "string" ? s.cwd : input.cwd };
|
|
@@ -2421,6 +2479,22 @@ function makeEvent(a, ctx) {
|
|
|
2421
2479
|
};
|
|
2422
2480
|
}
|
|
2423
2481
|
|
|
2482
|
+
// ../core/src/launched-by.ts
|
|
2483
|
+
var LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
2484
|
+
var LAUNCHED_BY = /^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/;
|
|
2485
|
+
function launchedBy(env) {
|
|
2486
|
+
const v = env[LAUNCHED_BY_ENV]?.trim();
|
|
2487
|
+
return v && LAUNCHED_BY.test(v) ? v : void 0;
|
|
2488
|
+
}
|
|
2489
|
+
function readHook(adapter, input) {
|
|
2490
|
+
const r = adapter.fromHook(input);
|
|
2491
|
+
if (r && !r.session.parent_id) {
|
|
2492
|
+
const launcher = launchedBy(input.env);
|
|
2493
|
+
if (launcher && launcher !== `${adapter.name}:${r.session.id}`) r.session.launched_by = launcher;
|
|
2494
|
+
}
|
|
2495
|
+
return r;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2424
2498
|
// ../core/src/outbox.ts
|
|
2425
2499
|
import {
|
|
2426
2500
|
appendFileSync,
|
|
@@ -2863,8 +2937,8 @@ var DATA_ALLOW = {
|
|
|
2863
2937
|
"session.ended": { 0: ["reason"] },
|
|
2864
2938
|
"session.backfill": { 0: ["started_at", "last_at", "turns"] },
|
|
2865
2939
|
"session.forgotten": { 0: [] },
|
|
2866
|
-
"turn.started": { 0: ["turn_id"], 1: ["prompt_chars"] },
|
|
2867
|
-
"turn.ended": { 0: ["turn_id", "reason", "ms"], 1: ["error"] },
|
|
2940
|
+
"turn.started": { 0: ["turn_id", "submitted_by", "injected"], 1: ["prompt_chars"] },
|
|
2941
|
+
"turn.ended": { 0: ["turn_id", "reason", "ms", "background"], 1: ["error"] },
|
|
2868
2942
|
"turn.transcript": { 2: ["turn", "user", "assistant", "at"] },
|
|
2869
2943
|
"turn.progress": { 2: ["turn", "user", "assistant", "at"] },
|
|
2870
2944
|
"tool.started": { 1: ["tool", "call_id", "turn_id", "agent_id"], 3: ["input"] },
|
|
@@ -2888,7 +2962,9 @@ var SESSION_ALLOW = [
|
|
|
2888
2962
|
"title_source",
|
|
2889
2963
|
"url",
|
|
2890
2964
|
"account_id",
|
|
2891
|
-
"
|
|
2965
|
+
"attended",
|
|
2966
|
+
"parent_id",
|
|
2967
|
+
"launched_by"
|
|
2892
2968
|
];
|
|
2893
2969
|
var MAX_SIDE = 2e4;
|
|
2894
2970
|
var MAX_IO = 64 * 1024;
|
|
@@ -3017,6 +3093,49 @@ import path14 from "node:path";
|
|
|
3017
3093
|
// src/control/aliases.ts
|
|
3018
3094
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
3019
3095
|
import path12 from "node:path";
|
|
3096
|
+
|
|
3097
|
+
// src/secrets.ts
|
|
3098
|
+
import { spawnSync } from "node:child_process";
|
|
3099
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
3100
|
+
var SERVICE = "sessionpipe";
|
|
3101
|
+
var defaultRunner = (cmd, args, input) => {
|
|
3102
|
+
const r = spawnSync(cmd, args, {
|
|
3103
|
+
input: input ?? "",
|
|
3104
|
+
encoding: "utf8",
|
|
3105
|
+
timeout: 8e3,
|
|
3106
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
3107
|
+
});
|
|
3108
|
+
return { status: r.error ? null : r.status, stdout: r.stdout ?? "" };
|
|
3109
|
+
};
|
|
3110
|
+
var sinkAccount = (name, what = "token") => {
|
|
3111
|
+
const scope = process.env.SESSIONPIPE_CONFIG ? `@${createHash5("sha256").update(configFile()).digest("hex").slice(0, 8)}` : "";
|
|
3112
|
+
return `sink:${name}:${what}${scope}`;
|
|
3113
|
+
};
|
|
3114
|
+
function secretGet(store, account, run = defaultRunner) {
|
|
3115
|
+
const r = store === "keychain" ? run("security", ["find-generic-password", "-s", SERVICE, "-a", account, "-w"]) : run("secret-tool", ["lookup", "service", SERVICE, "account", account]);
|
|
3116
|
+
if (r.status !== 0) return null;
|
|
3117
|
+
const v = r.stdout.replace(/\r?\n$/, "");
|
|
3118
|
+
return v || null;
|
|
3119
|
+
}
|
|
3120
|
+
function sinkWithSecrets(s, run = defaultRunner) {
|
|
3121
|
+
if (!s.token_in) return s;
|
|
3122
|
+
const token = secretGet(s.token_in, sinkAccount(s.name), run);
|
|
3123
|
+
if (!token) return null;
|
|
3124
|
+
const secret = secretGet(s.token_in, sinkAccount(s.name, "secret"), run);
|
|
3125
|
+
return { ...s, token, ...secret ? { secret } : {} };
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
// src/control/store.ts
|
|
3129
|
+
function startOptionsOf(v) {
|
|
3130
|
+
const o = v;
|
|
3131
|
+
if (!o || typeof o !== "object" || levelRank(o.permission) < 0 && o.permission !== "inherit") return null;
|
|
3132
|
+
return {
|
|
3133
|
+
permission: o.permission,
|
|
3134
|
+
...typeof o.model === "string" && MODEL_RE.test(o.model) ? { model: o.model } : {}
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
// src/control/aliases.ts
|
|
3020
3139
|
var aliasFile = (controlDir) => path12.join(controlDir, "aliases.json");
|
|
3021
3140
|
function readAliases(file) {
|
|
3022
3141
|
try {
|
|
@@ -3026,7 +3145,7 @@ function readAliases(file) {
|
|
|
3026
3145
|
for (const [k, v] of Object.entries(j)) {
|
|
3027
3146
|
const a = v;
|
|
3028
3147
|
if (a && typeof a.id === "string" && a.id && typeof a.cwd === "string")
|
|
3029
|
-
out[k] = { id: a.id, cwd: a.cwd, at: typeof a.at === "string" ? a.at : "" };
|
|
3148
|
+
out[k] = { id: a.id, cwd: a.cwd, at: typeof a.at === "string" ? a.at : "", ...startOptionsOf(a) };
|
|
3030
3149
|
}
|
|
3031
3150
|
return out;
|
|
3032
3151
|
} catch {
|
|
@@ -3079,10 +3198,10 @@ function ask(sock, req, timeoutMs) {
|
|
|
3079
3198
|
}
|
|
3080
3199
|
|
|
3081
3200
|
// src/http-sink.ts
|
|
3082
|
-
import { createHash as
|
|
3201
|
+
import { createHash as createHash6, createHmac } from "node:crypto";
|
|
3083
3202
|
var TIMEOUT_MS = 15e3;
|
|
3084
3203
|
function webhookId(events) {
|
|
3085
|
-
return `msg_${
|
|
3204
|
+
return `msg_${createHash6("sha256").update(events.map((e) => e.id).join(",")).digest("base64url").slice(0, 32)}`;
|
|
3086
3205
|
}
|
|
3087
3206
|
function retryAfterMs(header, now = Date.now()) {
|
|
3088
3207
|
if (header === null || header.trim() === "") return 6e4;
|
|
@@ -3173,37 +3292,6 @@ var HttpSink = class {
|
|
|
3173
3292
|
}
|
|
3174
3293
|
};
|
|
3175
3294
|
|
|
3176
|
-
// src/secrets.ts
|
|
3177
|
-
import { spawnSync } from "node:child_process";
|
|
3178
|
-
import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
|
|
3179
|
-
var SERVICE = "sessionpipe";
|
|
3180
|
-
var defaultRunner = (cmd, args, input) => {
|
|
3181
|
-
const r = spawnSync(cmd, args, {
|
|
3182
|
-
input: input ?? "",
|
|
3183
|
-
encoding: "utf8",
|
|
3184
|
-
timeout: 8e3,
|
|
3185
|
-
stdio: ["pipe", "pipe", "ignore"]
|
|
3186
|
-
});
|
|
3187
|
-
return { status: r.error ? null : r.status, stdout: r.stdout ?? "" };
|
|
3188
|
-
};
|
|
3189
|
-
var sinkAccount = (name, what = "token") => {
|
|
3190
|
-
const scope = process.env.SESSIONPIPE_CONFIG ? `@${createHash6("sha256").update(configFile()).digest("hex").slice(0, 8)}` : "";
|
|
3191
|
-
return `sink:${name}:${what}${scope}`;
|
|
3192
|
-
};
|
|
3193
|
-
function secretGet(store, account, run = defaultRunner) {
|
|
3194
|
-
const r = store === "keychain" ? run("security", ["find-generic-password", "-s", SERVICE, "-a", account, "-w"]) : run("secret-tool", ["lookup", "service", SERVICE, "account", account]);
|
|
3195
|
-
if (r.status !== 0) return null;
|
|
3196
|
-
const v = r.stdout.replace(/\r?\n$/, "");
|
|
3197
|
-
return v || null;
|
|
3198
|
-
}
|
|
3199
|
-
function sinkWithSecrets(s, run = defaultRunner) {
|
|
3200
|
-
if (!s.token_in) return s;
|
|
3201
|
-
const token = secretGet(s.token_in, sinkAccount(s.name), run);
|
|
3202
|
-
if (!token) return null;
|
|
3203
|
-
const secret = secretGet(s.token_in, sinkAccount(s.name, "secret"), run);
|
|
3204
|
-
return { ...s, token, ...secret ? { secret } : {} };
|
|
3205
|
-
}
|
|
3206
|
-
|
|
3207
3295
|
// src/run.ts
|
|
3208
3296
|
async function tellDaemon(state, job, session, cwd, transcript) {
|
|
3209
3297
|
const sock = socketPath(state);
|
|
@@ -3359,6 +3447,12 @@ function openTurn(read, o) {
|
|
|
3359
3447
|
};
|
|
3360
3448
|
}
|
|
3361
3449
|
var MAX_TURN_SIDE = 2e4;
|
|
3450
|
+
var JOB_OWN_ENV = [
|
|
3451
|
+
"CLAUDE_CODE_SESSION_ATTENDED",
|
|
3452
|
+
"CLAUDE_CODE_HOST_SESSION_ID",
|
|
3453
|
+
"SESSIONPIPE_CONTROL_JOB",
|
|
3454
|
+
"SESSIONPIPE_LAUNCHED_BY"
|
|
3455
|
+
];
|
|
3362
3456
|
async function runJob(job, opts = {}) {
|
|
3363
3457
|
const state = opts.state ?? stateDir();
|
|
3364
3458
|
const cfg = readConfig();
|
|
@@ -3367,9 +3461,20 @@ async function runJob(job, opts = {}) {
|
|
|
3367
3461
|
log(state, `${job.harness} ${job.event}: no adapter for harness "${job.harness}"; event dropped`);
|
|
3368
3462
|
return { events: [], delivered: {} };
|
|
3369
3463
|
}
|
|
3370
|
-
const
|
|
3464
|
+
const env = { ...process.env };
|
|
3465
|
+
for (const k of JOB_OWN_ENV) delete env[k];
|
|
3466
|
+
const r = readHook(adapter, { argv: job.argv, stdin: job.stdin, env: { ...env, ...job.env }, cwd: job.cwd });
|
|
3371
3467
|
if (!r || !r.session.id) {
|
|
3372
|
-
|
|
3468
|
+
let keys = [];
|
|
3469
|
+
try {
|
|
3470
|
+
const payload = JSON.parse(job.argv.find((a) => a.startsWith("{")) ?? job.stdin);
|
|
3471
|
+
if (payload && typeof payload === "object" && !Array.isArray(payload)) keys = Object.keys(payload);
|
|
3472
|
+
} catch {
|
|
3473
|
+
}
|
|
3474
|
+
log(
|
|
3475
|
+
state,
|
|
3476
|
+
`${job.harness} ${job.event}: the ${job.harness} adapter did not claim this payload; event dropped; keys: ${keys.join(", ") || "(none)"}`
|
|
3477
|
+
);
|
|
3373
3478
|
return { events: [], delivered: {} };
|
|
3374
3479
|
}
|
|
3375
3480
|
const id = receiverIdOf(readAliases(aliasFile(path14.join(state, "control"))), job.harness, r.session.id) ?? r.session.id;
|
|
@@ -3421,7 +3526,8 @@ async function runJob(job, opts = {}) {
|
|
|
3421
3526
|
seq: 0,
|
|
3422
3527
|
machine: machineName(cfg, os3.hostname()),
|
|
3423
3528
|
...cwdRaw ? { cwd: tilde(cwdRaw) } : {},
|
|
3424
|
-
...r.session.model ? { model: r.session.model } : {}
|
|
3529
|
+
...r.session.model ? { model: r.session.model } : {},
|
|
3530
|
+
...r.session.launched_by ? { launched_by: r.session.launched_by } : {}
|
|
3425
3531
|
};
|
|
3426
3532
|
const version = facts.get(job.harness, id).harness_version ?? void 0;
|
|
3427
3533
|
for (const a of r.events) {
|