@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,209 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { closeSync, constants, existsSync, fchmodSync, fstatSync, fsyncSync, lstatSync, openSync, readFileSync, readdirSync, readlinkSync, readSync, renameSync, rmSync, writeSync, } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { JournalRecoveryRequiredError } from "@claudexor/journal";
5
+ import { ensureCanonicalPrivateDirectory } from "@claudexor/util";
6
+ export function recoveryFrom(error, fallback) {
7
+ if (error instanceof JournalRecoveryRequiredError)
8
+ return cloneRecovery(error.recovery);
9
+ return recoveryAt(0, `${fallback}: ${safeMessage(error)}`);
10
+ }
11
+ export function recoveryAt(byteOffset, reason) {
12
+ return {
13
+ status: "recovery_required",
14
+ location: { kind: "byte", byteOffset },
15
+ reason,
16
+ discardedTailBytes: 0,
17
+ };
18
+ }
19
+ export function cloneRecovery(value) {
20
+ return value.status === "ready" ? { ...value } : { ...value, location: { ...value.location } };
21
+ }
22
+ export function safeMessage(value) {
23
+ return value instanceof Error ? value.message : String(value);
24
+ }
25
+ export function fingerprintPartition(path) {
26
+ const hash = createHash("sha256");
27
+ if (!existsSync(path))
28
+ return hash.update("missing\0").digest("hex");
29
+ const root = lstatSync(path, { bigint: true });
30
+ if (root.isSymbolicLink()) {
31
+ hash.update(`symlink\0${readlinkSync(path)}\0`);
32
+ return hash.digest("hex");
33
+ }
34
+ if (!root.isDirectory())
35
+ return hash.update(`other\0${metadata(root)}\0`).digest("hex");
36
+ // Deliberately exclude the root inode/timestamps: this content fingerprint
37
+ // must remain stable when the owned partition is atomically quarantined.
38
+ hash.update("directory\0");
39
+ for (const name of readdirSync(path).sort()) {
40
+ const entryPath = join(path, name);
41
+ const stat = lstatSync(entryPath, { bigint: true });
42
+ hash.update(`entry\0${name}\0${metadata(stat)}\0`);
43
+ if (stat.isSymbolicLink())
44
+ hash.update(`target\0${readlinkSync(entryPath)}\0`);
45
+ else if (stat.isFile() && stat.nlink === 1n)
46
+ hash.update(hashOwnedFile(entryPath));
47
+ }
48
+ return hash.digest("hex");
49
+ }
50
+ export function exportPartitionEntries(source, destination) {
51
+ if (!existsSync(source))
52
+ return [
53
+ { name: ".", type: "missing", mode: 0, size: 0, nlink: 0, sha256: null, copiedAs: null },
54
+ ];
55
+ const root = lstatSync(source, { bigint: true });
56
+ if (!root.isDirectory() || root.isSymbolicLink()) {
57
+ return [
58
+ {
59
+ name: ".",
60
+ type: root.isSymbolicLink() ? "symlink" : "other",
61
+ mode: Number(root.mode & 511n),
62
+ size: Number(root.size),
63
+ nlink: Number(root.nlink),
64
+ sha256: null,
65
+ copiedAs: null,
66
+ ...(root.isSymbolicLink() ? { linkTarget: readlinkSync(source) } : {}),
67
+ },
68
+ ];
69
+ }
70
+ return readdirSync(source)
71
+ .sort()
72
+ .map((name) => {
73
+ const path = join(source, name);
74
+ const stat = lstatSync(path, { bigint: true });
75
+ const type = stat.isFile()
76
+ ? "file"
77
+ : stat.isDirectory()
78
+ ? "directory"
79
+ : stat.isSymbolicLink()
80
+ ? "symlink"
81
+ : "other";
82
+ let digest = null;
83
+ let copiedAs = null;
84
+ if (stat.isFile() && stat.nlink === 1n) {
85
+ const bytes = readOwnedFile(path);
86
+ digest = sha256(bytes);
87
+ copiedAs = name;
88
+ writeExclusiveFile(join(destination, name), bytes, 0o400);
89
+ }
90
+ return {
91
+ name,
92
+ type,
93
+ mode: Number(stat.mode & 511n),
94
+ size: Number(stat.size),
95
+ nlink: Number(stat.nlink),
96
+ sha256: digest,
97
+ copiedAs,
98
+ ...(stat.isSymbolicLink() ? { linkTarget: readlinkSync(path) } : {}),
99
+ };
100
+ });
101
+ }
102
+ export function readOwnedFile(path) {
103
+ const fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
104
+ try {
105
+ const before = fstatSync(fd, { bigint: true });
106
+ assertOwnedRegular(path, before);
107
+ const bytes = readFileSync(fd);
108
+ const after = fstatSync(fd, { bigint: true });
109
+ if (metadata(before) !== metadata(after))
110
+ throw new Error(`journal file changed while exporting: ${path}`);
111
+ assertOwnedRegular(path, after);
112
+ return bytes;
113
+ }
114
+ finally {
115
+ closeSync(fd);
116
+ }
117
+ }
118
+ export function writeAtomicPrivateJson(path, value, exclusive) {
119
+ ensureCanonicalPrivateDirectory(dirname(path));
120
+ if (exclusive && existsSync(path)) {
121
+ throw Object.assign(new Error("recovery idempotency record already exists"), {
122
+ code: "idempotency_conflict",
123
+ status: 409,
124
+ });
125
+ }
126
+ const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;
127
+ try {
128
+ writeExclusiveFile(tmp, Buffer.from(`${JSON.stringify(value, null, 2)}\n`), 0o600);
129
+ renameSync(tmp, path);
130
+ fsyncDirectory(dirname(path));
131
+ }
132
+ finally {
133
+ try {
134
+ rmSync(tmp, { force: true });
135
+ }
136
+ catch {
137
+ /* renamed or absent */
138
+ }
139
+ }
140
+ }
141
+ export function fsyncDirectory(path) {
142
+ const fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
143
+ try {
144
+ fsyncSync(fd);
145
+ }
146
+ finally {
147
+ closeSync(fd);
148
+ }
149
+ }
150
+ export function sha256(bytes) {
151
+ return createHash("sha256").update(bytes).digest("hex");
152
+ }
153
+ export function sha256File(path) {
154
+ return hashOwnedFile(path).toString("hex");
155
+ }
156
+ function hashOwnedFile(path) {
157
+ const fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
158
+ try {
159
+ const before = fstatSync(fd, { bigint: true });
160
+ assertOwnedRegular(path, before);
161
+ const hash = createHash("sha256");
162
+ const buffer = Buffer.allocUnsafe(64 * 1024);
163
+ let offset = 0;
164
+ for (;;) {
165
+ const count = readSync(fd, buffer, 0, buffer.length, offset);
166
+ if (count === 0)
167
+ break;
168
+ hash.update(buffer.subarray(0, count));
169
+ offset += count;
170
+ }
171
+ const after = fstatSync(fd, { bigint: true });
172
+ if (metadata(before) !== metadata(after))
173
+ throw new Error(`journal file changed while hashing: ${path}`);
174
+ assertOwnedRegular(path, after);
175
+ return hash.digest();
176
+ }
177
+ finally {
178
+ closeSync(fd);
179
+ }
180
+ }
181
+ function assertOwnedRegular(path, opened) {
182
+ const named = lstatSync(path, { bigint: true });
183
+ if (!opened.isFile() ||
184
+ opened.nlink !== 1n ||
185
+ named.isSymbolicLink() ||
186
+ !named.isFile() ||
187
+ named.nlink !== 1n ||
188
+ opened.dev !== named.dev ||
189
+ opened.ino !== named.ino)
190
+ throw new Error(`journal recovery file is not a singly-linked owned regular file: ${path}`);
191
+ }
192
+ function metadata(stat) {
193
+ return [stat.dev, stat.ino, stat.mode, stat.nlink, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
194
+ }
195
+ export function writeExclusiveFile(path, bytes, mode) {
196
+ const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
197
+ try {
198
+ let offset = 0;
199
+ while (offset < bytes.length)
200
+ offset += writeSync(fd, bytes, offset, bytes.length - offset);
201
+ fsyncSync(fd);
202
+ fchmodSync(fd, mode);
203
+ fsyncSync(fd);
204
+ }
205
+ finally {
206
+ closeSync(fd);
207
+ }
208
+ }
209
+ //# sourceMappingURL=journal-recovery-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-recovery-files.js","sourceRoot":"","sources":["../src/journal-recovery-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { DurableJournal } from "@claudexor/journal";
2
+ export interface OperatorDecisionRecord {
3
+ runId: string;
4
+ action: "accept_risk" | "override_needs_human";
5
+ findingIds: string[];
6
+ acceptedRisks: string[];
7
+ patchSha256: string;
8
+ decidedAt: string;
9
+ }
10
+ /** Journal authority for the human decision that may unblock one exact run patch. */
11
+ export declare class OperatorDecisionStore {
12
+ private readonly journal;
13
+ private readonly byRun;
14
+ private readonly byKey;
15
+ constructor(journal: DurableJournal);
16
+ get(runId: string): OperatorDecisionRecord | null;
17
+ record(input: OperatorDecisionRecord, idempotency?: {
18
+ key: string;
19
+ client: string;
20
+ request: unknown;
21
+ }): OperatorDecisionRecord;
22
+ validateProjection(): void;
23
+ private apply;
24
+ }
25
+ export declare function operatorDecisionProjection(): {
26
+ name: string;
27
+ create: (journal: DurableJournal) => OperatorDecisionStore;
28
+ validate: (store: OperatorDecisionStore) => void;
29
+ };
30
+ //# sourceMappingURL=operator-decisions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operator-decisions.d.ts","sourceRoot":"","sources":["../src/operator-decisions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,GAAG,sBAAsB,CAAC;IAC/C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,qFAAqF;AACrF,qBAAa,qBAAqB;IAIpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+D;gBAExD,OAAO,EAAE,cAAc;IAQpD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAKjD,MAAM,CACJ,KAAK,EAAE,sBAAsB,EAC7B,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAC9D,sBAAsB;IAkBzB,kBAAkB,IAAI,IAAI;IAQ1B,OAAO,CAAC,KAAK;CAWd;AAED,wBAAgB,0BAA0B;;sBAGpB,cAAc;sBACd,qBAAqB;EAE1C"}
@@ -0,0 +1,137 @@
1
+ import { hashJson } from "@claudexor/util";
2
+ const RECORDED = "operator.decision_recorded";
3
+ /** Journal authority for the human decision that may unblock one exact run patch. */
4
+ export class OperatorDecisionStore {
5
+ journal;
6
+ byRun = new Map();
7
+ byKey = new Map();
8
+ constructor(journal) {
9
+ this.journal = journal;
10
+ for (const entry of journal.records()) {
11
+ if (entry.type !== RECORDED)
12
+ continue;
13
+ const mutation = parseMutation(entry.payload);
14
+ this.apply(mutation);
15
+ }
16
+ }
17
+ get(runId) {
18
+ const decision = this.byRun.get(runId);
19
+ return decision ? structuredClone(decision) : null;
20
+ }
21
+ record(input, idempotency) {
22
+ const decision = parseDecision(input);
23
+ const binding = decisionBinding(this.journal.options.partition, decision.runId, idempotency);
24
+ if (binding) {
25
+ const prior = this.byKey.get(binding.keyDigest);
26
+ if (prior) {
27
+ if (prior.requestDigest !== binding.requestDigest)
28
+ throw conflict();
29
+ const existing = this.byRun.get(prior.runId);
30
+ if (!existing)
31
+ throw new Error("operator decision idempotency index is dangling");
32
+ return structuredClone(existing);
33
+ }
34
+ }
35
+ const mutation = { decision, ...(binding ? { idempotency: binding } : {}) };
36
+ this.journal.append(RECORDED, mutation);
37
+ this.apply(mutation);
38
+ return structuredClone(decision);
39
+ }
40
+ validateProjection() {
41
+ for (const decision of this.byRun.values())
42
+ parseDecision(decision);
43
+ for (const binding of this.byKey.values()) {
44
+ if (!this.byRun.has(binding.runId))
45
+ throw new Error("operator decision idempotency index is dangling");
46
+ }
47
+ }
48
+ apply(mutation) {
49
+ this.byRun.set(mutation.decision.runId, structuredClone(mutation.decision));
50
+ if (mutation.idempotency) {
51
+ const { keyDigest, requestDigest, runId } = mutation.idempotency;
52
+ const prior = this.byKey.get(keyDigest);
53
+ if (prior && (prior.requestDigest !== requestDigest || prior.runId !== runId)) {
54
+ throw new Error("conflicting operator decision idempotency history");
55
+ }
56
+ this.byKey.set(keyDigest, { requestDigest, runId });
57
+ }
58
+ }
59
+ }
60
+ export function operatorDecisionProjection() {
61
+ return {
62
+ name: "operator-decisions",
63
+ create: (journal) => new OperatorDecisionStore(journal),
64
+ validate: (store) => store.validateProjection(),
65
+ };
66
+ }
67
+ function parseDecision(value) {
68
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
69
+ throw new Error("invalid operator decision record");
70
+ }
71
+ const input = value;
72
+ if (typeof input.runId !== "string" ||
73
+ !input.runId ||
74
+ (input.action !== "accept_risk" && input.action !== "override_needs_human") ||
75
+ !stringArray(input.findingIds) ||
76
+ !stringArray(input.acceptedRisks) ||
77
+ typeof input.patchSha256 !== "string" ||
78
+ !/^sha256:[a-f0-9]{64}$/.test(input.patchSha256) ||
79
+ typeof input.decidedAt !== "string" ||
80
+ !input.decidedAt) {
81
+ throw new Error("invalid operator decision record");
82
+ }
83
+ return structuredClone(input);
84
+ }
85
+ function parseMutation(value) {
86
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
87
+ throw new Error("invalid operator decision mutation");
88
+ }
89
+ const input = value;
90
+ // Accept the pre-idempotency v2 record shape while the release candidate is local-only.
91
+ if (!("decision" in input))
92
+ return { decision: parseDecision(value) };
93
+ const idempotency = input["idempotency"];
94
+ if (idempotency !== undefined &&
95
+ (!idempotency ||
96
+ typeof idempotency !== "object" ||
97
+ Array.isArray(idempotency) ||
98
+ typeof idempotency.keyDigest !== "string" ||
99
+ typeof idempotency.requestDigest !== "string" ||
100
+ typeof idempotency.runId !== "string")) {
101
+ throw new Error("invalid operator decision idempotency binding");
102
+ }
103
+ return {
104
+ decision: parseDecision(input["decision"]),
105
+ ...(idempotency ? { idempotency: { ...idempotency } } : {}),
106
+ };
107
+ }
108
+ function decisionBinding(partition, runId, input) {
109
+ if (!input)
110
+ return undefined;
111
+ if (!input.key || input.key.length > 256) {
112
+ throw Object.assign(new Error("Idempotency-Key must contain 1-256 characters"), {
113
+ code: "invalid_idempotency_key",
114
+ status: 400,
115
+ });
116
+ }
117
+ return {
118
+ keyDigest: hashJson({
119
+ client: input.client,
120
+ partition,
121
+ operation: "run.decision",
122
+ key: input.key,
123
+ }),
124
+ requestDigest: hashJson(input.request),
125
+ runId,
126
+ };
127
+ }
128
+ function conflict() {
129
+ return Object.assign(new Error("idempotency key was already used with a different request"), {
130
+ code: "idempotency_conflict",
131
+ status: 409,
132
+ });
133
+ }
134
+ function stringArray(value) {
135
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
136
+ }
137
+ //# sourceMappingURL=operator-decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operator-decisions.js","sourceRoot":"","sources":["../src/operator-decisions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import type { Project, RunEvent, Thread, ThreadTurn } from "@claudexor/schema";
2
+ import { type CommandStore } from "./command-store.js";
3
+ import { JournalManager, type JournalProjectionSlot } from "./journal-manager.js";
4
+ import { type InteractionStore } from "./interactions.js";
5
+ import { type OperatorDecisionRecord, type OperatorDecisionStore } from "./operator-decisions.js";
6
+ import { type RunEventStore } from "./run-events.js";
7
+ import { type SpecSessionStore } from "./spec-sessions.js";
8
+ import type { ProjectStore } from "./projects.js";
9
+ import { type CreateThreadInput, type CreateTurnInput, type ThreadHeadPingSink, type ThreadStore, type UpdateThreadInput } from "./threads.js";
10
+ import type { CommandAuthority } from "./command-authority.js";
11
+ export declare class ProjectPartitions implements CommandAuthority {
12
+ private readonly rootDir;
13
+ private readonly projects;
14
+ private readonly globalCommands;
15
+ private readonly globalInteractions;
16
+ private readonly globalDecisions;
17
+ private readonly globalRunEvents;
18
+ private readonly globalThreads;
19
+ /** Global-partition `thread.head.updated` sink, threaded into every project ThreadStore. */
20
+ private readonly headPing?;
21
+ private readonly partitions;
22
+ constructor(rootDir: string, projects: JournalProjectionSlot<ProjectStore>, globalCommands: JournalProjectionSlot<CommandStore>, globalInteractions: JournalProjectionSlot<InteractionStore>, globalDecisions: JournalProjectionSlot<OperatorDecisionStore>, globalRunEvents: JournalProjectionSlot<RunEventStore>, globalThreads: JournalProjectionSlot<ThreadStore>,
23
+ /** Global-partition `thread.head.updated` sink, threaded into every project ThreadStore. */
24
+ headPing?: ThreadHeadPingSink | undefined);
25
+ all(): CommandStore[];
26
+ interactionStores(): InteractionStore[];
27
+ interactionsForRequest(params: unknown): InteractionStore;
28
+ operatorDecision(params: unknown, runId: string): OperatorDecisionRecord | null;
29
+ recordOperatorDecision(params: unknown, decision: OperatorDecisionRecord, idempotency?: {
30
+ key: string;
31
+ client: string;
32
+ request: unknown;
33
+ }): OperatorDecisionRecord;
34
+ recordRunEvent(params: unknown, event: RunEvent): RunEvent;
35
+ specsForRequest(params: unknown): SpecSessionStore;
36
+ specStoreForSession(id: string): SpecSessionStore | undefined;
37
+ listSpecSessions(): {
38
+ state: "failed" | "cancelled" | "interrupted_unknown" | "questions" | "frozen" | "grounding" | "answered" | "freezing";
39
+ error: string | null;
40
+ createdAt: string;
41
+ prompt: string;
42
+ questions: {
43
+ options: {
44
+ id: string;
45
+ label: string;
46
+ }[];
47
+ kind: "text" | "single" | "multi";
48
+ id: string;
49
+ prompt: string;
50
+ tier: number;
51
+ allow_text: boolean;
52
+ rationale?: string | undefined;
53
+ }[];
54
+ answers: {
55
+ question_id: string;
56
+ text: string | null;
57
+ option_ids: string[];
58
+ }[];
59
+ planRunId: string | null;
60
+ scope: {
61
+ kind: "project";
62
+ root: string;
63
+ context: "auto";
64
+ };
65
+ specPath: string | null;
66
+ specId: string | null;
67
+ specHash: string | null;
68
+ sessionId: string;
69
+ updatedAt: string;
70
+ priorDecisions: {
71
+ question: string;
72
+ answer: string;
73
+ }[];
74
+ specDir: string | null;
75
+ }[];
76
+ forRequest(params: unknown): CommandStore;
77
+ findById(id: string): CommandStore | undefined;
78
+ beginDelivery(params: unknown, input: {
79
+ key: string;
80
+ client: string;
81
+ operation: string;
82
+ request: unknown;
83
+ }): {
84
+ reused: boolean;
85
+ id: string;
86
+ state: import("./server.js").JobState;
87
+ params: unknown;
88
+ result?: unknown;
89
+ error?: string;
90
+ errorCode?: string;
91
+ errorStatus?: number;
92
+ createdAt: string;
93
+ runId?: string;
94
+ taskId?: string;
95
+ runDir?: string;
96
+ startedAt?: string;
97
+ finishedAt?: string;
98
+ };
99
+ completeDelivery(id: string, result: unknown): void;
100
+ failDelivery(id: string, error: unknown): void;
101
+ registerProject(input: Parameters<ProjectStore["register"]>[0]): Project;
102
+ relinkProject(id: string, root: string): Project;
103
+ journal(partition: string): JournalManager;
104
+ createThread(input: CreateThreadInput): Thread;
105
+ listThreads(): Thread[];
106
+ getThread(id: string): Thread | undefined;
107
+ turnsFor(id: string): ThreadTurn[];
108
+ sessionsForThread(id: string): {
109
+ state: "live" | "stale" | "rebound";
110
+ profile_id: string | null;
111
+ harness_id: string;
112
+ created_at: string;
113
+ id: string;
114
+ updated_at: string;
115
+ thread_id: string;
116
+ native_session_id: string | null;
117
+ resume_kind: "none" | "resume_by_id";
118
+ last_observed_model: string | null;
119
+ }[];
120
+ createTurn(id: string, prompt: string, input?: CreateTurnInput): ThreadTurn;
121
+ updateThread(id: string, patch: UpdateThreadInput): Thread;
122
+ trashThread(id: string): Thread;
123
+ restoreThread(id: string): Thread;
124
+ purgeThread(id: string): Thread;
125
+ setThreadWorktree(id: string, path: string, baseSha: string, deliveredThroughRunId?: string): void;
126
+ assertKnownIds(threadId: unknown, turnId: unknown): {
127
+ threadId?: string;
128
+ turnId?: string;
129
+ };
130
+ getTurn(id: string): ThreadTurn | undefined;
131
+ bindTurnRun(id: string, runId: string): void;
132
+ setTurnEnqueueError(id: string, message: string, code?: string | null, retryable?: boolean): void;
133
+ resumeMap(id: string, profileId?: string | null): Record<string, {
134
+ sessionId: string;
135
+ profileId: string | null;
136
+ }>;
137
+ recordSession(id: string, harnessId: string, nativeSessionId: string, observedModel?: string | null, profileId?: string | null): void;
138
+ /**
139
+ * Run-terminal invalidation (the W12 path with no store mutation to ride):
140
+ * a terminal changes the thread's presented state (needs-me, outcome), so
141
+ * the daemon pings the owning store's head directly.
142
+ */
143
+ pingThreadHead(id: string): void;
144
+ close(): void;
145
+ private sync;
146
+ private ensure;
147
+ private healthy;
148
+ /**
149
+ * Canonical roots whose partition journal is READY — the set whose thread
150
+ * lineage / job records are trustworthy. Retention (W3.6) fails CLOSED on a
151
+ * quarantined partition: its runs are protected, never GC'd against an empty
152
+ * reference set (a non-ready partition contributes nothing to listThreads,
153
+ * so its referenced runs would otherwise look unreferenced).
154
+ */
155
+ healthyProjectRoots(): string[];
156
+ private partitionForRoot;
157
+ private threadStores;
158
+ private threadStoreForRoot;
159
+ private threadStoreForThread;
160
+ private threadStoreForTurn;
161
+ private requireThreadStore;
162
+ private requireTurnStore;
163
+ private commandStoreForThreadStore;
164
+ private decisionStoreForRequest;
165
+ private runEventStoreForRequest;
166
+ }
167
+ //# sourceMappingURL=project-partitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-partitions.d.ts","sourceRoot":"","sources":["../src/project-partitions.ts"],"names":[],"mappings":"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"}