sessionpipe-core 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/dist/control.js +121 -12
- package/dist/control.js.map +2 -2
- package/dist/index.js +846 -308
- package/dist/index.js.map +4 -4
- package/dist/schema/v1.d.ts +266 -33
- package/dist/schema/v1.d.ts.map +1 -1
- package/dist/schema.js +128 -33
- package/dist/schema.js.map +2 -2
- package/dist/service.js +155 -0
- package/dist/service.js.map +7 -0
- package/dist/src/adapters/acp-control.d.ts +87 -0
- package/dist/src/adapters/acp-control.d.ts.map +1 -0
- package/dist/src/adapters/antigravity-control.d.ts +15 -5
- package/dist/src/adapters/antigravity-control.d.ts.map +1 -1
- package/dist/src/adapters/claude-code-control.d.ts +39 -4
- package/dist/src/adapters/claude-code-control.d.ts.map +1 -1
- package/dist/src/adapters/claude-code.d.ts.map +1 -1
- package/dist/src/adapters/codex-control.d.ts +23 -7
- package/dist/src/adapters/codex-control.d.ts.map +1 -1
- package/dist/src/adapters/codex.d.ts.map +1 -1
- package/dist/src/adapters/headless.d.ts +4 -1
- package/dist/src/adapters/headless.d.ts.map +1 -1
- package/dist/src/adapters/index.d.ts +7 -1
- package/dist/src/adapters/index.d.ts.map +1 -1
- package/dist/src/control/verify.d.ts +72 -16
- package/dist/src/control/verify.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/launched-by.d.ts +12 -0
- package/dist/src/launched-by.d.ts.map +1 -0
- package/dist/src/paths.d.ts +4 -0
- package/dist/src/paths.d.ts.map +1 -1
- package/dist/src/privacy/filter.d.ts.map +1 -1
- package/dist/src/service/index.d.ts +83 -0
- package/dist/src/service/index.d.ts.map +1 -0
- package/dist/src/version.d.ts +39 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/version.js +75 -0
- package/dist/version.js.map +7 -0
- package/package.json +9 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Adapter, HookInput, HookResult } from "./adapters/types.js";
|
|
2
|
+
/** PROTOCOL.md §3 `launched_by`: a launcher that starts a session for another one (a
|
|
3
|
+
* script running `claude -p`) names itself here as `<harness>:<id>`, and the hook
|
|
4
|
+
* carries it along. */
|
|
5
|
+
export declare const LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
6
|
+
/** The launcher the environment names, or nothing when it is absent or malformed. */
|
|
7
|
+
export declare function launchedBy(env: Record<string, string | undefined>): string | undefined;
|
|
8
|
+
/** An adapter's reading of a hook, plus what every harness shares: the launcher, unless
|
|
9
|
+
* the harness gave the session a parent of its own (a subagent's launcher is its parent)
|
|
10
|
+
* or the value names the session itself (a launcher that forgot to reset it). */
|
|
11
|
+
export declare function readHook(adapter: Adapter, input: HookInput): HookResult | null;
|
|
12
|
+
//# sourceMappingURL=launched-by.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launched-by.d.ts","sourceRoot":"","sources":["../../src/launched-by.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE1E;;wBAEwB;AACxB,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAGzD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAGtF;AAED;;kFAEkF;AAClF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,IAAI,CAO9E"}
|
package/dist/src/paths.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export declare function configFile(env?: NodeJS.ProcessEnv): string;
|
|
|
5
5
|
export declare function stateDir(env?: NodeJS.ProcessEnv): string;
|
|
6
6
|
/** `~` for the home directory, as the session block writes paths. */
|
|
7
7
|
export declare function tilde(p: string, home?: string): string;
|
|
8
|
+
/** The other way: `~`, `~/…` (or `~\…`) under the home directory, as a control `start`'s
|
|
9
|
+
* `cwd` may name a folder an event reported (CONTROL.md §3.1). Anything else, `~user`
|
|
10
|
+
* included, is returned as it is. */
|
|
11
|
+
export declare function untilde(p: string, home?: string): string;
|
|
8
12
|
/** A file-name-safe id. */
|
|
9
13
|
export declare const safeId: (s: string) => string;
|
|
10
14
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/src/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAQA;oFACoF;AACpF,eAAO,MAAM,OAAO,QAAO,MAAsB,CAAC;AAElD,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAKvE;AAED,wBAAgB,QAAQ,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAKrE;AAED,qEAAqE;AACrE,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAIjE;AAED,2BAA2B;AAC3B,eAAO,MAAM,MAAM,MAAO,MAAM,KAAG,MAGjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAQA;oFACoF;AACpF,eAAO,MAAM,OAAO,QAAO,MAAsB,CAAC;AAElD,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAKvE;AAED,wBAAgB,QAAQ,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAKrE;AAED,qEAAqE;AACrE,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAIjE;AAED;;sCAEsC;AACtC,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAGnE;AAED,2BAA2B;AAC3B,eAAO,MAAM,MAAM,MAAO,MAAM,KAAG,MAGjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/privacy/filter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAI/C,qFAAqF;AACrF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAmB1C,CAAC;
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/privacy/filter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAI/C,qFAAqF;AACrF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAmB1C,CAAC;AA2DF,qFAAqF;AACrF,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,aAAkB,GAAG,KAAK,GAAG,IAAI,CAqC1G"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** One service, as both managers need it. */
|
|
2
|
+
export interface ServiceSpec {
|
|
3
|
+
/** The launchd label, also the plist's name: `org.sessionpipe.control`. */
|
|
4
|
+
label: string;
|
|
5
|
+
/** The systemd user unit's file name: `sessionpipe-control.service`. */
|
|
6
|
+
unit: string;
|
|
7
|
+
/** The unit's Description line. */
|
|
8
|
+
description: string;
|
|
9
|
+
/** The program and its arguments, each one argument (never through a shell). */
|
|
10
|
+
argv: string[];
|
|
11
|
+
/** More environment for the process, beside SESSIONPIPE_SERVICE. */
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
/** Where launchd writes its stdout and stderr (journald keeps a unit's). */
|
|
14
|
+
logPath: string;
|
|
15
|
+
/** The home the files go under; the user's own by default. */
|
|
16
|
+
home?: string;
|
|
17
|
+
}
|
|
18
|
+
/** A file the service writes, and what is in it. */
|
|
19
|
+
export interface ServiceFile {
|
|
20
|
+
path: string;
|
|
21
|
+
text: string;
|
|
22
|
+
}
|
|
23
|
+
/** Runs one command and answers its stdout; throws when it fails. */
|
|
24
|
+
export type Exec = (cmd: string, args: string[]) => string;
|
|
25
|
+
/** The plist and the unit for a service, and where each goes. */
|
|
26
|
+
export declare function serviceFiles(s: ServiceSpec): {
|
|
27
|
+
plist: ServiceFile;
|
|
28
|
+
unit: ServiceFile;
|
|
29
|
+
};
|
|
30
|
+
/** A systemd user service stops when its person's last login ends — closing the ssh
|
|
31
|
+
* session to a lab workstation or a cloud machine stopped the daemon with it — unless
|
|
32
|
+
* the user lingers. `loginctl enable-linger` for yourself needs no root on systemd's
|
|
33
|
+
* default policy; where it does, say the one command that does it. */
|
|
34
|
+
export declare function ensureLinger(user: string, exec?: Exec): {
|
|
35
|
+
on: boolean;
|
|
36
|
+
note: string;
|
|
37
|
+
};
|
|
38
|
+
/** What an install did, or would do in a dry run. */
|
|
39
|
+
export interface ServicePlan {
|
|
40
|
+
/** The files written (or that would be). */
|
|
41
|
+
files: ServiceFile[];
|
|
42
|
+
/** The commands run (or that would be), one string each, in order. */
|
|
43
|
+
commands: string[];
|
|
44
|
+
/** Which manager runs it now: null on a platform with none, or where it isn't reachable. */
|
|
45
|
+
manager: "launchd" | "systemd" | null;
|
|
46
|
+
/** launchd: `gui` when someone is at the screen, else `user` (it starts again at the next login there). */
|
|
47
|
+
domain?: "gui" | "user";
|
|
48
|
+
/** systemd: whether it outlives the login, in words. */
|
|
49
|
+
linger?: {
|
|
50
|
+
on: boolean;
|
|
51
|
+
note: string;
|
|
52
|
+
};
|
|
53
|
+
/** The file that was written for a manager that couldn't be reached. */
|
|
54
|
+
unreachable?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface InstallOptions extends ServiceSpec {
|
|
57
|
+
/** Answer the plan and touch nothing. */
|
|
58
|
+
dryRun?: boolean;
|
|
59
|
+
exec?: Exec;
|
|
60
|
+
platform?: NodeJS.Platform;
|
|
61
|
+
/** The user's id (launchd's domains) and name (linger); this process's by default. */
|
|
62
|
+
uid?: string;
|
|
63
|
+
user?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Write the service for this platform and start it now; a service already there is
|
|
66
|
+
* replaced (launchd: booted out first). */
|
|
67
|
+
export declare function installService(o: InstallOptions): ServicePlan;
|
|
68
|
+
export interface UninstallOptions {
|
|
69
|
+
label: string;
|
|
70
|
+
unit: string;
|
|
71
|
+
home?: string;
|
|
72
|
+
dryRun?: boolean;
|
|
73
|
+
exec?: Exec;
|
|
74
|
+
platform?: NodeJS.Platform;
|
|
75
|
+
uid?: string;
|
|
76
|
+
}
|
|
77
|
+
/** Stop the service and remove its file, where this platform has one; nothing where
|
|
78
|
+
* there is none. A manager that says it wasn't loaded is no failure. */
|
|
79
|
+
export declare function uninstallService(o: UninstallOptions): {
|
|
80
|
+
files: string[];
|
|
81
|
+
commands: string[];
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/service/index.ts"],"names":[],"mappings":"AAkBA,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qEAAqE;AACrE,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;AAS3D,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CA2CtF;AAED;;;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,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,4FAA4F;IAC5F,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;IACtC,2GAA2G;IAC3G,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,wDAAwD;IACxD,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,yCAAyC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID;4CAC4C;AAC5C,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,WAAW,CA+C7D;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;yEACyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA6B7F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** sessionpipe-core/version — versions, and restarting onto a new one: how two
|
|
2
|
+
* versions order, whether one is a release newer than another, the exit code that
|
|
3
|
+
* asks a service manager to start a process again on the code now on disk, and the
|
|
4
|
+
* parent that does so where no manager will. The control daemon updates itself with
|
|
5
|
+
* these, and a receiver of the person's own can do the same. Node only (the parent
|
|
6
|
+
* spawns its child), so never part of the root export. */
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
/** EX_TEMPFAIL: "start me again, on the code now on disk". Every plist and unit
|
|
9
|
+
* sessionpipe-core/service writes restarts on it. */
|
|
10
|
+
export declare const UPDATE_EXIT = 75;
|
|
11
|
+
export interface Parsed {
|
|
12
|
+
n: [number, number, number];
|
|
13
|
+
pre: string | null;
|
|
14
|
+
}
|
|
15
|
+
/** A version's numbers and its prerelease tag, or null when it isn't one. */
|
|
16
|
+
export declare function parseVersion(v: string): Parsed | null;
|
|
17
|
+
/** Order two versions: <0, 0, >0, or null if either isn't one. A release sorts above
|
|
18
|
+
* its own prereleases; prereleases compare by their tag. */
|
|
19
|
+
export declare function compareVersions(a: string, b: string): number | null;
|
|
20
|
+
/** `a` is a release newer than `b`. A prerelease is never offered as an update: the
|
|
21
|
+
* `latest` dist-tag is a release, and anything else is someone's experiment.
|
|
22
|
+
* Setup opts into prereleases when checking whether an installed build is newer. */
|
|
23
|
+
export declare function isNewer(a: string, b: string, includePrereleases?: boolean): boolean;
|
|
24
|
+
/** The parent left behind when no service manager will restart the daemon: runs
|
|
25
|
+
* `control run` as a child with the same env and output, starts it again when it exits
|
|
26
|
+
* UPDATE_EXIT (an update) or fails (after 5 s, like the service files), and exits
|
|
27
|
+
* with it when it exits cleanly or is told to stop. */
|
|
28
|
+
export declare function supervise(o: {
|
|
29
|
+
node: string;
|
|
30
|
+
args: string[];
|
|
31
|
+
env: NodeJS.ProcessEnv;
|
|
32
|
+
log: (line: string) => void;
|
|
33
|
+
spawn?: typeof spawn;
|
|
34
|
+
exit?: (code: number) => void;
|
|
35
|
+
failDelayMs?: number;
|
|
36
|
+
}): {
|
|
37
|
+
stop: (sig?: NodeJS.Signals) => void;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AACA;;;;;2DAK2D;AAC3D,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D;sDACsD;AACtD,eAAO,MAAM,WAAW,KAAK,CAAC;AAI9B,MAAM,WAAW,MAAM;IACrB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AACD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;6DAC6D;AAC7D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASnE;AAED;;qFAEqF;AACrF,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,UAAQ,GAAG,OAAO,CAKjF;AAED;;;wDAGwD;AACxD,wBAAgB,SAAS,CAAC,CAAC,EAAE;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG;IAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAA;CAAE,CAuC3C"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// sessionpipe-core 0.10.0 · Apache-2.0 · https://sessionpipe.org
|
|
2
|
+
|
|
3
|
+
// src/version.ts
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
var UPDATE_EXIT = 75;
|
|
6
|
+
var VERSION_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
7
|
+
function parseVersion(v) {
|
|
8
|
+
const m = VERSION_RE.exec(String(v).trim());
|
|
9
|
+
if (!m) return null;
|
|
10
|
+
return { n: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null };
|
|
11
|
+
}
|
|
12
|
+
function compareVersions(a, b) {
|
|
13
|
+
const x = parseVersion(a);
|
|
14
|
+
const y = parseVersion(b);
|
|
15
|
+
if (!x || !y) return null;
|
|
16
|
+
for (let i = 0; i < 3; i++) if (x.n[i] !== y.n[i]) return x.n[i] - y.n[i];
|
|
17
|
+
if (x.pre === y.pre) return 0;
|
|
18
|
+
if (x.pre === null) return 1;
|
|
19
|
+
if (y.pre === null) return -1;
|
|
20
|
+
return x.pre.localeCompare(y.pre, "en", { numeric: true });
|
|
21
|
+
}
|
|
22
|
+
function isNewer(a, b, includePrereleases = false) {
|
|
23
|
+
const x = parseVersion(a);
|
|
24
|
+
if (!x || !includePrereleases && x.pre !== null) return false;
|
|
25
|
+
const c = compareVersions(a, b);
|
|
26
|
+
return c !== null && c > 0;
|
|
27
|
+
}
|
|
28
|
+
function supervise(o) {
|
|
29
|
+
const run = o.spawn ?? spawn;
|
|
30
|
+
const exit = o.exit ?? ((c) => process.exit(c));
|
|
31
|
+
const env = { ...o.env, SESSIONPIPE_SERVICE: `supervisor:${process.pid}` };
|
|
32
|
+
let child = null;
|
|
33
|
+
let stopping = false;
|
|
34
|
+
let later = null;
|
|
35
|
+
const start = () => {
|
|
36
|
+
later = null;
|
|
37
|
+
const c = run(o.node, o.args, { env, stdio: "inherit", windowsHide: true });
|
|
38
|
+
child = c;
|
|
39
|
+
let done = false;
|
|
40
|
+
const ended = (code, signal) => {
|
|
41
|
+
if (done) return;
|
|
42
|
+
done = true;
|
|
43
|
+
child = null;
|
|
44
|
+
if (stopping) return exit(code ?? 0);
|
|
45
|
+
if (code === UPDATE_EXIT) {
|
|
46
|
+
o.log("the daemon is restarting onto its new version");
|
|
47
|
+
return start();
|
|
48
|
+
}
|
|
49
|
+
if (code === 0) return exit(0);
|
|
50
|
+
o.log(`the daemon exited (${signal ?? `code ${code}`}); starting it again in 5 s`);
|
|
51
|
+
later = setTimeout(start, o.failDelayMs ?? 5e3);
|
|
52
|
+
};
|
|
53
|
+
c.on("exit", ended);
|
|
54
|
+
c.on("error", (e) => {
|
|
55
|
+
o.log(`couldn't start the daemon: ${e.message}`);
|
|
56
|
+
ended(1, null);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const stop = (sig = "SIGTERM") => {
|
|
60
|
+
stopping = true;
|
|
61
|
+
if (later) clearTimeout(later);
|
|
62
|
+
if (child) child.kill(sig);
|
|
63
|
+
else exit(0);
|
|
64
|
+
};
|
|
65
|
+
start();
|
|
66
|
+
return { stop };
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
UPDATE_EXIT,
|
|
70
|
+
compareVersions,
|
|
71
|
+
isNewer,
|
|
72
|
+
parseVersion,
|
|
73
|
+
supervise
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/version.ts"],
|
|
4
|
+
"sourcesContent": ["// SPDX-License-Identifier: Apache-2.0\n/** sessionpipe-core/version \u2014 versions, and restarting onto a new one: how two\n * versions order, whether one is a release newer than another, the exit code that\n * asks a service manager to start a process again on the code now on disk, and the\n * parent that does so where no manager will. The control daemon updates itself with\n * these, and a receiver of the person's own can do the same. Node only (the parent\n * spawns its child), so never part of the root export. */\nimport { type ChildProcess, spawn } from \"node:child_process\";\n\n/** EX_TEMPFAIL: \"start me again, on the code now on disk\". Every plist and unit\n * sessionpipe-core/service writes restarts on it. */\nexport const UPDATE_EXIT = 75;\n\nconst VERSION_RE = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/;\n\nexport interface Parsed {\n n: [number, number, number];\n pre: string | null;\n}\n/** A version's numbers and its prerelease tag, or null when it isn't one. */\nexport function parseVersion(v: string): Parsed | null {\n const m = VERSION_RE.exec(String(v).trim());\n if (!m) return null;\n return { n: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null };\n}\n\n/** Order two versions: <0, 0, >0, or null if either isn't one. A release sorts above\n * its own prereleases; prereleases compare by their tag. */\nexport function compareVersions(a: string, b: string): number | null {\n const x = parseVersion(a);\n const y = parseVersion(b);\n if (!x || !y) return null;\n for (let i = 0; i < 3; i++) if (x.n[i] !== y.n[i]) return (x.n[i] as number) - (y.n[i] as number);\n if (x.pre === y.pre) return 0;\n if (x.pre === null) return 1;\n if (y.pre === null) return -1;\n return x.pre.localeCompare(y.pre, \"en\", { numeric: true });\n}\n\n/** `a` is a release newer than `b`. A prerelease is never offered as an update: the\n * `latest` dist-tag is a release, and anything else is someone's experiment.\n * Setup opts into prereleases when checking whether an installed build is newer. */\nexport function isNewer(a: string, b: string, includePrereleases = false): boolean {\n const x = parseVersion(a);\n if (!x || (!includePrereleases && x.pre !== null)) return false;\n const c = compareVersions(a, b);\n return c !== null && c > 0;\n}\n\n/** The parent left behind when no service manager will restart the daemon: runs\n * `control run` as a child with the same env and output, starts it again when it exits\n * UPDATE_EXIT (an update) or fails (after 5 s, like the service files), and exits\n * with it when it exits cleanly or is told to stop. */\nexport function supervise(o: {\n node: string;\n args: string[];\n env: NodeJS.ProcessEnv;\n log: (line: string) => void;\n spawn?: typeof spawn;\n exit?: (code: number) => void;\n failDelayMs?: number;\n}): { stop: (sig?: NodeJS.Signals) => void } {\n const run = o.spawn ?? spawn;\n const exit = o.exit ?? ((c: number) => process.exit(c));\n const env = { ...o.env, SESSIONPIPE_SERVICE: `supervisor:${process.pid}` };\n let child: ChildProcess | null = null;\n let stopping = false;\n let later: NodeJS.Timeout | null = null;\n const start = () => {\n later = null;\n const c = run(o.node, o.args, { env, stdio: \"inherit\", windowsHide: true });\n child = c;\n let done = false;\n const ended = (code: number | null, signal: NodeJS.Signals | null) => {\n if (done) return;\n done = true;\n child = null;\n if (stopping) return exit(code ?? 0);\n if (code === UPDATE_EXIT) {\n o.log(\"the daemon is restarting onto its new version\");\n return start();\n }\n if (code === 0) return exit(0);\n o.log(`the daemon exited (${signal ?? `code ${code}`}); starting it again in 5 s`);\n later = setTimeout(start, o.failDelayMs ?? 5000);\n };\n c.on(\"exit\", ended);\n c.on(\"error\", (e) => {\n o.log(`couldn't start the daemon: ${e.message}`);\n ended(1, null);\n });\n };\n const stop = (sig: NodeJS.Signals = \"SIGTERM\") => {\n stopping = true;\n if (later) clearTimeout(later);\n if (child) child.kill(sig);\n else exit(0);\n };\n start();\n return { stop };\n}\n"],
|
|
5
|
+
"mappings": ";;;AAOA,SAA4B,aAAa;AAIlC,IAAM,cAAc;AAE3B,IAAM,aAAa;AAOZ,SAAS,aAAa,GAA0B;AACrD,QAAM,IAAI,WAAW,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC;AAC1C,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,KAAK,KAAK;AAC5E;AAIO,SAAS,gBAAgB,GAAW,GAA0B;AACnE,QAAM,IAAI,aAAa,CAAC;AACxB,QAAM,IAAI,aAAa,CAAC;AACxB,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,EAAG,QAAQ,EAAE,EAAE,CAAC,IAAgB,EAAE,EAAE,CAAC;AACrF,MAAI,EAAE,QAAQ,EAAE,IAAK,QAAO;AAC5B,MAAI,EAAE,QAAQ,KAAM,QAAO;AAC3B,MAAI,EAAE,QAAQ,KAAM,QAAO;AAC3B,SAAO,EAAE,IAAI,cAAc,EAAE,KAAK,MAAM,EAAE,SAAS,KAAK,CAAC;AAC3D;AAKO,SAAS,QAAQ,GAAW,GAAW,qBAAqB,OAAgB;AACjF,QAAM,IAAI,aAAa,CAAC;AACxB,MAAI,CAAC,KAAM,CAAC,sBAAsB,EAAE,QAAQ,KAAO,QAAO;AAC1D,QAAM,IAAI,gBAAgB,GAAG,CAAC;AAC9B,SAAO,MAAM,QAAQ,IAAI;AAC3B;AAMO,SAAS,UAAU,GAQmB;AAC3C,QAAM,MAAM,EAAE,SAAS;AACvB,QAAM,OAAO,EAAE,SAAS,CAAC,MAAc,QAAQ,KAAK,CAAC;AACrD,QAAM,MAAM,EAAE,GAAG,EAAE,KAAK,qBAAqB,cAAc,QAAQ,GAAG,GAAG;AACzE,MAAI,QAA6B;AACjC,MAAI,WAAW;AACf,MAAI,QAA+B;AACnC,QAAM,QAAQ,MAAM;AAClB,YAAQ;AACR,UAAM,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,WAAW,aAAa,KAAK,CAAC;AAC1E,YAAQ;AACR,QAAI,OAAO;AACX,UAAM,QAAQ,CAAC,MAAqB,WAAkC;AACpE,UAAI,KAAM;AACV,aAAO;AACP,cAAQ;AACR,UAAI,SAAU,QAAO,KAAK,QAAQ,CAAC;AACnC,UAAI,SAAS,aAAa;AACxB,UAAE,IAAI,+CAA+C;AACrD,eAAO,MAAM;AAAA,MACf;AACA,UAAI,SAAS,EAAG,QAAO,KAAK,CAAC;AAC7B,QAAE,IAAI,sBAAsB,UAAU,QAAQ,IAAI,EAAE,6BAA6B;AACjF,cAAQ,WAAW,OAAO,EAAE,eAAe,GAAI;AAAA,IACjD;AACA,MAAE,GAAG,QAAQ,KAAK;AAClB,MAAE,GAAG,SAAS,CAAC,MAAM;AACnB,QAAE,IAAI,8BAA8B,EAAE,OAAO,EAAE;AAC/C,YAAM,GAAG,IAAI;AAAA,IACf,CAAC;AAAA,EACH;AACA,QAAM,OAAO,CAAC,MAAsB,cAAc;AAChD,eAAW;AACX,QAAI,MAAO,cAAa,KAAK;AAC7B,QAAI,MAAO,OAAM,KAAK,GAAG;AAAA,QACpB,MAAK,CAAC;AAAA,EACb;AACA,QAAM;AACN,SAAO,EAAE,KAAK;AAChB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sessionpipe-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "sessionpipe core: protocol types, harness adapters, privacy filter and redaction rulesets, outbox and sinks. Zero runtime dependencies. (published unscoped until the @sessionpipe npm org exists; the code is the same)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
"./control": {
|
|
44
44
|
"types": "./dist/src/control/index.d.ts",
|
|
45
45
|
"import": "./dist/control.js"
|
|
46
|
+
},
|
|
47
|
+
"./service": {
|
|
48
|
+
"types": "./dist/src/service/index.d.ts",
|
|
49
|
+
"import": "./dist/service.js"
|
|
50
|
+
},
|
|
51
|
+
"./version": {
|
|
52
|
+
"types": "./dist/src/version.d.ts",
|
|
53
|
+
"import": "./dist/version.js"
|
|
46
54
|
}
|
|
47
55
|
},
|
|
48
56
|
"types": "./dist/src/index.d.ts",
|