@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.
Files changed (105) hide show
  1. package/dist/client.d.ts +29 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +24 -4
  4. package/dist/client.js.map +1 -1
  5. package/dist/command-authority.d.ts +11 -0
  6. package/dist/command-authority.d.ts.map +1 -0
  7. package/dist/command-authority.js +15 -0
  8. package/dist/command-authority.js.map +1 -0
  9. package/dist/command-retention.d.ts +5 -0
  10. package/dist/command-retention.d.ts.map +1 -0
  11. package/dist/command-retention.js +18 -0
  12. package/dist/command-retention.js.map +1 -0
  13. package/dist/command-store.d.ts +41 -0
  14. package/dist/command-store.d.ts.map +1 -0
  15. package/dist/command-store.js +197 -0
  16. package/dist/command-store.js.map +1 -0
  17. package/dist/events.d.ts +2 -3
  18. package/dist/events.d.ts.map +1 -1
  19. package/dist/events.js +2 -3
  20. package/dist/events.js.map +1 -1
  21. package/dist/index.d.ts +13 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +13 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/interactions.d.ts +32 -22
  26. package/dist/interactions.d.ts.map +1 -1
  27. package/dist/interactions.js +183 -56
  28. package/dist/interactions.js.map +1 -1
  29. package/dist/journal-events.d.ts +4 -0
  30. package/dist/journal-events.d.ts.map +1 -0
  31. package/dist/journal-events.js +23 -0
  32. package/dist/journal-events.js.map +1 -0
  33. package/dist/journal-manager.d.ts +72 -0
  34. package/dist/journal-manager.d.ts.map +1 -0
  35. package/dist/journal-manager.js +463 -0
  36. package/dist/journal-manager.js.map +1 -0
  37. package/dist/journal-projection.d.ts +11 -0
  38. package/dist/journal-projection.d.ts.map +1 -0
  39. package/dist/journal-projection.js +2 -0
  40. package/dist/journal-projection.js.map +1 -0
  41. package/dist/journal-recovery-files.d.ts +27 -0
  42. package/dist/journal-recovery-files.d.ts.map +1 -0
  43. package/dist/journal-recovery-files.js +209 -0
  44. package/dist/journal-recovery-files.js.map +1 -0
  45. package/dist/operator-decisions.d.ts +30 -0
  46. package/dist/operator-decisions.d.ts.map +1 -0
  47. package/dist/operator-decisions.js +137 -0
  48. package/dist/operator-decisions.js.map +1 -0
  49. package/dist/project-partitions.d.ts +167 -0
  50. package/dist/project-partitions.d.ts.map +1 -0
  51. package/dist/project-partitions.js +365 -0
  52. package/dist/project-partitions.js.map +1 -0
  53. package/dist/projects.d.ts +29 -0
  54. package/dist/projects.d.ts.map +1 -0
  55. package/dist/projects.js +180 -0
  56. package/dist/projects.js.map +1 -0
  57. package/dist/quota-registry.d.ts +75 -0
  58. package/dist/quota-registry.d.ts.map +1 -0
  59. package/dist/quota-registry.js +208 -0
  60. package/dist/quota-registry.js.map +1 -0
  61. package/dist/resource-store.d.ts +22 -0
  62. package/dist/resource-store.d.ts.map +1 -0
  63. package/dist/resource-store.js +272 -0
  64. package/dist/resource-store.js.map +1 -0
  65. package/dist/run-events.d.ts +15 -0
  66. package/dist/run-events.d.ts.map +1 -0
  67. package/dist/run-events.js +29 -0
  68. package/dist/run-events.js.map +1 -0
  69. package/dist/server.d.ts +33 -33
  70. package/dist/server.d.ts.map +1 -1
  71. package/dist/server.js +231 -238
  72. package/dist/server.js.map +1 -1
  73. package/dist/spec-sessions.d.ts +72 -0
  74. package/dist/spec-sessions.d.ts.map +1 -0
  75. package/dist/spec-sessions.js +301 -0
  76. package/dist/spec-sessions.js.map +1 -0
  77. package/dist/terminate.d.ts +52 -0
  78. package/dist/terminate.d.ts.map +1 -0
  79. package/dist/terminate.js +111 -0
  80. package/dist/terminate.js.map +1 -0
  81. package/dist/thread-head-ping.d.ts +35 -0
  82. package/dist/thread-head-ping.d.ts.map +1 -0
  83. package/dist/thread-head-ping.js +67 -0
  84. package/dist/thread-head-ping.js.map +1 -0
  85. package/dist/thread-lifecycle.d.ts +5 -0
  86. package/dist/thread-lifecycle.d.ts.map +1 -0
  87. package/dist/thread-lifecycle.js +57 -0
  88. package/dist/thread-lifecycle.js.map +1 -0
  89. package/dist/thread-store-support.d.ts +37 -0
  90. package/dist/thread-store-support.d.ts.map +1 -0
  91. package/dist/thread-store-support.js +94 -0
  92. package/dist/thread-store-support.js.map +1 -0
  93. package/dist/threads.d.ts +59 -13
  94. package/dist/threads.d.ts.map +1 -1
  95. package/dist/threads.js +254 -141
  96. package/dist/threads.js.map +1 -1
  97. package/dist/token.d.ts +13 -4
  98. package/dist/token.d.ts.map +1 -1
  99. package/dist/token.js +134 -29
  100. package/dist/token.js.map +1 -1
  101. package/dist/writer-lease.d.ts +21 -0
  102. package/dist/writer-lease.d.ts.map +1 -0
  103. package/dist/writer-lease.js +94 -0
  104. package/dist/writer-lease.js.map +1 -0
  105. 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?: Thread["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
- * 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.
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 path;
54
+ private readonly journal;
55
+ private readonly headPing?;
37
56
  private state;
38
- constructor(path: string);
39
- private load;
40
- private persist;
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, 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
- recordSession(threadId: string, harnessId: string, nativeSessionId: string, observedModel?: string | null): void;
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
@@ -1 +1 @@
1
- {"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}