@claudexor/daemon 1.0.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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/client.d.ts +40 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +74 -0
- package/dist/client.js.map +1 -0
- package/dist/events.d.ts +15 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +27 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions.d.ts +44 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +81 -0
- package/dist/interactions.js.map +1 -0
- package/dist/server.d.ts +114 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +544 -0
- package/dist/server.js.map +1 -0
- package/dist/threads.d.ts +88 -0
- package/dist/threads.d.ts.map +1 -0
- package/dist/threads.js +322 -0
- package/dist/threads.js.map +1 -0
- package/dist/token.d.ts +11 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +63 -0
- package/dist/token.js.map +1 -0
- package/package.json +42 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
import { connect, createServer } from "node:net";
|
|
2
|
+
import { timingSafeEqual } from "node:crypto";
|
|
3
|
+
import { chmodSync, copyFileSync, mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { appendRunEvent } from "@claudexor/event-log";
|
|
8
|
+
import { assertNoInlineSecretValues, errorCode, newId, nowIso, pathExists, readJsonSafe, redactSecrets } from "@claudexor/util";
|
|
9
|
+
export const JOB_STATES = [
|
|
10
|
+
"queued",
|
|
11
|
+
"running",
|
|
12
|
+
"blocked",
|
|
13
|
+
"succeeded",
|
|
14
|
+
"no_op",
|
|
15
|
+
"ungated",
|
|
16
|
+
"review_not_run",
|
|
17
|
+
"failed",
|
|
18
|
+
"cancelled",
|
|
19
|
+
"interrupted",
|
|
20
|
+
"exhausted",
|
|
21
|
+
"not_converged",
|
|
22
|
+
"stuck_no_progress",
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Per-record validation for the persisted registry: one hand-edited or
|
|
26
|
+
* version-skewed record must not wipe the whole run history, and a record
|
|
27
|
+
* with a state outside the enum must never reach the strict control-api
|
|
28
|
+
* DTOs (where it would 500 the entire GET /runs list).
|
|
29
|
+
*/
|
|
30
|
+
function salvageJobRecord(raw) {
|
|
31
|
+
if (!raw || typeof raw !== "object")
|
|
32
|
+
return null;
|
|
33
|
+
const rec = raw;
|
|
34
|
+
if (typeof rec["id"] !== "string" || rec["id"].length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
if (typeof rec["state"] !== "string" || !JOB_STATES.includes(rec["state"]))
|
|
37
|
+
return null;
|
|
38
|
+
if (typeof rec["createdAt"] !== "string")
|
|
39
|
+
return null;
|
|
40
|
+
const optionalString = (key) => typeof rec[key] === "string" ? rec[key] : undefined;
|
|
41
|
+
return {
|
|
42
|
+
id: rec["id"],
|
|
43
|
+
state: rec["state"],
|
|
44
|
+
params: rec["params"],
|
|
45
|
+
error: optionalString("error"),
|
|
46
|
+
errorCode: optionalString("errorCode"),
|
|
47
|
+
createdAt: rec["createdAt"],
|
|
48
|
+
runId: optionalString("runId"),
|
|
49
|
+
taskId: optionalString("taskId"),
|
|
50
|
+
runDir: optionalString("runDir"),
|
|
51
|
+
startedAt: optionalString("startedAt"),
|
|
52
|
+
finishedAt: optionalString("finishedAt"),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Local daemon: Unix-socket JSON-RPC with token auth + a bounded-concurrency
|
|
57
|
+
* worker pool (up to maxConcurrent jobs in parallel) backed by an optional
|
|
58
|
+
* durable, atomically-written job registry. It does NOT contain a second
|
|
59
|
+
* scheduler — it calls the injected runner (the same Orchestrator the CLI uses).
|
|
60
|
+
*/
|
|
61
|
+
export class DaemonServer {
|
|
62
|
+
opts;
|
|
63
|
+
server;
|
|
64
|
+
queue = [];
|
|
65
|
+
records = new Map();
|
|
66
|
+
cancelled = new Set();
|
|
67
|
+
controllers = new Map();
|
|
68
|
+
active = 0;
|
|
69
|
+
startedAt = Date.now();
|
|
70
|
+
onClosed;
|
|
71
|
+
constructor(opts) {
|
|
72
|
+
this.opts = opts;
|
|
73
|
+
}
|
|
74
|
+
async start() {
|
|
75
|
+
// Refuse to clobber a LIVE daemon: deleting its socket would orphan it and
|
|
76
|
+
// turn jobs.json into a last-writer-wins race between two processes.
|
|
77
|
+
if (pathExists(this.opts.socketPath) && (await socketAlive(this.opts.socketPath))) {
|
|
78
|
+
throw new Error(`a claudexor daemon is already listening on ${this.opts.socketPath}; stop it first`);
|
|
79
|
+
}
|
|
80
|
+
this.load();
|
|
81
|
+
try {
|
|
82
|
+
rmSync(this.opts.socketPath, { force: true });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
/* nothing to clean */
|
|
86
|
+
}
|
|
87
|
+
await new Promise((resolve, reject) => {
|
|
88
|
+
this.server = createServer((sock) => this.onConnection(sock));
|
|
89
|
+
this.server.once("error", reject);
|
|
90
|
+
this.server.listen(this.opts.socketPath, () => {
|
|
91
|
+
// Owner-only socket: the bearer token is the auth layer, but a
|
|
92
|
+
// world-connectable socket needlessly exposes the RPC surface to every
|
|
93
|
+
// local user; chmod narrows it to the owning account.
|
|
94
|
+
try {
|
|
95
|
+
chmodSync(this.opts.socketPath, 0o600);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* best-effort on exotic filesystems */
|
|
99
|
+
}
|
|
100
|
+
resolve();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
// Resume any queued jobs re-enqueued from a previous session (see load()).
|
|
104
|
+
void this.drain();
|
|
105
|
+
}
|
|
106
|
+
async stop() {
|
|
107
|
+
// Graceful shutdown: abort in-flight runs so the runner cancels their harness
|
|
108
|
+
// children and settles each job (no orphaned processes / "running" zombies in
|
|
109
|
+
// jobs.json), then WAIT (bounded) for the cancellations to settle. Without
|
|
110
|
+
// the wait, the process could exit before the SIGKILL escalation timers
|
|
111
|
+
// fire, leaving a SIGTERM-ignoring harness child alive in its group.
|
|
112
|
+
for (const controller of this.controllers.values()) {
|
|
113
|
+
try {
|
|
114
|
+
controller.abort();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
/* already gone */
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const deadline = Date.now() + 5_000;
|
|
121
|
+
while (this.active > 0 && Date.now() < deadline) {
|
|
122
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
123
|
+
}
|
|
124
|
+
this.persist();
|
|
125
|
+
await new Promise((resolve) => {
|
|
126
|
+
if (!this.server)
|
|
127
|
+
return resolve();
|
|
128
|
+
this.server.close(() => resolve());
|
|
129
|
+
});
|
|
130
|
+
this.onClosed?.();
|
|
131
|
+
}
|
|
132
|
+
/** Resolves when the daemon is shut down via RPC. */
|
|
133
|
+
waitForShutdown() {
|
|
134
|
+
return new Promise((resolve) => {
|
|
135
|
+
this.onClosed = resolve;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
onConnection(sock) {
|
|
139
|
+
const rl = createInterface({ input: sock });
|
|
140
|
+
rl.on("line", (line) => {
|
|
141
|
+
void this.handle(line, sock);
|
|
142
|
+
});
|
|
143
|
+
sock.on("error", () => rl.close());
|
|
144
|
+
}
|
|
145
|
+
send(sock, obj) {
|
|
146
|
+
try {
|
|
147
|
+
sock.write(JSON.stringify(obj) + "\n");
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* socket closed */
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async handle(line, sock) {
|
|
154
|
+
const trimmed = line.trim();
|
|
155
|
+
if (!trimmed)
|
|
156
|
+
return;
|
|
157
|
+
let msg;
|
|
158
|
+
try {
|
|
159
|
+
msg = JSON.parse(trimmed);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const { id, method, params, token } = msg;
|
|
165
|
+
if (!tokenMatches(typeof token === "string" ? token : "", this.opts.token)) {
|
|
166
|
+
this.send(sock, { id, error: { message: "unauthorized" } });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
this.send(sock, { id, result: await this.dispatch(method, params) });
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
// Carry the machine-readable error code (e.g. inline_secret_rejected)
|
|
174
|
+
// alongside the redacted message so socket clients get the typed class.
|
|
175
|
+
const code = errorCode(err);
|
|
176
|
+
this.send(sock, { id, error: { message: redactSecrets(err instanceof Error ? err.message : String(err)), ...(code ? { code } : {}) } });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async dispatch(method, params) {
|
|
180
|
+
switch (method) {
|
|
181
|
+
case "claudexor.health":
|
|
182
|
+
return {
|
|
183
|
+
ok: true,
|
|
184
|
+
uptime_ms: Date.now() - this.startedAt,
|
|
185
|
+
queue: this.queue.length,
|
|
186
|
+
running: this.active > 0,
|
|
187
|
+
active: this.active,
|
|
188
|
+
jobs: this.records.size,
|
|
189
|
+
};
|
|
190
|
+
case "claudexor.enqueue": {
|
|
191
|
+
assertNoInlineSecretValues(params, "$", "daemon job params");
|
|
192
|
+
const id = newId("job");
|
|
193
|
+
this.records.set(id, { id, state: "queued", params, createdAt: nowIso() });
|
|
194
|
+
this.queue.push(id);
|
|
195
|
+
this.persist();
|
|
196
|
+
void this.drain();
|
|
197
|
+
return { id, state: "queued" };
|
|
198
|
+
}
|
|
199
|
+
case "claudexor.status": {
|
|
200
|
+
const rec = this.records.get(String(params?.id));
|
|
201
|
+
if (!rec)
|
|
202
|
+
throw new Error(`no such job: ${params?.id}`);
|
|
203
|
+
return publicJobRecord(rec);
|
|
204
|
+
}
|
|
205
|
+
case "claudexor.list":
|
|
206
|
+
return [...this.records.values()].map(publicJobRecord);
|
|
207
|
+
case "claudexor.cancel": {
|
|
208
|
+
const jid = String(params?.id);
|
|
209
|
+
// Honesty: cancelling an unknown id must fail loudly (like status),
|
|
210
|
+
// never claim `{cancelled:true}` for a job that does not exist.
|
|
211
|
+
const rec = this.records.get(jid);
|
|
212
|
+
if (!rec)
|
|
213
|
+
throw new Error(`no such job: ${jid}`);
|
|
214
|
+
this.cancelled.add(jid);
|
|
215
|
+
if (rec.state === "queued")
|
|
216
|
+
rec.state = "cancelled";
|
|
217
|
+
// Abort the in-flight run; the runner (Orchestrator) honors the signal,
|
|
218
|
+
// cancels the harness, then settles this job as cancelled.
|
|
219
|
+
this.controllers.get(jid)?.abort();
|
|
220
|
+
this.persist();
|
|
221
|
+
return { id: jid, cancelled: true };
|
|
222
|
+
}
|
|
223
|
+
case "claudexor.shutdown":
|
|
224
|
+
setTimeout(() => void this.stop(), 10);
|
|
225
|
+
return { ok: true };
|
|
226
|
+
default:
|
|
227
|
+
throw new Error(`unknown method: ${method}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
get maxConcurrent() {
|
|
231
|
+
return this.opts.maxConcurrent ?? 4;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Best-effort durable persistence of the job registry. Writes atomically
|
|
235
|
+
* (temp file + rename) so a crash mid-write cannot corrupt/drop the registry.
|
|
236
|
+
* The raw run `result` is intentionally NOT persisted: canonical output lives
|
|
237
|
+
* in .claudexor/runs (redacted), and result.summary can contain raw model text —
|
|
238
|
+
* keeping it out of jobs.json upholds the redaction-at-persistence invariant.
|
|
239
|
+
*/
|
|
240
|
+
persist() {
|
|
241
|
+
const path = this.opts.persistPath;
|
|
242
|
+
if (!path)
|
|
243
|
+
return;
|
|
244
|
+
try {
|
|
245
|
+
const view = [...this.records.values()].map(persistedJobRecord);
|
|
246
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
247
|
+
const tmp = `${path}.tmp`;
|
|
248
|
+
writeFileSync(tmp, JSON.stringify(view, null, 2) + "\n", { mode: 0o600 });
|
|
249
|
+
chmodSync(tmp, 0o600);
|
|
250
|
+
renameSync(tmp, path);
|
|
251
|
+
chmodSync(path, 0o600);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
/* best-effort; never break a run on a persistence failure */
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/** Bound memory/disk: prune the oldest terminal jobs beyond maxHistory.
|
|
258
|
+
* `blocked` runs are NEVER pruned — they are the needs-human inbox awaiting an
|
|
259
|
+
* operator decision; dropping one would silently lose a pending action. */
|
|
260
|
+
pruneHistory() {
|
|
261
|
+
const cap = this.opts.maxHistory ?? 500;
|
|
262
|
+
const terminal = [...this.records.values()].filter((r) => r.state !== "running" && r.state !== "queued" && r.state !== "blocked");
|
|
263
|
+
if (terminal.length <= cap)
|
|
264
|
+
return;
|
|
265
|
+
terminal.sort((a, b) => (a.createdAt < b.createdAt ? -1 : 1));
|
|
266
|
+
for (const r of terminal.slice(0, terminal.length - cap)) {
|
|
267
|
+
this.records.delete(r.id);
|
|
268
|
+
this.cancelled.delete(r.id);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/** Reload the registry on startup; a fresh process cannot resume in-memory runs. */
|
|
272
|
+
load() {
|
|
273
|
+
const path = this.opts.persistPath;
|
|
274
|
+
if (!path || !pathExists(path))
|
|
275
|
+
return;
|
|
276
|
+
const saved = readJsonSafe(path);
|
|
277
|
+
if (saved === null || !Array.isArray(saved)) {
|
|
278
|
+
// A corrupt registry must not be silently wiped: the run history includes
|
|
279
|
+
// the blocked needs-human inbox. Back the raw bytes up, start empty, and
|
|
280
|
+
// say so loudly (ThreadStore discipline).
|
|
281
|
+
this.backupCorruptRegistry(path, "registry file is not a JSON array");
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
let dropped = 0;
|
|
285
|
+
for (const raw of saved) {
|
|
286
|
+
const rec = salvageJobRecord(raw);
|
|
287
|
+
if (!rec) {
|
|
288
|
+
dropped += 1;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
// A fresh process cannot resume an in-memory RUN, so a `running` job becomes
|
|
292
|
+
// interrupted (honest). `blocked` is a TERMINAL outcome (NEEDS_HUMAN / web
|
|
293
|
+
// policy) the review queue must keep across restarts.
|
|
294
|
+
if (rec.state === "running") {
|
|
295
|
+
rec.state = "interrupted";
|
|
296
|
+
// Stamp the orphaned event log with a TERMINAL event: the
|
|
297
|
+
// canonical events.jsonl must agree with jobs.json, or SSE tailers and
|
|
298
|
+
// `follow` wait forever on a log that will never terminate.
|
|
299
|
+
if (rec.runDir && rec.runId) {
|
|
300
|
+
try {
|
|
301
|
+
appendRunEvent(join(rec.runDir, "events.jsonl"), rec.runId, rec.taskId ?? "", "run.failed", {
|
|
302
|
+
status: "interrupted",
|
|
303
|
+
error: "daemon restarted while the run was in flight",
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
/* best-effort: a missing/corrupt log must not block startup */
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
this.records.set(rec.id, rec);
|
|
312
|
+
// A `queued` job never started; its params are persisted, so RE-ENQUEUE it
|
|
313
|
+
// on restart (drain() runs after start()) instead of silently dropping
|
|
314
|
+
// pending work to interrupted.
|
|
315
|
+
if (rec.state === "queued")
|
|
316
|
+
this.queue.push(rec.id);
|
|
317
|
+
}
|
|
318
|
+
if (dropped > 0) {
|
|
319
|
+
this.backupCorruptRegistry(path, `${dropped} unparseable job record(s) dropped`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** Preserve the raw bytes of a damaged registry and report the loss loudly. */
|
|
323
|
+
backupCorruptRegistry(path, reason) {
|
|
324
|
+
try {
|
|
325
|
+
copyFileSync(path, `${path}.bak`);
|
|
326
|
+
console.error(`[claudexor] jobs store: ${reason}; original backed up to ${path}.bak`);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
console.error(`[claudexor] jobs store: ${reason}; backup to ${path}.bak FAILED`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
threadIdOf(rec) {
|
|
333
|
+
const p = rec.params;
|
|
334
|
+
return p && typeof p.threadId === "string" ? p.threadId : undefined;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Schedule queued jobs up to the concurrency limit (non-blocking).
|
|
338
|
+
*
|
|
339
|
+
* One active run per thread: a thread is a linear conversation and an in-place
|
|
340
|
+
* turn mutates the live tree, so two concurrent turns on the same thread would
|
|
341
|
+
* race the same files. We pick the first queued job whose thread is idle rather
|
|
342
|
+
* than always taking the head; thread-less jobs (CLI/MCP) keep running in
|
|
343
|
+
* parallel as before. drain() re-runs on every completion, so a thread's next
|
|
344
|
+
* turn starts as soon as its previous one settles.
|
|
345
|
+
*/
|
|
346
|
+
drain() {
|
|
347
|
+
while (this.active < this.maxConcurrent && this.queue.length > 0) {
|
|
348
|
+
const busyThreads = new Set([...this.records.values()]
|
|
349
|
+
.filter((r) => r.state === "running")
|
|
350
|
+
.map((r) => this.threadIdOf(r))
|
|
351
|
+
.filter((t) => !!t));
|
|
352
|
+
let pickIdx = -1;
|
|
353
|
+
for (let i = 0; i < this.queue.length; i++) {
|
|
354
|
+
const rec = this.records.get(this.queue[i]);
|
|
355
|
+
const tid = rec ? this.threadIdOf(rec) : undefined;
|
|
356
|
+
if (!rec || !tid || !busyThreads.has(tid)) {
|
|
357
|
+
pickIdx = i;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (pickIdx === -1)
|
|
362
|
+
break; // every queued job waits on a busy thread
|
|
363
|
+
const id = this.queue.splice(pickIdx, 1)[0];
|
|
364
|
+
const rec = this.records.get(id);
|
|
365
|
+
if (!rec)
|
|
366
|
+
continue;
|
|
367
|
+
if (this.cancelled.has(id)) {
|
|
368
|
+
rec.state = "cancelled";
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
this.active += 1;
|
|
372
|
+
void this.runJob(id, rec);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
async runJob(id, rec) {
|
|
376
|
+
const controller = new AbortController();
|
|
377
|
+
this.controllers.set(id, controller);
|
|
378
|
+
rec.state = "running";
|
|
379
|
+
rec.startedAt = nowIso();
|
|
380
|
+
this.persist();
|
|
381
|
+
try {
|
|
382
|
+
rec.result = await this.opts.runner(rec.params, {
|
|
383
|
+
signal: controller.signal,
|
|
384
|
+
onRunStart: (info) => {
|
|
385
|
+
rec.runId = info.runId;
|
|
386
|
+
rec.taskId = info.taskId;
|
|
387
|
+
rec.runDir = info.runDir;
|
|
388
|
+
// Persist the pointer immediately so a mid-run crash still reloads with
|
|
389
|
+
// runId/runDir to locate .claudexor/runs/<runId> (the recovery path).
|
|
390
|
+
this.persist();
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
rec.state = jobStateFromResult(rec.result, controller.signal.aborted);
|
|
394
|
+
// Only failure-shaped terminals carry an error string. no_op / ungated /
|
|
395
|
+
// review_not_run / blocked are HONEST terminals: fabricating an error here
|
|
396
|
+
// would make the control facade render a failure that never happened.
|
|
397
|
+
if (rec.state === "failed" || rec.state === "exhausted" || rec.state === "not_converged" || rec.state === "stuck_no_progress") {
|
|
398
|
+
rec.error = resultSummary(rec.result) ?? `run ended with status ${rec.state}`;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
rec.state = controller.signal.aborted ? "cancelled" : "failed";
|
|
403
|
+
rec.error = redactSecrets(err instanceof Error ? err.message : String(err));
|
|
404
|
+
// Preserve a typed throw's machine code (e.g. the trust gate) so
|
|
405
|
+
// consumers can key remedies on it instead of parsing the message.
|
|
406
|
+
const code = err && typeof err === "object" && "code" in err ? err.code : undefined;
|
|
407
|
+
if (typeof code === "string" && code)
|
|
408
|
+
rec.errorCode = code;
|
|
409
|
+
}
|
|
410
|
+
finally {
|
|
411
|
+
rec.finishedAt = nowIso();
|
|
412
|
+
this.controllers.delete(id);
|
|
413
|
+
this.active -= 1;
|
|
414
|
+
if (rec.runId) {
|
|
415
|
+
try {
|
|
416
|
+
this.opts.onRunTerminal?.(rec.runId);
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
/* observer failure must not corrupt terminal bookkeeping */
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else if (rec.error) {
|
|
423
|
+
// Failure-shaped terminal with NO run ever bound: the refusal happened
|
|
424
|
+
// before the run materialized. If this job carried a pre-created thread
|
|
425
|
+
// turn, persist the reason on it (honest inline refusal, INV-093).
|
|
426
|
+
const turnId = rec.params?.turnId;
|
|
427
|
+
if (typeof turnId === "string" && turnId) {
|
|
428
|
+
try {
|
|
429
|
+
this.opts.onTurnEnqueueFailed?.(turnId, rec.error, rec.errorCode ?? null);
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
/* observer failure must not corrupt terminal bookkeeping */
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
this.pruneHistory();
|
|
437
|
+
this.persist();
|
|
438
|
+
this.drain();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
function jobStateFromResult(result, aborted) {
|
|
443
|
+
if (aborted)
|
|
444
|
+
return "cancelled";
|
|
445
|
+
const status = resultStatus(result);
|
|
446
|
+
switch (status) {
|
|
447
|
+
case "success":
|
|
448
|
+
return "succeeded";
|
|
449
|
+
case "no_op":
|
|
450
|
+
return "no_op";
|
|
451
|
+
case "ungated":
|
|
452
|
+
return "ungated";
|
|
453
|
+
case "review_not_run":
|
|
454
|
+
return "review_not_run";
|
|
455
|
+
case "blocked":
|
|
456
|
+
return "blocked";
|
|
457
|
+
case "cancelled":
|
|
458
|
+
return "cancelled";
|
|
459
|
+
case "exhausted":
|
|
460
|
+
return "exhausted";
|
|
461
|
+
case "not_converged":
|
|
462
|
+
return "not_converged";
|
|
463
|
+
case "stuck_no_progress":
|
|
464
|
+
return "stuck_no_progress";
|
|
465
|
+
case "failed":
|
|
466
|
+
return "failed";
|
|
467
|
+
default:
|
|
468
|
+
// Fail loudly: a runner result without a recognizable status is NOT a
|
|
469
|
+
// success — success-by-default would mask malformed results forever.
|
|
470
|
+
return "failed";
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/** Constant-time token comparison (parity with the HTTP control facade). */
|
|
474
|
+
function tokenMatches(candidate, expected) {
|
|
475
|
+
const a = Buffer.from(candidate);
|
|
476
|
+
const b = Buffer.from(expected);
|
|
477
|
+
if (a.length !== b.length)
|
|
478
|
+
return false;
|
|
479
|
+
return timingSafeEqual(a, b);
|
|
480
|
+
}
|
|
481
|
+
/** True when something is actively accepting connections on the socket path. */
|
|
482
|
+
/** Is a daemon already listening on this socket? Exported so the claudexord
|
|
483
|
+
* entrypoint can refuse BEFORE running crash GC — a second daemon must never
|
|
484
|
+
* reap the live daemon's children or sweep envelopes its jobs still own. */
|
|
485
|
+
export function socketAlive(socketPath) {
|
|
486
|
+
return new Promise((resolve) => {
|
|
487
|
+
const sock = connect(socketPath);
|
|
488
|
+
const done = (alive) => {
|
|
489
|
+
sock.destroy();
|
|
490
|
+
resolve(alive);
|
|
491
|
+
};
|
|
492
|
+
sock.once("connect", () => done(true));
|
|
493
|
+
sock.once("error", () => done(false));
|
|
494
|
+
setTimeout(() => done(false), 500).unref();
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
function resultStatus(result) {
|
|
498
|
+
if (!result || typeof result !== "object" || Array.isArray(result))
|
|
499
|
+
return null;
|
|
500
|
+
const status = result["status"];
|
|
501
|
+
return typeof status === "string" ? status : null;
|
|
502
|
+
}
|
|
503
|
+
function resultSummary(result) {
|
|
504
|
+
if (!result || typeof result !== "object" || Array.isArray(result))
|
|
505
|
+
return null;
|
|
506
|
+
const summary = result["summary"];
|
|
507
|
+
return typeof summary === "string" ? redactSecrets(summary) : null;
|
|
508
|
+
}
|
|
509
|
+
function publicJobRecord(rec) {
|
|
510
|
+
return {
|
|
511
|
+
...rec,
|
|
512
|
+
error: rec.error ? redactSecrets(rec.error) : undefined,
|
|
513
|
+
params: redactParams(rec.params),
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
function persistedJobRecord(rec) {
|
|
517
|
+
return {
|
|
518
|
+
id: rec.id,
|
|
519
|
+
state: rec.state,
|
|
520
|
+
params: redactParams(rec.params),
|
|
521
|
+
error: rec.error ? redactSecrets(rec.error) : undefined,
|
|
522
|
+
errorCode: rec.errorCode,
|
|
523
|
+
createdAt: rec.createdAt,
|
|
524
|
+
runId: rec.runId,
|
|
525
|
+
taskId: rec.taskId,
|
|
526
|
+
runDir: rec.runDir,
|
|
527
|
+
startedAt: rec.startedAt,
|
|
528
|
+
finishedAt: rec.finishedAt,
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function redactParams(value) {
|
|
532
|
+
if (typeof value === "string")
|
|
533
|
+
return redactSecrets(value);
|
|
534
|
+
if (Array.isArray(value))
|
|
535
|
+
return value.map(redactParams);
|
|
536
|
+
if (!value || typeof value !== "object")
|
|
537
|
+
return value;
|
|
538
|
+
const out = {};
|
|
539
|
+
for (const [key, child] of Object.entries(value)) {
|
|
540
|
+
out[key] = key === "prompt" && typeof child === "string" ? redactSecrets(child) : redactParams(child);
|
|
541
|
+
}
|
|
542
|
+
return out;
|
|
543
|
+
}
|
|
544
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiChI,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,WAAW;IACX,OAAO;IACP,SAAS;IACT,gBAAgB;IAChB,QAAQ;IACR,WAAW;IACX,aAAa;IACb,WAAW;IACX,eAAe;IACf,mBAAmB;CACX,CAAC;AAIX;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,GAAY;IACpC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/G,IAAI,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,cAAc,GAAG,CAAC,GAAW,EAAsB,EAAE,CACzD,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC;QACb,KAAK,EAAE,GAAG,CAAC,OAAO,CAAa;QAC/B,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;QACrB,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC;QAC9B,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC;QACtC,SAAS,EAAE,GAAG,CAAC,WAAW,CAAC;QAC3B,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC;QAC9B,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC;QAChC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC;QAChC,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC;QACtC,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC;KACzC,CAAC;AACJ,CAAC;AAsBD;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IAUM;IATrB,MAAM,CAAU;IACP,KAAK,GAAa,EAAE,CAAC;IACrB,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;IACvC,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC1D,MAAM,GAAG,CAAC,CAAC;IACF,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,QAAQ,CAAc;IAE9B,YAA6B,IAAmB;QAAnB,SAAI,GAAJ,IAAI,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,KAAK;QACT,2EAA2E;QAC3E,qEAAqE;QACrE,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,CAAC,IAAI,CAAC,UAAU,iBAAiB,CAAC,CAAC;QACvG,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;QACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;gBAC5C,+DAA+D;gBAC/D,uEAAuE;gBACvE,sDAAsD;gBACtD,IAAI,CAAC;oBACH,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,uCAAuC;gBACzC,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,2EAA2E;QAC3E,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,8EAA8E;QAC9E,8EAA8E;QAC9E,2EAA2E;QAC3E,wEAAwE;QACxE,qEAAqE;QACrE,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,OAAO,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;IACpB,CAAC;IAED,qDAAqD;IACrD,eAAe;QACb,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,IAAY;QAC/B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IAEO,IAAI,CAAC,IAAY,EAAE,GAAY;QACrC,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,IAAY;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3E,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sEAAsE;YACtE,wEAAwE;YACxE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1I,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,MAAW;QAChD,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,kBAAkB;gBACrB,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS;oBACtC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;oBACxB,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;oBACxB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;iBACxB,CAAC;YACJ,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,0BAA0B,CAAC,MAAM,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;gBAC7D,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC3E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;gBAClB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACjC,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;gBACjD,IAAI,CAAC,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBACxD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,gBAAgB;gBACnB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACzD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC/B,oEAAoE;gBACpE,gEAAgE;gBAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxB,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;oBAAE,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;gBACpD,wEAAwE;gBACxE,2DAA2D;gBAC3D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;gBACnC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YACtC,CAAC;YACD,KAAK,oBAAoB;gBACvB,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACtB;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,IAAY,aAAa;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACK,OAAO;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAChE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;YAC1B,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1E,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtB,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;QAC/D,CAAC;IACH,CAAC;IAED;;+EAE2E;IACnE,YAAY;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC;QACxC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAC9E,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG;YAAE,OAAO;QACnC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,oFAAoF;IAC5E,IAAI;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO;QACvC,MAAM,KAAK,GAAG,YAAY,CAAU,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,0EAA0E;YAC1E,yEAAyE;YACzE,0CAA0C;YAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,mCAAmC,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YACD,6EAA6E;YAC7E,2EAA2E;YAC3E,sDAAsD;YACtD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC5B,GAAG,CAAC,KAAK,GAAG,aAAa,CAAC;gBAC1B,0DAA0D;gBAC1D,uEAAuE;gBACvE,4DAA4D;gBAC5D,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACH,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,YAAY,EAAE;4BAC1F,MAAM,EAAE,aAAa;4BACrB,KAAK,EAAE,8CAA8C;yBACtD,CAAC,CAAC;oBACL,CAAC;oBAAC,MAAM,CAAC;wBACP,+DAA+D;oBACjE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC9B,2EAA2E;YAC3E,uEAAuE;YACvE,+BAA+B;YAC/B,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,GAAG,OAAO,oCAAoC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,+EAA+E;IACvE,qBAAqB,CAAC,IAAY,EAAE,MAAc;QACxD,IAAI,CAAC;YACH,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,2BAA2B,IAAI,MAAM,CAAC,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,eAAe,IAAI,aAAa,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,GAAc;QAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,MAAmD,CAAC;QAClE,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK;QACX,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;iBACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC;iBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;iBAC9B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACnC,CAAC;YACF,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;YACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACnD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1C,OAAO,GAAG,CAAC,CAAC;oBACZ,MAAM;gBACR,CAAC;YACH,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,CAAC;gBAAE,MAAM,CAAC,0CAA0C;YACrE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACjB,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,GAAc;QAC7C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACrC,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;QACtB,GAAG,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;gBAC9C,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;oBACnB,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;oBACvB,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBACzB,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBACzB,wEAAwE;oBACxE,sEAAsE;oBACtE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,CAAC;aACF,CAAC,CAAC;YACH,GAAG,CAAC,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtE,yEAAyE;YACzE,2EAA2E;YAC3E,sEAAsE;YACtE,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,KAAK,KAAK,eAAe,IAAI,GAAG,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;gBAC9H,GAAG,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,yBAAyB,GAAG,CAAC,KAAK,EAAE,CAAC;YAChF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC/D,GAAG,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5E,iEAAiE;YACjE,mEAAmE;YACnE,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAE,GAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3G,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI;gBAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,UAAU,GAAG,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACjB,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACvC,CAAC;gBAAC,MAAM,CAAC;oBACP,4DAA4D;gBAC9D,CAAC;YACH,CAAC;iBAAM,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACrB,uEAAuE;gBACvE,wEAAwE;gBACxE,mEAAmE;gBACnE,MAAM,MAAM,GAAI,GAAG,CAAC,MAAkD,EAAE,MAAM,CAAC;gBAC/E,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,EAAE,CAAC;oBACzC,IAAI,CAAC;wBACH,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;oBAC5E,CAAC;oBAAC,MAAM,CAAC;wBACP,4DAA4D;oBAC9D,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,SAAS,kBAAkB,CAAC,MAAe,EAAE,OAAgB;IAC3D,IAAI,OAAO;QAAE,OAAO,WAAW,CAAC;IAChC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,WAAW,CAAC;QACrB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,gBAAgB;YACnB,OAAO,gBAAgB,CAAC;QAC1B,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,eAAe;YAClB,OAAO,eAAe,CAAC;QACzB,KAAK,mBAAmB;YACtB,OAAO,mBAAmB,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB;YACE,sEAAsE;YACtE,qEAAqE;YACrE,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,YAAY,CAAC,SAAiB,EAAE,QAAgB;IACvD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAChF;;4EAE4E;AAC5E,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE;YAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,MAAe;IACnC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,MAAM,MAAM,GAAI,MAAkC,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,SAAS,aAAa,CAAC,MAAe;IACpC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,MAAM,OAAO,GAAI,MAAkC,CAAC,SAAS,CAAC,CAAC;IAC/D,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC;AAED,SAAS,eAAe,CAAC,GAAc;IACrC,OAAO;QACL,GAAG,GAAG;QACN,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;QACvD,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAc;IACxC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;QAChC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;QACvD,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,UAAU,EAAE,GAAG,CAAC,UAAU;KAC3B,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Attachment, Session, Thread, ThreadTurn, WorkspaceMode } from "@claudexor/schema";
|
|
2
|
+
export interface CreateThreadInput {
|
|
3
|
+
title?: string;
|
|
4
|
+
repoRoot?: string | null;
|
|
5
|
+
mode?: Thread["mode"];
|
|
6
|
+
/** in_place (default) mutates the live tree; isolated keeps a thread worktree. */
|
|
7
|
+
workspace?: WorkspaceMode;
|
|
8
|
+
authPreference?: Thread["auth_preference"];
|
|
9
|
+
primaryHarness?: string | null;
|
|
10
|
+
/** Sticky eligible harness pool for the thread (turns inherit when unset). */
|
|
11
|
+
eligibleHarnesses?: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface CreateTurnInput {
|
|
14
|
+
kind?: ThreadTurn["kind"];
|
|
15
|
+
parentRunId?: string | null;
|
|
16
|
+
/** Set when this turn implements an approved plan from an earlier run. */
|
|
17
|
+
planRunId?: string | null;
|
|
18
|
+
/** Files/images attached to this turn, already resolved to scoped on-disk paths. */
|
|
19
|
+
attachments?: Attachment[];
|
|
20
|
+
}
|
|
21
|
+
export interface UpdateThreadInput {
|
|
22
|
+
title?: string;
|
|
23
|
+
state?: Thread["state"];
|
|
24
|
+
/** Switch the sticky primary harness (null => clear back to auto). */
|
|
25
|
+
primaryHarness?: string | null;
|
|
26
|
+
/** Replace the sticky eligible harness pool. */
|
|
27
|
+
eligibleHarnesses?: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Durable thread/session registry (chat/session-first SSOT). The Thread is
|
|
31
|
+
* the Claudexor-owned conversation; Sessions are re-hostable pointers to each
|
|
32
|
+
* harness's native CLI session. Persisted as one JSON file with atomic writes
|
|
33
|
+
* (temp + rename), mirroring the daemon job registry's durability contract.
|
|
34
|
+
*/
|
|
35
|
+
export declare class ThreadStore {
|
|
36
|
+
private readonly path;
|
|
37
|
+
private state;
|
|
38
|
+
constructor(path: string);
|
|
39
|
+
private load;
|
|
40
|
+
private persist;
|
|
41
|
+
createThread(input: CreateThreadInput): Thread;
|
|
42
|
+
/** Rename and/or open/close (archive) a thread. */
|
|
43
|
+
updateThread(id: string, patch: UpdateThreadInput): Thread;
|
|
44
|
+
/** Persist the resolved isolated worktree path + base sha for a thread. */
|
|
45
|
+
setThreadWorktree(id: string, worktreePath: string, baseSha: string): void;
|
|
46
|
+
listThreads(): Thread[];
|
|
47
|
+
getThread(id: string): Thread | undefined;
|
|
48
|
+
turnsFor(threadId: string): ThreadTurn[];
|
|
49
|
+
getTurn(turnId: string): ThreadTurn | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Fail-loud prologue for the daemon runner: control-api validates thread/turn
|
|
52
|
+
* ids at the HTTP boundary, but a direct socket caller can pass bogus ids —
|
|
53
|
+
* a silent unbind would orphan the run from its conversation. A typed throw
|
|
54
|
+
* settles the job `failed` instead. Returns the normalized ids.
|
|
55
|
+
*/
|
|
56
|
+
assertKnownIds(rawThreadId: unknown, rawTurnId: unknown): {
|
|
57
|
+
threadId?: string;
|
|
58
|
+
turnId?: string;
|
|
59
|
+
};
|
|
60
|
+
sessionsForThread(threadId: string): Session[];
|
|
61
|
+
/** Native resume map for a thread: harnessId -> native session id (live sessions only). */
|
|
62
|
+
resumeMap(threadId: string): Record<string, string>;
|
|
63
|
+
/**
|
|
64
|
+
* Create a turn BEFORE its run is enqueued (run_id is bound later via
|
|
65
|
+
* `bindTurnRun`). This is the single-writer entry point: the control API and
|
|
66
|
+
* the daemon runner both create here, so a run is recorded on its thread
|
|
67
|
+
* exactly once — there is no second "POST /runs with threadId silently skips
|
|
68
|
+
* the turn" path. `parentRunId` is captured here (head at creation time), so
|
|
69
|
+
* concurrent turns cannot both claim the same stale head.
|
|
70
|
+
*/
|
|
71
|
+
createTurn(threadId: string, prompt: string, input?: CreateTurnInput): ThreadTurn;
|
|
72
|
+
/** Bind a started run to its turn and advance the thread head (runner-owned). */
|
|
73
|
+
bindTurnRun(turnId: string, runId: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Persist the reason a turn's run could NOT be enqueued/started (trust
|
|
76
|
+
* refusal, preflight validation, enqueue throw). Only meaningful for a
|
|
77
|
+
* RUNLESS turn: once a run is bound the turn's honesty lives on the run's
|
|
78
|
+
* own terminal artifacts, so a late failure report is ignored. `code` is
|
|
79
|
+
* the typed throw's machine code (e.g. trust_full_access_required) that
|
|
80
|
+
* surfaces key remedies on; `retryable=false` marks refusals with NO
|
|
81
|
+
* recorded job to replay (the enqueue itself threw) so surfaces offer
|
|
82
|
+
* "send a new message" instead of a doomed Retry.
|
|
83
|
+
*/
|
|
84
|
+
setTurnEnqueueError(turnId: string, message: string, code?: string | null, retryable?: boolean): void;
|
|
85
|
+
/** Record/refresh the native CLI session a harness emitted for this thread. */
|
|
86
|
+
recordSession(threadId: string, harnessId: string, nativeSessionId: string, observedModel?: string | null): void;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=threads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
|