sessionpipe 0.4.0 → 0.5.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 +10 -0
- package/dist/cli.js +3073 -2366
- package/dist/cli.js.map +4 -4
- package/dist/connect.d.ts +22 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/control/cli.d.ts +6 -1
- package/dist/control/cli.d.ts.map +1 -1
- package/dist/control/daemon.d.ts +21 -0
- package/dist/control/daemon.d.ts.map +1 -1
- package/dist/control/pair.d.ts +11 -0
- package/dist/control/pair.d.ts.map +1 -1
- package/dist/control/store.d.ts +18 -2
- package/dist/control/store.d.ts.map +1 -1
- package/dist/hook.js +1 -1
- package/dist/index.js +45 -7
- package/dist/index.js.map +4 -4
- package/dist/launcher.d.ts +31 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/run.d.ts +3 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/secrets.d.ts +39 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/worker.js +45 -7
- package/dist/worker.js.map +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** The home folder, or a folder that contains it (/, /Users), or the filesystem root. */
|
|
2
|
+
export declare function isBroad(dir: string, home: string): boolean;
|
|
3
|
+
export interface FolderChoice {
|
|
4
|
+
folders: string[];
|
|
5
|
+
/** Where they came from: the flags, the machine's own list, the folder this ran in,
|
|
6
|
+
* the folders recent sessions ran in, or nowhere. */
|
|
7
|
+
from: "flags" | "existing" | "here" | "recent" | "none";
|
|
8
|
+
}
|
|
9
|
+
/** `recent`: the folders this machine's sessions ran in, newest first. */
|
|
10
|
+
export declare function connectFolders(o: {
|
|
11
|
+
cwd: string;
|
|
12
|
+
home: string;
|
|
13
|
+
flags: string[];
|
|
14
|
+
existing: string[];
|
|
15
|
+
recent: string[];
|
|
16
|
+
exists?: (dir: string) => boolean;
|
|
17
|
+
max?: number;
|
|
18
|
+
}): FolderChoice;
|
|
19
|
+
/** The tier `connect` reports at: --tier when given; otherwise 2 (what a session board
|
|
20
|
+
* needs: the asks and the answers, secrets removed), never lowering a sink set higher. */
|
|
21
|
+
export declare function connectTier(flag: string | undefined, current: number | undefined): 0 | 1 | 2 | 3;
|
|
22
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAMA,yFAAyF;AACzF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1D;AAKD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;0DACsD;IACtD,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;CACzD;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,CAAC,EAAE;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,YAAY,CAiBf;AAED;2FAC2F;AAC3F,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAIhG"}
|
package/dist/control/cli.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { type Tier } from "@sessionpipe/core";
|
|
2
|
+
export declare const CONTROL_HELP = " sessionpipe control pair <receiver> [--folder DIR]\u2026 [--mode safe|auto] [--tier 0-3] [--token T] [--name N] [--no-service]\n sessionpipe control mode auto|safe (how sessions run when you message them)\n sessionpipe control status | keys [remove <id>] | off [<receiver>] | run\n sessionpipe wait [--session <harness>:<id>] (a session runs this in the background)";
|
|
2
3
|
export declare function controlMain(argv: string[], out: (s?: string) => void, distDir: string): Promise<void>;
|
|
3
4
|
export declare function waitMain(argv: string[], out: (s?: string) => void): Promise<void>;
|
|
5
|
+
/** Give a sink the key a receiver handed over at pairing. A sink for the receiver that
|
|
6
|
+
* has a key keeps it ("kept"); one without a key gets this one ("filled"); otherwise a
|
|
7
|
+
* new sink at `tier` ("added"). */
|
|
8
|
+
export declare function adoptSinkToken(url: string, token: string, tier: Tier, file?: string): "kept" | "filled" | "added";
|
|
4
9
|
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/control/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/control/cli.ts"],"names":[],"mappings":"AAKA,OAAO,EAA2D,KAAK,IAAI,EAAe,MAAM,mBAAmB,CAAC;AAepH,eAAO,MAAM,YAAY,2YAGkE,CAAC;AA+B5F,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2H3G;AAqDD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CASvF;AAED;;oCAEoC;AACpC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CASjH"}
|
package/dist/control/daemon.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { claudeControl } from "@sessionpipe/core";
|
|
|
2
2
|
import { type ControlConfig, type PairedReceiver } from "./store.js";
|
|
3
3
|
type Caps = claudeControl.Caps;
|
|
4
4
|
type RunResult = claudeControl.RunResult;
|
|
5
|
+
type Login = claudeControl.Login;
|
|
5
6
|
/** The message as the receiver carried it (control.json). */
|
|
6
7
|
export interface Carried {
|
|
7
8
|
id: string;
|
|
@@ -65,6 +66,14 @@ export interface DaemonDeps {
|
|
|
65
66
|
/** Close an SDK session idle this long (a held session costs ~300 MB). */
|
|
66
67
|
sdkIdleMs?: number;
|
|
67
68
|
env?: NodeJS.ProcessEnv;
|
|
69
|
+
/** Is Claude Code signed in for this account, as this process sees it? Asked before
|
|
70
|
+
* a headless run, so a login the daemon can't read (a macOS keychain with nobody at
|
|
71
|
+
* the screen) fails with what to do, not with Claude Code's "please run /login". */
|
|
72
|
+
login?: (configDir?: string) => Promise<Login>;
|
|
73
|
+
/** Read a receiver's machine token again: it may live in a keychain that was
|
|
74
|
+
* locked when the daemon started and has unlocked since. */
|
|
75
|
+
token?: (r: PairedReceiver) => string | null;
|
|
76
|
+
platform?: NodeJS.Platform;
|
|
68
77
|
}
|
|
69
78
|
export interface Status {
|
|
70
79
|
version: string;
|
|
@@ -124,10 +133,17 @@ export declare class ControlDaemon {
|
|
|
124
133
|
private readonly aborts;
|
|
125
134
|
/** Per receiver: the MCP servers its sessions may use unattended (its well-known). */
|
|
126
135
|
private readonly sessionTools;
|
|
136
|
+
/** Sessions a run of the daemon's own is working on right now (a start, a resume):
|
|
137
|
+
* a message for one waits for that run and resumes it — never a copy, which would
|
|
138
|
+
* set two agents on one task (2026-10-02: a "just merge when ready" sent while the
|
|
139
|
+
* start still ran forked a second agent that raced the first toward main). */
|
|
140
|
+
private readonly ownRuns;
|
|
127
141
|
private startsRunning;
|
|
128
142
|
private startTimes;
|
|
129
143
|
private procs;
|
|
130
144
|
private readonly procWaiters;
|
|
145
|
+
/** configDir → the last login answer and when (a yes is kept 10 minutes, a no 30 s). */
|
|
146
|
+
private readonly logins;
|
|
131
147
|
constructor(cfg: ControlConfig, dir: string, sock: string, deps: DaemonDeps);
|
|
132
148
|
start(): Promise<void>;
|
|
133
149
|
stop(): Promise<void>;
|
|
@@ -164,6 +180,9 @@ export declare class ControlDaemon {
|
|
|
164
180
|
private reroute;
|
|
165
181
|
/** Jobs for one session (and its copy) run one at a time, in order. */
|
|
166
182
|
private serial;
|
|
183
|
+
/** Null when Claude Code is signed in for this account (or can't say); otherwise what
|
|
184
|
+
* to tell the person. */
|
|
185
|
+
private loginProblem;
|
|
167
186
|
private headless;
|
|
168
187
|
private outcome;
|
|
169
188
|
private addKey;
|
|
@@ -179,6 +198,8 @@ export declare class ControlDaemon {
|
|
|
179
198
|
private answerStream;
|
|
180
199
|
/** How a headless run prints: streamed where this Claude Code can, else one JSON at the end. */
|
|
181
200
|
private outputArgs;
|
|
201
|
+
/** Mark a session as held by one of the daemon's runs while `fn` runs. */
|
|
202
|
+
private owning;
|
|
182
203
|
private limits;
|
|
183
204
|
/** One headless Claude Code process at a time per slot; the rest wait in order. */
|
|
184
205
|
private slot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/control/daemon.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,aAAa,EAAiB,MAAM,mBAAmB,CAAC;AAKjE,OAAO,EAGL,KAAK,aAAa,EAGlB,KAAK,cAAc,EAIpB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/control/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/control/pair.d.ts
CHANGED
|
@@ -46,11 +46,22 @@ export declare function serviceFiles(o: {
|
|
|
46
46
|
body: string;
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
|
+
export type Exec = (cmd: string, args: string[]) => string;
|
|
50
|
+
/** A systemd user service stops when its person's last login ends — closing the ssh
|
|
51
|
+
* session to a lab workstation or a cloud machine stopped the daemon with it — unless
|
|
52
|
+
* the user lingers. `loginctl enable-linger` for yourself needs no root on systemd's
|
|
53
|
+
* default policy; where it does, say the one command that does it. */
|
|
54
|
+
export declare function ensureLinger(user: string, exec?: Exec): {
|
|
55
|
+
on: boolean;
|
|
56
|
+
note: string;
|
|
57
|
+
};
|
|
49
58
|
/** Write and start the service for this platform. Returns what it did, in words. */
|
|
50
59
|
export declare function installService(o: {
|
|
51
60
|
node: string;
|
|
52
61
|
cli: string;
|
|
53
62
|
env?: NodeJS.ProcessEnv;
|
|
63
|
+
exec?: Exec;
|
|
64
|
+
platform?: NodeJS.Platform;
|
|
54
65
|
}): string;
|
|
55
66
|
export declare function uninstallService(env?: NodeJS.ProcessEnv): void;
|
|
56
67
|
//# sourceMappingURL=pair.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pair.d.ts","sourceRoot":"","sources":["../../src/control/pair.ts"],"names":[],"mappings":"AAYA,OAAO,
|
|
1
|
+
{"version":3,"file":"pair.d.ts","sourceRoot":"","sources":["../../src/control/pair.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,aAAa,EAMnB,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ;;8CAE0C;IAC1C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAUD,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,CAAC,EAAE,OAAO,KAAK,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAkBlF;AAED,uFAAuF;AACvF,wBAAsB,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CA+FjE;AAED,gFAAgF;AAChF,wBAAsB,GAAG,CAAC,CAAC,EAAE;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,iCAaA;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAWrE;AAOD,wBAAgB,YAAY,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;EAmC3F;AAED,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;AAI3D;;;uEAGuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAgB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiBhG;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,CAAC,EAAE;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B,GAAG,MAAM,CAqCT;AAED,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAiB9D"}
|
package/dist/control/store.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type TrustedKey } from "@sessionpipe/core/control";
|
|
2
|
+
import { type Runner, type SecretStore, type StoreName } from "../secrets.js";
|
|
2
3
|
export interface PairedReceiver {
|
|
3
4
|
/** The receiver's origin, as the person typed it. */
|
|
4
5
|
url: string;
|
|
@@ -6,8 +7,11 @@ export interface PairedReceiver {
|
|
|
6
7
|
control: string;
|
|
7
8
|
rpId: string;
|
|
8
9
|
machine: string;
|
|
9
|
-
/** The machine's own bearer (polls, acks, hello, off): opens nothing else.
|
|
10
|
+
/** The machine's own bearer (polls, acks, hello, off): opens nothing else. Empty
|
|
11
|
+
* when it lives in a store this process can't read right now. */
|
|
10
12
|
token: string;
|
|
13
|
+
/** The token lives in this store, not in control.json (secrets.ts). */
|
|
14
|
+
token_in?: SecretStore;
|
|
11
15
|
keys: (TrustedKey & {
|
|
12
16
|
name?: string;
|
|
13
17
|
added_at: string;
|
|
@@ -31,8 +35,20 @@ export interface ControlConfig {
|
|
|
31
35
|
}
|
|
32
36
|
export declare const controlFile: (env?: NodeJS.ProcessEnv) => string;
|
|
33
37
|
export declare const controlState: (env?: NodeJS.ProcessEnv) => string;
|
|
34
|
-
export declare function readControl(env?: NodeJS.ProcessEnv): ControlConfig | null;
|
|
38
|
+
export declare function readControl(env?: NodeJS.ProcessEnv, run?: Runner): ControlConfig | null;
|
|
39
|
+
/** A token kept in a store is never written back into the file. */
|
|
35
40
|
export declare const writeControl: (c: ControlConfig, env?: NodeJS.ProcessEnv) => void;
|
|
41
|
+
/** Move every paired receiver's token into `to` (or back into control.json). A token
|
|
42
|
+
* this process can't read is left where it is. */
|
|
43
|
+
export declare function moveControlSecrets(to: StoreName, o?: {
|
|
44
|
+
env?: NodeJS.ProcessEnv;
|
|
45
|
+
run?: Runner;
|
|
46
|
+
}): {
|
|
47
|
+
moved: string[];
|
|
48
|
+
kept: string[];
|
|
49
|
+
};
|
|
50
|
+
/** Forget a receiver's token wherever it is (control off). */
|
|
51
|
+
export declare function dropControlSecret(r: PairedReceiver, run?: Runner): void;
|
|
36
52
|
/** Nonces the machine has run, for NONCE_TTL_MS. `seen()` records a new nonce
|
|
37
53
|
* durably BEFORE it answers false; a write that fails throws, and the verifier
|
|
38
54
|
* refuses the command (`nonce_store`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/control/store.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/control/store.ts"],"names":[],"mappings":"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"}
|
package/dist/hook.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// sessionpipe 0.
|
|
1
|
+
// sessionpipe 0.5.0 · Apache-2.0 · https://sessionpipe.org
|
|
2
2
|
|
|
3
3
|
// src/http-sink.ts
|
|
4
4
|
import { createHash, createHmac } from "node:crypto";
|
|
@@ -342,7 +342,7 @@ function readAntigravity(lines, from) {
|
|
|
342
342
|
// ../core/src/adapters/claude-shaped.ts
|
|
343
343
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
344
344
|
import path3 from "node:path";
|
|
345
|
-
var OURS = /sessionpipe[^"\n]*[\\/]hook\.js"?\s+[a-z][a-z-]*\s+[A-Za-z]+\s*$/;
|
|
345
|
+
var OURS = /(?:sessionpipe[^"\n]*[\\/]hook\.js|[\\/]sessionpipe-hook)"?\s+[a-z][a-z-]*\s+[A-Za-z]+\s*$/;
|
|
346
346
|
var isOurs = (h) => Array.isArray(h?.hooks) && h.hooks.some((x) => typeof x.command === "string" && OURS.test(x.command));
|
|
347
347
|
function readJsonFile(file) {
|
|
348
348
|
let raw;
|
|
@@ -1309,7 +1309,7 @@ import path6 from "node:path";
|
|
|
1309
1309
|
// ../core/src/adapters/codex-config.ts
|
|
1310
1310
|
var NOTIFY_LINE = /^[ \t]*notify[ \t]*=[ \t]*(\[.*\])[ \t]*(?:#.*)?$/m;
|
|
1311
1311
|
var NOTIFY_KEY = /^[ \t]*notify[ \t]*=/m;
|
|
1312
|
-
var OURS2 = /hook\.js",\s*"codex",\s*"notify"/;
|
|
1312
|
+
var OURS2 = /(?:hook\.js|sessionpipe-hook)",\s*"codex",\s*"notify"/;
|
|
1313
1313
|
function scan(line, st) {
|
|
1314
1314
|
let i = 0;
|
|
1315
1315
|
while (i < line.length) {
|
|
@@ -2614,6 +2614,37 @@ function ask(sock, req, timeoutMs) {
|
|
|
2614
2614
|
});
|
|
2615
2615
|
}
|
|
2616
2616
|
|
|
2617
|
+
// src/secrets.ts
|
|
2618
|
+
import { spawnSync } from "node:child_process";
|
|
2619
|
+
import { createHash as createHash4, randomBytes as randomBytes2 } from "node:crypto";
|
|
2620
|
+
var SERVICE = "sessionpipe";
|
|
2621
|
+
var defaultRunner = (cmd, args, input) => {
|
|
2622
|
+
const r = spawnSync(cmd, args, {
|
|
2623
|
+
input: input ?? "",
|
|
2624
|
+
encoding: "utf8",
|
|
2625
|
+
timeout: 8e3,
|
|
2626
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
2627
|
+
});
|
|
2628
|
+
return { status: r.error ? null : r.status, stdout: r.stdout ?? "" };
|
|
2629
|
+
};
|
|
2630
|
+
var sinkAccount = (name, what = "token") => {
|
|
2631
|
+
const scope = process.env.SESSIONPIPE_CONFIG ? `@${createHash4("sha256").update(configFile()).digest("hex").slice(0, 8)}` : "";
|
|
2632
|
+
return `sink:${name}:${what}${scope}`;
|
|
2633
|
+
};
|
|
2634
|
+
function secretGet(store, account, run = defaultRunner) {
|
|
2635
|
+
const r = store === "keychain" ? run("security", ["find-generic-password", "-s", SERVICE, "-a", account, "-w"]) : run("secret-tool", ["lookup", "service", SERVICE, "account", account]);
|
|
2636
|
+
if (r.status !== 0) return null;
|
|
2637
|
+
const v = r.stdout.replace(/\r?\n$/, "");
|
|
2638
|
+
return v || null;
|
|
2639
|
+
}
|
|
2640
|
+
function sinkWithSecrets(s, run = defaultRunner) {
|
|
2641
|
+
if (!s.token_in) return s;
|
|
2642
|
+
const token = secretGet(s.token_in, sinkAccount(s.name), run);
|
|
2643
|
+
if (!token) return null;
|
|
2644
|
+
const secret = secretGet(s.token_in, sinkAccount(s.name, "secret"), run);
|
|
2645
|
+
return { ...s, token, ...secret ? { secret } : {} };
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2617
2648
|
// src/run.ts
|
|
2618
2649
|
async function tellDaemon(state, job, session, transcript) {
|
|
2619
2650
|
const sock = socketPath(state);
|
|
@@ -2669,10 +2700,15 @@ function factsState(state) {
|
|
|
2669
2700
|
}
|
|
2670
2701
|
};
|
|
2671
2702
|
}
|
|
2672
|
-
function buildSinks(sinks) {
|
|
2703
|
+
function buildSinks(sinks, o = {}) {
|
|
2673
2704
|
const out = [];
|
|
2674
|
-
for (const
|
|
2675
|
-
if (
|
|
2705
|
+
for (const raw of sinks) {
|
|
2706
|
+
if (raw.paused) continue;
|
|
2707
|
+
const s = sinkWithSecrets(raw);
|
|
2708
|
+
if (!s) {
|
|
2709
|
+
o.locked?.(raw.name);
|
|
2710
|
+
continue;
|
|
2711
|
+
}
|
|
2676
2712
|
const tier = Math.min(s.tier, s.max_tier ?? 3);
|
|
2677
2713
|
if (s.url === "stdout") out.push(new StdoutSink(s.name, tier, !!s.pii));
|
|
2678
2714
|
else if (s.url.startsWith("file:"))
|
|
@@ -2781,7 +2817,9 @@ var BATCH = 50;
|
|
|
2781
2817
|
var MAX_PER_RUN = 500;
|
|
2782
2818
|
async function flush(state, sinkConfigs, outbox, first) {
|
|
2783
2819
|
const delivered = {};
|
|
2784
|
-
const sinks = buildSinks(sinkConfigs
|
|
2820
|
+
const sinks = buildSinks(sinkConfigs, {
|
|
2821
|
+
locked: (name) => log(state, `sink ${name}: its token is in a keychain this process can't read; left for later`)
|
|
2822
|
+
});
|
|
2785
2823
|
const refs = outbox.sessions();
|
|
2786
2824
|
if (first) {
|
|
2787
2825
|
const k = `${first.harness}/${safeId(first.session)}`;
|