@vercel/factory 0.0.16 → 0.0.18

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 (186) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/api-contracts.d.mts +665 -715
  3. package/dist/api-contracts.mjs +91 -4
  4. package/dist/api-contracts.mjs.map +1 -1
  5. package/dist/api-task-graph.mjs +14 -5
  6. package/dist/api-task-graph.mjs.map +1 -1
  7. package/dist/api.d.mts +58 -11
  8. package/dist/api.mjs +715 -399
  9. package/dist/api.mjs.map +1 -1
  10. package/dist/approval-access.d.mts +1 -1
  11. package/dist/approval-contracts.d.mts +3 -4
  12. package/dist/approval-contracts.mjs +1 -2
  13. package/dist/approval-contracts.mjs.map +1 -1
  14. package/dist/blob/index.d.mts +1 -1
  15. package/dist/budget.mjs +20 -3
  16. package/dist/budget.mjs.map +1 -1
  17. package/dist/change-verification/brief.d.mts +1 -1
  18. package/dist/change-verification/dispatch.mjs +8 -1
  19. package/dist/change-verification/dispatch.mjs.map +1 -1
  20. package/dist/changes/eve-record-change.mjs +4 -1
  21. package/dist/changes/eve-record-change.mjs.map +1 -1
  22. package/dist/client-stream.d.mts +19 -2
  23. package/dist/client-stream.mjs +115 -53
  24. package/dist/client-stream.mjs.map +1 -1
  25. package/dist/client-transcript.d.mts +25 -2
  26. package/dist/client-transcript.mjs +95 -13
  27. package/dist/client-transcript.mjs.map +1 -1
  28. package/dist/client.d.mts +145 -19
  29. package/dist/client.mjs +89 -16
  30. package/dist/client.mjs.map +1 -1
  31. package/dist/code-review/contracts.d.mts +1 -0
  32. package/dist/code-review/eve-post-review.d.mts +4 -2
  33. package/dist/code-review/eve-post-review.mjs +8 -0
  34. package/dist/code-review/eve-post-review.mjs.map +1 -1
  35. package/dist/code-review/github-reporter.d.mts +6 -2
  36. package/dist/code-review/github-reporter.mjs +86 -35
  37. package/dist/code-review/github-reporter.mjs.map +1 -1
  38. package/dist/code-review/preparation.d.mts +2 -1
  39. package/dist/code-review/preparation.mjs +2 -1
  40. package/dist/code-review/preparation.mjs.map +1 -1
  41. package/dist/code-review/stall.mjs +11 -2
  42. package/dist/code-review/stall.mjs.map +1 -1
  43. package/dist/connectors/github.d.mts +1 -1
  44. package/dist/connectors/index.d.mts +1 -1
  45. package/dist/connectors/slack.d.mts +1 -1
  46. package/dist/delivery-metrics/metrics.d.mts +1 -1
  47. package/dist/dispatch.mjs +3 -3
  48. package/dist/dispatch.mjs.map +1 -1
  49. package/dist/eve/index.d.mts +1 -1
  50. package/dist/eve/index.mjs +8 -1
  51. package/dist/eve/index.mjs.map +1 -1
  52. package/dist/eve/task-execution.d.mts +4 -4
  53. package/dist/eve/transcript.d.mts +3 -1
  54. package/dist/eve/transcript.mjs.map +1 -1
  55. package/dist/finding-remediation/admission.d.mts +1 -1
  56. package/dist/finding-remediation/brief.d.mts +1 -1
  57. package/dist/github-app.d.mts +1 -1
  58. package/dist/github-publication.d.mts +1 -1
  59. package/dist/github.d.mts +9 -1
  60. package/dist/github.mjs +29 -11
  61. package/dist/github.mjs.map +1 -1
  62. package/dist/index.d.mts +1 -1
  63. package/dist/intake-contracts.d.mts +1 -0
  64. package/dist/intake-contracts.mjs +2 -1
  65. package/dist/intake-contracts.mjs.map +1 -1
  66. package/dist/integrations/github-issues.d.mts +53 -0
  67. package/dist/integrations/github-issues.mjs +170 -0
  68. package/dist/integrations/github-issues.mjs.map +1 -0
  69. package/dist/integrations/github.d.mts +2 -1
  70. package/dist/integrations/github.mjs +2 -1
  71. package/dist/multi-repository-changes/coordination.mjs +1 -1
  72. package/dist/planning/reconcile.mjs +15 -2
  73. package/dist/planning/reconcile.mjs.map +1 -1
  74. package/dist/postgres/index.d.mts +2 -1
  75. package/dist/postgres/index.mjs +11 -5
  76. package/dist/postgres/index.mjs.map +1 -1
  77. package/dist/postgres/indexed-codec.mjs +137 -0
  78. package/dist/postgres/indexed-codec.mjs.map +1 -0
  79. package/dist/postgres/indexed-schema.mjs +99 -0
  80. package/dist/postgres/indexed-schema.mjs.map +1 -0
  81. package/dist/postgres/indexed.d.mts +28 -0
  82. package/dist/postgres/indexed.mjs +277 -0
  83. package/dist/postgres/indexed.mjs.map +1 -0
  84. package/dist/postgres/record-predicates.mjs +23 -0
  85. package/dist/postgres/record-predicates.mjs.map +1 -0
  86. package/dist/presets/software-development/deepsec-brief.d.mts +1 -1
  87. package/dist/presets/software-development/dispatch.mjs +1 -1
  88. package/dist/presets/software-development/dispatch.mjs.map +1 -1
  89. package/dist/presets/software-development/recovery.mjs +9 -2
  90. package/dist/presets/software-development/recovery.mjs.map +1 -1
  91. package/dist/pull-requests/eve-fetch.d.mts +4 -1
  92. package/dist/pull-requests/eve-fetch.mjs +9 -0
  93. package/dist/pull-requests/eve-fetch.mjs.map +1 -1
  94. package/dist/pull-requests/github-publisher.d.mts +1 -1
  95. package/dist/pull-requests/github-publisher.mjs +19 -7
  96. package/dist/pull-requests/github-publisher.mjs.map +1 -1
  97. package/dist/repositories.mjs +20 -13
  98. package/dist/repositories.mjs.map +1 -1
  99. package/dist/sandbox/execution-run-ledger.d.mts +2 -2
  100. package/dist/sandbox/execution-run-ledger.mjs.map +1 -1
  101. package/dist/sandbox/execution.d.mts +2 -2
  102. package/dist/sandbox/execution.mjs.map +1 -1
  103. package/dist/schema/catalog.mjs +1 -1
  104. package/dist/schema/change.d.mts +1 -1
  105. package/dist/schema/communication.d.mts +2 -2
  106. package/dist/schema/factory-config.d.mts +1 -1
  107. package/dist/schema/outbox.d.mts +6 -6
  108. package/dist/schema/session-summary.d.mts +218 -0
  109. package/dist/schema/session-summary.mjs +68 -0
  110. package/dist/schema/session-summary.mjs.map +1 -0
  111. package/dist/schema/session.d.mts +39 -59
  112. package/dist/schema/session.mjs +6 -6
  113. package/dist/schema/session.mjs.map +1 -1
  114. package/dist/schema/task-graph.d.mts +24 -24
  115. package/dist/schema/transcript.d.mts +141 -3
  116. package/dist/schema/transcript.mjs +19 -3
  117. package/dist/schema/transcript.mjs.map +1 -1
  118. package/dist/schema/transitions.d.mts +1 -1
  119. package/dist/schema/transitions.mjs +1 -1
  120. package/dist/schema/transitions.mjs.map +1 -1
  121. package/dist/signals.d.mts +1 -1
  122. package/dist/stall.mjs +10 -2
  123. package/dist/stall.mjs.map +1 -1
  124. package/dist/storage.d.mts +10 -1
  125. package/dist/storage.mjs +7 -1
  126. package/dist/store/approvals.d.mts +14 -0
  127. package/dist/store/approvals.mjs +78 -0
  128. package/dist/store/approvals.mjs.map +1 -0
  129. package/dist/store/conversations.d.mts +59 -0
  130. package/dist/store/conversations.mjs +549 -0
  131. package/dist/store/conversations.mjs.map +1 -0
  132. package/dist/store/driver.d.mts +1 -1
  133. package/dist/store/driver.mjs.map +1 -1
  134. package/dist/store/engine.d.mts +38 -16
  135. package/dist/store/engine.mjs +229 -106
  136. package/dist/store/engine.mjs.map +1 -1
  137. package/dist/store/indexed-engine.d.mts +57 -0
  138. package/dist/store/indexed-engine.mjs +155 -0
  139. package/dist/store/indexed-engine.mjs.map +1 -0
  140. package/dist/store/indexed-memory.d.mts +7 -0
  141. package/dist/store/indexed-memory.mjs +200 -0
  142. package/dist/store/indexed-memory.mjs.map +1 -0
  143. package/dist/store/indexed-projections.d.mts +280 -0
  144. package/dist/store/indexed-projections.mjs +481 -0
  145. package/dist/store/indexed-projections.mjs.map +1 -0
  146. package/dist/store/indexed.d.mts +101 -0
  147. package/dist/store/indexed.mjs +19 -0
  148. package/dist/store/indexed.mjs.map +1 -0
  149. package/dist/store/iterate.d.mts +9 -0
  150. package/dist/store/iterate.mjs +23 -0
  151. package/dist/store/iterate.mjs.map +1 -0
  152. package/dist/store/query-scope.mjs +62 -0
  153. package/dist/store/query-scope.mjs.map +1 -0
  154. package/dist/store/query.d.mts +32 -0
  155. package/dist/store/query.mjs +103 -0
  156. package/dist/store/query.mjs.map +1 -0
  157. package/dist/store/session-history.mjs +24 -0
  158. package/dist/store/session-history.mjs.map +1 -0
  159. package/dist/store/slack-pr-notifications.d.mts +2 -2
  160. package/dist/store/slack-pr-notifications.mjs.map +1 -1
  161. package/dist/store/state.d.mts +26 -0
  162. package/dist/store/state.mjs +95 -0
  163. package/dist/store/state.mjs.map +1 -0
  164. package/dist/store/task-effects.d.mts +1 -1
  165. package/dist/store/task-graphs.d.mts +1 -1
  166. package/dist/store/task-messages.d.mts +1 -1
  167. package/dist/store/task-work.d.mts +1 -1
  168. package/dist/store/task-work.mjs +1 -1
  169. package/dist/store/transcripts.mjs +308 -0
  170. package/dist/store/transcripts.mjs.map +1 -0
  171. package/dist/sweep.d.mts +1 -1
  172. package/dist/sweep.mjs +12 -7
  173. package/dist/sweep.mjs.map +1 -1
  174. package/dist/task-communication.mjs +15 -1
  175. package/dist/task-communication.mjs.map +1 -1
  176. package/dist/task-protocols.d.mts +3 -3
  177. package/dist/tasks.d.mts +1 -1
  178. package/dist/vercel.d.mts +1 -1
  179. package/dist/work-triage/find-existing-work.d.mts +1 -1
  180. package/dist/work-triage/find-existing-work.mjs +12 -2
  181. package/dist/work-triage/find-existing-work.mjs.map +1 -1
  182. package/docs/index.md +4 -0
  183. package/docs/recipes/persistence-recovery.md +15 -9
  184. package/docs/recipes/postgres-indexed-engine.md +108 -0
  185. package/docs/recipes/postgres-indexed-storage.md +145 -0
  186. package/package.json +6 -1
@@ -0,0 +1,481 @@
1
+ import { changeIdSchema, receiptIdSchema, repositoryIdSchema, signalIdSchema, taskIdSchema } from "../schema/id.mjs";
2
+ import { isoDateTimeSchema, replyToSchema } from "../schema/common.mjs";
3
+ import { repositorySchema } from "../schema/repository.mjs";
4
+ import { executionReferenceSchema, taskSchema, taskStateSchema } from "../schema/task.mjs";
5
+ import { receiptSchema } from "../schema/receipt.mjs";
6
+ import { transcriptSnapshotSchema } from "../schema/transcript.mjs";
7
+ import { changeSchema, changeStateSchema } from "../schema/change.mjs";
8
+ import { agentSessionIdSchema, agentSessionSchema } from "../schema/session.mjs";
9
+ import { signalSchema } from "../schema/signal.mjs";
10
+ import { sessionContinuationRecordSchema, sessionNotificationRecordSchema } from "./session-history.mjs";
11
+ import { createHash } from "node:crypto";
12
+ import { z } from "zod";
13
+ //#region src/store/indexed-projections.ts
14
+ const collectionSchema = z.enum([
15
+ "repositories",
16
+ "signals",
17
+ "tasks",
18
+ "changes",
19
+ "receipts",
20
+ "sessions",
21
+ "externalSessions",
22
+ "sessionContinuations",
23
+ "sessionNotifications",
24
+ "transcripts"
25
+ ]);
26
+ const sessionCollections = z.enum(["sessions", "externalSessions"]);
27
+ /** Validates an exact, trusted query scope; transport callers must authorize it before querying. */
28
+ const factoryIndexScopeSchema = z.union([
29
+ z.strictObject({
30
+ collection: z.enum(["sessionContinuations", "sessionNotifications"]).describe("Paginated session history collection."),
31
+ by: z.literal("session").describe("History within an exact session."),
32
+ sessionId: agentSessionIdSchema.describe("Session whose history is selected.")
33
+ }),
34
+ z.strictObject({
35
+ collection: collectionSchema.describe("Source collection to query."),
36
+ by: z.literal("all").describe("All records in the namespace's collection.")
37
+ }),
38
+ z.strictObject({
39
+ collection: collectionSchema.exclude(["repositories", "transcripts"]).describe("Source collection with repository memberships."),
40
+ by: z.literal("repository").describe("Records belonging to the selected repository."),
41
+ repositoryId: repositoryIdSchema.describe("Repository membership to query.")
42
+ }),
43
+ z.strictObject({
44
+ collection: z.literal("tasks").describe("Task source summaries."),
45
+ by: z.literal("state").describe("Tasks in one lifecycle state."),
46
+ state: taskStateSchema.describe("Exact Task lifecycle state to query."),
47
+ repositoryId: repositoryIdSchema.optional().describe("Optional repository membership filter.")
48
+ }),
49
+ z.strictObject({
50
+ collection: z.literal("changes").describe("Change source summaries."),
51
+ by: z.literal("state").describe("Changes in one lifecycle state."),
52
+ state: changeStateSchema.describe("Exact Change lifecycle state to query."),
53
+ repositoryId: repositoryIdSchema.optional().describe("Optional repository membership filter.")
54
+ }),
55
+ z.strictObject({
56
+ collection: z.literal("tasks").describe("Task source summaries."),
57
+ by: z.literal("root").describe("Tasks in one canonical root graph."),
58
+ rootTaskId: taskIdSchema.describe("Root Task identifying the graph.")
59
+ }),
60
+ z.strictObject({
61
+ collection: z.literal("tasks").describe("Task source summaries."),
62
+ by: z.literal("reply").describe("Tasks sharing an exact reply destination."),
63
+ replyTo: replyToSchema.describe("Exact reply destination to query.")
64
+ }),
65
+ z.strictObject({
66
+ collection: z.enum([
67
+ "receipts",
68
+ "changes",
69
+ "sessions",
70
+ "sessionContinuations"
71
+ ]).describe("Task-bound source collection."),
72
+ by: z.literal("task").describe("Records bound to one Task."),
73
+ taskId: taskIdSchema.describe("Task whose bound records are selected.")
74
+ }),
75
+ z.strictObject({
76
+ collection: sessionCollections.describe("Internal or external session collection."),
77
+ by: z.literal("owner").describe("Sessions belonging to one owner."),
78
+ owner: z.string().min(1).describe("Authorized session owner to query."),
79
+ repositoryId: repositoryIdSchema.optional().describe("Optional repository membership filter.")
80
+ }),
81
+ z.strictObject({
82
+ collection: sessionCollections.describe("Internal or external session collection."),
83
+ by: z.literal("execution").describe("Sessions bound to an exact provider execution."),
84
+ execution: executionReferenceSchema.describe("Execution identity; only provider and sessionId select the scope.")
85
+ }),
86
+ z.strictObject({
87
+ collection: z.enum(["tasks", "changes"]).describe("Source collection requiring attention."),
88
+ by: z.literal("attention").describe("Source attention, without conversation deduplication."),
89
+ repositoryId: repositoryIdSchema.optional().describe("Optional repository membership filter.")
90
+ }),
91
+ z.strictObject({
92
+ collection: z.literal("transcripts").describe("Transcript source summaries."),
93
+ by: z.literal("attention").describe("Source attention, without conversation deduplication.")
94
+ })
95
+ ]);
96
+ const common = {
97
+ id: z.string().min(1).describe("Canonical source record key."),
98
+ repositoryIds: z.array(repositoryIdSchema).readonly().describe("Repository memberships; callers must authorize every repository."),
99
+ createdAt: isoDateTimeSchema.describe("Source timestamp used to order this summary.")
100
+ };
101
+ /** Validates compact source summaries, without Task inputs, messages, histories, or transcript bodies. */
102
+ const factoryRecordSummarySchema = z.discriminatedUnion("collection", [
103
+ z.strictObject({
104
+ ...common,
105
+ collection: z.literal("sessionContinuations").describe("Separate follow-up intent."),
106
+ sessionId: agentSessionIdSchema.describe("Owning conversation."),
107
+ taskId: taskIdSchema.describe("Task admitted for this follow-up."),
108
+ committed: z.boolean().describe("Whether the session head admitted this intent.")
109
+ }),
110
+ z.strictObject({
111
+ ...common,
112
+ collection: z.literal("sessionNotifications").describe("Separate delivered notification."),
113
+ sessionId: agentSessionIdSchema.describe("Owning conversation."),
114
+ outcome: z.string().describe("Notification outcome.")
115
+ }),
116
+ z.strictObject({
117
+ ...common,
118
+ collection: z.literal("repositories").describe("Repository source summary."),
119
+ id: repositoryIdSchema.describe("Canonical repository ID."),
120
+ slug: z.string().describe("Provider repository slug."),
121
+ enabled: z.boolean().describe("Whether the repository is enabled for work.")
122
+ }),
123
+ z.strictObject({
124
+ ...common,
125
+ collection: z.literal("signals").describe("Signal source summary."),
126
+ id: signalIdSchema.describe("Canonical Signal ID."),
127
+ source: z.string().describe("Signal source kind."),
128
+ outcome: z.string().describe("Recorded triage outcome.")
129
+ }),
130
+ z.strictObject({
131
+ ...common,
132
+ collection: z.literal("tasks").describe("Task source summary."),
133
+ title: z.string().max(256).describe("Work title without input or history payloads."),
134
+ id: taskIdSchema.describe("Canonical Task ID."),
135
+ kind: z.string().describe("Descriptive Task kind, not routing authority."),
136
+ state: taskStateSchema.describe("Current Task lifecycle state."),
137
+ rootTaskId: taskIdSchema.describe("Root of the canonical Task graph."),
138
+ parentTaskId: taskIdSchema.optional().describe("Immediate parent Task when present."),
139
+ attempt: z.number().int().positive().describe("Current Task execution attempt."),
140
+ changeId: changeIdSchema.optional().describe("Associated Change when present."),
141
+ route: z.object({
142
+ id: z.string().describe("Exact registered agent route ID."),
143
+ version: z.number().describe("Exact registered agent route version.")
144
+ }).optional().describe("Persisted agent route when the Task uses one."),
145
+ approval: z.enum([
146
+ "required",
147
+ "granted",
148
+ "denied"
149
+ ]).optional().describe("Task approval state."),
150
+ updatedAt: isoDateTimeSchema.describe("Latest canonical Task update."),
151
+ attention: z.enum([
152
+ "question",
153
+ "failed",
154
+ "stalled",
155
+ "approval"
156
+ ]).optional().describe("Task attention reason; not a deduplicated conversation decision.")
157
+ }),
158
+ z.strictObject({
159
+ ...common,
160
+ collection: z.literal("changes").describe("Change source summary."),
161
+ id: changeIdSchema.describe("Canonical Change ID."),
162
+ state: changeStateSchema.describe("Current Change lifecycle state."),
163
+ taskId: taskIdSchema.optional().describe("Task that created the Change, when present."),
164
+ prNumber: z.number().int().positive().describe("Repository-local pull request number."),
165
+ updatedAt: isoDateTimeSchema.describe("Latest canonical Change update."),
166
+ attention: z.literal("review").optional().describe("The Change is ready for review.")
167
+ }),
168
+ z.strictObject({
169
+ ...common,
170
+ collection: z.literal("receipts").describe("Receipt source summary."),
171
+ id: receiptIdSchema.describe("Immutable receipt ID."),
172
+ taskId: taskIdSchema.optional().describe("Task evidenced by this receipt, when present."),
173
+ changeId: changeIdSchema.optional().describe("Associated Change when present."),
174
+ kind: z.string().describe("Receipt evidence kind."),
175
+ state: z.string().describe("State recorded by the receipt."),
176
+ attempt: z.number().int().positive().describe("Attempt recorded by the receipt.")
177
+ }),
178
+ z.strictObject({
179
+ ...common,
180
+ collection: z.literal("sessions").describe("Internal session source summary."),
181
+ id: agentSessionIdSchema.describe("Canonical session ID."),
182
+ owner: z.string().describe("Session owner used for access scoping."),
183
+ title: z.string().max(256).describe("Bounded display title from the initial message."),
184
+ agent: z.string().describe("Agent selected when the session was admitted."),
185
+ taskId: taskIdSchema.optional().describe("Task bound to the session, when present."),
186
+ attached: z.boolean().describe("Whether the session is attached to existing work."),
187
+ execution: executionReferenceSchema.optional().describe("Bound provider execution, when present.")
188
+ }),
189
+ z.strictObject({
190
+ ...common,
191
+ collection: z.literal("externalSessions").describe("External session source summary."),
192
+ id: agentSessionIdSchema.describe("Canonical external session ID."),
193
+ owner: z.string().describe("Session owner used for access scoping."),
194
+ title: z.string().max(256).describe("Bounded display title from the initial message."),
195
+ agent: z.string().describe("Agent selected for the external session."),
196
+ execution: executionReferenceSchema.describe("Bound provider execution."),
197
+ source: z.string().describe("External reply channel.")
198
+ }),
199
+ z.strictObject({
200
+ ...common,
201
+ collection: z.literal("transcripts").describe("Transcript source summary."),
202
+ execution: executionReferenceSchema.describe("Execution that owns the transcript."),
203
+ state: transcriptSnapshotSchema.unwrap().shape.state.describe("Provider conversation state."),
204
+ cursor: z.number().int().nonnegative().describe("Latest persisted transcript cursor."),
205
+ inputCount: z.number().int().nonnegative().describe("Number of transcript input descriptors."),
206
+ updatedAt: isoDateTimeSchema.describe("Latest persisted transcript update."),
207
+ attention: z.enum(["failed", "conversation"]).optional().describe("Transcript attention reason; not an internal session's attention decision.")
208
+ })
209
+ ]);
210
+ function hash(value) {
211
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex");
212
+ }
213
+ function factoryIndexKey(input) {
214
+ let scope = factoryIndexScopeSchema.parse(input);
215
+ if (scope.by === "execution") scope = {
216
+ ...scope,
217
+ execution: {
218
+ provider: scope.execution.provider,
219
+ sessionId: scope.execution.sessionId
220
+ }
221
+ };
222
+ return `factory:v1:${scope.collection}:${scope.by}:${hash(scope)}`;
223
+ }
224
+ function projectIndexedRecord(collection, id, value) {
225
+ if (!collectionSchema.safeParse(collection).success) return [];
226
+ const scopes = [];
227
+ let summary;
228
+ if (collection === "sessionContinuations") {
229
+ const record = sessionContinuationRecordSchema.parse(value);
230
+ if (record.id !== id) throw new Error("Continuation storage key mismatch");
231
+ summary = {
232
+ collection,
233
+ id,
234
+ repositoryIds: [],
235
+ createdAt: record.createdAt,
236
+ sessionId: record.sessionId,
237
+ taskId: record.continuation.taskId,
238
+ committed: record.committed
239
+ };
240
+ scopes.push({
241
+ collection,
242
+ by: "session",
243
+ sessionId: record.sessionId
244
+ }, {
245
+ collection,
246
+ by: "task",
247
+ taskId: record.continuation.taskId
248
+ });
249
+ } else if (collection === "sessionNotifications") {
250
+ const record = sessionNotificationRecordSchema.parse(value);
251
+ if (record.id !== id) throw new Error("Notification storage key mismatch");
252
+ summary = {
253
+ collection,
254
+ id,
255
+ repositoryIds: record.event.repositoryIds,
256
+ createdAt: record.createdAt,
257
+ sessionId: record.sessionId,
258
+ outcome: record.event.outcome
259
+ };
260
+ scopes.push({
261
+ collection,
262
+ by: "session",
263
+ sessionId: record.sessionId
264
+ });
265
+ } else if (collection === "tasks") {
266
+ const task = taskSchema.parse(value);
267
+ if (task.id !== id) throw new Error("Task storage key mismatch");
268
+ const attention = task.state === "needs_human" ? "question" : task.state === "failed" || task.state === "stalled" ? task.state : task.state === "queued" && task.approval === "required" ? "approval" : void 0;
269
+ summary = {
270
+ collection,
271
+ id: task.id,
272
+ repositoryIds: task.repositoryIds,
273
+ title: task.work.title,
274
+ kind: task.kind,
275
+ state: task.state,
276
+ rootTaskId: task.rootTaskId,
277
+ parentTaskId: task.parentTaskId,
278
+ attempt: task.attempt,
279
+ changeId: task.changeId,
280
+ route: task.work.route,
281
+ approval: task.approval,
282
+ createdAt: task.createdAt,
283
+ updatedAt: task.updatedAt,
284
+ attention
285
+ };
286
+ scopes.push({
287
+ collection,
288
+ by: "state",
289
+ state: task.state
290
+ }, {
291
+ collection,
292
+ by: "root",
293
+ rootTaskId: task.rootTaskId
294
+ }, {
295
+ collection,
296
+ by: "reply",
297
+ replyTo: task.replyTo
298
+ });
299
+ for (const repositoryId of new Set(task.repositoryIds)) scopes.push({
300
+ collection,
301
+ by: "state",
302
+ state: task.state,
303
+ repositoryId
304
+ });
305
+ if (attention) {
306
+ scopes.push({
307
+ collection,
308
+ by: "attention"
309
+ });
310
+ for (const repositoryId of new Set(task.repositoryIds)) scopes.push({
311
+ collection,
312
+ by: "attention",
313
+ repositoryId
314
+ });
315
+ }
316
+ } else if (collection === "sessions" || collection === "externalSessions") {
317
+ const session = agentSessionSchema.parse(value);
318
+ if (session.id !== id || collection === "externalSessions" !== (session.external !== void 0)) throw new Error("Session storage key or collection mismatch");
319
+ const base = {
320
+ id: session.id,
321
+ repositoryIds: session.external?.repositoryIds ?? (session.repositoryId ? [session.repositoryId] : []),
322
+ owner: session.owner,
323
+ title: session.message.slice(0, 256).replace(/[\uD800-\uDBFF]$/u, ""),
324
+ agent: session.agent,
325
+ createdAt: session.createdAt
326
+ };
327
+ summary = collection === "externalSessions" && session.external && session.execution ? {
328
+ ...base,
329
+ collection,
330
+ execution: session.execution,
331
+ source: session.external.replyTo.channel
332
+ } : {
333
+ ...base,
334
+ collection: "sessions",
335
+ taskId: session.taskId,
336
+ attached: session.attached ?? false,
337
+ execution: session.execution
338
+ };
339
+ scopes.push({
340
+ collection,
341
+ by: "owner",
342
+ owner: session.owner
343
+ });
344
+ for (const repositoryId of new Set(base.repositoryIds)) scopes.push({
345
+ collection,
346
+ by: "owner",
347
+ owner: session.owner,
348
+ repositoryId
349
+ });
350
+ if (session.execution) scopes.push({
351
+ collection,
352
+ by: "execution",
353
+ execution: session.execution
354
+ });
355
+ if (collection === "sessions" && session.taskId) scopes.push({
356
+ collection,
357
+ by: "task",
358
+ taskId: session.taskId
359
+ });
360
+ } else if (collection === "changes") {
361
+ const change = changeSchema.parse(value);
362
+ if (change.id !== id) throw new Error("Change storage key mismatch");
363
+ summary = {
364
+ collection,
365
+ id: change.id,
366
+ repositoryIds: [change.repositoryId],
367
+ state: change.state,
368
+ taskId: change.taskId,
369
+ prNumber: change.prNumber,
370
+ createdAt: change.createdAt,
371
+ updatedAt: change.updatedAt,
372
+ attention: change.state === "ready" ? "review" : void 0
373
+ };
374
+ scopes.push({
375
+ collection,
376
+ by: "state",
377
+ state: change.state
378
+ }, {
379
+ collection,
380
+ by: "state",
381
+ state: change.state,
382
+ repositoryId: change.repositoryId
383
+ });
384
+ if (change.taskId) scopes.push({
385
+ collection,
386
+ by: "task",
387
+ taskId: change.taskId
388
+ });
389
+ if (change.state === "ready") scopes.push({
390
+ collection,
391
+ by: "attention"
392
+ }, {
393
+ collection,
394
+ by: "attention",
395
+ repositoryId: change.repositoryId
396
+ });
397
+ } else if (collection === "receipts") {
398
+ const receipt = receiptSchema.parse(value);
399
+ if (receipt.receiptId !== id) throw new Error("Receipt storage key mismatch");
400
+ summary = {
401
+ collection,
402
+ id: receipt.receiptId,
403
+ repositoryIds: receipt.repositoryIds,
404
+ taskId: receipt.taskId,
405
+ changeId: receipt.changeId,
406
+ kind: receipt.kind,
407
+ state: receipt.state,
408
+ attempt: receipt.attempt,
409
+ createdAt: receipt.recordedAt
410
+ };
411
+ if (receipt.taskId) scopes.push({
412
+ collection,
413
+ by: "task",
414
+ taskId: receipt.taskId
415
+ });
416
+ } else if (collection === "signals") {
417
+ const signal = signalSchema.parse(value);
418
+ if (signal.id !== id) throw new Error("Signal storage key mismatch");
419
+ summary = {
420
+ collection,
421
+ id: signal.id,
422
+ repositoryIds: [signal.repositoryId],
423
+ source: signal.source,
424
+ outcome: signal.outcome,
425
+ createdAt: signal.receivedAt
426
+ };
427
+ } else if (collection === "repositories") {
428
+ const repository = repositorySchema.parse(value);
429
+ if (repository.id !== id) throw new Error("Repository storage key mismatch");
430
+ summary = {
431
+ collection,
432
+ id: repository.id,
433
+ repositoryIds: [repository.id],
434
+ slug: repository.slug,
435
+ enabled: repository.enabled,
436
+ createdAt: repository.connectedAt
437
+ };
438
+ } else {
439
+ const transcript = z.object({
440
+ execution: executionReferenceSchema,
441
+ snapshot: transcriptSnapshotSchema,
442
+ updatedAt: isoDateTimeSchema
443
+ }).parse(value);
444
+ const attention = transcript.snapshot.state === "failed" ? "failed" : transcript.snapshot.state === "waiting" || transcript.snapshot.state === "needs input" ? "conversation" : void 0;
445
+ summary = {
446
+ collection: "transcripts",
447
+ id,
448
+ repositoryIds: [],
449
+ execution: transcript.execution,
450
+ state: transcript.snapshot.state,
451
+ cursor: transcript.snapshot.cursor,
452
+ inputCount: transcript.snapshot.inputs.length,
453
+ createdAt: transcript.updatedAt,
454
+ updatedAt: transcript.updatedAt,
455
+ attention
456
+ };
457
+ if (attention) scopes.push({
458
+ collection: "transcripts",
459
+ by: "attention"
460
+ });
461
+ }
462
+ const parsed = factoryRecordSummarySchema.parse(summary);
463
+ scopes.push({
464
+ collection: parsed.collection,
465
+ by: "all"
466
+ });
467
+ if (parsed.collection !== "repositories" && parsed.collection !== "transcripts") for (const repositoryId of new Set(parsed.repositoryIds)) scopes.push({
468
+ collection: parsed.collection,
469
+ by: "repository",
470
+ repositoryId
471
+ });
472
+ return scopes.map((scope) => ({
473
+ index: factoryIndexKey(scope),
474
+ sortKey: new Date(parsed.createdAt).toISOString(),
475
+ summary: parsed
476
+ }));
477
+ }
478
+ //#endregion
479
+ export { factoryIndexKey, factoryIndexScopeSchema, factoryRecordSummarySchema, projectIndexedRecord };
480
+
481
+ //# sourceMappingURL=indexed-projections.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexed-projections.mjs","names":[],"sources":["../../src/store/indexed-projections.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { isoDateTimeSchema, replyToSchema } from \"../schema/common\";\nimport { changeSchema, changeStateSchema } from \"../schema/change\";\nimport {\n changeIdSchema,\n receiptIdSchema,\n repositoryIdSchema,\n signalIdSchema,\n taskIdSchema,\n} from \"../schema/id\";\nimport { receiptSchema } from \"../schema/receipt\";\nimport { repositorySchema } from \"../schema/repository\";\nimport { agentSessionIdSchema, agentSessionSchema } from \"../schema/session\";\nimport { signalSchema } from \"../schema/signal\";\nimport { executionReferenceSchema, taskSchema, taskStateSchema } from \"../schema/task\";\nimport { transcriptSnapshotSchema } from \"../schema/transcript\";\nimport {\n sessionContinuationRecordSchema,\n sessionNotificationRecordSchema,\n} from \"./session-history\";\nimport type { CollectionName } from \"./driver\";\nimport type { StoreIndexEntry } from \"./indexed\";\n\nconst collectionSchema = z.enum([\n \"repositories\",\n \"signals\",\n \"tasks\",\n \"changes\",\n \"receipts\",\n \"sessions\",\n \"externalSessions\",\n \"sessionContinuations\",\n \"sessionNotifications\",\n \"transcripts\",\n]);\nconst sessionCollections = z.enum([\"sessions\", \"externalSessions\"]);\n\n/** Validates an exact, trusted query scope; transport callers must authorize it before querying. */\nexport const factoryIndexScopeSchema = z.union([\n z.strictObject({\n collection: z\n .enum([\"sessionContinuations\", \"sessionNotifications\"])\n .describe(\"Paginated session history collection.\"),\n by: z.literal(\"session\").describe(\"History within an exact session.\"),\n sessionId: agentSessionIdSchema.describe(\"Session whose history is selected.\"),\n }),\n z.strictObject({\n collection: collectionSchema.describe(\"Source collection to query.\"),\n by: z.literal(\"all\").describe(\"All records in the namespace's collection.\"),\n }),\n z.strictObject({\n collection: collectionSchema\n .exclude([\"repositories\", \"transcripts\"])\n .describe(\"Source collection with repository memberships.\"),\n by: z.literal(\"repository\").describe(\"Records belonging to the selected repository.\"),\n repositoryId: repositoryIdSchema.describe(\"Repository membership to query.\"),\n }),\n z.strictObject({\n collection: z.literal(\"tasks\").describe(\"Task source summaries.\"),\n by: z.literal(\"state\").describe(\"Tasks in one lifecycle state.\"),\n state: taskStateSchema.describe(\"Exact Task lifecycle state to query.\"),\n repositoryId: repositoryIdSchema.optional().describe(\"Optional repository membership filter.\"),\n }),\n z.strictObject({\n collection: z.literal(\"changes\").describe(\"Change source summaries.\"),\n by: z.literal(\"state\").describe(\"Changes in one lifecycle state.\"),\n state: changeStateSchema.describe(\"Exact Change lifecycle state to query.\"),\n repositoryId: repositoryIdSchema.optional().describe(\"Optional repository membership filter.\"),\n }),\n z.strictObject({\n collection: z.literal(\"tasks\").describe(\"Task source summaries.\"),\n by: z.literal(\"root\").describe(\"Tasks in one canonical root graph.\"),\n rootTaskId: taskIdSchema.describe(\"Root Task identifying the graph.\"),\n }),\n z.strictObject({\n collection: z.literal(\"tasks\").describe(\"Task source summaries.\"),\n by: z.literal(\"reply\").describe(\"Tasks sharing an exact reply destination.\"),\n replyTo: replyToSchema.describe(\"Exact reply destination to query.\"),\n }),\n z.strictObject({\n collection: z\n .enum([\"receipts\", \"changes\", \"sessions\", \"sessionContinuations\"])\n .describe(\"Task-bound source collection.\"),\n by: z.literal(\"task\").describe(\"Records bound to one Task.\"),\n taskId: taskIdSchema.describe(\"Task whose bound records are selected.\"),\n }),\n z.strictObject({\n collection: sessionCollections.describe(\"Internal or external session collection.\"),\n by: z.literal(\"owner\").describe(\"Sessions belonging to one owner.\"),\n owner: z.string().min(1).describe(\"Authorized session owner to query.\"),\n repositoryId: repositoryIdSchema.optional().describe(\"Optional repository membership filter.\"),\n }),\n z.strictObject({\n collection: sessionCollections.describe(\"Internal or external session collection.\"),\n by: z.literal(\"execution\").describe(\"Sessions bound to an exact provider execution.\"),\n execution: executionReferenceSchema.describe(\n \"Execution identity; only provider and sessionId select the scope.\",\n ),\n }),\n z.strictObject({\n collection: z.enum([\"tasks\", \"changes\"]).describe(\"Source collection requiring attention.\"),\n by: z.literal(\"attention\").describe(\"Source attention, without conversation deduplication.\"),\n repositoryId: repositoryIdSchema.optional().describe(\"Optional repository membership filter.\"),\n }),\n z.strictObject({\n collection: z.literal(\"transcripts\").describe(\"Transcript source summaries.\"),\n by: z.literal(\"attention\").describe(\"Source attention, without conversation deduplication.\"),\n }),\n]);\n\n/** Exact membership partition selected by the trusted engine or authorized application. */\nexport type FactoryIndexScope = z.infer<typeof factoryIndexScopeSchema>;\n\nconst common = {\n id: z.string().min(1).describe(\"Canonical source record key.\"),\n repositoryIds: z\n .array(repositoryIdSchema)\n .readonly()\n .describe(\"Repository memberships; callers must authorize every repository.\"),\n createdAt: isoDateTimeSchema.describe(\"Source timestamp used to order this summary.\"),\n};\n\n/** Validates compact source summaries, without Task inputs, messages, histories, or transcript bodies. */\nexport const factoryRecordSummarySchema = z.discriminatedUnion(\"collection\", [\n z.strictObject({\n ...common,\n collection: z.literal(\"sessionContinuations\").describe(\"Separate follow-up intent.\"),\n sessionId: agentSessionIdSchema.describe(\"Owning conversation.\"),\n taskId: taskIdSchema.describe(\"Task admitted for this follow-up.\"),\n committed: z.boolean().describe(\"Whether the session head admitted this intent.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"sessionNotifications\").describe(\"Separate delivered notification.\"),\n sessionId: agentSessionIdSchema.describe(\"Owning conversation.\"),\n outcome: z.string().describe(\"Notification outcome.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"repositories\").describe(\"Repository source summary.\"),\n id: repositoryIdSchema.describe(\"Canonical repository ID.\"),\n slug: z.string().describe(\"Provider repository slug.\"),\n enabled: z.boolean().describe(\"Whether the repository is enabled for work.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"signals\").describe(\"Signal source summary.\"),\n id: signalIdSchema.describe(\"Canonical Signal ID.\"),\n source: z.string().describe(\"Signal source kind.\"),\n outcome: z.string().describe(\"Recorded triage outcome.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"tasks\").describe(\"Task source summary.\"),\n title: z.string().max(256).describe(\"Work title without input or history payloads.\"),\n id: taskIdSchema.describe(\"Canonical Task ID.\"),\n kind: z.string().describe(\"Descriptive Task kind, not routing authority.\"),\n state: taskStateSchema.describe(\"Current Task lifecycle state.\"),\n rootTaskId: taskIdSchema.describe(\"Root of the canonical Task graph.\"),\n parentTaskId: taskIdSchema.optional().describe(\"Immediate parent Task when present.\"),\n attempt: z.number().int().positive().describe(\"Current Task execution attempt.\"),\n changeId: changeIdSchema.optional().describe(\"Associated Change when present.\"),\n route: z\n .object({\n id: z.string().describe(\"Exact registered agent route ID.\"),\n version: z.number().describe(\"Exact registered agent route version.\"),\n })\n .optional()\n .describe(\"Persisted agent route when the Task uses one.\"),\n approval: z.enum([\"required\", \"granted\", \"denied\"]).optional().describe(\"Task approval state.\"),\n updatedAt: isoDateTimeSchema.describe(\"Latest canonical Task update.\"),\n attention: z\n .enum([\"question\", \"failed\", \"stalled\", \"approval\"])\n .optional()\n .describe(\"Task attention reason; not a deduplicated conversation decision.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"changes\").describe(\"Change source summary.\"),\n id: changeIdSchema.describe(\"Canonical Change ID.\"),\n state: changeStateSchema.describe(\"Current Change lifecycle state.\"),\n taskId: taskIdSchema.optional().describe(\"Task that created the Change, when present.\"),\n prNumber: z.number().int().positive().describe(\"Repository-local pull request number.\"),\n updatedAt: isoDateTimeSchema.describe(\"Latest canonical Change update.\"),\n attention: z.literal(\"review\").optional().describe(\"The Change is ready for review.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"receipts\").describe(\"Receipt source summary.\"),\n id: receiptIdSchema.describe(\"Immutable receipt ID.\"),\n taskId: taskIdSchema.optional().describe(\"Task evidenced by this receipt, when present.\"),\n changeId: changeIdSchema.optional().describe(\"Associated Change when present.\"),\n kind: z.string().describe(\"Receipt evidence kind.\"),\n state: z.string().describe(\"State recorded by the receipt.\"),\n attempt: z.number().int().positive().describe(\"Attempt recorded by the receipt.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"sessions\").describe(\"Internal session source summary.\"),\n id: agentSessionIdSchema.describe(\"Canonical session ID.\"),\n owner: z.string().describe(\"Session owner used for access scoping.\"),\n title: z.string().max(256).describe(\"Bounded display title from the initial message.\"),\n agent: z.string().describe(\"Agent selected when the session was admitted.\"),\n taskId: taskIdSchema.optional().describe(\"Task bound to the session, when present.\"),\n attached: z.boolean().describe(\"Whether the session is attached to existing work.\"),\n execution: executionReferenceSchema\n .optional()\n .describe(\"Bound provider execution, when present.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"externalSessions\").describe(\"External session source summary.\"),\n id: agentSessionIdSchema.describe(\"Canonical external session ID.\"),\n owner: z.string().describe(\"Session owner used for access scoping.\"),\n title: z.string().max(256).describe(\"Bounded display title from the initial message.\"),\n agent: z.string().describe(\"Agent selected for the external session.\"),\n execution: executionReferenceSchema.describe(\"Bound provider execution.\"),\n source: z.string().describe(\"External reply channel.\"),\n }),\n z.strictObject({\n ...common,\n collection: z.literal(\"transcripts\").describe(\"Transcript source summary.\"),\n execution: executionReferenceSchema.describe(\"Execution that owns the transcript.\"),\n state: transcriptSnapshotSchema.unwrap().shape.state.describe(\"Provider conversation state.\"),\n cursor: z.number().int().nonnegative().describe(\"Latest persisted transcript cursor.\"),\n inputCount: z.number().int().nonnegative().describe(\"Number of transcript input descriptors.\"),\n updatedAt: isoDateTimeSchema.describe(\"Latest persisted transcript update.\"),\n attention: z\n .enum([\"failed\", \"conversation\"])\n .optional()\n .describe(\"Transcript attention reason; not an internal session's attention decision.\"),\n }),\n]);\n\n/** Compact, discriminated source entity projection returned by indexed engine queries. */\nexport type FactoryRecordSummary = z.infer<typeof factoryRecordSummarySchema>;\n\nfunction hash(value: unknown): string {\n return createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\");\n}\n\nexport function factoryIndexKey(input: FactoryIndexScope): string {\n let scope = factoryIndexScopeSchema.parse(input);\n if (scope.by === \"execution\")\n scope = {\n ...scope,\n execution: { provider: scope.execution.provider, sessionId: scope.execution.sessionId },\n };\n // Zod emits fields in schema order; caller object insertion order cannot change a query partition.\n return `factory:v1:${scope.collection}:${scope.by}:${hash(scope)}`;\n}\n\nexport function projectIndexedRecord(\n collection: CollectionName,\n id: string,\n value: unknown,\n): StoreIndexEntry[] {\n if (!collectionSchema.safeParse(collection).success) return [];\n const scopes: FactoryIndexScope[] = [];\n let summary: FactoryRecordSummary;\n if (collection === \"sessionContinuations\") {\n const record = sessionContinuationRecordSchema.parse(value);\n if (record.id !== id) throw new Error(\"Continuation storage key mismatch\");\n summary = {\n collection,\n id,\n repositoryIds: [],\n createdAt: record.createdAt,\n sessionId: record.sessionId,\n taskId: record.continuation.taskId,\n committed: record.committed,\n };\n scopes.push(\n { collection, by: \"session\", sessionId: record.sessionId },\n { collection, by: \"task\", taskId: record.continuation.taskId },\n );\n } else if (collection === \"sessionNotifications\") {\n const record = sessionNotificationRecordSchema.parse(value);\n if (record.id !== id) throw new Error(\"Notification storage key mismatch\");\n summary = {\n collection,\n id,\n repositoryIds: record.event.repositoryIds,\n createdAt: record.createdAt,\n sessionId: record.sessionId,\n outcome: record.event.outcome,\n };\n scopes.push({ collection, by: \"session\", sessionId: record.sessionId });\n } else if (collection === \"tasks\") {\n const task = taskSchema.parse(value);\n if (task.id !== id) throw new Error(\"Task storage key mismatch\");\n const attention =\n task.state === \"needs_human\"\n ? \"question\"\n : task.state === \"failed\" || task.state === \"stalled\"\n ? task.state\n : task.state === \"queued\" && task.approval === \"required\"\n ? \"approval\"\n : undefined;\n summary = {\n collection,\n id: task.id,\n repositoryIds: task.repositoryIds,\n title: task.work.title,\n kind: task.kind,\n state: task.state,\n rootTaskId: task.rootTaskId,\n parentTaskId: task.parentTaskId,\n attempt: task.attempt,\n changeId: task.changeId,\n route: task.work.route,\n approval: task.approval,\n createdAt: task.createdAt,\n updatedAt: task.updatedAt,\n attention,\n };\n scopes.push(\n { collection, by: \"state\", state: task.state },\n { collection, by: \"root\", rootTaskId: task.rootTaskId },\n { collection, by: \"reply\", replyTo: task.replyTo },\n );\n for (const repositoryId of new Set(task.repositoryIds))\n scopes.push({ collection, by: \"state\", state: task.state, repositoryId });\n if (attention) {\n scopes.push({ collection, by: \"attention\" });\n for (const repositoryId of new Set(task.repositoryIds))\n scopes.push({ collection, by: \"attention\", repositoryId });\n }\n } else if (collection === \"sessions\" || collection === \"externalSessions\") {\n const session = agentSessionSchema.parse(value);\n if (\n session.id !== id ||\n (collection === \"externalSessions\") !== (session.external !== undefined)\n )\n throw new Error(\"Session storage key or collection mismatch\");\n const base = {\n id: session.id,\n repositoryIds:\n session.external?.repositoryIds ?? (session.repositoryId ? [session.repositoryId] : []),\n owner: session.owner,\n title: session.message.slice(0, 256).replace(/[\\uD800-\\uDBFF]$/u, \"\"),\n agent: session.agent,\n createdAt: session.createdAt,\n };\n summary =\n collection === \"externalSessions\" && session.external && session.execution\n ? {\n ...base,\n collection,\n execution: session.execution,\n source: session.external.replyTo.channel,\n }\n : {\n ...base,\n collection: \"sessions\",\n taskId: session.taskId,\n attached: session.attached ?? false,\n execution: session.execution,\n };\n scopes.push({ collection, by: \"owner\", owner: session.owner });\n for (const repositoryId of new Set(base.repositoryIds))\n scopes.push({ collection, by: \"owner\", owner: session.owner, repositoryId });\n if (session.execution)\n scopes.push({ collection, by: \"execution\", execution: session.execution });\n if (collection === \"sessions\" && session.taskId)\n scopes.push({ collection, by: \"task\", taskId: session.taskId });\n } else if (collection === \"changes\") {\n const change = changeSchema.parse(value);\n if (change.id !== id) throw new Error(\"Change storage key mismatch\");\n summary = {\n collection,\n id: change.id,\n repositoryIds: [change.repositoryId],\n state: change.state,\n taskId: change.taskId,\n prNumber: change.prNumber,\n createdAt: change.createdAt,\n updatedAt: change.updatedAt,\n attention: change.state === \"ready\" ? \"review\" : undefined,\n };\n scopes.push(\n { collection, by: \"state\", state: change.state },\n { collection, by: \"state\", state: change.state, repositoryId: change.repositoryId },\n );\n if (change.taskId) scopes.push({ collection, by: \"task\", taskId: change.taskId });\n if (change.state === \"ready\")\n scopes.push(\n { collection, by: \"attention\" },\n { collection, by: \"attention\", repositoryId: change.repositoryId },\n );\n } else if (collection === \"receipts\") {\n const receipt = receiptSchema.parse(value);\n if (receipt.receiptId !== id) throw new Error(\"Receipt storage key mismatch\");\n summary = {\n collection,\n id: receipt.receiptId,\n repositoryIds: receipt.repositoryIds,\n taskId: receipt.taskId,\n changeId: receipt.changeId,\n kind: receipt.kind,\n state: receipt.state,\n attempt: receipt.attempt,\n createdAt: receipt.recordedAt,\n };\n if (receipt.taskId) scopes.push({ collection, by: \"task\", taskId: receipt.taskId });\n } else if (collection === \"signals\") {\n const signal = signalSchema.parse(value);\n if (signal.id !== id) throw new Error(\"Signal storage key mismatch\");\n summary = {\n collection,\n id: signal.id,\n repositoryIds: [signal.repositoryId],\n source: signal.source,\n outcome: signal.outcome,\n createdAt: signal.receivedAt,\n };\n } else if (collection === \"repositories\") {\n const repository = repositorySchema.parse(value);\n if (repository.id !== id) throw new Error(\"Repository storage key mismatch\");\n summary = {\n collection,\n id: repository.id,\n repositoryIds: [repository.id],\n slug: repository.slug,\n enabled: repository.enabled,\n createdAt: repository.connectedAt,\n };\n } else {\n const transcript = z\n .object({\n execution: executionReferenceSchema,\n snapshot: transcriptSnapshotSchema,\n updatedAt: isoDateTimeSchema,\n })\n .parse(value);\n const attention =\n transcript.snapshot.state === \"failed\"\n ? \"failed\"\n : transcript.snapshot.state === \"waiting\" || transcript.snapshot.state === \"needs input\"\n ? \"conversation\"\n : undefined;\n summary = {\n collection: \"transcripts\",\n id,\n repositoryIds: [],\n execution: transcript.execution,\n state: transcript.snapshot.state,\n cursor: transcript.snapshot.cursor,\n inputCount: transcript.snapshot.inputs.length,\n createdAt: transcript.updatedAt,\n updatedAt: transcript.updatedAt,\n attention,\n };\n if (attention) scopes.push({ collection: \"transcripts\", by: \"attention\" });\n }\n const parsed = factoryRecordSummarySchema.parse(summary);\n scopes.push({ collection: parsed.collection, by: \"all\" });\n if (parsed.collection !== \"repositories\" && parsed.collection !== \"transcripts\") {\n for (const repositoryId of new Set(parsed.repositoryIds))\n scopes.push({ collection: parsed.collection, by: \"repository\", repositoryId });\n }\n return scopes.map((scope) => ({\n index: factoryIndexKey(scope),\n sortKey: new Date(parsed.createdAt).toISOString(),\n summary: parsed,\n }));\n}\n"],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { FactoryRecordQuery } from "./query.mjs";
2
+ import { CollectionName, StoredRecord } from "./driver.mjs";
3
+ //#region src/store/indexed.d.ts
4
+ /** One compact, ordered membership in an application-defined query index. */
5
+ interface StoreIndexEntry {
6
+ /** Exact query partition, including the authorized workspace or owner scope. */
7
+ readonly index: string;
8
+ /** Lexically ordered key, such as an ISO creation timestamp. IDs break ties. */
9
+ readonly sortKey: string;
10
+ /** Small display projection; keep Task inputs, outputs, and transcript bodies out. */
11
+ readonly summary: unknown;
12
+ /** Optional engine-owned facet group; each record contributes once per distinct facet. */
13
+ readonly countGroup?: {
14
+ readonly group: string;
15
+ readonly attributes: unknown;
16
+ };
17
+ }
18
+ /** Atomic replacement of a record and its complete set of index memberships. */
19
+ interface WriteIndexedRecordInput {
20
+ readonly collection: CollectionName;
21
+ readonly id: string;
22
+ /** Durable retry identity. Reuse only for the identical write intent. */
23
+ readonly operationId: string;
24
+ /** Zero inserts a new record; a positive version replaces that exact snapshot. */
25
+ readonly expectedVersion: number;
26
+ /** Engine-validated canonical JSON. Storage does not decide lifecycle policy. */
27
+ readonly value: unknown;
28
+ /** Complete replacement, including an empty array when removing all memberships. */
29
+ readonly indexes: readonly StoreIndexEntry[];
30
+ }
31
+ /** Committed version returned both for a new write and a durable idempotent replay. */
32
+ interface WriteIndexedRecordResult {
33
+ readonly version: number;
34
+ }
35
+ /** One bounded page from an exact index partition; filtering must be encoded in the index. */
36
+ interface QueryStoreIndexInput {
37
+ readonly index: string;
38
+ /** Required page bound, from 1 through 100. */
39
+ readonly limit: number;
40
+ /** Opaque continuation from the same index and ordering. */
41
+ readonly cursor?: string;
42
+ /** Defaults to descending order for newest-first listings. */
43
+ readonly order?: "asc" | "desc";
44
+ }
45
+ /** Compact index result with the source record identity and committed version. */
46
+ interface StoreIndexRecord extends StoreIndexEntry {
47
+ readonly collection: CollectionName;
48
+ readonly id: string;
49
+ readonly version: number;
50
+ }
51
+ /** A bounded summary page and an opaque continuation when more results may remain. */
52
+ interface QueryStoreIndexResult {
53
+ readonly entries: readonly StoreIndexRecord[];
54
+ readonly nextCursor: string | null;
55
+ }
56
+ /** Bounded canonical records selected through a source index and indexed JSON containment. */
57
+ interface QueryStoreRecordsInput extends FactoryRecordQuery {
58
+ readonly sources: readonly {
59
+ readonly collection: CollectionName;
60
+ readonly index: string;
61
+ }[];
62
+ }
63
+ /** Versioned canonical page returned for background work and explicit record inspection. */
64
+ interface QueryStoreRecordsResult {
65
+ readonly totalCount?: number;
66
+ readonly entries: readonly {
67
+ readonly collection: CollectionName;
68
+ readonly id: string;
69
+ readonly record: StoredRecord;
70
+ }[];
71
+ readonly nextCursor: string | null;
72
+ }
73
+ /**
74
+ * Bounded persistence for new indexed consumers. Deliberately separate from StoreDriver:
75
+ * it has no list/scan operation and cannot back the catalog-based engine unchanged.
76
+ * Callers own schema validation, authorization, lifecycle rules, and index selection.
77
+ */
78
+ interface IndexedStore {
79
+ readonly name: string;
80
+ /**
81
+ * Commit engine-owned related writes together under serializable isolation.
82
+ * The callback can repeat after serialization failures and must contain only storage operations.
83
+ * Retain operation IDs when retrying an uncertain result; external effects belong after commit.
84
+ */
85
+ transaction<T>(run: (transaction: IndexedStore) => Promise<T>): Promise<T>;
86
+ get(collection: CollectionName, id: string): Promise<StoredRecord | null>;
87
+ write(input: WriteIndexedRecordInput): Promise<WriteIndexedRecordResult>;
88
+ query(input: QueryStoreIndexInput): Promise<QueryStoreIndexResult>;
89
+ queryRecords(input: QueryStoreRecordsInput): Promise<QueryStoreRecordsResult>;
90
+ /** Strongly consistent maintained membership count; never counts by querying items. */
91
+ count(index: string): Promise<number>;
92
+ /** Sums maintained facet counts, never canonical records. */
93
+ sumCounts(group: string, query: Pick<FactoryRecordQuery, "match" | "fields">): Promise<number>;
94
+ }
95
+ /** A durable operation identity was reused for a different mutation. */
96
+ declare class StoreOperationConflictError extends Error {
97
+ constructor(operationId: string);
98
+ }
99
+ //#endregion
100
+ export { IndexedStore, QueryStoreIndexInput, QueryStoreIndexResult, QueryStoreRecordsInput, QueryStoreRecordsResult, StoreIndexEntry, StoreIndexRecord, StoreOperationConflictError, WriteIndexedRecordInput, WriteIndexedRecordResult };
101
+ //# sourceMappingURL=indexed.d.mts.map