sessionpipe-core 0.12.0 → 0.13.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/control.js +26 -11
- package/dist/control.js.map +3 -3
- package/dist/index.js +271 -71
- package/dist/index.js.map +4 -4
- package/dist/schema/v1.d.ts +75 -1
- package/dist/schema/v1.d.ts.map +1 -1
- package/dist/schema.js +77 -10
- package/dist/schema.js.map +2 -2
- package/dist/service.js +1 -1
- package/dist/src/adapters/acp-control.d.ts.map +1 -1
- package/dist/src/adapters/claude-code-control.d.ts +136 -6
- package/dist/src/adapters/claude-code-control.d.ts.map +1 -1
- package/dist/src/adapters/headless.d.ts +3 -1
- package/dist/src/adapters/headless.d.ts.map +1 -1
- package/dist/src/adapters/types.d.ts +6 -0
- package/dist/src/adapters/types.d.ts.map +1 -1
- package/dist/src/control/verify.d.ts +3 -0
- package/dist/src/control/verify.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/launched-by.d.ts +20 -3
- package/dist/src/launched-by.d.ts.map +1 -1
- package/dist/src/privacy/filter.d.ts.map +1 -1
- package/dist/src/readers/transcripts.d.ts +11 -1
- package/dist/src/readers/transcripts.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// sessionpipe-core 0.
|
|
1
|
+
// sessionpipe-core 0.13.0 · Apache-2.0 · https://sessionpipe.org
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __export = (target, all) => {
|
|
4
4
|
for (var name in all)
|
|
@@ -211,7 +211,14 @@ ${m.text}`;
|
|
|
211
211
|
continue;
|
|
212
212
|
}
|
|
213
213
|
if (cur) turns.push(cur);
|
|
214
|
-
cur = {
|
|
214
|
+
cur = {
|
|
215
|
+
user: m.text,
|
|
216
|
+
assistant: "",
|
|
217
|
+
at: m.at,
|
|
218
|
+
startLine: m.line,
|
|
219
|
+
endLine: m.line,
|
|
220
|
+
...m.injected ? { injected: true } : {}
|
|
221
|
+
};
|
|
215
222
|
} else {
|
|
216
223
|
if (!cur) cur = { user: "", assistant: "", at: m.at, startLine: m.line, endLine: m.line };
|
|
217
224
|
cur.assistant += (cur.assistant ? "\n\n" : "") + m.text;
|
|
@@ -221,10 +228,17 @@ ${m.text}`;
|
|
|
221
228
|
if (cur?.assistant) turns.push(cur);
|
|
222
229
|
const line = cur && !cur.assistant ? cur.startLine : endLine;
|
|
223
230
|
const out = {
|
|
224
|
-
turns: turns.map((t) => ({
|
|
231
|
+
turns: turns.map((t) => ({
|
|
232
|
+
user: t.user,
|
|
233
|
+
assistant: t.assistant,
|
|
234
|
+
at: t.at,
|
|
235
|
+
endLine: t.endLine,
|
|
236
|
+
...t.injected ? { injected: true } : {}
|
|
237
|
+
})),
|
|
225
238
|
line
|
|
226
239
|
};
|
|
227
|
-
if (cur && !cur.assistant && cur.user)
|
|
240
|
+
if (cur && !cur.assistant && cur.user)
|
|
241
|
+
out.open = { user: cur.user, at: cur.at, ...cur.injected ? { injected: true } : {} };
|
|
228
242
|
return out;
|
|
229
243
|
}
|
|
230
244
|
var isInjected = (text) => /^<[a-z_-]+(?:\s[^>]*)?>/i.test(text) && /<\/[a-z_-]+>\s*$/i.test(text) || /^<!--\s/.test(text) || /^<command-/.test(text);
|
|
@@ -247,27 +261,51 @@ var textParts = (c, kinds) => {
|
|
|
247
261
|
(b) => b && typeof b === "object" && kinds.includes(b.type ?? "") && typeof b.text === "string"
|
|
248
262
|
).map((b) => b.text).join("\n");
|
|
249
263
|
};
|
|
264
|
+
var SPOKEN = /* @__PURE__ */ new Set(["human", "peer"]);
|
|
265
|
+
var PEER_INTRO = /sent a message[^\n]*:$/;
|
|
266
|
+
var PEER_OUTRO = "\n\nThis came from another ";
|
|
267
|
+
var ENVELOPE = /^<cross-session-message\b[^>]*>\n([\s\S]*)\n<\/cross-session-message>$/;
|
|
268
|
+
function peerAsk(origin, text) {
|
|
269
|
+
const body = origin?.body;
|
|
270
|
+
let t = typeof body === "string" && body.trim() ? body : text;
|
|
271
|
+
if (t !== body) {
|
|
272
|
+
const nl = t.indexOf("\n");
|
|
273
|
+
if (nl > 0 && PEER_INTRO.test(t.slice(0, nl))) t = t.slice(nl + 1);
|
|
274
|
+
const outro = t.indexOf(PEER_OUTRO);
|
|
275
|
+
if (outro > 0) t = t.slice(0, outro);
|
|
276
|
+
}
|
|
277
|
+
return (ENVELOPE.exec(t.trim())?.[1] ?? t).trim();
|
|
278
|
+
}
|
|
250
279
|
var queuedPrompt = (a) => {
|
|
251
280
|
if (!a || typeof a !== "object") return "";
|
|
252
281
|
const q = a;
|
|
253
282
|
if (q.type !== "queued_command" || (q.commandMode ?? "prompt") !== "prompt") return "";
|
|
254
|
-
|
|
255
|
-
|
|
283
|
+
const kind = q.origin?.kind ?? "human";
|
|
284
|
+
if (!SPOKEN.has(kind)) return "";
|
|
285
|
+
const text = textParts(q.prompt, ["text"]).trim();
|
|
286
|
+
return kind === "peer" ? peerAsk(q.origin, text) : text;
|
|
256
287
|
};
|
|
288
|
+
var channelText = (text) => /^<channel\b[^>]*>([\s\S]*)<\/channel>$/.exec(text)?.[1]?.trim() ?? "";
|
|
257
289
|
function readClaude(lines, from) {
|
|
258
290
|
const msgs = [];
|
|
259
291
|
for (let i = from; i < lines.length; i++) {
|
|
260
292
|
const j = lines[i] ? parse(lines[i]) : null;
|
|
261
293
|
if (!j || j.isSidechain) continue;
|
|
262
294
|
const origin = j.origin;
|
|
263
|
-
|
|
264
|
-
|
|
295
|
+
const channel = j.type === "user" && origin?.kind === "channel";
|
|
296
|
+
const peer = origin?.kind === "peer";
|
|
297
|
+
if (j.type === "user" && (j.isCompactSummary || j.repeatsCompactSummary)) continue;
|
|
298
|
+
if (j.type === "user" && !channel && !peer && (j.isMeta || origin?.kind && origin.kind !== "human")) continue;
|
|
265
299
|
const at = Date.parse(String(j.timestamp ?? "")) || Date.now();
|
|
266
300
|
const c = j.message?.content;
|
|
267
|
-
if (
|
|
268
|
-
const text = textParts(c, ["text"]).trim();
|
|
301
|
+
if (channel) {
|
|
302
|
+
const text = channelText(textParts(c, ["text"]).trim());
|
|
303
|
+
if (text) msgs.push({ role: "user", text, at, line: i, injected: true });
|
|
304
|
+
} else if (j.type === "user") {
|
|
305
|
+
const raw = textParts(c, ["text"]).trim();
|
|
306
|
+
const text = peer ? peerAsk(origin, raw) : raw;
|
|
269
307
|
if (!text || isInjected(text)) continue;
|
|
270
|
-
msgs.push({ role: "user", text, at, line: i });
|
|
308
|
+
msgs.push({ role: "user", text, at, line: i, ...peer ? { injected: true } : {} });
|
|
271
309
|
} else if (j.type === "assistant" && Array.isArray(c)) {
|
|
272
310
|
const text = textParts(c, ["text"]).trim();
|
|
273
311
|
if (text) msgs.push({ role: "assistant", text, at, line: i });
|
|
@@ -1635,6 +1673,41 @@ import path7 from "node:path";
|
|
|
1635
1673
|
import { spawn } from "node:child_process";
|
|
1636
1674
|
import { accessSync, constants, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
|
|
1637
1675
|
import path6 from "node:path";
|
|
1676
|
+
|
|
1677
|
+
// src/launched-by.ts
|
|
1678
|
+
var LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
1679
|
+
var DELEGATED_BY_ENV = "SESSIONPIPE_ASKED_BY";
|
|
1680
|
+
var ASK_CHAIN_ENV = "SESSIONPIPE_ASK_CHAIN";
|
|
1681
|
+
var LINEAGE_ENV = [LAUNCHED_BY_ENV, DELEGATED_BY_ENV, ASK_CHAIN_ENV];
|
|
1682
|
+
var SESSION_REF = /^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/;
|
|
1683
|
+
function withoutLineage(env) {
|
|
1684
|
+
const e = { ...env };
|
|
1685
|
+
for (const k of LINEAGE_ENV) delete e[k];
|
|
1686
|
+
return e;
|
|
1687
|
+
}
|
|
1688
|
+
function refIn(env, name) {
|
|
1689
|
+
const v = env[name]?.trim();
|
|
1690
|
+
return v && SESSION_REF.test(v) ? v : void 0;
|
|
1691
|
+
}
|
|
1692
|
+
function launchedBy(env) {
|
|
1693
|
+
return refIn(env, LAUNCHED_BY_ENV);
|
|
1694
|
+
}
|
|
1695
|
+
function delegatedBy(env) {
|
|
1696
|
+
return refIn(env, DELEGATED_BY_ENV);
|
|
1697
|
+
}
|
|
1698
|
+
function readHook(adapter, input) {
|
|
1699
|
+
const r = adapter.fromHook(input);
|
|
1700
|
+
if (r && !r.session.parent_id) {
|
|
1701
|
+
const self = `${adapter.name}:${r.session.id}`;
|
|
1702
|
+
const launcher = launchedBy(input.env);
|
|
1703
|
+
if (launcher && launcher !== self) r.session.launched_by = launcher;
|
|
1704
|
+
const asker = delegatedBy(input.env);
|
|
1705
|
+
if (asker && asker !== self) r.session.delegated_by = asker;
|
|
1706
|
+
}
|
|
1707
|
+
return r;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
// src/adapters/headless.ts
|
|
1638
1711
|
var JOB_TIMEOUT_MS = 30 * 6e4;
|
|
1639
1712
|
var OUT_CAP = 1024 * 1024;
|
|
1640
1713
|
function isExe(p) {
|
|
@@ -1682,7 +1755,7 @@ function probe(bin, args) {
|
|
|
1682
1755
|
return s ? { ...s, shell: false } : { file: [`"${bin}"`, ...args].join(" "), args: [], shell: true };
|
|
1683
1756
|
}
|
|
1684
1757
|
function jobEnv(env = process.env) {
|
|
1685
|
-
return { ...env, SESSIONPIPE_CONTROL_JOB: "1" };
|
|
1758
|
+
return { ...withoutLineage(env), SESSIONPIPE_CONTROL_JOB: "1" };
|
|
1686
1759
|
}
|
|
1687
1760
|
function runHeadless(bin, args, o) {
|
|
1688
1761
|
return new Promise((resolve) => {
|
|
@@ -1904,7 +1977,9 @@ function startAcp(o) {
|
|
|
1904
1977
|
try {
|
|
1905
1978
|
child = spawn2(c.file, c.args, {
|
|
1906
1979
|
cwd: o.cwd,
|
|
1907
|
-
env
|
|
1980
|
+
// The caller's env as given (the daemon's is jobEnv's already, with the ask's
|
|
1981
|
+
// lineage on top), marked as a control job.
|
|
1982
|
+
env: { ...o.env, SESSIONPIPE_CONTROL_JOB: "1" },
|
|
1908
1983
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1909
1984
|
detached: process.platform !== "win32",
|
|
1910
1985
|
windowsHide: true
|
|
@@ -2591,7 +2666,10 @@ var reading = () => new AgyReading();
|
|
|
2591
2666
|
// src/adapters/claude-code-control.ts
|
|
2592
2667
|
var claude_code_control_exports = {};
|
|
2593
2668
|
__export(claude_code_control_exports, {
|
|
2669
|
+
CLAUDE_MODES: () => CLAUDE_MODES,
|
|
2594
2670
|
JOB_TIMEOUT_MS: () => JOB_TIMEOUT_MS,
|
|
2671
|
+
MODE_RANK: () => MODE_RANK,
|
|
2672
|
+
NO_HOME_SETTINGS: () => NO_HOME_SETTINGS,
|
|
2595
2673
|
ceilingLevel: () => ceilingLevel,
|
|
2596
2674
|
claudeArgs: () => claudeArgs,
|
|
2597
2675
|
claudeEnv: () => claudeEnv,
|
|
@@ -2601,17 +2679,26 @@ __export(claude_code_control_exports, {
|
|
|
2601
2679
|
detectCaps: () => detectCaps,
|
|
2602
2680
|
findClaude: () => findClaude,
|
|
2603
2681
|
findTranscript: () => findTranscript,
|
|
2682
|
+
findTranscripts: () => findTranscripts,
|
|
2683
|
+
homeSettings: () => homeSettings,
|
|
2684
|
+
hookMode: () => hookMode,
|
|
2604
2685
|
isUuid: () => isUuid,
|
|
2605
2686
|
liveProcess: () => liveProcess,
|
|
2687
|
+
liveRecord: () => liveRecord,
|
|
2688
|
+
liveRecords: () => liveRecords,
|
|
2606
2689
|
loginCommand: () => loginCommand,
|
|
2607
2690
|
loginHint: () => loginHint,
|
|
2608
2691
|
modeFlags: () => modeFlags,
|
|
2692
|
+
modeRank: () => modeRank,
|
|
2609
2693
|
offeredLevels: () => offeredLevels2,
|
|
2610
2694
|
outputArgs: () => outputArgs,
|
|
2611
2695
|
parseAuthStatus: () => parseAuthStatus,
|
|
2612
2696
|
parseCaps: () => parseCaps,
|
|
2613
2697
|
parseResult: () => parseResult,
|
|
2698
|
+
peerClass: () => peerClass,
|
|
2614
2699
|
recentlyWritten: () => recentlyWritten,
|
|
2700
|
+
relaunchMode: () => relaunchMode,
|
|
2701
|
+
resolveHome: () => resolveHome,
|
|
2615
2702
|
runClaude: () => runClaude,
|
|
2616
2703
|
sessionFolder: () => sessionFolder
|
|
2617
2704
|
});
|
|
@@ -2630,10 +2717,10 @@ var MODEL_RE = /^[A-Za-z0-9][A-Za-z0-9._:/@[\]-]*$/;
|
|
|
2630
2717
|
var START_PERMISSIONS = ["read", "safe", "edits", "auto"];
|
|
2631
2718
|
var levelRank = (l) => START_PERMISSIONS.indexOf(l);
|
|
2632
2719
|
var FIELDS = {
|
|
2633
|
-
prompt: ["text", "files"],
|
|
2720
|
+
prompt: ["text", "files", "reply_to"],
|
|
2634
2721
|
"permission.answer": ["for", "decision"],
|
|
2635
2722
|
cancel: [],
|
|
2636
|
-
start: ["text", "cwd", "files", "permission", "model"],
|
|
2723
|
+
start: ["text", "cwd", "files", "permission", "model", "reply_to"],
|
|
2637
2724
|
"key.add": ["key", "name"],
|
|
2638
2725
|
pool: ["pool_action", "pool_account", "pool_order", "pool_code"]
|
|
2639
2726
|
};
|
|
@@ -2705,6 +2792,8 @@ var LEVEL_MODE = {
|
|
|
2705
2792
|
};
|
|
2706
2793
|
function modeFlags(level, caps) {
|
|
2707
2794
|
if (level === "inherit") return { args: [] };
|
|
2795
|
+
if (caps.unread)
|
|
2796
|
+
return { error: `this machine couldn't read its Claude Code's options (${caps.unread}); try again in a minute` };
|
|
2708
2797
|
if (level === "auto" && !caps.modes.includes("auto"))
|
|
2709
2798
|
return { error: "this machine is in auto mode, but its Claude Code has no auto permission mode" };
|
|
2710
2799
|
if (level !== "safe") {
|
|
@@ -2724,6 +2813,7 @@ function modeFlags(level, caps) {
|
|
|
2724
2813
|
}
|
|
2725
2814
|
var ceilingLevel = (mode) => mode === "inherit" ? "safe" : mode;
|
|
2726
2815
|
function offeredLevels2(mode, caps) {
|
|
2816
|
+
if (caps.unread) return [];
|
|
2727
2817
|
return START_PERMISSIONS.filter(
|
|
2728
2818
|
(l) => levelRank(l) <= levelRank(ceilingLevel(mode)) && (l === "safe" || caps.modes.includes(LEVEL_MODE[l]))
|
|
2729
2819
|
);
|
|
@@ -2749,7 +2839,7 @@ function claudeArgs(o) {
|
|
|
2749
2839
|
};
|
|
2750
2840
|
}
|
|
2751
2841
|
function claudeEnv(configDir, env = process.env) {
|
|
2752
|
-
const e =
|
|
2842
|
+
const e = withoutLineage(env);
|
|
2753
2843
|
for (const k of [
|
|
2754
2844
|
"CLAUDECODE",
|
|
2755
2845
|
"CLAUDE_CODE_SESSION_ID",
|
|
@@ -2806,43 +2896,73 @@ function loginHint(configDir, platform = process.platform) {
|
|
|
2806
2896
|
return `Claude Code (${shown}) isn't signed in as this machine's background service sees it. On a Mac its login lives in the login keychain, which a background service can read only while someone is logged in at the screen: log in at the Mac, or run ${login} there.`;
|
|
2807
2897
|
return `Claude Code (${shown}) isn't signed in on this machine: run ${login} there.`;
|
|
2808
2898
|
}
|
|
2809
|
-
function detectCaps(bin) {
|
|
2810
|
-
let help = "";
|
|
2899
|
+
function detectCaps(bin, timeoutMs = 3e4) {
|
|
2811
2900
|
const c = probe(bin, ["--help"]);
|
|
2812
2901
|
try {
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2902
|
+
return parseCaps(
|
|
2903
|
+
execFileSync3(c.file, c.args, {
|
|
2904
|
+
encoding: "utf8",
|
|
2905
|
+
timeout: timeoutMs,
|
|
2906
|
+
env: claudeEnv(),
|
|
2907
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2908
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
2909
|
+
shell: c.shell
|
|
2910
|
+
})
|
|
2911
|
+
);
|
|
2821
2912
|
} catch (e) {
|
|
2822
|
-
|
|
2913
|
+
const err = e;
|
|
2914
|
+
const caps = parseCaps(String(err?.stdout || ""));
|
|
2915
|
+
if (caps.hasMode) return caps;
|
|
2916
|
+
const why = err?.code === "ETIMEDOUT" ? `timed out after ${timeoutMs / 1e3} s` : "failed";
|
|
2917
|
+
return { ...caps, unread: `\`${path10.basename(bin)} --help\` ${why}` };
|
|
2823
2918
|
}
|
|
2824
|
-
return parseCaps(help);
|
|
2825
2919
|
}
|
|
2826
|
-
function
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2920
|
+
function transcriptIn(session, dir) {
|
|
2921
|
+
let projects = [];
|
|
2922
|
+
try {
|
|
2923
|
+
projects = readdirSync4(path10.join(dir, "projects"), { withFileTypes: true });
|
|
2924
|
+
} catch {
|
|
2925
|
+
return null;
|
|
2926
|
+
}
|
|
2927
|
+
for (const p of projects) {
|
|
2928
|
+
if (!p.isDirectory()) continue;
|
|
2929
|
+
const file = path10.join(dir, "projects", p.name, `${session}.jsonl`);
|
|
2830
2930
|
try {
|
|
2831
|
-
|
|
2931
|
+
if (statSync5(file).isFile()) return { file, configDir: dir, project: p.name };
|
|
2832
2932
|
} catch {
|
|
2833
|
-
continue;
|
|
2834
|
-
}
|
|
2835
|
-
for (const p of projects) {
|
|
2836
|
-
if (!p.isDirectory()) continue;
|
|
2837
|
-
const file = path10.join(dir, "projects", p.name, `${session}.jsonl`);
|
|
2838
|
-
try {
|
|
2839
|
-
if (statSync5(file).isFile()) return { file, configDir: dir, project: p.name };
|
|
2840
|
-
} catch {
|
|
2841
|
-
}
|
|
2842
2933
|
}
|
|
2843
2934
|
}
|
|
2844
2935
|
return null;
|
|
2845
2936
|
}
|
|
2937
|
+
function findTranscript(session, dirs) {
|
|
2938
|
+
if (!UUID_RE2.test(session)) return null;
|
|
2939
|
+
for (const dir of dirs) {
|
|
2940
|
+
const t = transcriptIn(session, dir);
|
|
2941
|
+
if (t) return t;
|
|
2942
|
+
}
|
|
2943
|
+
return null;
|
|
2944
|
+
}
|
|
2945
|
+
function findTranscripts(session, dirs) {
|
|
2946
|
+
if (!UUID_RE2.test(session)) return [];
|
|
2947
|
+
const out = [];
|
|
2948
|
+
for (const dir of dirs) {
|
|
2949
|
+
const t = transcriptIn(session, dir);
|
|
2950
|
+
if (t) out.push(t);
|
|
2951
|
+
}
|
|
2952
|
+
return out;
|
|
2953
|
+
}
|
|
2954
|
+
var homeName = (t) => path10.basename(t.configDir);
|
|
2955
|
+
function resolveHome(session, dirs) {
|
|
2956
|
+
const all = findTranscripts(session, dirs);
|
|
2957
|
+
if (!all.length) return null;
|
|
2958
|
+
if (all.length === 1) return { transcript: all[0] };
|
|
2959
|
+
const live = all.filter((t) => liveRecords(session, t.configDir).length > 0);
|
|
2960
|
+
if (live.length === 1) return { transcript: live[0] };
|
|
2961
|
+
return {
|
|
2962
|
+
ambiguous: [...new Set(all.map(homeName))].sort(),
|
|
2963
|
+
live: [...new Set(live.map(homeName))].sort()
|
|
2964
|
+
};
|
|
2965
|
+
}
|
|
2846
2966
|
var projectName = (cwd) => cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
2847
2967
|
function sessionFolder(t, cap2 = 8 * 1024 * 1024) {
|
|
2848
2968
|
let first = null;
|
|
@@ -2914,22 +3034,105 @@ function pidAlive(pid) {
|
|
|
2914
3034
|
return e.code === "EPERM";
|
|
2915
3035
|
}
|
|
2916
3036
|
}
|
|
2917
|
-
|
|
2918
|
-
|
|
3037
|
+
var registryRow = (file, configDir, j) => {
|
|
3038
|
+
const pid = Number(j.pid ?? path10.basename(file).slice(0, -5));
|
|
3039
|
+
const str2 = (v) => typeof v === "string" && v ? v : null;
|
|
3040
|
+
let keyFile = null;
|
|
2919
3041
|
try {
|
|
2920
|
-
|
|
3042
|
+
const want = new RegExp(`^${pid}\\.[0-9a-f]{64}\\.key$`);
|
|
3043
|
+
const hit = readdirSync4(path10.dirname(file)).find((n) => want.test(n));
|
|
3044
|
+
if (hit) keyFile = path10.join(path10.dirname(file), hit);
|
|
2921
3045
|
} catch {
|
|
2922
|
-
return false;
|
|
2923
3046
|
}
|
|
2924
|
-
|
|
3047
|
+
return {
|
|
3048
|
+
configDir,
|
|
3049
|
+
file,
|
|
3050
|
+
pid,
|
|
3051
|
+
socket: str2(j.messagingSocketPath),
|
|
3052
|
+
peerProtocol: typeof j.peerProtocol === "number" ? j.peerProtocol : null,
|
|
3053
|
+
procStart: str2(j.procStart),
|
|
3054
|
+
status: str2(j.status),
|
|
3055
|
+
kind: str2(j.kind),
|
|
3056
|
+
entrypoint: str2(j.entrypoint),
|
|
3057
|
+
keyFile
|
|
3058
|
+
};
|
|
3059
|
+
};
|
|
3060
|
+
function liveRecords(session, dirs) {
|
|
3061
|
+
const out = [];
|
|
3062
|
+
for (const dir of typeof dirs === "string" ? [dirs] : dirs) {
|
|
3063
|
+
let names = [];
|
|
2925
3064
|
try {
|
|
2926
|
-
|
|
2927
|
-
if (String(j.sessionId) !== session) continue;
|
|
2928
|
-
if (pidAlive(Number(j.pid ?? n.slice(0, -5)))) return true;
|
|
3065
|
+
names = readdirSync4(path10.join(dir, "sessions")).filter((n) => /^\d+\.json$/.test(n));
|
|
2929
3066
|
} catch {
|
|
3067
|
+
continue;
|
|
3068
|
+
}
|
|
3069
|
+
for (const n of names) {
|
|
3070
|
+
const file = path10.join(dir, "sessions", n);
|
|
3071
|
+
let j;
|
|
3072
|
+
try {
|
|
3073
|
+
j = JSON.parse(readFileSync6(file, "utf8"));
|
|
3074
|
+
} catch {
|
|
3075
|
+
continue;
|
|
3076
|
+
}
|
|
3077
|
+
if (String(j.sessionId) !== session) continue;
|
|
3078
|
+
const row = registryRow(file, dir, j);
|
|
3079
|
+
if (pidAlive(row.pid)) out.push(row);
|
|
2930
3080
|
}
|
|
2931
3081
|
}
|
|
2932
|
-
return
|
|
3082
|
+
return out;
|
|
3083
|
+
}
|
|
3084
|
+
function liveRecord(session, dirs) {
|
|
3085
|
+
const all = liveRecords(session, dirs);
|
|
3086
|
+
return all.length === 1 ? all[0] : null;
|
|
3087
|
+
}
|
|
3088
|
+
function liveProcess(session, configDir) {
|
|
3089
|
+
return liveRecords(session, configDir).length > 0;
|
|
3090
|
+
}
|
|
3091
|
+
var MODE_RANK = {
|
|
3092
|
+
plan: 0,
|
|
3093
|
+
default: 1,
|
|
3094
|
+
manual: 1,
|
|
3095
|
+
dontAsk: 1,
|
|
3096
|
+
acceptEdits: 2,
|
|
3097
|
+
auto: 3,
|
|
3098
|
+
bypassPermissions: 4
|
|
3099
|
+
};
|
|
3100
|
+
var CLAUDE_MODES = Object.keys(MODE_RANK);
|
|
3101
|
+
var modeRank = (m) => m && m in MODE_RANK ? MODE_RANK[m] : -1;
|
|
3102
|
+
function hookMode(payload) {
|
|
3103
|
+
if (!payload || typeof payload !== "object") return null;
|
|
3104
|
+
const p = payload;
|
|
3105
|
+
const v = typeof p.permission_mode === "string" ? p.permission_mode : p.permissionMode;
|
|
3106
|
+
return typeof v === "string" && CLAUDE_MODES.includes(v) ? v : null;
|
|
3107
|
+
}
|
|
3108
|
+
function peerClass(mode) {
|
|
3109
|
+
if (mode === "bypassPermissions") return "bypass";
|
|
3110
|
+
if (mode === "default" || mode === "manual" || mode === "dontAsk" || mode === "acceptEdits") return "prompting";
|
|
3111
|
+
return null;
|
|
3112
|
+
}
|
|
3113
|
+
var NO_HOME_SETTINGS = { defaultMode: null, disableAutoMode: false, disableBypass: false };
|
|
3114
|
+
function homeSettings(configDir, home = os5.homedir()) {
|
|
3115
|
+
const file = path10.join(configDir ?? path10.join(home, ".claude"), "settings.json");
|
|
3116
|
+
let j;
|
|
3117
|
+
try {
|
|
3118
|
+
j = JSON.parse(readFileSync6(file, "utf8"));
|
|
3119
|
+
} catch {
|
|
3120
|
+
return { ...NO_HOME_SETTINGS };
|
|
3121
|
+
}
|
|
3122
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) return { ...NO_HOME_SETTINGS };
|
|
3123
|
+
const p = j.permissions && typeof j.permissions === "object" ? j.permissions : {};
|
|
3124
|
+
const off = (k) => j[k] === "disable" || p[k] === "disable";
|
|
3125
|
+
return {
|
|
3126
|
+
defaultMode: typeof p.defaultMode === "string" && CLAUDE_MODES.includes(p.defaultMode) ? p.defaultMode : null,
|
|
3127
|
+
disableAutoMode: off("disableAutoMode"),
|
|
3128
|
+
disableBypass: off("disableBypassPermissionsMode")
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
3131
|
+
function relaunchMode(recorded, home) {
|
|
3132
|
+
if (recorded === "plan") return recorded;
|
|
3133
|
+
if ((recorded === "dontAsk" || recorded === "acceptEdits") && modeRank(home.defaultMode) >= modeRank(recorded))
|
|
3134
|
+
return recorded;
|
|
3135
|
+
return null;
|
|
2933
3136
|
}
|
|
2934
3137
|
function recentlyWritten(file, ourLastEnd, now = Date.now()) {
|
|
2935
3138
|
let m;
|
|
@@ -4347,22 +4550,6 @@ function makeEvent(a, ctx) {
|
|
|
4347
4550
|
};
|
|
4348
4551
|
}
|
|
4349
4552
|
|
|
4350
|
-
// src/launched-by.ts
|
|
4351
|
-
var LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
4352
|
-
var LAUNCHED_BY = /^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/;
|
|
4353
|
-
function launchedBy(env) {
|
|
4354
|
-
const v = env[LAUNCHED_BY_ENV]?.trim();
|
|
4355
|
-
return v && LAUNCHED_BY.test(v) ? v : void 0;
|
|
4356
|
-
}
|
|
4357
|
-
function readHook(adapter, input) {
|
|
4358
|
-
const r = adapter.fromHook(input);
|
|
4359
|
-
if (r && !r.session.parent_id) {
|
|
4360
|
-
const launcher = launchedBy(input.env);
|
|
4361
|
-
if (launcher && launcher !== `${adapter.name}:${r.session.id}`) r.session.launched_by = launcher;
|
|
4362
|
-
}
|
|
4363
|
-
return r;
|
|
4364
|
-
}
|
|
4365
|
-
|
|
4366
4553
|
// src/outbox.ts
|
|
4367
4554
|
import {
|
|
4368
4555
|
appendFileSync,
|
|
@@ -4801,6 +4988,8 @@ var TYPE_TIER = {
|
|
|
4801
4988
|
"subagent.ended": 1,
|
|
4802
4989
|
"context.compacted": 1,
|
|
4803
4990
|
"limits.observed": 1,
|
|
4991
|
+
"delegation.started": 0,
|
|
4992
|
+
"delegation.ended": 0,
|
|
4804
4993
|
native: 3
|
|
4805
4994
|
};
|
|
4806
4995
|
var DATA_ALLOW = {
|
|
@@ -4811,8 +5000,8 @@ var DATA_ALLOW = {
|
|
|
4811
5000
|
"session.forgotten": { 0: [] },
|
|
4812
5001
|
"turn.started": { 0: ["turn_id", "submitted_by", "injected"], 1: ["prompt_chars"] },
|
|
4813
5002
|
"turn.ended": { 0: ["turn_id", "reason", "ms", "background"], 1: ["error"] },
|
|
4814
|
-
"turn.transcript": { 2: ["turn", "user", "assistant", "at"] },
|
|
4815
|
-
"turn.progress": { 2: ["turn", "user", "assistant", "at"] },
|
|
5003
|
+
"turn.transcript": { 2: ["turn", "user", "assistant", "at", "injected"] },
|
|
5004
|
+
"turn.progress": { 2: ["turn", "user", "assistant", "at", "injected"] },
|
|
4816
5005
|
"tool.started": { 1: ["tool", "call_id", "turn_id", "agent_id"], 3: ["input"] },
|
|
4817
5006
|
"tool.ended": { 1: ["tool", "call_id", "turn_id", "agent_id", "ms", "ok", "error"], 3: ["input", "output"] },
|
|
4818
5007
|
"files.changed": { 1: ["paths"] },
|
|
@@ -4821,7 +5010,9 @@ var DATA_ALLOW = {
|
|
|
4821
5010
|
"subagent.started": { 1: ["agent_id", "agent_type"] },
|
|
4822
5011
|
"subagent.ended": { 1: ["agent_id", "agent_type"] },
|
|
4823
5012
|
"context.compacted": { 1: ["trigger"] },
|
|
4824
|
-
"limits.observed": { 1: ["windows", "plan", "account_id"] }
|
|
5013
|
+
"limits.observed": { 1: ["windows", "plan", "account_id"] },
|
|
5014
|
+
"delegation.started": { 0: ["ask_id", "via", "harness", "to"], 1: ["text"] },
|
|
5015
|
+
"delegation.ended": { 0: ["ask_id", "to", "ok", "ms", "error", "relayed"], 2: ["reply"] }
|
|
4825
5016
|
};
|
|
4826
5017
|
var SESSION_ALLOW = [
|
|
4827
5018
|
"id",
|
|
@@ -4837,7 +5028,8 @@ var SESSION_ALLOW = [
|
|
|
4837
5028
|
"account_id",
|
|
4838
5029
|
"attended",
|
|
4839
5030
|
"parent_id",
|
|
4840
|
-
"launched_by"
|
|
5031
|
+
"launched_by",
|
|
5032
|
+
"delegated_by"
|
|
4841
5033
|
];
|
|
4842
5034
|
var MAX_SIDE = 2e4;
|
|
4843
5035
|
var MAX_IO = 64 * 1024;
|
|
@@ -4876,6 +5068,8 @@ function filterEvent(event, tier, pii, opts = {}) {
|
|
|
4876
5068
|
if (data.input !== void 0) data.input = cap(data.input, MAX_IO);
|
|
4877
5069
|
if (data.output !== void 0) data.output = cap(data.output, MAX_IO);
|
|
4878
5070
|
if (typeof data.message === "string") data.message = cap(data.message, 200);
|
|
5071
|
+
if (event.type === "delegation.started" && typeof data.text === "string") data.text = cap(data.text, 200);
|
|
5072
|
+
if (event.type === "delegation.ended" && typeof data.reply === "string") data.reply = cap(data.reply, MAX_SIDE);
|
|
4879
5073
|
const rulesets = [];
|
|
4880
5074
|
let out = { ...event, tier, session, data, privacy: { rulesets, pii } };
|
|
4881
5075
|
if (tier > 0) {
|
|
@@ -4955,13 +5149,16 @@ var PROTOCOL_VERSION = 1;
|
|
|
4955
5149
|
export {
|
|
4956
5150
|
ADAPTERS,
|
|
4957
5151
|
AG_STALE_PRETOOL,
|
|
5152
|
+
ASK_CHAIN_ENV,
|
|
4958
5153
|
Cursors,
|
|
4959
5154
|
DEFAULT_CONFIG,
|
|
5155
|
+
DELEGATED_BY_ENV,
|
|
4960
5156
|
DEVIN_EVENTS,
|
|
4961
5157
|
FileSink,
|
|
4962
5158
|
HELLO_HARNESSES_MAX,
|
|
4963
5159
|
JOB_TIMEOUT_MS,
|
|
4964
5160
|
LAUNCHED_BY_ENV,
|
|
5161
|
+
LINEAGE_ENV,
|
|
4965
5162
|
Outbox,
|
|
4966
5163
|
PROTOCOL_VERSION,
|
|
4967
5164
|
REDACTED,
|
|
@@ -4983,6 +5180,7 @@ export {
|
|
|
4983
5180
|
codex,
|
|
4984
5181
|
codex_control_exports as codexControl,
|
|
4985
5182
|
configFile,
|
|
5183
|
+
delegatedBy,
|
|
4986
5184
|
deniedNote,
|
|
4987
5185
|
devin,
|
|
4988
5186
|
devinConfigDir,
|
|
@@ -5003,6 +5201,7 @@ export {
|
|
|
5003
5201
|
makeEvent,
|
|
5004
5202
|
notClaudeCode,
|
|
5005
5203
|
pairTurns,
|
|
5204
|
+
peerAsk,
|
|
5006
5205
|
processAlive,
|
|
5007
5206
|
readAntigravity,
|
|
5008
5207
|
readClaude,
|
|
@@ -5025,6 +5224,7 @@ export {
|
|
|
5025
5224
|
tilde,
|
|
5026
5225
|
ulid,
|
|
5027
5226
|
untilde,
|
|
5227
|
+
withoutLineage,
|
|
5028
5228
|
writeConfig
|
|
5029
5229
|
};
|
|
5030
5230
|
//# sourceMappingURL=index.js.map
|