@tokenfactory/acc-runner 0.39.0 → 0.40.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.
package/dist/cli.js CHANGED
@@ -10,6 +10,7 @@ import { fetchPricing } from "./cost-pricing.js";
10
10
  import { loginCommand } from "./login.js";
11
11
  import { logoutCommand } from "./logout.js";
12
12
  import { watchCommand } from "./watch.js";
13
+ import { companionCommand, companionInstallCommand, companionStatusCommand, companionUninstallCommand, } from "./companion-run.js";
13
14
  import { doctorCommand } from "./doctor.js";
14
15
  import { clearQuarantine, getQuarantine } from "./runtime/quarantine.js";
15
16
  import { clearChatCircuit, getChatCircuit } from "./runtime/chat-circuit-breaker.js";
@@ -63,6 +64,65 @@ program
63
64
  process.exitCode = 1;
64
65
  }
65
66
  });
67
+ // CC-3C (COMPANION): companion mode — an owner-affinity chat runner. Serves
68
+ // ONLY the logged-in owner's interactive chat turns (no code tasks), mirrors
69
+ // the turn stream to the same-machine browser over a loopback socket, and on
70
+ // exit requeues in-flight turns so an Auto turn fails over to the fleet.
71
+ const companionCmd = program
72
+ .command("companion")
73
+ .description("Long-running. Serve the owner's interactive chat turns (companion mode).")
74
+ .action(async () => {
75
+ try {
76
+ const handle = await companionCommand();
77
+ const shutdown = () => {
78
+ void handle.stop().finally(() => process.exit(0));
79
+ };
80
+ process.on("SIGINT", shutdown);
81
+ process.on("SIGTERM", shutdown);
82
+ // Keep the process alive; the loop runs on timers until a signal.
83
+ await new Promise(() => { });
84
+ }
85
+ catch (err) {
86
+ console.error(chalk.red(`✗ ${err.message}`));
87
+ process.exitCode = 1;
88
+ }
89
+ });
90
+ companionCmd
91
+ .command("status")
92
+ .description("Print the one-line companion status (menu-bar friendly).")
93
+ .action(async () => {
94
+ try {
95
+ await companionStatusCommand();
96
+ }
97
+ catch (err) {
98
+ console.error(chalk.red(`✗ ${err.message}`));
99
+ process.exitCode = 1;
100
+ }
101
+ });
102
+ companionCmd
103
+ .command("install")
104
+ .description("Install the companion login agent (autostart at login).")
105
+ .action(async () => {
106
+ try {
107
+ await companionInstallCommand();
108
+ }
109
+ catch (err) {
110
+ console.error(chalk.red(`✗ ${err.message}`));
111
+ process.exitCode = 1;
112
+ }
113
+ });
114
+ companionCmd
115
+ .command("uninstall")
116
+ .description("Remove the companion login agent.")
117
+ .action(async () => {
118
+ try {
119
+ await companionUninstallCommand();
120
+ }
121
+ catch (err) {
122
+ console.error(chalk.red(`✗ ${err.message}`));
123
+ process.exitCode = 1;
124
+ }
125
+ });
66
126
  program
67
127
  .command("doctor")
68
128
  .description("Run environment checks. Exit 0 if all green, 1 otherwise.")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import type { RunnerCapacityClass } from "./engines/types.js";
2
+ /** LaunchAgent / systemd label for the companion login agent (distinct from the fleet `watch` job). */
3
+ export declare const COMPANION_AUTOSTART_LABEL: "com.tokenfactory.acc-runner-companion";
4
+ /** Injectable host surface so install/uninstall are testable without real fs. */
5
+ export interface AutostartHost {
6
+ platform: NodeJS.Platform;
7
+ home: string;
8
+ /** Absolute path to the acc-runner CLI binary. */
9
+ binPath: string;
10
+ writeFile: (p: string, contents: string) => Promise<void>;
11
+ removeFile: (p: string) => Promise<void>;
12
+ fileExists: (p: string) => Promise<boolean>;
13
+ mkdirp: (dir: string) => Promise<void>;
14
+ }
15
+ /** Where the companion login agent is written on the current platform (null = unsupported). */
16
+ export declare function autostartUnitPath(host: Pick<AutostartHost, "platform" | "home">): string | null;
17
+ /**
18
+ * macOS LaunchAgent plist for `acc-runner companion`. `caffeinate -i` keeps the
19
+ * system awake WHILE serving (released the instant it exits, so lid-close
20
+ * behaviour is otherwise unchanged); KeepAlive restarts on crash with a 60s
21
+ * throttle to bound a crash loop.
22
+ */
23
+ export declare function buildLaunchAgentPlist(opts: {
24
+ binPath: string;
25
+ home: string;
26
+ caffeinatePath?: string;
27
+ }): string;
28
+ /** Linux systemd --user unit for `acc-runner companion` (restart-on-failure). */
29
+ export declare function buildSystemdUnit(opts: {
30
+ binPath: string;
31
+ }): string;
32
+ /** Result of an install/uninstall attempt. */
33
+ export interface AutostartResult {
34
+ ok: boolean;
35
+ /** The unit path written/removed, or null on an unsupported platform. */
36
+ unitPath: string | null;
37
+ /** Human-readable follow-up (e.g. the `launchctl load` command to run). */
38
+ detail: string;
39
+ }
40
+ /**
41
+ * Install the companion login agent for the current user. Writes the unit file
42
+ * only — it never runs `launchctl load` / `systemctl --user enable` itself (a
43
+ * privileged/interactive step the operator runs, echoed in `detail`), mirroring
44
+ * the HALT-before-side-effect discipline of the existing install-launchd.sh.
45
+ */
46
+ export declare function installAutostart(host: AutostartHost): Promise<AutostartResult>;
47
+ /** Remove the companion login agent unit file (idempotent). */
48
+ export declare function uninstallAutostart(host: AutostartHost): Promise<AutostartResult>;
49
+ /** Build the default production host (real fs + this machine's platform/home). */
50
+ export declare function defaultAutostartHost(binPath: string): AutostartHost;
51
+ /** State a companion status line renders. */
52
+ export interface CompanionStatusView {
53
+ online: boolean;
54
+ ownerEmail: string | null;
55
+ conversations: number;
56
+ activeTurns: number;
57
+ capacity: RunnerCapacityClass | null;
58
+ /** Chat circuit open (chat lane benched). */
59
+ circuitOpen: boolean;
60
+ /** Whether the loopback mirror socket is serving. */
61
+ mirror: boolean;
62
+ }
63
+ /**
64
+ * Render the one-line companion status. Compact and dot-prefixed so it drops
65
+ * straight into a menu-bar tool, e.g.:
66
+ * ● acc companion · u@example.com · 2 convo · 1 turn · idle · mirror
67
+ * ○ acc companion · offline
68
+ * ⚠ acc companion · u@example.com · chat circuit open
69
+ */
70
+ export declare function companionStatusLine(v: CompanionStatusView): string;
71
+ //# sourceMappingURL=companion-autostart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion-autostart.d.ts","sourceRoot":"","sources":["../src/companion-autostart.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,uGAAuG;AACvG,eAAO,MAAM,yBAAyB,EAAG,uCAAgD,CAAC;AAE1F,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAQ/F;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CA6C9G;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAelE;AAED,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,yEAAyE;IACzE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBpF;AAED,+DAA+D;AAC/D,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAetF;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAmBnE;AAED,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAalE"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * CC-3C (COMPANION): autostart-at-login + status output.
3
+ *
4
+ * A companion should come up with the operator's machine — quit and it stops
5
+ * serving turns; log back in and it resumes — so this module installs a
6
+ * per-user login agent that runs `acc-runner companion`:
7
+ *
8
+ * - macOS → a LaunchAgent plist in ~/Library/LaunchAgents (RunAtLoad +
9
+ * KeepAlive, wrapped in `caffeinate -i` so serving a turn doesn't
10
+ * let the Mac idle-sleep out from under it). This is the companion
11
+ * sibling of the fleet `watch` LaunchAgent (doctor.ts LAUNCHD_LABEL)
12
+ * under its OWN label so both can run on one machine.
13
+ * - Linux → a systemd --user unit in ~/.config/systemd/user.
14
+ *
15
+ * Content generation is pure (`buildLaunchAgentPlist` / `buildSystemdUnit`) so
16
+ * the install shape is unit-tested without touching the real filesystem, and
17
+ * the fs + platform are injected into `installAutostart` / `uninstallAutostart`.
18
+ *
19
+ * `companionStatusLine` renders the one-line status the `companion status`
20
+ * command prints — compact enough to pipe into a menu-bar tool (xbar/SwiftBar)
21
+ * yet self-describing on a terminal.
22
+ */
23
+ import os from "node:os";
24
+ import path from "node:path";
25
+ import fs from "node:fs/promises";
26
+ /** LaunchAgent / systemd label for the companion login agent (distinct from the fleet `watch` job). */
27
+ export const COMPANION_AUTOSTART_LABEL = "com.tokenfactory.acc-runner-companion";
28
+ /** Where the companion login agent is written on the current platform (null = unsupported). */
29
+ export function autostartUnitPath(host) {
30
+ if (host.platform === "darwin") {
31
+ return path.join(host.home, "Library", "LaunchAgents", `${COMPANION_AUTOSTART_LABEL}.plist`);
32
+ }
33
+ if (host.platform === "linux") {
34
+ return path.join(host.home, ".config", "systemd", "user", `${COMPANION_AUTOSTART_LABEL}.service`);
35
+ }
36
+ return null;
37
+ }
38
+ /**
39
+ * macOS LaunchAgent plist for `acc-runner companion`. `caffeinate -i` keeps the
40
+ * system awake WHILE serving (released the instant it exits, so lid-close
41
+ * behaviour is otherwise unchanged); KeepAlive restarts on crash with a 60s
42
+ * throttle to bound a crash loop.
43
+ */
44
+ export function buildLaunchAgentPlist(opts) {
45
+ const caffeinate = opts.caffeinatePath ?? "/usr/bin/caffeinate";
46
+ return `<?xml version="1.0" encoding="UTF-8"?>
47
+ <plist version="1.0">
48
+ <dict>
49
+ <key>Label</key>
50
+ <string>${COMPANION_AUTOSTART_LABEL}</string>
51
+
52
+ <key>ProgramArguments</key>
53
+ <array>
54
+ <string>${caffeinate}</string>
55
+ <string>-i</string>
56
+ <string>${opts.binPath}</string>
57
+ <string>companion</string>
58
+ </array>
59
+
60
+ <key>RunAtLoad</key>
61
+ <true/>
62
+
63
+ <key>KeepAlive</key>
64
+ <true/>
65
+
66
+ <key>ThrottleInterval</key>
67
+ <integer>60</integer>
68
+
69
+ <key>ProcessType</key>
70
+ <string>Interactive</string>
71
+
72
+ <key>StandardOutPath</key>
73
+ <string>${opts.home}/Library/Logs/acc-runner-companion.out.log</string>
74
+
75
+ <key>StandardErrorPath</key>
76
+ <string>${opts.home}/Library/Logs/acc-runner-companion.err.log</string>
77
+
78
+ <key>EnvironmentVariables</key>
79
+ <dict>
80
+ <key>PATH</key>
81
+ <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
82
+ </dict>
83
+
84
+ <key>WorkingDirectory</key>
85
+ <string>${opts.home}</string>
86
+ </dict>
87
+ </plist>
88
+ `;
89
+ }
90
+ /** Linux systemd --user unit for `acc-runner companion` (restart-on-failure). */
91
+ export function buildSystemdUnit(opts) {
92
+ return `[Unit]
93
+ Description=Agent Control Center companion runner
94
+ After=network-online.target
95
+ Wants=network-online.target
96
+
97
+ [Service]
98
+ Type=simple
99
+ ExecStart=${opts.binPath} companion
100
+ Restart=on-failure
101
+ RestartSec=60
102
+
103
+ [Install]
104
+ WantedBy=default.target
105
+ `;
106
+ }
107
+ /**
108
+ * Install the companion login agent for the current user. Writes the unit file
109
+ * only — it never runs `launchctl load` / `systemctl --user enable` itself (a
110
+ * privileged/interactive step the operator runs, echoed in `detail`), mirroring
111
+ * the HALT-before-side-effect discipline of the existing install-launchd.sh.
112
+ */
113
+ export async function installAutostart(host) {
114
+ const unitPath = autostartUnitPath(host);
115
+ if (!unitPath) {
116
+ return { ok: false, unitPath: null, detail: `autostart is not supported on ${host.platform}` };
117
+ }
118
+ await host.mkdirp(path.dirname(unitPath));
119
+ const contents = host.platform === "darwin"
120
+ ? buildLaunchAgentPlist({ binPath: host.binPath, home: host.home })
121
+ : buildSystemdUnit({ binPath: host.binPath });
122
+ await host.writeFile(unitPath, contents);
123
+ const detail = host.platform === "darwin"
124
+ ? `Wrote ${unitPath}. Enable it now with: launchctl load ${unitPath}`
125
+ : `Wrote ${unitPath}. Enable it now with: systemctl --user enable --now ${COMPANION_AUTOSTART_LABEL}.service`;
126
+ return { ok: true, unitPath, detail };
127
+ }
128
+ /** Remove the companion login agent unit file (idempotent). */
129
+ export async function uninstallAutostart(host) {
130
+ const unitPath = autostartUnitPath(host);
131
+ if (!unitPath) {
132
+ return { ok: false, unitPath: null, detail: `autostart is not supported on ${host.platform}` };
133
+ }
134
+ const exists = await host.fileExists(unitPath);
135
+ if (!exists) {
136
+ return { ok: true, unitPath, detail: `No companion login agent installed (${unitPath} absent).` };
137
+ }
138
+ await host.removeFile(unitPath);
139
+ const detail = host.platform === "darwin"
140
+ ? `Removed ${unitPath}. Stop it now with: launchctl unload ${unitPath}`
141
+ : `Removed ${unitPath}. Stop it now with: systemctl --user disable --now ${COMPANION_AUTOSTART_LABEL}.service`;
142
+ return { ok: true, unitPath, detail };
143
+ }
144
+ /** Build the default production host (real fs + this machine's platform/home). */
145
+ export function defaultAutostartHost(binPath) {
146
+ return {
147
+ platform: process.platform,
148
+ home: os.homedir(),
149
+ binPath,
150
+ writeFile: (p, c) => fs.writeFile(p, c, "utf8"),
151
+ removeFile: (p) => fs.rm(p, { force: true }),
152
+ fileExists: async (p) => {
153
+ try {
154
+ await fs.access(p);
155
+ return true;
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ },
161
+ mkdirp: async (dir) => {
162
+ await fs.mkdir(dir, { recursive: true });
163
+ },
164
+ };
165
+ }
166
+ /**
167
+ * Render the one-line companion status. Compact and dot-prefixed so it drops
168
+ * straight into a menu-bar tool, e.g.:
169
+ * ● acc companion · u@example.com · 2 convo · 1 turn · idle · mirror
170
+ * ○ acc companion · offline
171
+ * ⚠ acc companion · u@example.com · chat circuit open
172
+ */
173
+ export function companionStatusLine(v) {
174
+ if (!v.online)
175
+ return "○ acc companion · offline";
176
+ const dot = v.circuitOpen ? "⚠" : "●";
177
+ const parts = [`${dot} acc companion`, v.ownerEmail ?? "unknown owner"];
178
+ if (v.circuitOpen) {
179
+ parts.push("chat circuit open");
180
+ }
181
+ else {
182
+ parts.push(`${v.conversations} convo`);
183
+ parts.push(`${v.activeTurns} turn${v.activeTurns === 1 ? "" : "s"}`);
184
+ if (v.capacity)
185
+ parts.push(v.capacity);
186
+ if (v.mirror)
187
+ parts.push("mirror");
188
+ }
189
+ return parts.join(" · ");
190
+ }
191
+ //# sourceMappingURL=companion-autostart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion-autostart.js","sourceRoot":"","sources":["../src/companion-autostart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * CC-3C (COMPANION): the localhost mirror socket.
3
+ *
4
+ * A companion runner already streams its chat-turn output to the control plane
5
+ * over the `chat:<conversation_id>` Realtime topic (chat-transport.ts) — that
6
+ * path is authoritative: the server-side consumer persists deltas into
7
+ * acc.chat_turn_deltas and the DB stays the SINGLE source of truth. This module
8
+ * adds a SECOND, purely-local delivery of the same frames over a loopback-only
9
+ * WebSocket so the operator's browser — running on the same machine as the
10
+ * companion — can paint the reply with sub-round-trip latency instead of waiting
11
+ * on the Realtime fan-out.
12
+ *
13
+ * Two invariants make the fast path safe, and both are enforced structurally so
14
+ * a conformance test can assert them:
15
+ *
16
+ * 1. AUTHENTICATED — the server binds to 127.0.0.1 ONLY (never a routable
17
+ * interface) and every upgrade must present the session-bound handshake
18
+ * token. A missing/blank/wrong token is closed with 1008 before a single
19
+ * frame is delivered. The expected token is injected (bound to the runner's
20
+ * current keychain session, rotated on logout), so the socket can never
21
+ * outlive the session it mirrors.
22
+ *
23
+ * 2. MIRROR-ONLY — the server is constructed with an OUTBOUND broadcast source
24
+ * and nothing else. It holds no Supabase client, no `ChatLaneTransport`, no
25
+ * RPC handle: there is literally no method by which an inbound frame could
26
+ * mutate DB state. Inbound frames are accepted (so the browser may send
27
+ * liveness pings) but routed to a no-op sink; the module exposes an
28
+ * `inboundCount()` so the conformance test can prove traffic arrived AND
29
+ * that arrival changed nothing. The `mirror_only: true` flag stamped on
30
+ * every frame tells the browser the same thing on the wire: treat the DB
31
+ * read as truth; this is a latency shim.
32
+ *
33
+ * The whole surface (server factory, clock, log sink) is injectable so the
34
+ * conformance suite exercises it against a real loopback socket without any
35
+ * network or `claude` binary.
36
+ */
37
+ import { type Server } from "node:http";
38
+ import { CHAT_LANE_PROTOCOL_VERSION } from "./chat-lane.js";
39
+ /** The loopback address the mirror socket binds to — never a routable interface. */
40
+ export declare const MIRROR_SOCKET_HOST: "127.0.0.1";
41
+ /** Query-string key the browser passes the session-bound handshake token under. */
42
+ export declare const MIRROR_TOKEN_QUERY_KEY: "token";
43
+ /** WebSocket close code for an unauthenticated / unauthorised upgrade (policy violation). */
44
+ export declare const MIRROR_CLOSE_UNAUTHORIZED: 1008;
45
+ /** Mirror-frame lifecycle events (the subset of chat-topic events worth mirroring). */
46
+ export type MirrorFrameEvent = "turn_stream" | "turn_complete" | "turn_requeued";
47
+ /**
48
+ * One frame pushed over the loopback mirror. `mirror_only: true` and
49
+ * `source: "companion-mirror"` are on the wire so the browser never mistakes a
50
+ * latency-shim frame for an authoritative DB read.
51
+ */
52
+ export interface MirrorFrame {
53
+ protocol_version: typeof CHAT_LANE_PROTOCOL_VERSION;
54
+ source: "companion-mirror";
55
+ /** Always true — the DB (via the Realtime topic) is the source of truth. */
56
+ mirror_only: true;
57
+ conversation_id: string;
58
+ turn_id: string;
59
+ event: MirrorFrameEvent;
60
+ /** The chat-lane stream/complete/requeue payload, verbatim. */
61
+ payload: unknown;
62
+ ts: string;
63
+ }
64
+ /** Constant-time token compare that tolerates length mismatch without throwing. */
65
+ export declare function tokensMatch(a: string, b: string): boolean;
66
+ /**
67
+ * Extract the handshake token from an upgrade request URL's query string.
68
+ * Returns "" when absent so the caller's compare fails closed.
69
+ */
70
+ export declare function extractMirrorToken(url: string | undefined): string;
71
+ export interface CompanionMirrorSocketOptions {
72
+ /**
73
+ * The session-bound handshake token an upgrade must present. Bound to the
74
+ * runner's current keychain session; a rotated/absent session means a new
75
+ * (or no) token, so the mirror never outlives the session it reflects.
76
+ */
77
+ expectedToken: string;
78
+ /** Loopback port to bind (0 = ephemeral; read back via `port()` after `start`). */
79
+ port: number;
80
+ /** Clock (test seam). */
81
+ now?: () => number;
82
+ /** Best-effort log sink. */
83
+ onLog?: (line: string) => void;
84
+ /**
85
+ * Test/observability seam invoked for every INBOUND frame. It is a pure
86
+ * sink — it cannot (and must not) mutate any control-plane state; its only
87
+ * purpose is to let the conformance test prove inbound traffic arrived and
88
+ * changed nothing.
89
+ */
90
+ onInbound?: (raw: string) => void;
91
+ /** Injected server factory (default: node http.createServer). Test seam. */
92
+ createHttpServer?: () => Server;
93
+ }
94
+ /**
95
+ * The loopback mirror server. Construct it with an OUTBOUND broadcast source
96
+ * only: `mirror()` fans a frame to every authed browser client; there is no
97
+ * inbound → mutation path by construction (see module header, invariant 2).
98
+ */
99
+ export declare class CompanionMirrorSocket {
100
+ private readonly opts;
101
+ private http;
102
+ private wss;
103
+ private readonly clients;
104
+ private inbound;
105
+ private boundPort;
106
+ private readonly now;
107
+ constructor(opts: CompanionMirrorSocketOptions);
108
+ /** Bind the loopback server and begin accepting authed upgrades. */
109
+ start(): Promise<void>;
110
+ /** The bound loopback port (meaningful only after `start`; resolves an ephemeral 0). */
111
+ port(): number;
112
+ /** Live authed browser client count. */
113
+ clientCount(): number;
114
+ /** Total inbound frames received (all routed to the no-op sink — proof of mirror-only). */
115
+ inboundCount(): number;
116
+ /**
117
+ * Fan one chat-lane frame to every connected browser. Best-effort: a send
118
+ * failure to one stale client never blocks the others or the turn. Returns
119
+ * the number of clients the frame was written to.
120
+ */
121
+ mirror(event: MirrorFrameEvent, conversationId: string, turnId: string, payload: unknown): number;
122
+ /** Tear the server down: close every client, then the WS + HTTP servers. */
123
+ close(): Promise<void>;
124
+ private accept;
125
+ }
126
+ //# sourceMappingURL=companion-mirror-socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion-mirror-socket.d.ts","sourceRoot":"","sources":["../src/companion-mirror-socket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,EAAG,WAAoB,CAAC;AAEvD,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,EAAG,OAAgB,CAAC;AAEvD,6FAA6F;AAC7F,eAAO,MAAM,yBAAyB,EAAG,IAAa,CAAC;AAEvD,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,eAAe,GAAG,eAAe,CAAC;AAEjF;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,OAAO,0BAA0B,CAAC;IACpD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,4EAA4E;IAC5E,WAAW,EAAE,IAAI,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,+DAA+D;IAC/D,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMlE;AAED,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,qBAAa,qBAAqB;IAQpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEN,IAAI,EAAE,4BAA4B;IAI/D,oEAAoE;IAC9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC5B,wFAAwF;IACxF,IAAI,IAAI,MAAM;IAId,wCAAwC;IACxC,WAAW,IAAI,MAAM;IAIrB,2FAA2F;IAC3F,YAAY,IAAI,MAAM;IAItB;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM;IA0BjG,4EAA4E;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,OAAO,CAAC,MAAM;CAYf"}