@tokenfactory/acc-runner 0.40.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.
@@ -0,0 +1,343 @@
1
+ /**
2
+ * CC-3C (COMPANION): companion-mode runtime for the acc-runner CLI.
3
+ *
4
+ * A COMPANION is a runner attached to its owner's operator chats. It is a
5
+ * distinct execution shape from the fleet `watch` runner:
6
+ *
7
+ * - OWNER-AFFINITY LANE — a companion serves ONLY its bound owner's chat
8
+ * turns. `OwnerConversationSource` is the runner-side guarantee: a
9
+ * conversation is only served when its owner is the bound user, so a
10
+ * companion never claims another operator's turn even if the queue is
11
+ * shared. Cross-runner contention is still resolved by the per-conversation
12
+ * advisory lock in `acc.claim_chat_turn` (migration 0254) — a fleet runner
13
+ * and a companion can race the SAME conversation and exactly one wins; the
14
+ * companion just never races a conversation that isn't its owner's.
15
+ *
16
+ * - NO CODE LANE BY DEFAULT — the `companion` command drives the chat lane
17
+ * only (`activeCodeTasks` is always 0 and no task/review pump runs). A
18
+ * companion claims interactive turns, not build tasks. (The `watch` command
19
+ * remains the code/review fleet runner; the same machine may run both.)
20
+ *
21
+ * - FAIL-OVER TO FLEET — when the companion stops (operator quit, laptop
22
+ * sleep, crash), its in-flight turns are REQUEUED (via the driver's
23
+ * abort→requeue path) and an `companion_lost` identity event flips the
24
+ * identity offline immediately, so an Auto-routed turn fails over to a
25
+ * fleet runner with no duplicate side effects (the driver emits exactly one
26
+ * terminal transport call per turn).
27
+ *
28
+ * - LOCALHOST MIRROR — the companion's turn stream is teed to a loopback
29
+ * mirror socket (companion-mirror-socket.ts) so the same-machine browser
30
+ * paints replies with sub-round-trip latency. The DB (via the chat topic)
31
+ * stays the single source of truth; the mirror is a read-only latency shim.
32
+ *
33
+ * Everything side-effecting (transport, engine, identity broadcaster, heartbeat,
34
+ * clock, mirror socket) is injected so the orchestrator is exercised
35
+ * deterministically without a network or a `claude` binary.
36
+ */
37
+ import { createHash } from "node:crypto";
38
+ import { ChatCompanion } from "./chat-companion.js";
39
+ import { resolveChatLaneConfig, } from "./chat-lane.js";
40
+ /** Build the per-identity capacity Realtime topic (mirror of the web builder). */
41
+ export function identityTopic(userId) {
42
+ return `identity:${userId}`;
43
+ }
44
+ /* ------------------------------------------------------------------ *
45
+ * 2. Companion config (env resolution)
46
+ * ------------------------------------------------------------------ */
47
+ /** Opt the runner's chat lane into serving code tasks too (default: chat only). */
48
+ export const COMPANION_CODE_TASKS_ENV = "ACC_RUNNER_COMPANION_CODE_TASKS";
49
+ /** Disable the localhost mirror socket (default: enabled). */
50
+ export const COMPANION_MIRROR_ENV = "ACC_RUNNER_COMPANION_MIRROR";
51
+ /** Loopback port the mirror socket binds to. */
52
+ export const COMPANION_MIRROR_PORT_ENV = "ACC_RUNNER_COMPANION_MIRROR_PORT";
53
+ /** Explicit mirror handshake token override (else derived from the session). */
54
+ export const COMPANION_MIRROR_TOKEN_ENV = "ACC_RUNNER_COMPANION_MIRROR_TOKEN";
55
+ /** Default loopback port for the mirror socket. */
56
+ export const DEFAULT_COMPANION_MIRROR_PORT = 7717;
57
+ function isTruthyFlag(raw) {
58
+ const v = (raw ?? "").trim().toLowerCase();
59
+ return v === "1" || v === "true" || v === "yes" || v === "on";
60
+ }
61
+ function isFalsyFlag(raw) {
62
+ const v = (raw ?? "").trim().toLowerCase();
63
+ return v === "0" || v === "false" || v === "no" || v === "off";
64
+ }
65
+ /** Resolve companion knobs from the environment in one place. */
66
+ export function resolveCompanionConfig(env = process.env) {
67
+ const portRaw = Number.parseInt((env[COMPANION_MIRROR_PORT_ENV] ?? "").trim(), 10);
68
+ const mirrorPort = Number.isFinite(portRaw) && portRaw > 0 && portRaw < 65_536 ? portRaw : DEFAULT_COMPANION_MIRROR_PORT;
69
+ const tokenRaw = (env[COMPANION_MIRROR_TOKEN_ENV] ?? "").trim();
70
+ return {
71
+ codeTasksEnabled: isTruthyFlag(env[COMPANION_CODE_TASKS_ENV]),
72
+ // Mirror is on unless explicitly disabled.
73
+ mirrorEnabled: !isFalsyFlag(env[COMPANION_MIRROR_ENV]),
74
+ mirrorPort,
75
+ mirrorToken: tokenRaw || null,
76
+ };
77
+ }
78
+ /**
79
+ * Derive the loopback mirror handshake token from the session. Bound to the
80
+ * refresh token (stable across hourly access-token refreshes, rotated on
81
+ * re-login / logout) + the runner id, one-way hashed so the token never leaks
82
+ * either. The same-machine browser obtains the matching token through the
83
+ * authenticated control plane; this keeps the mirror strictly session-bound —
84
+ * it cannot outlive the session it reflects.
85
+ */
86
+ export function deriveMirrorToken(session) {
87
+ return createHash("sha256")
88
+ .update(`${session.refresh_token}:${session.runner_id}:acc-companion-mirror`)
89
+ .digest("hex")
90
+ .slice(0, 32);
91
+ }
92
+ /* ------------------------------------------------------------------ *
93
+ * 3. Owner-affinity conversation source
94
+ * ------------------------------------------------------------------ */
95
+ /**
96
+ * The set of conversations a companion is allowed to serve — the OWNER-AFFINITY
97
+ * guarantee. A conversation enters the set only when its owner is the bound
98
+ * user; `add` returns false and no-ops for any other owner, so the companion's
99
+ * claim loop can never present a foreign operator's conversation to the claim
100
+ * RPC. Fed by the control plane (the browser announces which conversation the
101
+ * operator is active in over the authenticated `identity:<user>` topic); an
102
+ * optional seed lists conversations known at boot.
103
+ */
104
+ export class OwnerConversationSource {
105
+ boundUserId;
106
+ ids = new Set();
107
+ constructor(boundUserId, seed = []) {
108
+ this.boundUserId = boundUserId;
109
+ for (const s of seed)
110
+ this.add(s.conversationId, s.ownerUserId);
111
+ }
112
+ /**
113
+ * Register a conversation IF and only if its owner is the bound user. Returns
114
+ * true when it was added (owner match), false when rejected (foreign owner or
115
+ * blank id). This is the single enforcement point for owner-affinity.
116
+ */
117
+ add(conversationId, ownerUserId) {
118
+ const id = (conversationId ?? "").trim();
119
+ if (!id)
120
+ return false;
121
+ if (ownerUserId !== this.boundUserId)
122
+ return false;
123
+ this.ids.add(id);
124
+ return true;
125
+ }
126
+ /** Drop a conversation (operator closed it / it moved to another owner). */
127
+ remove(conversationId) {
128
+ this.ids.delete((conversationId ?? "").trim());
129
+ }
130
+ /** True when the conversation is currently served by this companion. */
131
+ has(conversationId) {
132
+ return this.ids.has((conversationId ?? "").trim());
133
+ }
134
+ /** Stable snapshot of the served conversations (for the claim loop). */
135
+ snapshot() {
136
+ return [...this.ids];
137
+ }
138
+ /** Count of served conversations. */
139
+ size() {
140
+ return this.ids.size;
141
+ }
142
+ }
143
+ /* ------------------------------------------------------------------ *
144
+ * 4. Mirror tee — teeing the outbound turn stream onto the loopback socket
145
+ * ------------------------------------------------------------------ */
146
+ /**
147
+ * Wrap a `ChatLaneTransport` so every OUTBOUND lifecycle message (stream /
148
+ * complete / requeue) is ALSO pushed to the loopback mirror socket after the
149
+ * authoritative transport call succeeds. This is a strict tee: the wrapper only
150
+ * reads the payloads the driver already sends to the DB path — it introduces no
151
+ * new mutation and no inbound path. With no mirror socket it is the identity
152
+ * wrapper. `claim` / `markStreaming` pass straight through (nothing to mirror).
153
+ */
154
+ export function mirrorTee(transport, mirror) {
155
+ if (!mirror)
156
+ return transport;
157
+ return {
158
+ claim: (args) => transport.claim(args),
159
+ ...(transport.markStreaming
160
+ ? { markStreaming: (turn) => transport.markStreaming(turn) }
161
+ : {}),
162
+ async stream(turn, payload) {
163
+ await transport.stream(turn, payload);
164
+ mirror.mirror("turn_stream", turn.conversation_id, turn.id, payload);
165
+ },
166
+ async complete(turn, payload) {
167
+ await transport.complete(turn, payload);
168
+ mirror.mirror("turn_complete", turn.conversation_id, turn.id, payload);
169
+ },
170
+ async requeue(turn, payload) {
171
+ await transport.requeue(turn, payload);
172
+ mirror.mirror("turn_requeued", turn.conversation_id, turn.id, payload);
173
+ },
174
+ };
175
+ }
176
+ /**
177
+ * Drive companion mode: register the owner-bound identity, serve the owner's
178
+ * chat turns through a `ChatCompanion` (chat lane only — `activeCodeTasks` is
179
+ * always 0), tee the stream to the loopback mirror, heartbeat the identity
180
+ * online, and on stop requeue in-flight turns + flip the identity offline so an
181
+ * Auto turn fails over to the fleet.
182
+ */
183
+ export class CompanionRunner {
184
+ deps;
185
+ companion = null;
186
+ heartbeatTimer = null;
187
+ lastCapacity = null;
188
+ stopped = false;
189
+ now;
190
+ constructor(deps) {
191
+ this.deps = deps;
192
+ this.now = deps.now ?? Date.now;
193
+ }
194
+ /** Chat turns currently in flight on this companion. */
195
+ activeChatTurns() {
196
+ return this.companion?.activeChatTurns() ?? 0;
197
+ }
198
+ /** Register the owner-bound identity, start the pump + mirror + heartbeat. */
199
+ async start() {
200
+ if (this.companion || this.stopped)
201
+ return;
202
+ const probe = await this.deps.engine.credentialProbe().catch(() => null);
203
+ const capacity = await this.deps.engine.classifyCapacity().catch(() => "light");
204
+ this.lastCapacity = capacity;
205
+ const capabilities = {
206
+ ...this.deps.engine.capabilities,
207
+ // Report the tier the resolved credential actually authorises (probe wins
208
+ // over the static declaration; an unavailable probe drops to unavailable).
209
+ ...(probe ? { tier: probe.tier } : {}),
210
+ };
211
+ const register = {
212
+ mode: "companion",
213
+ bound_user_id: this.deps.boundUserId,
214
+ engine_ids: [this.deps.engine.id],
215
+ capability_matrix: capabilities,
216
+ capacity,
217
+ };
218
+ await this.deps.announce("companion_registered", register);
219
+ if (this.deps.mirror)
220
+ await this.deps.mirror.start();
221
+ this.companion = new ChatCompanion({
222
+ runnerId: this.deps.runnerId,
223
+ engine: this.deps.engine,
224
+ transport: mirrorTee(this.deps.transport, this.deps.mirror),
225
+ breaker: this.deps.breaker,
226
+ concurrencyLimit: this.deps.concurrencyLimit,
227
+ maxShare: this.deps.maxShare,
228
+ leaseMs: this.deps.leaseMs,
229
+ conversations: () => this.deps.conversations.snapshot(),
230
+ // Companion is a chat-only lane: no code/review tasks contend for slots.
231
+ activeCodeTasks: () => 0,
232
+ ...(this.deps.cwd !== undefined ? { cwd: this.deps.cwd } : {}),
233
+ ...(this.deps.mintDelegation ? { mintDelegation: this.deps.mintDelegation } : {}),
234
+ ...(this.deps.now ? { now: this.deps.now } : {}),
235
+ ...(this.deps.onLog ? { onLog: this.deps.onLog } : {}),
236
+ });
237
+ this.companion.start(this.deps.pumpMs ?? 1_000);
238
+ // Heartbeat keeps the identity online; a lapse (sleep/crash) is what flips
239
+ // it offline server-side and fails Auto over to the fleet.
240
+ await this.beat();
241
+ const beatMs = this.deps.heartbeatMs ?? 4_000;
242
+ this.heartbeatTimer = setInterval(() => void this.beat(), beatMs);
243
+ this.heartbeatTimer.unref?.();
244
+ }
245
+ /**
246
+ * Stop the companion: requeue in-flight turns (clean fail-over — the driver
247
+ * emits exactly one requeue, no duplicate completion), flip the identity
248
+ * offline so Auto routes to the fleet, and tear the mirror down.
249
+ */
250
+ async stop() {
251
+ if (this.stopped)
252
+ return;
253
+ this.stopped = true;
254
+ if (this.heartbeatTimer) {
255
+ clearInterval(this.heartbeatTimer);
256
+ this.heartbeatTimer = null;
257
+ }
258
+ // Requeue every in-flight turn so a fleet runner can finish it.
259
+ if (this.companion)
260
+ await this.companion.stop().catch(() => []);
261
+ // Flip the identity offline immediately (don't wait for the heartbeat lapse).
262
+ await this.deps
263
+ .announce("companion_lost", {
264
+ runner_id: this.deps.runnerId,
265
+ capacity: "overloaded",
266
+ available_engine_ids: [],
267
+ ts: new Date(this.now()).toISOString(),
268
+ })
269
+ .catch(() => undefined);
270
+ if (this.deps.mirror)
271
+ await this.deps.mirror.close().catch(() => undefined);
272
+ }
273
+ /** One heartbeat: keep the identity online + announce a capacity change. */
274
+ async beat() {
275
+ if (this.stopped)
276
+ return;
277
+ await this.deps.heartbeat().catch((err) => {
278
+ this.deps.onLog?.(`[acc-runner] companion heartbeat failed: ${err.message}`);
279
+ });
280
+ const capacity = await this.deps.engine.classifyCapacity().catch(() => this.lastCapacity);
281
+ if (capacity && capacity !== this.lastCapacity) {
282
+ this.lastCapacity = capacity;
283
+ await this.deps
284
+ .announce("capacity_changed", {
285
+ runner_id: this.deps.runnerId,
286
+ capacity,
287
+ available_engine_ids: [this.deps.engine.id],
288
+ ts: new Date(this.now()).toISOString(),
289
+ })
290
+ .catch(() => undefined);
291
+ }
292
+ }
293
+ }
294
+ /**
295
+ * Build the identity-topic broadcaster for a companion. Broadcasts on
296
+ * `identity:<userId>` via the runner's Supabase realtime client. Kept separate
297
+ * from the orchestrator so tests inject a recording fake instead.
298
+ */
299
+ export function createIdentityBroadcaster(
300
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
301
+ client, userId, opts = {}) {
302
+ const topic = identityTopic(userId);
303
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
304
+ let channel = null;
305
+ async function ensure() {
306
+ if (channel)
307
+ return channel;
308
+ channel = client.channel(topic);
309
+ await new Promise((resolve) => {
310
+ channel.subscribe((status) => {
311
+ if (status === "SUBSCRIBED")
312
+ resolve();
313
+ });
314
+ setTimeout(resolve, 2_000).unref?.();
315
+ });
316
+ return channel;
317
+ }
318
+ return {
319
+ async announce(event, payload) {
320
+ try {
321
+ const ch = await ensure();
322
+ await ch.send({ type: "broadcast", event, payload });
323
+ }
324
+ catch (err) {
325
+ opts.onLog?.(`[acc-runner] identity broadcast(${event}) failed: ${err.message}`);
326
+ }
327
+ },
328
+ async close() {
329
+ if (channel) {
330
+ try {
331
+ await client.removeChannel(channel);
332
+ }
333
+ catch {
334
+ /* best-effort */
335
+ }
336
+ channel = null;
337
+ }
338
+ },
339
+ };
340
+ }
341
+ /** Re-export for callers that resolve chat-lane knobs alongside companion knobs. */
342
+ export { resolveChatLaneConfig };
343
+ //# sourceMappingURL=companion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion.js","sourceRoot":"","sources":["../src/companion.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenfactory/acc-runner",
3
- "version": "0.40.0",
3
+ "version": "0.40.1",
4
4
  "description": "Agent Control Center local runner. Spawns Claude Code sessions assigned via ACC.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,