@cotal-ai/seat 0.0.0-bootstrap.0 → 0.47.1

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.
@@ -0,0 +1,102 @@
1
+ import { spawn, spawnSync } from "node:child_process";
2
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { capabilityToken, recordPath, seatId, socketPath, readRecord } from "./record.js";
6
+ import { unsupportedTransport } from "./protocol.js";
7
+ function packageRoot() {
8
+ return dirname(dirname(fileURLToPath(import.meta.url)));
9
+ }
10
+ /** Always the compiled entry. tsx loading `src/` must not spawn a missing `src/custodian.js`. */
11
+ function custodianEntry() {
12
+ const path = join(packageRoot(), "dist", "custodian.js");
13
+ if (!existsSync(path))
14
+ throw new Error(`custodian entry missing at ${path}; build @cotal-ai/seat first`);
15
+ return path;
16
+ }
17
+ function pidLive(pid) {
18
+ if (typeof pid !== "number" || pid <= 0)
19
+ return false;
20
+ try {
21
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
22
+ const state = stat.slice(stat.lastIndexOf(") ") + 2).split(" ")[0];
23
+ return state !== "Z";
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ export function launchSeat(opts) {
30
+ if (process.platform !== "linux")
31
+ throw unsupportedTransport();
32
+ mkdirSync(opts.root, { recursive: true, mode: 0o700 });
33
+ const id = seatId();
34
+ const token = capabilityToken();
35
+ const socket = socketPath(opts.root, id);
36
+ const recPath = recordPath(opts.root, id);
37
+ mkdirSync(dirname(recPath), { recursive: true, mode: 0o700 });
38
+ const logPath = join(dirname(recPath), "custodian.log");
39
+ const payload = JSON.stringify({
40
+ id,
41
+ name: opts.name,
42
+ command: opts.spec.command,
43
+ args: opts.spec.args,
44
+ env: opts.spec.env ?? {},
45
+ cwd: opts.cwd,
46
+ socket,
47
+ token,
48
+ recordPath: recPath,
49
+ logPath,
50
+ confirm: Boolean(opts.spec.confirm),
51
+ });
52
+ // Payload carries spec.env (provider keys) and the capability token.
53
+ // argv is world-readable via /proc/<pid>/cmdline (0444). Inherit a 0600
54
+ // file as stdin so the JSON never appears on argv.
55
+ const launchPath = join(dirname(recPath), "launch.json");
56
+ writeFileSync(launchPath, payload, { mode: 0o600 });
57
+ const launchFd = openSync(launchPath, "r");
58
+ const child = spawn(process.execPath, [custodianEntry()], {
59
+ detached: true,
60
+ stdio: [launchFd, "ignore", "ignore"],
61
+ env: { PATH: process.env.PATH ?? "" },
62
+ });
63
+ closeSync(launchFd);
64
+ try {
65
+ unlinkSync(launchPath);
66
+ }
67
+ catch {
68
+ /* child still holds the fd */
69
+ }
70
+ child.unref();
71
+ const deadline = Date.now() + 10_000;
72
+ while (Date.now() < deadline) {
73
+ try {
74
+ const rec = readRecord(recPath);
75
+ if (rec.custodianPid > 0 && rec.childPid > 0) {
76
+ return rec;
77
+ }
78
+ }
79
+ catch {
80
+ /* record not written yet */
81
+ }
82
+ if (!pidLive(child.pid)) {
83
+ let err = "";
84
+ try {
85
+ err = readFileSync(logPath, "utf8").trim();
86
+ }
87
+ catch {
88
+ /* no log */
89
+ }
90
+ throw new Error(`custodian exited before ready: ${err || `pid ${String(child.pid)} gone`}`);
91
+ }
92
+ spawnSync("sleep", ["0.025"], { stdio: "ignore" });
93
+ }
94
+ throw new Error(`custodian did not write a seat record at ${recPath}`);
95
+ }
96
+ export function loadSeat(root, id) {
97
+ return readRecord(recordPath(root, id));
98
+ }
99
+ export function readSeatFile(path) {
100
+ return JSON.parse(readFileSync(path, "utf8"));
101
+ }
102
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Socket } from "node:net";
2
+ export interface PeerCredentials {
3
+ pid: number;
4
+ uid: number;
5
+ gid: number;
6
+ }
7
+ export declare const LINUX_NATIVE_ARCHES: readonly ["x64", "arm64"];
8
+ export declare function nativeHelperPath(arch?: string): string;
9
+ export declare function unsupportedNativeArch(platform: string, arch: string): Error;
10
+ export declare function socketFd(sock: Socket): number;
11
+ export declare function peerCredentials(sock: Socket): PeerCredentials;
12
+ //# sourceMappingURL=peercred.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peercred.d.ts","sourceRoot":"","sources":["../src/peercred.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAID,eAAO,MAAM,mBAAmB,2BAA4B,CAAC;AAI7D,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,MAAqB,GAAG,MAAM,CAGpE;AAMD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAI3E;AAqBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAE7D"}
@@ -0,0 +1,49 @@
1
+ import { createRequire } from "node:module";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { unsupportedTransport } from "./protocol.js";
6
+ export const LINUX_NATIVE_ARCHES = ["x64", "arm64"];
7
+ let loaded;
8
+ export function nativeHelperPath(arch = process.arch) {
9
+ const here = dirname(fileURLToPath(import.meta.url));
10
+ return join(here, "..", "build", "Release", `linux-${arch}`, "peercred.node");
11
+ }
12
+ function isLinuxNativeArch(arch) {
13
+ return LINUX_NATIVE_ARCHES.includes(arch);
14
+ }
15
+ export function unsupportedNativeArch(platform, arch) {
16
+ return new Error(`@cotal-ai/seat: SO_PEERCRED native helper unsupported on ${platform}-${arch} (supported: linux-x64, linux-arm64)`);
17
+ }
18
+ function loadNative() {
19
+ if (loaded)
20
+ return loaded;
21
+ if (process.platform !== "linux")
22
+ throw unsupportedTransport();
23
+ const platformArch = `${process.platform}-${process.arch}`;
24
+ if (!isLinuxNativeArch(process.arch))
25
+ throw unsupportedNativeArch(process.platform, process.arch);
26
+ const path = nativeHelperPath(process.arch);
27
+ if (!existsSync(path))
28
+ throw new Error(`@cotal-ai/seat: SO_PEERCRED native helper missing at ${path}`);
29
+ const require = createRequire(import.meta.url);
30
+ try {
31
+ loaded = require(path);
32
+ }
33
+ catch (err) {
34
+ const detail = err instanceof Error ? err.message : String(err);
35
+ throw new Error(`@cotal-ai/seat: SO_PEERCRED native helper failed to load at ${path} for ${platformArch}: ${detail}`);
36
+ }
37
+ return loaded;
38
+ }
39
+ export function socketFd(sock) {
40
+ const handle = sock._handle;
41
+ const fd = handle?.fd;
42
+ if (typeof fd !== "number" || fd < 0)
43
+ throw new Error("unix socket has no file descriptor");
44
+ return fd;
45
+ }
46
+ export function peerCredentials(sock) {
47
+ return loadNative().peercred(socketFd(sock));
48
+ }
49
+ //# sourceMappingURL=peercred.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peercred.js","sourceRoot":"","sources":["../src/peercred.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAUrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAU,CAAC;AAE7D,IAAI,MAAkC,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAAC,OAAe,OAAO,CAAC,IAAI;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAQ,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,IAAY;IAClE,OAAO,IAAI,KAAK,CACd,4DAA4D,QAAQ,IAAI,IAAI,sCAAsC,CACnH,CAAC;AACJ,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,MAAM,oBAAoB,EAAE,CAAC;IAC/D,MAAM,YAAY,GAAG,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3D,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,MAAM,qBAAqB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,IAAI,EAAE,CAAC,CAAC;IACvG,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,OAAO,CAAC,IAAI,CAAmB,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,+DAA+D,IAAI,QAAQ,YAAY,KAAK,MAAM,EAAE,CACrG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,MAAM,GAAI,IAAiD,CAAC,OAAO,CAAC;IAC1E,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IACtB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC5F,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,UAAU,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,137 @@
1
+ /** Protocol version this process speaks. Additive later; M2 is a single implicit controller. */
2
+ export declare const PROTOCOL_VERSION = 1;
3
+ export declare const DEFAULT_COLS = 120;
4
+ export declare const DEFAULT_ROWS = 32;
5
+ export declare const SCROLLBACK_ROWS = 1000;
6
+ export declare const CONFIRM_INTERVAL_MS = 1000;
7
+ export declare const MAX_CONFIRMS = 5;
8
+ export declare const GRACE_MS = 3000;
9
+ /**
10
+ * Max JSON body the local protocol accepts in one frame.
11
+ * A 1000-row, 120-col 16-color serialize is ~744 KiB, and JSON-escaping that
12
+ * snapshot is 1_365_109 bytes. Truecolor fg+bg per cell is 4_876_998. 8 MiB
13
+ * covers both so adopt can return scrollback; a 500 MiB claimed length still
14
+ * fails the per-frame check.
15
+ */
16
+ export declare const MAX_FRAME_SIZE: number;
17
+ /** Max undecoded residual AFTER complete frames have been drained. */
18
+ export declare const MAX_BUFFER_SIZE: number;
19
+ export type StopMode = "graceful" | "hard";
20
+ export type ClientRequest = {
21
+ id: number;
22
+ op: "hello";
23
+ token: string;
24
+ } | {
25
+ id: number;
26
+ op: "snapshot";
27
+ } | {
28
+ id: number;
29
+ op: "subscribe-output";
30
+ } | {
31
+ id: number;
32
+ op: "unsubscribe-output";
33
+ sub: number;
34
+ } | {
35
+ id: number;
36
+ op: "write";
37
+ data: string;
38
+ } | {
39
+ id: number;
40
+ op: "resize";
41
+ cols: number;
42
+ rows: number;
43
+ } | {
44
+ id: number;
45
+ op: "interrupt";
46
+ } | {
47
+ id: number;
48
+ op: "stop";
49
+ mode: StopMode;
50
+ } | {
51
+ id: number;
52
+ op: "wait-exit";
53
+ } | {
54
+ id: number;
55
+ op: "health";
56
+ };
57
+ export type ServerEvent = {
58
+ event: "output";
59
+ sub: number;
60
+ data: string;
61
+ } | {
62
+ event: "exit";
63
+ sub?: number;
64
+ };
65
+ export type ServerReply = {
66
+ id: number;
67
+ ok: true;
68
+ op: "hello";
69
+ name: string;
70
+ pid: number;
71
+ cols: number;
72
+ rows: number;
73
+ status: "running" | "exited";
74
+ exit?: {
75
+ code?: number;
76
+ signal?: number;
77
+ };
78
+ } | {
79
+ id: number;
80
+ ok: true;
81
+ op: "snapshot";
82
+ data: string;
83
+ cols: number;
84
+ rows: number;
85
+ } | {
86
+ id: number;
87
+ ok: true;
88
+ op: "subscribe-output";
89
+ sub: number;
90
+ } | {
91
+ id: number;
92
+ ok: true;
93
+ op: "unsubscribe-output";
94
+ } | {
95
+ id: number;
96
+ ok: true;
97
+ op: "write";
98
+ } | {
99
+ id: number;
100
+ ok: true;
101
+ op: "resize";
102
+ } | {
103
+ id: number;
104
+ ok: true;
105
+ op: "interrupt";
106
+ } | {
107
+ id: number;
108
+ ok: true;
109
+ op: "stop";
110
+ } | {
111
+ id: number;
112
+ ok: true;
113
+ op: "wait-exit";
114
+ exit?: {
115
+ code?: number;
116
+ signal?: number;
117
+ };
118
+ } | {
119
+ id: number;
120
+ ok: true;
121
+ op: "health";
122
+ pid: number;
123
+ status: "running" | "exited";
124
+ protocol: number;
125
+ } | {
126
+ id: number;
127
+ ok: false;
128
+ error: string;
129
+ };
130
+ export type ServerMessage = ServerReply | ServerEvent;
131
+ export declare function encodeFrame(value: unknown): Buffer;
132
+ export declare class FrameReader {
133
+ private buf;
134
+ push(chunk: Buffer): unknown[];
135
+ }
136
+ export declare function unsupportedTransport(platform?: string): Error;
137
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /** Protocol version this process speaks. Additive later; M2 is a single implicit controller. */
2
+ export const PROTOCOL_VERSION = 1;
3
+ export const DEFAULT_COLS = 120;
4
+ export const DEFAULT_ROWS = 32;
5
+ export const SCROLLBACK_ROWS = 1000;
6
+ export const CONFIRM_INTERVAL_MS = 1_000;
7
+ export const MAX_CONFIRMS = 5;
8
+ export const GRACE_MS = 3_000;
9
+ /**
10
+ * Max JSON body the local protocol accepts in one frame.
11
+ * A 1000-row, 120-col 16-color serialize is ~744 KiB, and JSON-escaping that
12
+ * snapshot is 1_365_109 bytes. Truecolor fg+bg per cell is 4_876_998. 8 MiB
13
+ * covers both so adopt can return scrollback; a 500 MiB claimed length still
14
+ * fails the per-frame check.
15
+ */
16
+ export const MAX_FRAME_SIZE = 8 * 1024 * 1024;
17
+ /** Max undecoded residual AFTER complete frames have been drained. */
18
+ export const MAX_BUFFER_SIZE = MAX_FRAME_SIZE + 4;
19
+ export function encodeFrame(value) {
20
+ const body = Buffer.from(JSON.stringify(value), "utf8");
21
+ if (body.length > MAX_FRAME_SIZE) {
22
+ throw new Error(`frame length ${body.length} exceeds ${MAX_FRAME_SIZE} bytes`);
23
+ }
24
+ const header = Buffer.allocUnsafe(4);
25
+ header.writeUInt32BE(body.length, 0);
26
+ return Buffer.concat([header, body]);
27
+ }
28
+ export class FrameReader {
29
+ buf = Buffer.alloc(0);
30
+ push(chunk) {
31
+ this.buf = Buffer.concat([this.buf, chunk]);
32
+ const out = [];
33
+ while (this.buf.length >= 4) {
34
+ const size = this.buf.readUInt32BE(0);
35
+ if (size > MAX_FRAME_SIZE) {
36
+ this.buf = Buffer.alloc(0);
37
+ throw new Error(`frame length ${size} exceeds ${MAX_FRAME_SIZE} bytes`);
38
+ }
39
+ if (this.buf.length < 4 + size)
40
+ break;
41
+ const body = this.buf.subarray(4, 4 + size);
42
+ this.buf = this.buf.subarray(4 + size);
43
+ out.push(JSON.parse(body.toString("utf8")));
44
+ }
45
+ if (this.buf.length > MAX_BUFFER_SIZE) {
46
+ this.buf = Buffer.alloc(0);
47
+ throw new Error(`frame buffer exceeds ${MAX_BUFFER_SIZE} bytes`);
48
+ }
49
+ return out;
50
+ }
51
+ }
52
+ export function unsupportedTransport(platform = process.platform) {
53
+ return new Error(`custody transport unsupported on ${platform}`);
54
+ }
55
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC9B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,GAAG,CAAC,CAAC;AAoDlD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,MAAM,YAAY,cAAc,QAAQ,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,OAAO,WAAW;IACd,GAAG,GAAW,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtC,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,YAAY,cAAc,QAAQ,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI;gBAAE,MAAM;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,wBAAwB,eAAe,QAAQ,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,WAAmB,OAAO,CAAC,QAAQ;IACtE,OAAO,IAAI,KAAK,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare const RECORD_VERSION = 1;
2
+ export interface SeatRecord {
3
+ version: number;
4
+ id: string;
5
+ name: string;
6
+ socket: string;
7
+ token: string;
8
+ custodianPid: number;
9
+ childPid: number;
10
+ }
11
+ export declare function seatId(): string;
12
+ export declare function capabilityToken(): string;
13
+ export declare function recordPath(root: string, id: string): string;
14
+ export declare function socketPath(root: string, id: string): string;
15
+ export declare function writeRecord(path: string, record: SeatRecord): void;
16
+ export declare function readRecord(path: string): SeatRecord;
17
+ //# sourceMappingURL=record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAKlE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAkBnD"}
package/dist/record.js ADDED
@@ -0,0 +1,49 @@
1
+ import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { randomBytes } from "node:crypto";
4
+ export const RECORD_VERSION = 1;
5
+ export function seatId() {
6
+ return randomBytes(16).toString("hex");
7
+ }
8
+ export function capabilityToken() {
9
+ return randomBytes(32).toString("hex");
10
+ }
11
+ export function recordPath(root, id) {
12
+ return join(root, id, "record.json");
13
+ }
14
+ export function socketPath(root, id) {
15
+ return join(root, id, "seat.sock");
16
+ }
17
+ export function writeRecord(path, record) {
18
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
19
+ writeFileSync(path, `${JSON.stringify(record)}\n`, { mode: 0o600, flag: "w" });
20
+ chmodSync(path, 0o600);
21
+ chmodSync(dirname(path), 0o700);
22
+ }
23
+ export function readRecord(path) {
24
+ const raw = JSON.parse(readFileSync(path, "utf8"));
25
+ if (raw.version !== RECORD_VERSION)
26
+ throw new Error(`unsupported seat record version ${String(raw.version)}`);
27
+ if (typeof raw.id !== "string" || raw.id.length === 0)
28
+ throw new Error("seat record missing id");
29
+ if (typeof raw.name !== "string" || raw.name.length === 0)
30
+ throw new Error("seat record missing name");
31
+ if (typeof raw.socket !== "string" || raw.socket.length === 0)
32
+ throw new Error("seat record missing socket");
33
+ if (typeof raw.token !== "string" || raw.token.length === 0)
34
+ throw new Error("seat record missing token");
35
+ if (typeof raw.custodianPid !== "number" || !Number.isInteger(raw.custodianPid))
36
+ throw new Error("seat record missing custodianPid");
37
+ if (typeof raw.childPid !== "number" || !Number.isInteger(raw.childPid))
38
+ throw new Error("seat record missing childPid");
39
+ return {
40
+ version: RECORD_VERSION,
41
+ id: raw.id,
42
+ name: raw.name,
43
+ socket: raw.socket,
44
+ token: raw.token,
45
+ custodianPid: raw.custodianPid,
46
+ childPid: raw.childPid,
47
+ };
48
+ }
49
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,22 +1,38 @@
1
1
  {
2
2
  "name": "@cotal-ai/seat",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Bootstrap placeholder for configuring npm trusted publishing. Not a functional release.",
3
+ "description": "Local PTY seat custody: one detached custodian process per seat, a one-shot launcher, and the authenticated local protocol a manager worker uses to adopt the handle. Depends on nothing else in the repo.",
4
+ "version": "0.47.1",
5
5
  "license": "Apache-2.0",
6
- "type": "module",
7
- "main": "index.js",
8
- "files": [
9
- "index.js",
10
- "README.md"
11
- ],
12
6
  "repository": {
13
7
  "type": "git",
14
8
  "url": "https://github.com/Cotal-AI/Cotal.git",
15
9
  "directory": "packages/seat"
16
10
  },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "dependencies": {
21
+ "@lydell/node-pty": "1.2.0-beta.12",
22
+ "@xterm/addon-serialize": "^0.13.0",
23
+ "@xterm/headless": "^5.5.0"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "build"
28
+ ],
17
29
  "publishConfig": {
18
- "access": "public",
19
- "registry": "https://registry.npmjs.org/",
20
- "tag": "bootstrap"
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "typecheck": "tsc -p tsconfig.check.json",
34
+ "build": "node scripts/build-native.mjs && tsc -p tsconfig.json",
35
+ "build:native": "node scripts/build-native.mjs",
36
+ "test": "pnpm run build && tsx smoke/platform.smoke.ts && tsx smoke/protocol.smoke.ts && tsx smoke/lifecycle.smoke.ts && tsx smoke/isolation.smoke.ts"
21
37
  }
22
- }
38
+ }
package/index.js DELETED
@@ -1 +0,0 @@
1
- throw new Error("@cotal-ai/seat bootstrap placeholder: this version provides no runtime implementation. Install an official release after trusted publishing is configured.");