@claudexor/daemon 1.0.0 → 2.1.2
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/client.d.ts +29 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +24 -4
- package/dist/client.js.map +1 -1
- package/dist/command-authority.d.ts +11 -0
- package/dist/command-authority.d.ts.map +1 -0
- package/dist/command-authority.js +15 -0
- package/dist/command-authority.js.map +1 -0
- package/dist/command-retention.d.ts +5 -0
- package/dist/command-retention.d.ts.map +1 -0
- package/dist/command-retention.js +18 -0
- package/dist/command-retention.js.map +1 -0
- package/dist/command-store.d.ts +41 -0
- package/dist/command-store.d.ts.map +1 -0
- package/dist/command-store.js +197 -0
- package/dist/command-store.js.map +1 -0
- package/dist/events.d.ts +2 -3
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +2 -3
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/interactions.d.ts +32 -22
- package/dist/interactions.d.ts.map +1 -1
- package/dist/interactions.js +183 -56
- package/dist/interactions.js.map +1 -1
- package/dist/journal-events.d.ts +4 -0
- package/dist/journal-events.d.ts.map +1 -0
- package/dist/journal-events.js +23 -0
- package/dist/journal-events.js.map +1 -0
- package/dist/journal-manager.d.ts +72 -0
- package/dist/journal-manager.d.ts.map +1 -0
- package/dist/journal-manager.js +463 -0
- package/dist/journal-manager.js.map +1 -0
- package/dist/journal-projection.d.ts +11 -0
- package/dist/journal-projection.d.ts.map +1 -0
- package/dist/journal-projection.js +2 -0
- package/dist/journal-projection.js.map +1 -0
- package/dist/journal-recovery-files.d.ts +27 -0
- package/dist/journal-recovery-files.d.ts.map +1 -0
- package/dist/journal-recovery-files.js +209 -0
- package/dist/journal-recovery-files.js.map +1 -0
- package/dist/operator-decisions.d.ts +30 -0
- package/dist/operator-decisions.d.ts.map +1 -0
- package/dist/operator-decisions.js +137 -0
- package/dist/operator-decisions.js.map +1 -0
- package/dist/project-partitions.d.ts +167 -0
- package/dist/project-partitions.d.ts.map +1 -0
- package/dist/project-partitions.js +365 -0
- package/dist/project-partitions.js.map +1 -0
- package/dist/projects.d.ts +29 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +180 -0
- package/dist/projects.js.map +1 -0
- package/dist/quota-registry.d.ts +75 -0
- package/dist/quota-registry.d.ts.map +1 -0
- package/dist/quota-registry.js +208 -0
- package/dist/quota-registry.js.map +1 -0
- package/dist/resource-store.d.ts +22 -0
- package/dist/resource-store.d.ts.map +1 -0
- package/dist/resource-store.js +272 -0
- package/dist/resource-store.js.map +1 -0
- package/dist/run-events.d.ts +15 -0
- package/dist/run-events.d.ts.map +1 -0
- package/dist/run-events.js +29 -0
- package/dist/run-events.js.map +1 -0
- package/dist/server.d.ts +33 -33
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +231 -238
- package/dist/server.js.map +1 -1
- package/dist/spec-sessions.d.ts +72 -0
- package/dist/spec-sessions.d.ts.map +1 -0
- package/dist/spec-sessions.js +301 -0
- package/dist/spec-sessions.js.map +1 -0
- package/dist/terminate.d.ts +52 -0
- package/dist/terminate.d.ts.map +1 -0
- package/dist/terminate.js +111 -0
- package/dist/terminate.js.map +1 -0
- package/dist/thread-head-ping.d.ts +35 -0
- package/dist/thread-head-ping.d.ts.map +1 -0
- package/dist/thread-head-ping.js +67 -0
- package/dist/thread-head-ping.js.map +1 -0
- package/dist/thread-lifecycle.d.ts +5 -0
- package/dist/thread-lifecycle.d.ts.map +1 -0
- package/dist/thread-lifecycle.js +57 -0
- package/dist/thread-lifecycle.js.map +1 -0
- package/dist/thread-store-support.d.ts +37 -0
- package/dist/thread-store-support.d.ts.map +1 -0
- package/dist/thread-store-support.js +94 -0
- package/dist/thread-store-support.js.map +1 -0
- package/dist/threads.d.ts +59 -13
- package/dist/threads.d.ts.map +1 -1
- package/dist/threads.js +254 -141
- package/dist/threads.js.map +1 -1
- package/dist/token.d.ts +13 -4
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +134 -29
- package/dist/token.js.map +1 -1
- package/dist/writer-lease.d.ts +21 -0
- package/dist/writer-lease.d.ts.map +1 -0
- package/dist/writer-lease.js +94 -0
- package/dist/writer-lease.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminate.js","sourceRoot":"","sources":["../src/terminate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DurableJournal } from "@claudexor/journal";
|
|
2
|
+
/**
|
|
3
|
+
* GLOBAL-partition emitter of `thread.head.updated` — the content-free sidebar
|
|
4
|
+
* invalidation ping `{thread_id, project_id, revision}`.
|
|
5
|
+
*
|
|
6
|
+
* Thread mutations persist to their OWNING partition (`project:{id}` for
|
|
7
|
+
* project threads), which the app's single global stream never sees. This
|
|
8
|
+
* projection holds a handle on the GLOBAL journal so every ThreadStore can
|
|
9
|
+
* announce "this thread's summary changed" on the one stream consumers already
|
|
10
|
+
* follow. Content-free by contract: no thread data rides the ping — consumers
|
|
11
|
+
* refetch the authoritative ThreadSummary from the thread endpoints.
|
|
12
|
+
*
|
|
13
|
+
* `revision` is a monotonic per-thread counter, journal-backed so it survives
|
|
14
|
+
* daemon restarts: consumers may drop a ping whose revision they have already
|
|
15
|
+
* reflected without ever trusting payload content.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ThreadHeadPingEmitter {
|
|
18
|
+
private readonly journal;
|
|
19
|
+
private readonly revisions;
|
|
20
|
+
constructor(journal: DurableJournal);
|
|
21
|
+
private replay;
|
|
22
|
+
ping(input: {
|
|
23
|
+
threadId: string;
|
|
24
|
+
projectId: string | null;
|
|
25
|
+
}): void;
|
|
26
|
+
/** Last emitted revision for a thread (0 = never pinged). */
|
|
27
|
+
revision(threadId: string): number;
|
|
28
|
+
validateProjection(): void;
|
|
29
|
+
}
|
|
30
|
+
export declare function threadHeadPingProjection(): {
|
|
31
|
+
name: string;
|
|
32
|
+
create: (journal: DurableJournal) => ThreadHeadPingEmitter;
|
|
33
|
+
validate: (emitter: ThreadHeadPingEmitter) => void;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=thread-head-ping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-head-ping.d.ts","sourceRoot":"","sources":["../src/thread-head-ping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMzD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,qBAAqB;IAGpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;gBAE1B,OAAO,EAAE,cAAc;IAIpD,OAAO,CAAC,MAAM;IAUd,IAAI,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAWjE,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIlC,kBAAkB,IAAI,IAAI;CAO3B;AAED,wBAAgB,wBAAwB;;sBAGlB,cAAc;wBACZ,qBAAqB;EAE5C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ThreadHeadPing } from "@claudexor/schema";
|
|
2
|
+
/** Journal record type of the sidebar-staleness invalidation ping. */
|
|
3
|
+
const UPDATED = "thread.head.updated";
|
|
4
|
+
/**
|
|
5
|
+
* GLOBAL-partition emitter of `thread.head.updated` — the content-free sidebar
|
|
6
|
+
* invalidation ping `{thread_id, project_id, revision}`.
|
|
7
|
+
*
|
|
8
|
+
* Thread mutations persist to their OWNING partition (`project:{id}` for
|
|
9
|
+
* project threads), which the app's single global stream never sees. This
|
|
10
|
+
* projection holds a handle on the GLOBAL journal so every ThreadStore can
|
|
11
|
+
* announce "this thread's summary changed" on the one stream consumers already
|
|
12
|
+
* follow. Content-free by contract: no thread data rides the ping — consumers
|
|
13
|
+
* refetch the authoritative ThreadSummary from the thread endpoints.
|
|
14
|
+
*
|
|
15
|
+
* `revision` is a monotonic per-thread counter, journal-backed so it survives
|
|
16
|
+
* daemon restarts: consumers may drop a ping whose revision they have already
|
|
17
|
+
* reflected without ever trusting payload content.
|
|
18
|
+
*/
|
|
19
|
+
export class ThreadHeadPingEmitter {
|
|
20
|
+
journal;
|
|
21
|
+
revisions = new Map();
|
|
22
|
+
constructor(journal) {
|
|
23
|
+
this.journal = journal;
|
|
24
|
+
this.replay();
|
|
25
|
+
}
|
|
26
|
+
replay() {
|
|
27
|
+
for (const record of this.journal.records()) {
|
|
28
|
+
if (record.type !== UPDATED)
|
|
29
|
+
continue;
|
|
30
|
+
const ping = ThreadHeadPing.safeParse(record.payload);
|
|
31
|
+
if (!ping.success)
|
|
32
|
+
continue;
|
|
33
|
+
const prior = this.revisions.get(ping.data.thread_id) ?? 0;
|
|
34
|
+
if (ping.data.revision > prior)
|
|
35
|
+
this.revisions.set(ping.data.thread_id, ping.data.revision);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ping(input) {
|
|
39
|
+
const revision = (this.revisions.get(input.threadId) ?? 0) + 1;
|
|
40
|
+
const payload = ThreadHeadPing.parse({
|
|
41
|
+
thread_id: input.threadId,
|
|
42
|
+
project_id: input.projectId,
|
|
43
|
+
revision,
|
|
44
|
+
});
|
|
45
|
+
this.journal.append(UPDATED, payload);
|
|
46
|
+
this.revisions.set(input.threadId, revision);
|
|
47
|
+
}
|
|
48
|
+
/** Last emitted revision for a thread (0 = never pinged). */
|
|
49
|
+
revision(threadId) {
|
|
50
|
+
return this.revisions.get(threadId) ?? 0;
|
|
51
|
+
}
|
|
52
|
+
validateProjection() {
|
|
53
|
+
for (const [threadId, revision] of this.revisions) {
|
|
54
|
+
if (!threadId || !Number.isInteger(revision) || revision <= 0) {
|
|
55
|
+
throw new Error(`invalid thread head revision: ${threadId} -> ${revision}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function threadHeadPingProjection() {
|
|
61
|
+
return {
|
|
62
|
+
name: "thread-head-ping",
|
|
63
|
+
create: (journal) => new ThreadHeadPingEmitter(journal),
|
|
64
|
+
validate: (emitter) => emitter.validateProjection(),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=thread-head-ping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-head-ping.js","sourceRoot":"","sources":["../src/thread-head-ping.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,sEAAsE;AACtE,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,qBAAqB;IAGH;IAFZ,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEO,MAAM;QACZ,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;gBAAE,SAAS;YACtC,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,SAAS;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK;gBAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAqD;QACxD,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC;YACnC,SAAS,EAAE,KAAK,CAAC,QAAQ;YACzB,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,QAAQ;SACT,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,6DAA6D;IAC7D,QAAQ,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,kBAAkB;QAChB,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,OAAO,QAAQ,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,CAAC,OAAuB,EAAE,EAAE,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC;QACvE,QAAQ,EAAE,CAAC,OAA8B,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE;KAC3E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Thread } from "@claudexor/schema";
|
|
2
|
+
export type ThreadLifecycleAction = "trash" | "restore" | "purge";
|
|
3
|
+
/** Pure lifecycle reducer; ThreadStore remains the sole journal writer. */
|
|
4
|
+
export declare function reduceThreadLifecycle(thread: Thread, action: ThreadLifecycleAction): Thread;
|
|
5
|
+
//# sourceMappingURL=thread-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-lifecycle.d.ts","sourceRoot":"","sources":["../src/thread-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAElE,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAiD3F"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Thread as ThreadSchema } from "@claudexor/schema";
|
|
2
|
+
import { nowIso } from "@claudexor/util";
|
|
3
|
+
/** Pure lifecycle reducer; ThreadStore remains the sole journal writer. */
|
|
4
|
+
export function reduceThreadLifecycle(thread, action) {
|
|
5
|
+
if (thread.state === "purged") {
|
|
6
|
+
if (action === "purge")
|
|
7
|
+
return thread;
|
|
8
|
+
throw Object.assign(new Error(`thread ${thread.id} was purged`), {
|
|
9
|
+
status: 410,
|
|
10
|
+
code: "thread_purged",
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
if (action === "trash") {
|
|
14
|
+
if (thread.state === "trashed")
|
|
15
|
+
return thread;
|
|
16
|
+
const at = nowIso();
|
|
17
|
+
return ThreadSchema.parse({
|
|
18
|
+
...thread,
|
|
19
|
+
state: "trashed",
|
|
20
|
+
trashed_at: at,
|
|
21
|
+
purge_after: new Date(Date.parse(at) + 30 * 24 * 60 * 60 * 1_000).toISOString(),
|
|
22
|
+
pre_trash_state: thread.state,
|
|
23
|
+
updated_at: at,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (action === "restore") {
|
|
27
|
+
if (thread.state !== "trashed")
|
|
28
|
+
return thread;
|
|
29
|
+
if (!thread.purge_after || Date.parse(thread.purge_after) <= Date.now()) {
|
|
30
|
+
throw Object.assign(new Error(`thread ${thread.id} trash retention expired`), {
|
|
31
|
+
status: 410,
|
|
32
|
+
code: "thread_trash_expired",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return ThreadSchema.parse({
|
|
36
|
+
...thread,
|
|
37
|
+
state: thread.pre_trash_state ?? "active",
|
|
38
|
+
trashed_at: null,
|
|
39
|
+
purge_after: null,
|
|
40
|
+
pre_trash_state: null,
|
|
41
|
+
updated_at: nowIso(),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (thread.state !== "trashed") {
|
|
45
|
+
throw Object.assign(new Error(`thread ${thread.id} must be trashed before purge`), {
|
|
46
|
+
status: 409,
|
|
47
|
+
code: "thread_not_trashed",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return ThreadSchema.parse({
|
|
51
|
+
...thread,
|
|
52
|
+
state: "purged",
|
|
53
|
+
workspace: { ...thread.workspace, worktree_path: null },
|
|
54
|
+
updated_at: nowIso(),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=thread-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-lifecycle.js","sourceRoot":"","sources":["../src/thread-lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzC,2EAA2E;AAC3E,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,MAA6B;IACjF,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC;QACtC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,EAAE,aAAa,CAAC,EAAE;YAC/D,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QAC9C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,OAAO,YAAY,CAAC,KAAK,CAAC;YACxB,GAAG,MAAM;YACT,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,EAAE;YACd,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,EAAE;YAC/E,eAAe,EAAE,MAAM,CAAC,KAAK;YAC7B,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACxE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,EAAE,0BAA0B,CAAC,EAAE;gBAC5E,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,sBAAsB;aAC7B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,CAAC;YACxB,GAAG,MAAM;YACT,KAAK,EAAE,MAAM,CAAC,eAAe,IAAI,QAAQ;YACzC,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,eAAe,EAAE,IAAI;YACrB,UAAU,EAAE,MAAM,EAAE;SACrB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,EAAE,+BAA+B,CAAC,EAAE;YACjF,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,oBAAoB;SAC3B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,CAAC;QACxB,GAAG,MAAM;QACT,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE;QACvD,UAAU,EAAE,MAAM,EAAE;KACrB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Session, Thread, ThreadTurn } from "@claudexor/schema";
|
|
2
|
+
import type { CreateThreadInput, CreateTurnInput } from "./threads.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure ThreadStore support: the journal mutation codec and the idempotency
|
|
5
|
+
* digests. Extracted from `threads.ts` so the store file stays under the
|
|
6
|
+
* new-file complexity cap (INV-124); no behavior lives here — only parsing,
|
|
7
|
+
* hashing, and array upkeep.
|
|
8
|
+
*/
|
|
9
|
+
export interface ThreadMutation {
|
|
10
|
+
threads?: Thread[];
|
|
11
|
+
sessions?: Session[];
|
|
12
|
+
turns?: ThreadTurn[];
|
|
13
|
+
idempotency?: {
|
|
14
|
+
keyDigest: string;
|
|
15
|
+
requestDigest: string;
|
|
16
|
+
turnId: string;
|
|
17
|
+
};
|
|
18
|
+
threadCreation?: {
|
|
19
|
+
keyDigest: string;
|
|
20
|
+
requestDigest: string;
|
|
21
|
+
threadId: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare function parseMutation(value: unknown): ThreadMutation;
|
|
25
|
+
export declare function threadCreationIdempotency(partition: string, input: CreateThreadInput["idempotency"]): ThreadMutation["threadCreation"];
|
|
26
|
+
export declare function turnIdempotency(partition: string, threadId: string, input: CreateTurnInput["idempotency"]): ThreadMutation["idempotency"];
|
|
27
|
+
export declare function idempotencyConflict(): Error & {
|
|
28
|
+
code: string;
|
|
29
|
+
status: number;
|
|
30
|
+
};
|
|
31
|
+
export declare function upsert<T extends {
|
|
32
|
+
id: string;
|
|
33
|
+
}>(items: T[], value: T): void;
|
|
34
|
+
export declare function assertUnique(items: Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
}>, kind: string): void;
|
|
37
|
+
//# sourceMappingURL=thread-store-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-store-support.d.ts","sourceRoot":"","sources":["../src/thread-store-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAOrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEvE;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3E,cAAc,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACjF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAsC5D;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,iBAAiB,CAAC,aAAa,CAAC,GACtC,cAAc,CAAC,gBAAgB,CAAC,CAalC;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,CAAC,aAAa,CAAC,GACpC,cAAc,CAAC,aAAa,CAAC,CAa/B;AAWD,wBAAgB,mBAAmB,IAAI,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAK9E;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAI3E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI7E"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Session as SessionSchema, Thread as ThreadSchema, ThreadTurn as ThreadTurnSchema, } from "@claudexor/schema";
|
|
2
|
+
import { hashJson } from "@claudexor/util";
|
|
3
|
+
export function parseMutation(value) {
|
|
4
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5
|
+
throw new Error("invalid thread mutation");
|
|
6
|
+
}
|
|
7
|
+
const mutation = value;
|
|
8
|
+
const idempotency = mutation.idempotency;
|
|
9
|
+
const threadCreation = mutation.threadCreation;
|
|
10
|
+
if (idempotency !== undefined &&
|
|
11
|
+
(!idempotency ||
|
|
12
|
+
typeof idempotency.keyDigest !== "string" ||
|
|
13
|
+
typeof idempotency.requestDigest !== "string" ||
|
|
14
|
+
typeof idempotency.turnId !== "string")) {
|
|
15
|
+
throw new Error("invalid thread idempotency record");
|
|
16
|
+
}
|
|
17
|
+
if (threadCreation !== undefined &&
|
|
18
|
+
(!threadCreation ||
|
|
19
|
+
typeof threadCreation.keyDigest !== "string" ||
|
|
20
|
+
typeof threadCreation.requestDigest !== "string" ||
|
|
21
|
+
typeof threadCreation.threadId !== "string")) {
|
|
22
|
+
throw new Error("invalid thread creation idempotency record");
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
...(mutation.threads
|
|
26
|
+
? { threads: mutation.threads.map((item) => ThreadSchema.parse(item)) }
|
|
27
|
+
: {}),
|
|
28
|
+
...(mutation.sessions
|
|
29
|
+
? { sessions: mutation.sessions.map((item) => SessionSchema.parse(item)) }
|
|
30
|
+
: {}),
|
|
31
|
+
...(mutation.turns
|
|
32
|
+
? { turns: mutation.turns.map((item) => ThreadTurnSchema.parse(item)) }
|
|
33
|
+
: {}),
|
|
34
|
+
...(idempotency ? { idempotency: { ...idempotency } } : {}),
|
|
35
|
+
...(threadCreation ? { threadCreation: { ...threadCreation } } : {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function threadCreationIdempotency(partition, input) {
|
|
39
|
+
if (!input)
|
|
40
|
+
return undefined;
|
|
41
|
+
validateIdempotencyKey(input.key);
|
|
42
|
+
return {
|
|
43
|
+
keyDigest: hashJson({
|
|
44
|
+
client: input.client,
|
|
45
|
+
partition,
|
|
46
|
+
operation: "thread.create",
|
|
47
|
+
key: input.key,
|
|
48
|
+
}),
|
|
49
|
+
requestDigest: hashJson(input.request),
|
|
50
|
+
threadId: "",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function turnIdempotency(partition, threadId, input) {
|
|
54
|
+
if (!input)
|
|
55
|
+
return undefined;
|
|
56
|
+
validateIdempotencyKey(input.key);
|
|
57
|
+
return {
|
|
58
|
+
keyDigest: hashJson({
|
|
59
|
+
client: input.client,
|
|
60
|
+
partition,
|
|
61
|
+
operation: "thread.turn.create",
|
|
62
|
+
key: input.key,
|
|
63
|
+
}),
|
|
64
|
+
requestDigest: hashJson(input.request),
|
|
65
|
+
turnId: "",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function validateIdempotencyKey(key) {
|
|
69
|
+
if (!key || key.length > 256) {
|
|
70
|
+
throw Object.assign(new Error("Idempotency-Key must contain 1-256 characters"), {
|
|
71
|
+
code: "invalid_idempotency_key",
|
|
72
|
+
status: 400,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function idempotencyConflict() {
|
|
77
|
+
return Object.assign(new Error("idempotency key was already used with a different request"), {
|
|
78
|
+
code: "idempotency_conflict",
|
|
79
|
+
status: 409,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function upsert(items, value) {
|
|
83
|
+
const index = items.findIndex((item) => item.id === value.id);
|
|
84
|
+
if (index < 0)
|
|
85
|
+
items.push(value);
|
|
86
|
+
else
|
|
87
|
+
items[index] = value;
|
|
88
|
+
}
|
|
89
|
+
export function assertUnique(items, kind) {
|
|
90
|
+
if (new Set(items.map((item) => item.id)).size !== items.length) {
|
|
91
|
+
throw new Error(`duplicate ${kind} id in journal projection`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=thread-store-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-store-support.js","sourceRoot":"","sources":["../src/thread-store-support.ts"],"names":[],"mappings":"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"}
|
package/dist/threads.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DurableJournal } from "@claudexor/journal";
|
|
1
2
|
import type { Attachment, Session, Thread, ThreadTurn, WorkspaceMode } from "@claudexor/schema";
|
|
2
3
|
export interface CreateThreadInput {
|
|
3
4
|
title?: string;
|
|
@@ -6,9 +7,15 @@ export interface CreateThreadInput {
|
|
|
6
7
|
/** in_place (default) mutates the live tree; isolated keeps a thread worktree. */
|
|
7
8
|
workspace?: WorkspaceMode;
|
|
8
9
|
authPreference?: Thread["auth_preference"];
|
|
10
|
+
credentialProfileId?: string | null;
|
|
9
11
|
primaryHarness?: string | null;
|
|
10
12
|
/** Sticky eligible harness pool for the thread (turns inherit when unset). */
|
|
11
13
|
eligibleHarnesses?: string[];
|
|
14
|
+
idempotency?: {
|
|
15
|
+
key: string;
|
|
16
|
+
client: string;
|
|
17
|
+
request: unknown;
|
|
18
|
+
};
|
|
12
19
|
}
|
|
13
20
|
export interface CreateTurnInput {
|
|
14
21
|
kind?: ThreadTurn["kind"];
|
|
@@ -17,32 +24,58 @@ export interface CreateTurnInput {
|
|
|
17
24
|
planRunId?: string | null;
|
|
18
25
|
/** Files/images attached to this turn, already resolved to scoped on-disk paths. */
|
|
19
26
|
attachments?: Attachment[];
|
|
27
|
+
idempotency?: {
|
|
28
|
+
key: string;
|
|
29
|
+
client: string;
|
|
30
|
+
request: unknown;
|
|
31
|
+
};
|
|
20
32
|
}
|
|
21
33
|
export interface UpdateThreadInput {
|
|
22
34
|
title?: string;
|
|
23
|
-
state?:
|
|
35
|
+
state?: "active" | "closed";
|
|
24
36
|
/** Switch the sticky primary harness (null => clear back to auto). */
|
|
25
37
|
primaryHarness?: string | null;
|
|
38
|
+
/** Switch the thread's sticky credential profile (null => engine default). */
|
|
39
|
+
credentialProfileId?: string | null;
|
|
26
40
|
/** Replace the sticky eligible harness pool. */
|
|
27
41
|
eligibleHarnesses?: string[];
|
|
28
42
|
}
|
|
29
43
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* (temp + rename), mirroring the daemon job registry's durability contract.
|
|
44
|
+
* Sink for the content-free `thread.head.updated` invalidation ping (W12).
|
|
45
|
+
* Bound at composition time to the GLOBAL-partition emitter, so a mutation in
|
|
46
|
+
* a project partition still reaches the app's single global stream.
|
|
34
47
|
*/
|
|
48
|
+
export type ThreadHeadPingSink = (ping: {
|
|
49
|
+
threadId: string;
|
|
50
|
+
projectId: string | null;
|
|
51
|
+
}) => void;
|
|
52
|
+
/** Journal-backed thread/session projection. Returned mutations are fsynced. */
|
|
35
53
|
export declare class ThreadStore {
|
|
36
|
-
private readonly
|
|
54
|
+
private readonly journal;
|
|
55
|
+
private readonly headPing?;
|
|
37
56
|
private state;
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
57
|
+
private readonly turnIdByKey;
|
|
58
|
+
private readonly threadIdByKey;
|
|
59
|
+
constructor(journal: DurableJournal, headPing?: ThreadHeadPingSink | undefined);
|
|
60
|
+
validateProjection(): void;
|
|
61
|
+
private replay;
|
|
62
|
+
private commit;
|
|
63
|
+
/**
|
|
64
|
+
* Emit the content-free head-invalidation ping for one thread. The owning
|
|
65
|
+
* partition name is this store's journal partition — the single source of
|
|
66
|
+
* the thread->project mapping.
|
|
67
|
+
*/
|
|
68
|
+
pingHead(threadId: string): void;
|
|
69
|
+
private apply;
|
|
41
70
|
createThread(input: CreateThreadInput): Thread;
|
|
42
71
|
/** Rename and/or open/close (archive) a thread. */
|
|
43
72
|
updateThread(id: string, patch: UpdateThreadInput): Thread;
|
|
73
|
+
trashThread(id: string): Thread;
|
|
74
|
+
restoreThread(id: string): Thread;
|
|
75
|
+
purgeThread(id: string): Thread;
|
|
76
|
+
private changeLifecycle;
|
|
44
77
|
/** Persist the resolved isolated worktree path + base sha for a thread. */
|
|
45
|
-
setThreadWorktree(id: string, worktreePath: string, baseSha: string): void;
|
|
78
|
+
setThreadWorktree(id: string, worktreePath: string, baseSha: string, deliveredThroughRunId?: string): void;
|
|
46
79
|
listThreads(): Thread[];
|
|
47
80
|
getThread(id: string): Thread | undefined;
|
|
48
81
|
turnsFor(threadId: string): ThreadTurn[];
|
|
@@ -59,7 +92,10 @@ export declare class ThreadStore {
|
|
|
59
92
|
};
|
|
60
93
|
sessionsForThread(threadId: string): Session[];
|
|
61
94
|
/** Native resume map for a thread: harnessId -> native session id (live sessions only). */
|
|
62
|
-
resumeMap(threadId: string): Record<string,
|
|
95
|
+
resumeMap(threadId: string, profileId?: string | null): Record<string, {
|
|
96
|
+
sessionId: string;
|
|
97
|
+
profileId: string | null;
|
|
98
|
+
}>;
|
|
63
99
|
/**
|
|
64
100
|
* Create a turn BEFORE its run is enqueued (run_id is bound later via
|
|
65
101
|
* `bindTurnRun`). This is the single-writer entry point: the control API and
|
|
@@ -82,7 +118,17 @@ export declare class ThreadStore {
|
|
|
82
118
|
* "send a new message" instead of a doomed Retry.
|
|
83
119
|
*/
|
|
84
120
|
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
|
-
|
|
121
|
+
/** Record/refresh the native CLI session a harness emitted for this thread.
|
|
122
|
+
* Keyed by (thread, harness, PROFILE) — resume eligibility is
|
|
123
|
+
* profile-specific (release wave round-16 #3), so profile B's session must
|
|
124
|
+
* never overwrite profile A's row: an A→B→A sequence resumes A's own native
|
|
125
|
+
* conversation (the null engine default is its own row too). */
|
|
126
|
+
recordSession(threadId: string, harnessId: string, nativeSessionId: string, observedModel?: string | null, profileId?: string | null): void;
|
|
127
|
+
relinkProjectRoot(root: string): void;
|
|
87
128
|
}
|
|
129
|
+
export declare function threadProjection(headPing?: ThreadHeadPingSink): {
|
|
130
|
+
name: string;
|
|
131
|
+
create: (journal: DurableJournal) => ThreadStore;
|
|
132
|
+
validate: (store: ThreadStore) => void;
|
|
133
|
+
};
|
|
88
134
|
//# sourceMappingURL=threads.d.ts.map
|
package/dist/threads.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
|