@gajae-code/coding-agent 0.12.10 → 0.12.12
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/CHANGELOG.md +47 -2
- package/dist/types/cli/notify-cli.d.ts +42 -1
- package/dist/types/cli/update-cli.d.ts +9 -3
- package/dist/types/commands/notify.d.ts +6 -0
- package/dist/types/config/file-lock.d.ts +3 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/question-state.d.ts +3 -1
- package/dist/types/extensibility/extensions/index.d.ts +1 -0
- package/dist/types/extensibility/extensions/ouroboros-ooo-bridge.d.ts +13 -0
- package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +0 -1
- package/dist/types/extensibility/extensions/types.d.ts +2 -0
- package/dist/types/main.d.ts +6 -2
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/utils/host-status.d.ts +23 -0
- package/dist/types/runtime-mcp/types.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +12 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +3 -0
- package/dist/types/sdk/bus/chat-daemon-command-channel.d.ts +244 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +13 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +7 -0
- package/dist/types/sdk/bus/control-plane-frames.d.ts +43 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +18 -0
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +71 -0
- package/dist/types/sdk/bus/notification-service.d.ts +10 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +27 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +11 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +14 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +140 -0
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +25 -7
- package/dist/types/sdk/bus/telegram-daemon.d.ts +104 -16
- package/dist/types/sdk/bus/telegram-reference.d.ts +10 -1
- package/dist/types/sdk/bus/topic-registry.d.ts +130 -85
- package/dist/types/sdk/host/host.d.ts +52 -0
- package/dist/types/sdk/lifecycle-session.d.ts +6 -0
- package/dist/types/sdk/session-activation.d.ts +41 -0
- package/dist/types/sdk/session.d.ts +18 -0
- package/dist/types/sdk/startup-capability.d.ts +8 -1
- package/dist/types/session/agent-session.d.ts +7 -0
- package/dist/types/session/artifacts.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +12 -2
- package/dist/types/session/session-manager.d.ts +40 -5
- package/dist/types/session/session-storage.d.ts +1 -0
- package/dist/types/tools/computer.d.ts +35 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/todo-write.d.ts +2 -0
- package/dist/types/utils/npm-registry.d.ts +71 -0
- package/examples/extensions/README.md +38 -4
- package/examples/extensions/ooo-bridge.ts +15 -0
- package/package.json +8 -8
- package/scripts/generate-sdk-operation-inventory.ts +4 -0
- package/src/async/job-manager.ts +9 -2
- package/src/cli/notify-cli.ts +226 -2
- package/src/cli/update-cli.ts +90 -23
- package/src/commands/notify.ts +27 -3
- package/src/commands/sdk.ts +1 -0
- package/src/config/file-lock-gc.ts +18 -0
- package/src/config/file-lock.ts +61 -16
- package/src/config/model-profiles.ts +31 -15
- package/src/coordinator/contract.ts +1 -0
- package/src/coordinator-mcp/question-state.ts +2 -0
- package/src/coordinator-mcp/server.ts +358 -7
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +2 -0
- package/src/extensibility/extensions/index.ts +1 -0
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +235 -0
- package/src/extensibility/extensions/prefix-command-bridge.ts +4 -9
- package/src/extensibility/extensions/runner.ts +15 -2
- package/src/extensibility/extensions/types.ts +2 -0
- package/src/gjc-runtime/launch-tmux.ts +53 -1
- package/src/internal-urls/docs-index.generated.ts +13 -12
- package/src/main.ts +203 -67
- package/src/modes/DESIGN.md +8 -5
- package/src/modes/components/footer.ts +10 -18
- package/src/modes/components/session-selector.ts +26 -3
- package/src/modes/components/status-line/gh.ts +23 -2
- package/src/modes/controllers/event-controller.ts +3 -0
- package/src/modes/controllers/extension-ui-controller.ts +2 -0
- package/src/modes/controllers/input-controller.ts +11 -0
- package/src/modes/controllers/selector-controller.ts +8 -2
- package/src/modes/interactive-mode.ts +7 -1
- package/src/modes/utils/host-status.ts +38 -0
- package/src/prompts/tools/computer.md +6 -1
- package/src/runtime-mcp/types.ts +2 -0
- package/src/sdk/broker/lifecycle.ts +60 -3
- package/src/sdk/bus/chat-daemon-cli.ts +42 -0
- package/src/sdk/bus/chat-daemon-command-channel.ts +921 -0
- package/src/sdk/bus/chat-daemon-control.ts +18 -3
- package/src/sdk/bus/chat-daemon-runtime.ts +257 -21
- package/src/sdk/bus/control-plane-frames.ts +51 -0
- package/src/sdk/bus/conversation-store.ts +29 -1
- package/src/sdk/bus/existing-thread-readiness.ts +155 -0
- package/src/sdk/bus/index.ts +70 -0
- package/src/sdk/bus/notification-service.ts +28 -1
- package/src/sdk/bus/rich-render.ts +3 -2
- package/src/sdk/bus/slack-daemon.ts +99 -4
- package/src/sdk/bus/slack-live-provider.ts +32 -2
- package/src/sdk/bus/slack-provider.ts +11 -0
- package/src/sdk/bus/slack-thread-binding.ts +641 -0
- package/src/sdk/bus/telegram-daemon-cli.ts +11 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +25 -7
- package/src/sdk/bus/telegram-daemon.ts +1961 -497
- package/src/sdk/bus/telegram-reference.ts +42 -6
- package/src/sdk/bus/topic-registry.ts +674 -181
- package/src/sdk/host/host.ts +180 -1
- package/src/sdk/lifecycle-session.ts +8 -2
- package/src/sdk/protocol/operation-inventory.generated.json +22 -0
- package/src/sdk/session-activation.ts +127 -0
- package/src/sdk/session.ts +139 -28
- package/src/sdk/startup-capability.ts +10 -1
- package/src/session/agent-session.ts +331 -30
- package/src/session/artifacts.ts +56 -13
- package/src/session/internal/managed-session-storage.ts +440 -243
- package/src/session/session-manager.ts +288 -44
- package/src/session/session-storage.ts +3 -0
- package/src/setup/provider-presets.json +1 -1
- package/src/task/index.ts +92 -44
- package/src/tools/computer.ts +322 -45
- package/src/tools/index.ts +8 -0
- package/src/tools/todo-write.ts +29 -11
- package/src/utils/npm-registry.ts +660 -0
package/src/config/file-lock.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import type { Stats } from "node:fs";
|
|
2
3
|
import * as fs from "node:fs/promises";
|
|
3
4
|
import * as path from "node:path";
|
|
@@ -7,9 +8,11 @@ export interface FileLockOptions {
|
|
|
7
8
|
staleMs?: number;
|
|
8
9
|
retries?: number;
|
|
9
10
|
retryDelayMs?: number;
|
|
11
|
+
/** Stable host identity required to safely reclaim locks on a shared volume. */
|
|
12
|
+
ownerHostId?: string;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
const DEFAULT_OPTIONS: Required<FileLockOptions
|
|
15
|
+
const DEFAULT_OPTIONS: Required<Omit<FileLockOptions, "ownerHostId">> = {
|
|
13
16
|
staleMs: 10_000,
|
|
14
17
|
retries: 50,
|
|
15
18
|
retryDelayMs: 100,
|
|
@@ -61,8 +64,16 @@ function ownerIsAlive(owner: FileLockOwnerToken, startTimeCache?: Map<string, st
|
|
|
61
64
|
return currentStartTime === null || currentStartTime === owner.start_time;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
function
|
|
65
|
-
|
|
67
|
+
function lockInfo(ownerHostId?: string): LockInfo {
|
|
68
|
+
return {
|
|
69
|
+
pid: process.pid,
|
|
70
|
+
start_time: currentProcessStartTime(),
|
|
71
|
+
timestamp: Date.now(),
|
|
72
|
+
...(ownerHostId === undefined ? {} : { owner_host_id: ownerHostId }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function writeLockInfo(lockPath: string, info: LockInfo): Promise<LockInfo> {
|
|
66
77
|
return Bun.write(`${lockPath}/info`, JSON.stringify(info)).then(() => info);
|
|
67
78
|
}
|
|
68
79
|
|
|
@@ -76,17 +87,18 @@ async function readLockInfo(lockPath: string): Promise<LockInfo | null> {
|
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
|
|
79
|
-
const { pid, start_time, timestamp } = parsed as Partial<LockInfo>;
|
|
90
|
+
const { pid, start_time, timestamp, owner_host_id } = parsed as Partial<LockInfo>;
|
|
80
91
|
if (
|
|
81
92
|
typeof pid !== "number" ||
|
|
82
93
|
!Number.isInteger(pid) ||
|
|
83
94
|
pid <= 0 ||
|
|
84
95
|
typeof timestamp !== "number" ||
|
|
85
96
|
!Number.isFinite(timestamp) ||
|
|
86
|
-
(start_time !== undefined && (typeof start_time !== "string" || !start_time))
|
|
97
|
+
(start_time !== undefined && (typeof start_time !== "string" || !start_time)) ||
|
|
98
|
+
(owner_host_id !== undefined && (typeof owner_host_id !== "string" || !owner_host_id))
|
|
87
99
|
)
|
|
88
100
|
return null;
|
|
89
|
-
return { pid, start_time, timestamp };
|
|
101
|
+
return { pid, start_time, timestamp, owner_host_id };
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
/** @internal */
|
|
@@ -98,7 +110,7 @@ export async function readFileLockInfoForGc(lockDir: string): Promise<FileLockOw
|
|
|
98
110
|
export interface FileLockOwnerToken {
|
|
99
111
|
pid: number;
|
|
100
112
|
start_time?: string;
|
|
101
|
-
|
|
113
|
+
owner_host_id?: string;
|
|
102
114
|
timestamp: number;
|
|
103
115
|
}
|
|
104
116
|
|
|
@@ -147,6 +159,7 @@ export async function removeFileLockDirForGc(
|
|
|
147
159
|
if (
|
|
148
160
|
current.pid !== expected.pid ||
|
|
149
161
|
(expected.start_time !== undefined && current.start_time !== expected.start_time) ||
|
|
162
|
+
current.owner_host_id !== expected.owner_host_id ||
|
|
150
163
|
current.timestamp !== expected.timestamp
|
|
151
164
|
) {
|
|
152
165
|
return "owner_changed";
|
|
@@ -187,6 +200,7 @@ function sameStatToken(a: LockDirStatToken, b: LockDirStatToken): boolean {
|
|
|
187
200
|
async function staleLockSnapshot(
|
|
188
201
|
lockPath: string,
|
|
189
202
|
staleMs: number,
|
|
203
|
+
ownerHostId?: string,
|
|
190
204
|
startTimeCache?: Map<string, string | null>,
|
|
191
205
|
): Promise<LockStaleSnapshot> {
|
|
192
206
|
let info: LockInfo | null;
|
|
@@ -199,6 +213,7 @@ async function staleLockSnapshot(
|
|
|
199
213
|
if (hasFsCode(error, "EPERM")) return { stale: false };
|
|
200
214
|
throw error;
|
|
201
215
|
}
|
|
216
|
+
if (!info && ownerHostId !== undefined) return { stale: false };
|
|
202
217
|
if (!info) {
|
|
203
218
|
try {
|
|
204
219
|
const stats = await fs.stat(lockPath);
|
|
@@ -210,6 +225,10 @@ async function staleLockSnapshot(
|
|
|
210
225
|
}
|
|
211
226
|
}
|
|
212
227
|
|
|
228
|
+
// A host-qualified lock may only be reclaimed after proving that its owner is
|
|
229
|
+
// local. Foreign and malformed host-qualified records fail closed: PID values
|
|
230
|
+
// and clocks are not meaningful across hosts.
|
|
231
|
+
if (ownerHostId !== undefined && info.owner_host_id !== ownerHostId) return { stale: false };
|
|
213
232
|
// Never reap a live owner by elapsed time: a long legitimate critical section must
|
|
214
233
|
// not have its lock stolen (#652). Reclaim a dead owner immediately. Only when owner
|
|
215
234
|
// liveness is indeterminate do we fall back to the staleMs elapsed-time heuristic.
|
|
@@ -239,18 +258,43 @@ async function removeStaleLockForAcquire(lockPath: string, snapshot: LockStaleSn
|
|
|
239
258
|
}
|
|
240
259
|
}
|
|
241
260
|
|
|
242
|
-
async function tryAcquireLock(lockPath: string): Promise<LockInfo | null> {
|
|
261
|
+
async function tryAcquireLock(lockPath: string, ownerHostId?: string): Promise<LockInfo | null> {
|
|
243
262
|
await fs.mkdir(path.dirname(lockPath), { recursive: true });
|
|
244
263
|
const afterParentMkdir = FileLockTestHooks.afterParentMkdir;
|
|
245
264
|
if (afterParentMkdir) await afterParentMkdir(lockPath);
|
|
265
|
+
if (ownerHostId === undefined) {
|
|
266
|
+
try {
|
|
267
|
+
await fs.mkdir(lockPath);
|
|
268
|
+
return await writeLockInfo(lockPath, lockInfo());
|
|
269
|
+
} catch (error) {
|
|
270
|
+
if ((error as NodeJS.ErrnoException).code === "EEXIST") return null;
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const pendingPath = `${lockPath}.pending.${process.pid}.${crypto.randomUUID()}`;
|
|
276
|
+
const owner = lockInfo(ownerHostId);
|
|
246
277
|
try {
|
|
247
|
-
await fs.mkdir(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return
|
|
278
|
+
await fs.mkdir(pendingPath);
|
|
279
|
+
await writeLockInfo(pendingPath, owner);
|
|
280
|
+
try {
|
|
281
|
+
await fs.rename(pendingPath, lockPath);
|
|
282
|
+
return owner;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
285
|
+
if (code === "EEXIST" || code === "ENOTEMPTY") return null;
|
|
286
|
+
if (code === "EPERM") {
|
|
287
|
+
try {
|
|
288
|
+
await fs.stat(lockPath);
|
|
289
|
+
return null;
|
|
290
|
+
} catch (statError) {
|
|
291
|
+
if (!isEnoent(statError)) throw statError;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
throw error;
|
|
252
295
|
}
|
|
253
|
-
|
|
296
|
+
} finally {
|
|
297
|
+
await fs.rm(pendingPath, { recursive: true, force: true }).catch(() => undefined);
|
|
254
298
|
}
|
|
255
299
|
}
|
|
256
300
|
|
|
@@ -259,14 +303,15 @@ async function releaseLock(lockPath: string, owner: FileLockOwnerToken): Promise
|
|
|
259
303
|
if (outcome !== "removed") throw new Error(`Failed to release file lock: ${outcome}.`);
|
|
260
304
|
}
|
|
261
305
|
async function acquireLock(filePath: string, options: FileLockOptions = {}): Promise<() => Promise<void>> {
|
|
306
|
+
if (options.ownerHostId !== undefined && !options.ownerHostId) throw new Error("ownerHostId must be non-empty");
|
|
262
307
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
263
308
|
const lockPath = getLockPath(filePath);
|
|
264
309
|
const contentionStartTimes = new Map<string, string | null>();
|
|
265
310
|
for (let attempt = 0; attempt < opts.retries; attempt++) {
|
|
266
|
-
const owner = await tryAcquireLock(lockPath);
|
|
311
|
+
const owner = await tryAcquireLock(lockPath, opts.ownerHostId);
|
|
267
312
|
if (owner) return () => releaseLock(lockPath, owner);
|
|
268
313
|
|
|
269
|
-
const stale = await staleLockSnapshot(lockPath, opts.staleMs, contentionStartTimes);
|
|
314
|
+
const stale = await staleLockSnapshot(lockPath, opts.staleMs, opts.ownerHostId, contentionStartTimes);
|
|
270
315
|
if (await removeStaleLockForAcquire(lockPath, stale)) continue;
|
|
271
316
|
await Bun.sleep(opts.retryDelayMs);
|
|
272
317
|
}
|
|
@@ -243,25 +243,25 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
243
243
|
architect: "grok-build/grok-build",
|
|
244
244
|
}),
|
|
245
245
|
profile("cursor-eco", ["cursor"], {
|
|
246
|
-
default: "cursor/composer-
|
|
247
|
-
executor: "cursor/composer-
|
|
248
|
-
planner: "cursor/composer-
|
|
249
|
-
critic: "cursor/composer-
|
|
250
|
-
architect: "cursor/composer-
|
|
246
|
+
default: "cursor/composer-2.5",
|
|
247
|
+
executor: "cursor/composer-2.5",
|
|
248
|
+
planner: "cursor/composer-2.5",
|
|
249
|
+
critic: "cursor/composer-2.5",
|
|
250
|
+
architect: "cursor/composer-2.5",
|
|
251
251
|
}),
|
|
252
252
|
profile("cursor-medium", ["cursor"], {
|
|
253
|
-
default: "cursor/composer-
|
|
254
|
-
executor: "cursor/composer-
|
|
255
|
-
planner: "cursor/composer-
|
|
256
|
-
critic: "cursor/composer-
|
|
257
|
-
architect: "cursor/composer-
|
|
253
|
+
default: "cursor/composer-2.5",
|
|
254
|
+
executor: "cursor/composer-2.5-fast",
|
|
255
|
+
planner: "cursor/composer-2.5",
|
|
256
|
+
critic: "cursor/composer-2.5-fast",
|
|
257
|
+
architect: "cursor/composer-2.5-fast",
|
|
258
258
|
}),
|
|
259
259
|
profile("cursor-pro", ["cursor"], {
|
|
260
|
-
default: "cursor/composer-
|
|
261
|
-
executor: "cursor/composer-
|
|
262
|
-
planner: "cursor/composer-
|
|
263
|
-
critic: "cursor/composer-
|
|
264
|
-
architect: "cursor/composer-
|
|
260
|
+
default: "cursor/composer-2.5-fast",
|
|
261
|
+
executor: "cursor/composer-2.5-fast",
|
|
262
|
+
planner: "cursor/composer-2.5-fast",
|
|
263
|
+
critic: "cursor/composer-2.5-fast",
|
|
264
|
+
architect: "cursor/composer-2.5-fast",
|
|
265
265
|
}),
|
|
266
266
|
profile("minimax-eco", ["minimax-code"], {
|
|
267
267
|
default: "minimax-code/minimax-m3:low",
|
|
@@ -305,6 +305,20 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
305
305
|
architect: "alibaba-token-plan/qwen3.8-max-preview:xhigh",
|
|
306
306
|
critic: "alibaba-token-plan/qwen3.8-max-preview:xhigh",
|
|
307
307
|
}),
|
|
308
|
+
profile("alibaba-token-plan-qwen-deepseek", ["alibaba-token-plan"], {
|
|
309
|
+
default: "alibaba-token-plan/qwen-3.8-max:high",
|
|
310
|
+
executor: "alibaba-token-plan/deepseek-v4-flash-0731:high",
|
|
311
|
+
planner: "alibaba-token-plan/deepseek-v4-flash-0731:max",
|
|
312
|
+
architect: "alibaba-token-plan/qwen-3.8-max:xhigh",
|
|
313
|
+
critic: "alibaba-token-plan/qwen-3.8-max:xhigh",
|
|
314
|
+
}),
|
|
315
|
+
profile("alibaba-token-plan-glm-deepseek", ["alibaba-token-plan"], {
|
|
316
|
+
default: "alibaba-token-plan/glm-5.2:high",
|
|
317
|
+
executor: "alibaba-token-plan/deepseek-v4-flash-0731:high",
|
|
318
|
+
planner: "alibaba-token-plan/deepseek-v4-flash-0731:max",
|
|
319
|
+
architect: "alibaba-token-plan/glm-5.2:xhigh",
|
|
320
|
+
critic: "alibaba-token-plan/glm-5.2:xhigh",
|
|
321
|
+
}),
|
|
308
322
|
profile("opus-codex", ["anthropic", "openai-codex"], {
|
|
309
323
|
default: "anthropic/claude-opus-5:xhigh",
|
|
310
324
|
executor: "openai-codex/gpt-5.6-terra:low",
|
|
@@ -370,6 +384,8 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
370
384
|
"alibaba-token-plan-balanced": { displayName: "Balanced", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
371
385
|
"alibaba-token-plan-pro": { displayName: "Pro", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
372
386
|
"alibaba-token-plan-qwenmaxxing": { displayName: "QwenMaxxing", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
387
|
+
"alibaba-token-plan-qwen-deepseek": { displayName: "Qwen + DeepSeek", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
388
|
+
"alibaba-token-plan-glm-deepseek": { displayName: "GLM + DeepSeek", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
373
389
|
"opus-codex": { displayName: "Opus + Codex", providerGroup: "COMBOS" },
|
|
374
390
|
"codex-opencodego": { displayName: "Codex + OpenCodeGo", providerGroup: "COMBOS" },
|
|
375
391
|
"fable-opus-codex": { displayName: "Fable + Opus + Codex", providerGroup: "COMBOS" },
|
|
@@ -12,6 +12,7 @@ export const COORDINATOR_MCP_TOOL_NAMES = [
|
|
|
12
12
|
"gjc_coordinator_watch_events",
|
|
13
13
|
"gjc_coordinator_register_session",
|
|
14
14
|
"gjc_coordinator_start_session",
|
|
15
|
+
"gjc_coordinator_activate_session",
|
|
15
16
|
"gjc_coordinator_stop_session",
|
|
16
17
|
"gjc_coordinator_send_prompt",
|
|
17
18
|
"gjc_coordinator_submit_question_answer",
|
|
@@ -6,6 +6,8 @@ import type { PrivateAskGateCodecV1, PublicReason } from "./question-gate-codec"
|
|
|
6
6
|
|
|
7
7
|
export type CoordinatorSessionState =
|
|
8
8
|
| "booting"
|
|
9
|
+
/** Live and endpoint-addressable, but withholding readiness until activation. */
|
|
10
|
+
| "prepared"
|
|
9
11
|
| "ready_for_input"
|
|
10
12
|
| "running"
|
|
11
13
|
| "needs_user_input"
|