@sentry/junior 0.202.0 → 0.204.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/agent-CMyTD4DD.js +17509 -0
  2. package/dist/agent-hooks-Bbcp9e33.js +4040 -0
  3. package/dist/agent-runner-DNb1A49M.js +678 -0
  4. package/dist/api/schema.d.ts +2728 -2639
  5. package/dist/api/schema.js +4 -169
  6. package/dist/api.d.ts +23 -17
  7. package/dist/api.js +3881 -5326
  8. package/dist/app-B1TOqBI8.d.ts +246 -0
  9. package/dist/app.d.ts +4 -520
  10. package/dist/app.js +9522 -11875
  11. package/dist/auth-pause-state-DosEalIG.js +168 -0
  12. package/dist/catalog-runtime-BReos-D4.js +7 -0
  13. package/dist/checkpoint-CNrPyRJN.js +2450 -0
  14. package/dist/cli/chat.d.ts +20 -0
  15. package/dist/cli/chat.js +229 -336
  16. package/dist/cli/check.d.ts +8 -0
  17. package/dist/cli/check.js +513 -806
  18. package/dist/cli/env.d.ts +13 -0
  19. package/dist/cli/env.js +63 -12
  20. package/dist/cli/init.d.ts +3 -0
  21. package/dist/cli/init.js +90 -159
  22. package/dist/cli/main.d.ts +6 -0
  23. package/dist/cli/main.js +43 -64
  24. package/dist/cli/plugins.d.ts +13 -0
  25. package/dist/cli/plugins.js +148 -227
  26. package/dist/cli/run.d.ts +16 -0
  27. package/dist/cli/run.js +52 -8
  28. package/dist/cli/snapshot-create.d.ts +4 -0
  29. package/dist/cli/snapshot-create.js +71 -125
  30. package/dist/cli/upgrade.d.ts +15 -0
  31. package/dist/cli/upgrade.js +232 -335
  32. package/dist/config-nGCW1OTG.js +941 -0
  33. package/dist/context-B45_WqVX.js +298 -0
  34. package/dist/conversation-privacy-B4voFRSm.js +182 -0
  35. package/dist/conversation-work-C6y3T5Hx.js +51 -0
  36. package/dist/credential-sync-kXr1hvO1.js +2660 -0
  37. package/dist/db-BeyXKJOI.d.ts +5 -0
  38. package/dist/destinations-BeBiJeEM.js +29 -0
  39. package/dist/execution-stats-DWfSihcH.js +373 -0
  40. package/dist/executor-DcMSlI5c.js +721 -0
  41. package/dist/experimental-CIXf7Uye.js +46 -0
  42. package/dist/history-ClE4toxe.d.ts +32 -0
  43. package/dist/history-CqTuSAdI.js +441 -0
  44. package/dist/instrumentation.d.ts +3 -3
  45. package/dist/instrumentation.js +130 -176
  46. package/dist/job-queue-Drn_LXlM.js +63 -0
  47. package/dist/logging-BzAk1S_s.js +1210 -0
  48. package/dist/model-profile-CZmVoGdX.js +49 -0
  49. package/dist/nitro.d.ts +31 -36
  50. package/dist/nitro.js +275 -456
  51. package/dist/oauth-callback-server-JiftokvA.js +130 -0
  52. package/dist/oauth-relay-CdCnu80W.js +62 -0
  53. package/dist/package-discovery-7a9YqLhE.js +455 -0
  54. package/dist/pending-auth-CWmSdZVg.js +185 -0
  55. package/dist/plugin-module-BKGOXca2.js +81 -0
  56. package/dist/plugins-BI9A1vKA.d.ts +95 -0
  57. package/dist/plugins-egKWjgue.js +99 -0
  58. package/dist/private-trace-result-BLvBjy_e.js +16 -0
  59. package/dist/profile-CrT5nXbw.js +861 -0
  60. package/dist/registry-DH1xUo2N.js +1419 -0
  61. package/dist/reporting-schema-DosTN__Q.js +105 -0
  62. package/dist/resolve-CZHnfxaS.js +546 -0
  63. package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
  64. package/dist/runner-CZV2sC46.js +392 -0
  65. package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
  66. package/dist/schema-Rn8-XEaN.js +1140 -0
  67. package/dist/sentry-CD3SdJl-.js +26 -0
  68. package/dist/skills-CIcDQSgM.js +316 -0
  69. package/dist/spawn-DdkUFRmq.js +29 -0
  70. package/dist/stats-DTUbAb88.js +2634 -0
  71. package/dist/store-C5qxF2ac.d.ts +208 -0
  72. package/dist/task-queue-CJIR4RF7.js +136 -0
  73. package/dist/task-runner-D-O3A-Cp.js +639 -0
  74. package/dist/thread-state-CRc9jTJS.js +431 -0
  75. package/dist/turn-execution-BkinIdJF.js +47 -0
  76. package/dist/turn-lifecycle-DQV19VTW.js +54 -0
  77. package/dist/usage-D3EbSO7w.js +296 -0
  78. package/dist/usage-schema-CKaDkH_j.js +20 -0
  79. package/dist/validation-C2CR-OX3.js +40 -0
  80. package/dist/vercel-queue-DIkVcfK4.js +167 -0
  81. package/dist/vercel.d.ts +6 -6
  82. package/dist/vercel.js +14 -6
  83. package/dist/version-CnXZ614E.d.ts +5 -0
  84. package/dist/version-DxcWdoKa.js +8 -0
  85. package/dist/version.d.ts +2 -4
  86. package/dist/version.js +2 -6
  87. package/dist/web-authorization-RMBxAR_t.js +76 -0
  88. package/dist/web-input-3EPfpf55.js +494 -0
  89. package/dist/work-fGofI7Op.js +509 -0
  90. package/dist/worker-CsOLq-mR.js +625 -0
  91. package/package.json +9 -9
  92. package/dist/agent-hooks-UXITLYOK.js +0 -51
  93. package/dist/catalog-runtime-BG3JLLK2.js +0 -14
  94. package/dist/chunk-2LYHWMR4.js +0 -46
  95. package/dist/chunk-2MK3QBGA.js +0 -321
  96. package/dist/chunk-3PGQSKJV.js +0 -692
  97. package/dist/chunk-3UI3WFTX.js +0 -519
  98. package/dist/chunk-3Y47VMHV.js +0 -6
  99. package/dist/chunk-4UO6FK4G.js +0 -64
  100. package/dist/chunk-5NOPO64K.js +0 -198
  101. package/dist/chunk-5PKWYPFT.js +0 -2943
  102. package/dist/chunk-63NKKFJL.js +0 -1228
  103. package/dist/chunk-6AYH6252.js +0 -787
  104. package/dist/chunk-6Y5B5PEX.js +0 -80
  105. package/dist/chunk-7DHZP5KJ.js +0 -333
  106. package/dist/chunk-7H2VZTWN.js +0 -103
  107. package/dist/chunk-7NL7T6VU.js +0 -406
  108. package/dist/chunk-A76OIMYN.js +0 -102
  109. package/dist/chunk-AWMS3SPP.js +0 -58
  110. package/dist/chunk-B3LY5RCL.js +0 -229
  111. package/dist/chunk-BD2KT3OB.js +0 -36
  112. package/dist/chunk-BXCX5QKA.js +0 -2086
  113. package/dist/chunk-C6VVF43U.js +0 -81
  114. package/dist/chunk-CEMMLV5L.js +0 -98
  115. package/dist/chunk-CM5HNV2W.js +0 -131
  116. package/dist/chunk-DA2KGZZI.js +0 -13
  117. package/dist/chunk-DBVY6HLX.js +0 -64
  118. package/dist/chunk-DIB4GX3G.js +0 -8
  119. package/dist/chunk-DKIJ2RP5.js +0 -68
  120. package/dist/chunk-DL2KLKVH.js +0 -931
  121. package/dist/chunk-DWPN6SCH.js +0 -172
  122. package/dist/chunk-ELWOYVOY.js +0 -206
  123. package/dist/chunk-EWT7H65X.js +0 -506
  124. package/dist/chunk-FA6POGLH.js +0 -70
  125. package/dist/chunk-HMREVIO2.js +0 -135
  126. package/dist/chunk-IIWUT4FO.js +0 -820
  127. package/dist/chunk-JAL3CH4G.js +0 -27
  128. package/dist/chunk-JSJQEWBJ.js +0 -3295
  129. package/dist/chunk-KHKKHDLD.js +0 -387
  130. package/dist/chunk-LA6R4A7Q.js +0 -706
  131. package/dist/chunk-LOOU2DUR.js +0 -20428
  132. package/dist/chunk-M6FHWXE3.js +0 -700
  133. package/dist/chunk-M76HMB7M.js +0 -1856
  134. package/dist/chunk-MAGNK5J4.js +0 -1520
  135. package/dist/chunk-MTM5IFCY.js +0 -1190
  136. package/dist/chunk-N7TMSOZH.js +0 -235
  137. package/dist/chunk-NHJU2ZAL.js +0 -56
  138. package/dist/chunk-NSXKRGRT.js +0 -717
  139. package/dist/chunk-OWMPFXJA.js +0 -1764
  140. package/dist/chunk-PDO5BLNM.js +0 -22
  141. package/dist/chunk-PEQXYSSE.js +0 -45
  142. package/dist/chunk-PW4P4JYF.js +0 -1135
  143. package/dist/chunk-QB54UQUS.js +0 -320
  144. package/dist/chunk-QP3OGJXF.js +0 -105
  145. package/dist/chunk-RC745GGZ.js +0 -122
  146. package/dist/chunk-REOIRYPR.js +0 -37
  147. package/dist/chunk-SCOZRLZ4.js +0 -164
  148. package/dist/chunk-TXJSXBV5.js +0 -1433
  149. package/dist/chunk-TXKUKMVO.js +0 -417
  150. package/dist/chunk-U2GPUYAL.js +0 -3656
  151. package/dist/chunk-UIE3R5XU.js +0 -17
  152. package/dist/chunk-UXPG6ZIN.js +0 -84
  153. package/dist/chunk-VFUK3X5B.js +0 -50
  154. package/dist/chunk-WQSHDTTI.js +0 -1163
  155. package/dist/chunk-X6GDDWQH.js +0 -60
  156. package/dist/chunk-Y2CM7HXH.js +0 -111
  157. package/dist/chunk-Y7X25LFY.js +0 -15
  158. package/dist/chunk-YDUR3ZYW.js +0 -10
  159. package/dist/conversation-work-VIOQ5ZF3.js +0 -54
  160. package/dist/db-3L2MCVRI.js +0 -26
  161. package/dist/discovery-DWVDM7UK.js +0 -44
  162. package/dist/experimental-P5FZM4CU.js +0 -12
  163. package/dist/oauth-callback-server-YVV6C6T2.js +0 -243
  164. package/dist/oauth-relay-5XPVRPYB.js +0 -8
  165. package/dist/plugins-YTYJMMJF.js +0 -14
  166. package/dist/runner-LQ7RETDP.js +0 -522
  167. package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
  168. package/dist/sentry-MB3NL3IR.js +0 -42
  169. package/dist/skills-XRWYEDCD.js +0 -27
  170. package/dist/spawn-RC6SJUAI.js +0 -42
  171. package/dist/task-runner-7DY7ARYH.js +0 -36
  172. package/dist/validation-7MNQGCJA.js +0 -17
  173. package/dist/work-COALHUCG.js +0 -51
  174. package/dist/worker-6MURZIPD.js +0 -24
@@ -0,0 +1,1140 @@
1
+ import { t as juniorDestinationKindSchema } from "./destinations-BeBiJeEM.js";
2
+ import { a as conversationTurnFailureReasonSchema, i as conversationTurnFailureCodeSchema } from "./history-CqTuSAdI.js";
3
+ import { t as usageSchema } from "./usage-schema-CKaDkH_j.js";
4
+ import "./reporting-schema-DosTN__Q.js";
5
+ import { z } from "zod";
6
+ import { codeChangeStateSchema, conversationAnnotationInputSchema, conversationEventPresentationSchema, conversationSidebarAnnotationSchema, taskOutcomeSchema } from "@sentry/junior-plugin-api";
7
+ //#region src/api/schema/common.ts
8
+ /** Stable error body returned by Junior-owned REST endpoints. */
9
+ const apiErrorSchema = z.object({ error: z.string().min(1) }).strict();
10
+ //#endregion
11
+ //#region src/api/schema/conversation.ts
12
+ const conversationReportStatusSchema = z.enum([
13
+ "active",
14
+ "completed",
15
+ "failed"
16
+ ]);
17
+ const conversationSurfaceSchema = z.enum([
18
+ "api",
19
+ "internal",
20
+ "scheduler",
21
+ "slack"
22
+ ]);
23
+ const conversationUsageSchema = usageSchema;
24
+ const conversationParamsSchema = z.object({ conversationId: z.string().min(1) }).strict();
25
+ const conversationAttachmentParamsSchema = z.object({
26
+ attachmentId: z.string().min(1),
27
+ conversationId: z.string().min(1)
28
+ }).strict();
29
+ const conversationDetailQuerySchema = z.object({ limit: z.coerce.number().int().min(1).max(1e3).default(500) }).strict();
30
+ const conversationEventsQuerySchema = z.object({
31
+ before: z.string().min(1),
32
+ limit: z.coerce.number().int().min(1).max(1e3).default(500)
33
+ }).strict();
34
+ const conversationFeedQuerySchema = z.object({
35
+ actorEmail: z.string().trim().email().transform((value) => value.toLowerCase()).optional(),
36
+ q: z.string().trim().max(200).optional(),
37
+ status: z.enum(["active", "archived"]).default("active")
38
+ }).strict();
39
+ const archiveConversationBodySchema = z.object({
40
+ archived: z.boolean(),
41
+ lastSeenAt: z.string().datetime()
42
+ }).strict();
43
+ const archiveConversationResponseSchema = z.object({ archivedAt: z.string().datetime().nullable() }).strict();
44
+ const createConversationBodySchema = z.object({
45
+ idempotencyKey: z.string().trim().min(1).max(200),
46
+ message: z.string().trim().min(1).max(32e3),
47
+ /** New roots default public. Private roots stay participant-only. */
48
+ visibility: z.enum(["private", "public"]).optional()
49
+ }).strict();
50
+ const createConversationMessageBodySchema = z.object({
51
+ idempotencyKey: z.string().trim().min(1).max(200),
52
+ message: z.string().trim().min(1).max(32e3)
53
+ }).strict();
54
+ const acceptedConversationMessageSchema = z.object({
55
+ conversationId: z.string().min(1),
56
+ messageId: z.string().min(1),
57
+ status: z.enum(["accepted", "duplicate"])
58
+ }).strict();
59
+ const actorIdentitySchema = z.object({
60
+ email: z.string().optional(),
61
+ fullName: z.string().optional(),
62
+ slackUserId: z.string().optional(),
63
+ slackUserName: z.string().optional()
64
+ }).strict();
65
+ /** Mailbox delivery mode for one accepted inbound message. */
66
+ const conversationPendingMessageDeliverySchema = z.enum(["defer", "interrupt"]);
67
+ /** One accepted mailbox message that has not reached durable history yet. */
68
+ const conversationPendingMessageSchema = z.object({
69
+ actorIdentity: actorIdentitySchema.optional(),
70
+ createdAt: z.string().datetime(),
71
+ delivery: conversationPendingMessageDeliverySchema,
72
+ inboundMessageId: z.string().min(1),
73
+ messageId: z.string().min(1),
74
+ receivedAt: z.string().datetime(),
75
+ role: z.literal("user"),
76
+ source: z.enum(["slack", "web"]),
77
+ text: z.string().optional(),
78
+ redacted: z.literal(true).optional()
79
+ }).strict().superRefine((data, context) => {
80
+ if (data.text === void 0 === (data.redacted !== true)) context.addIssue({
81
+ code: "custom",
82
+ message: "pending message content must be text or explicitly redacted"
83
+ });
84
+ if (data.redacted && data.actorIdentity) context.addIssue({
85
+ code: "custom",
86
+ message: "redacted pending messages must not expose actor identity"
87
+ });
88
+ });
89
+ /** Participant-only authorization prompt for a parked web turn. */
90
+ const conversationPendingAuthorizationSchema = z.object({
91
+ authorizationUrl: z.string().url(),
92
+ completionText: z.string().min(1),
93
+ label: z.string().min(1)
94
+ }).strict();
95
+ /** Bounded mailbox snapshot for one conversation transcript. */
96
+ const conversationPendingMessagesReportSchema = z.object({
97
+ authorization: conversationPendingAuthorizationSchema.optional(),
98
+ conversationId: z.string().min(1),
99
+ generatedAt: z.string().datetime(),
100
+ messages: z.array(conversationPendingMessageSchema)
101
+ }).strict();
102
+ /** Optional filters for cancelling accepted mailbox rows. */
103
+ const cancelConversationPendingMessagesBodySchema = z.object({
104
+ inboundMessageIds: z.array(z.string().min(1)).min(1).optional(),
105
+ receivedBefore: z.string().datetime().optional()
106
+ }).strict();
107
+ /** Result of cancelling accepted human-facing mailbox rows. */
108
+ const cancelConversationPendingMessagesResponseSchema = z.object({
109
+ cancelledCount: z.number().int().nonnegative(),
110
+ cancelledInboundMessageIds: z.array(z.string().min(1)),
111
+ conversationId: z.string().min(1)
112
+ }).strict();
113
+ const conversationAuxiliaryCostsSchema = z.object({
114
+ costUsd: z.number().finite().nonnegative(),
115
+ operations: z.array(z.object({
116
+ costUsd: z.number().finite().nonnegative(),
117
+ events: z.number().int().positive(),
118
+ name: z.string().min(1),
119
+ namespace: z.string().min(1)
120
+ }).strict()).min(1)
121
+ }).strict();
122
+ /** Optional reverse link from a task-triggered conversation back to its task. */
123
+ const conversationSourceTaskSchema = z.object({
124
+ id: z.string().min(1).optional(),
125
+ kind: z.enum(["scheduled", "event"]),
126
+ label: z.string().min(1).optional(),
127
+ title: z.string().min(1).optional()
128
+ }).strict().superRefine((value, context) => {
129
+ if (Boolean(value.id) !== Boolean(value.label)) context.addIssue({
130
+ code: "custom",
131
+ message: "sourceTask id and label must both be set or both omitted"
132
+ });
133
+ });
134
+ const conversationAnnotationReportSchema = conversationAnnotationInputSchema.and(z.object({
135
+ plugin: z.string().min(1),
136
+ createdAt: z.string().datetime(),
137
+ updatedAt: z.string().datetime()
138
+ }));
139
+ const conversationActivityPreviewSchema = z.object({
140
+ createdAt: z.string().datetime(),
141
+ role: z.enum(["assistant", "user"]),
142
+ text: z.string().min(1)
143
+ }).strict();
144
+ const conversationSummaryReportSchema = z.object({
145
+ displayTitle: z.string(),
146
+ activityPreview: conversationActivityPreviewSchema.optional(),
147
+ cumulativeDurationMs: z.number(),
148
+ cumulativeUsage: conversationUsageSchema.optional(),
149
+ auxiliaryCosts: conversationAuxiliaryCostsSchema.optional(),
150
+ conversationId: z.string(),
151
+ isParticipant: z.boolean(),
152
+ visibility: z.enum(["private", "public"]).optional(),
153
+ status: conversationReportStatusSchema,
154
+ startedAt: z.string(),
155
+ lastSeenAt: z.string(),
156
+ lastProgressAt: z.string(),
157
+ surface: conversationSurfaceSchema,
158
+ actorIdentity: actorIdentitySchema.optional(),
159
+ archivedAt: z.string().datetime().nullable().optional(),
160
+ channel: z.string().optional(),
161
+ channelName: z.string().optional(),
162
+ channelNameRedacted: z.boolean().optional(),
163
+ locationId: z.string().optional(),
164
+ sentryTraceUrl: z.string().optional(),
165
+ locationUrl: z.string().url().optional(),
166
+ traceId: z.string().optional(),
167
+ /**
168
+ * Plugin-owned resource links for this conversation.
169
+ * Present on the conversation feed when the viewer can see private content.
170
+ * Clients must not fetch provider state while rendering these links.
171
+ */
172
+ annotations: z.array(conversationAnnotationReportSchema).optional(),
173
+ /** Plugin-selected annotations for the compact conversation row. */
174
+ sidebarAnnotations: z.array(conversationSidebarAnnotationSchema).optional(),
175
+ assignedWork: z.boolean().optional(),
176
+ finishedWorkAt: z.string().datetime().optional(),
177
+ /**
178
+ * Dashboard Priority membership for this conversation summary.
179
+ * Present on the conversation feed. Clients must not recompute it.
180
+ *
181
+ * True only when:
182
+ * - unfinished work was last seen within 48 hours
183
+ * - finished assigned work has conversation activity after the finish time
184
+ * - there is no known work and the conversation was last seen within 3 hours
185
+ */
186
+ isPriority: z.boolean().optional(),
187
+ unfinishedWork: z.boolean().optional()
188
+ }).strict();
189
+ const conversationReportMessageEventDataSchema = z.object({
190
+ type: z.literal("message"),
191
+ messageId: z.string().min(1),
192
+ role: z.enum([
193
+ "assistant",
194
+ "system",
195
+ "user"
196
+ ]),
197
+ source: z.enum(["slack", "web"]).optional(),
198
+ actorIdentity: actorIdentitySchema.optional(),
199
+ eventType: z.string().min(1).optional(),
200
+ explicitMention: z.boolean().optional(),
201
+ trustedSummary: z.string().min(1).optional(),
202
+ text: z.string().optional(),
203
+ redacted: z.literal(true).optional()
204
+ }).strict().superRefine((data, context) => {
205
+ if (data.text === void 0 === (data.redacted !== true)) context.addIssue({
206
+ code: "custom",
207
+ message: "message content must be text or explicitly redacted"
208
+ });
209
+ if (data.redacted && data.actorIdentity) context.addIssue({
210
+ code: "custom",
211
+ message: "redacted messages must not expose actor identity"
212
+ });
213
+ });
214
+ const conversationReportMessageHandledEventDataSchema = z.object({
215
+ type: z.literal("message_handled"),
216
+ messageId: z.string().min(1)
217
+ }).strict();
218
+ const conversationReportToolCallSchema = z.object({
219
+ toolCallId: z.string().min(1),
220
+ name: z.string().min(1),
221
+ status: z.enum([
222
+ "running",
223
+ "completed",
224
+ "error"
225
+ ]),
226
+ startedAt: z.string().datetime().optional(),
227
+ startedSeq: z.number().int().nonnegative().optional(),
228
+ input: z.unknown().optional(),
229
+ output: z.unknown().optional()
230
+ }).strict().superRefine((call, context) => {
231
+ if (call.startedAt === void 0 !== (call.startedSeq === void 0)) context.addIssue({
232
+ code: "custom",
233
+ message: "tool start sequence and timestamp must be provided together"
234
+ });
235
+ });
236
+ const conversationReportReasoningPartSchema = z.object({
237
+ type: z.literal("reasoning"),
238
+ text: z.string().min(1).optional(),
239
+ redacted: z.literal(true).optional()
240
+ }).strict().superRefine((data, context) => {
241
+ if (data.text === void 0 === (data.redacted !== true)) context.addIssue({
242
+ code: "custom",
243
+ message: "reasoning content must be text or explicitly redacted"
244
+ });
245
+ });
246
+ const conversationReportAssistantToolCallPartSchema = z.object({
247
+ type: z.literal("tool_call"),
248
+ toolCallId: z.string().min(1)
249
+ }).strict();
250
+ const conversationReportAssistantMetadataSchema = z.object({ parts: z.array(z.discriminatedUnion("type", [conversationReportReasoningPartSchema, conversationReportAssistantToolCallPartSchema])).min(1) }).strict();
251
+ const conversationReportToolCallsEventDataSchema = z.object({
252
+ type: z.literal("tool_calls"),
253
+ calls: z.array(conversationReportToolCallSchema).min(1),
254
+ assistant: conversationReportAssistantMetadataSchema.optional()
255
+ }).strict().superRefine((data, context) => {
256
+ if (!data.assistant) return;
257
+ const callCounts = /* @__PURE__ */ new Map();
258
+ for (const call of data.calls) callCounts.set(call.toolCallId, (callCounts.get(call.toolCallId) ?? 0) + 1);
259
+ const partCounts = /* @__PURE__ */ new Map();
260
+ for (const part of data.assistant.parts) {
261
+ if (part.type !== "tool_call") continue;
262
+ partCounts.set(part.toolCallId, (partCounts.get(part.toolCallId) ?? 0) + 1);
263
+ }
264
+ if (callCounts.size !== partCounts.size || [...callCounts].some(([toolCallId, count]) => partCounts.get(toolCallId) !== count)) context.addIssue({
265
+ code: "custom",
266
+ path: ["assistant", "parts"],
267
+ message: "assistant tool parts must reference every call exactly once"
268
+ });
269
+ });
270
+ const conversationReportAssistantMessageEventDataSchema = z.object({
271
+ type: z.literal("assistant_message"),
272
+ parts: z.array(conversationReportReasoningPartSchema).min(1)
273
+ }).strict();
274
+ const conversationReportTurnLifecycleEventDataSchema = z.discriminatedUnion("state", [
275
+ z.object({
276
+ type: z.literal("turn_lifecycle"),
277
+ turnId: z.string().min(1),
278
+ state: z.enum(["succeeded", "no_reply"])
279
+ }).strict(),
280
+ z.object({
281
+ type: z.literal("turn_lifecycle"),
282
+ turnId: z.string().min(1),
283
+ state: z.literal("started"),
284
+ inputMessageIds: z.array(z.string().min(1)).min(1).optional()
285
+ }).strict(),
286
+ z.object({
287
+ type: z.literal("turn_lifecycle"),
288
+ turnId: z.string().min(1),
289
+ state: z.literal("failed"),
290
+ failureCode: conversationTurnFailureCodeSchema,
291
+ failureReason: conversationTurnFailureReasonSchema.optional(),
292
+ eventId: z.string().regex(/^[a-f0-9]{32}$/i).optional(),
293
+ sentryEventUrl: z.string().url().optional()
294
+ }).strict()
295
+ ]);
296
+ const conversationReportTurnRoutedEventDataSchema = z.object({
297
+ type: z.literal("turn_routed"),
298
+ turnId: z.string().min(1),
299
+ modelProfile: z.string().min(1),
300
+ modelId: z.string().min(1),
301
+ costUsd: z.number().finite().nonnegative().optional(),
302
+ reasoningLevel: z.string().min(1),
303
+ confidence: z.number().min(0).max(1).optional(),
304
+ source: z.enum([
305
+ "configured",
306
+ "inherited",
307
+ "router"
308
+ ])
309
+ }).strict();
310
+ const conversationReportGuardianActionReviewedEventDataSchema = z.object({
311
+ type: z.literal("guardian_action_reviewed"),
312
+ turnId: z.string().min(1),
313
+ toolCallId: z.string().min(1),
314
+ toolName: z.string().min(1),
315
+ decision: z.enum([
316
+ "allow",
317
+ "ask",
318
+ "deny"
319
+ ]),
320
+ riskLevel: z.enum([
321
+ "low",
322
+ "medium",
323
+ "high",
324
+ "critical"
325
+ ]),
326
+ userAuthorization: z.enum([
327
+ "high",
328
+ "medium",
329
+ "low",
330
+ "unknown"
331
+ ])
332
+ }).strict();
333
+ const conversationReportTurnContextEventDataSchema = z.object({
334
+ type: z.literal("turn_context"),
335
+ turnId: z.string().min(1),
336
+ pluginName: z.string().min(1),
337
+ kind: z.string().min(1),
338
+ version: z.number().int().positive(),
339
+ content: z.record(z.string(), z.unknown())
340
+ }).strict();
341
+ const conversationReportStructuredEventDataSchema = z.object({
342
+ type: z.literal("structured_event"),
343
+ namespace: z.string().min(1),
344
+ name: z.string().min(1),
345
+ version: z.number().int().positive(),
346
+ turnId: z.string().min(1).optional(),
347
+ presentation: conversationEventPresentationSchema
348
+ }).strict();
349
+ /** Public attachment metadata on conversation reports and transcript media. */
350
+ const conversationReportDeliveredAttachmentSchema = z.object({
351
+ id: z.string().min(1),
352
+ filename: z.string().min(1),
353
+ contentType: z.string().min(1),
354
+ bytes: z.number().int().nonnegative()
355
+ }).strict();
356
+ const conversationReportAttachmentsDeliveredEventDataSchema = z.object({
357
+ type: z.literal("attachments_delivered"),
358
+ attachments: z.array(conversationReportDeliveredAttachmentSchema).min(1)
359
+ }).strict();
360
+ const conversationReportCompactionEventDataSchema = z.object({
361
+ type: z.literal("compaction"),
362
+ modelProfile: z.string().min(1).optional(),
363
+ modelId: z.string().min(1).optional(),
364
+ summary: z.string().min(1).optional(),
365
+ details: z.object({
366
+ reason: z.literal("capacity"),
367
+ estimatedInputTokens: z.number().int().nonnegative(),
368
+ replacementInputTokens: z.number().int().nonnegative().optional(),
369
+ triggerTokens: z.number().int().nonnegative(),
370
+ inputLimitTokens: z.number().int().positive(),
371
+ inputMessageCount: z.number().int().nonnegative(),
372
+ retainedMessageCount: z.number().int().nonnegative(),
373
+ summaryChars: z.number().int().nonnegative()
374
+ }).strict().optional()
375
+ }).strict();
376
+ const conversationReportHandoffEventDataSchema = z.object({
377
+ type: z.literal("handoff"),
378
+ modelProfile: z.string().min(1),
379
+ modelId: z.string().min(1),
380
+ reasoningLevel: z.string().min(1).optional(),
381
+ triggeringToolCallId: z.string().min(1).optional(),
382
+ summary: z.string().min(1).optional()
383
+ }).strict();
384
+ const conversationReportSubagentEventDataSchema = z.object({
385
+ type: z.literal("subagent"),
386
+ startedSeq: z.number().int().nonnegative(),
387
+ startedAt: z.string().datetime(),
388
+ childConversationId: z.string().min(1),
389
+ subagentKind: z.string().min(1),
390
+ parentToolCallId: z.string().min(1).optional(),
391
+ status: z.enum([
392
+ "running",
393
+ "completed",
394
+ "error",
395
+ "aborted"
396
+ ])
397
+ }).strict();
398
+ /** Privacy-safe event variants owned by the conversation reporting API. */
399
+ const conversationReportEventDataSchema = z.discriminatedUnion("type", [
400
+ conversationReportMessageEventDataSchema,
401
+ conversationReportMessageHandledEventDataSchema,
402
+ conversationReportAssistantMessageEventDataSchema,
403
+ conversationReportToolCallsEventDataSchema,
404
+ conversationReportTurnLifecycleEventDataSchema,
405
+ conversationReportTurnContextEventDataSchema,
406
+ conversationReportStructuredEventDataSchema,
407
+ conversationReportAttachmentsDeliveredEventDataSchema,
408
+ conversationReportTurnRoutedEventDataSchema,
409
+ conversationReportGuardianActionReviewedEventDataSchema,
410
+ conversationReportCompactionEventDataSchema,
411
+ conversationReportHandoffEventDataSchema,
412
+ conversationReportSubagentEventDataSchema
413
+ ]);
414
+ /** One ordered, privacy-safe canonical event projected for API consumers. */
415
+ const conversationReportEventSchema = z.object({
416
+ seq: z.number().int().nonnegative(),
417
+ createdAt: z.string().datetime(),
418
+ data: conversationReportEventDataSchema
419
+ }).strict();
420
+ /** Availability of the canonical event history attached to a detail report. */
421
+ const conversationEventHistorySchema = z.discriminatedUnion("status", [
422
+ z.object({ status: z.literal("available") }).strict(),
423
+ z.object({
424
+ status: z.literal("redacted"),
425
+ reason: z.literal("non_public_conversation")
426
+ }).strict(),
427
+ z.object({
428
+ status: z.literal("expired"),
429
+ expiredAt: z.string().datetime()
430
+ }).strict()
431
+ ]);
432
+ const conversationModelUsageSchema = z.object({
433
+ modelId: z.string(),
434
+ usage: conversationUsageSchema
435
+ }).strict();
436
+ /** Enforce event ordering and history visibility across paginated wire payloads. */
437
+ function validateConversationEvents(report, context) {
438
+ if (report.eventHistory.status === "expired" && report.events.length > 0) context.addIssue({
439
+ code: "custom",
440
+ path: ["events"],
441
+ message: "expired event history must not contain events"
442
+ });
443
+ for (let index = 1; index < report.events.length; index += 1) if (report.events[index].seq <= report.events[index - 1].seq) context.addIssue({
444
+ code: "custom",
445
+ path: [
446
+ "events",
447
+ index,
448
+ "seq"
449
+ ],
450
+ message: "report event sequences must be strictly increasing"
451
+ });
452
+ for (const [index, event] of report.events.entries()) {
453
+ if (event.data.type === "message") {
454
+ if (report.eventHistory.status === "redacted" && event.data.redacted !== true) context.addIssue({
455
+ code: "custom",
456
+ path: [
457
+ "events",
458
+ index,
459
+ "data"
460
+ ],
461
+ message: "redacted event history must redact messages"
462
+ });
463
+ if (report.eventHistory.status === "available" && event.data.redacted === true) context.addIssue({
464
+ code: "custom",
465
+ path: [
466
+ "events",
467
+ index,
468
+ "data"
469
+ ],
470
+ message: "available event history must expose messages"
471
+ });
472
+ }
473
+ if (report.eventHistory.status === "redacted" && event.data.type === "tool_calls" && event.data.calls.some((call) => call.input !== void 0 || call.output !== void 0)) context.addIssue({
474
+ code: "custom",
475
+ path: [
476
+ "events",
477
+ index,
478
+ "data"
479
+ ],
480
+ message: "redacted event history must redact tool payloads"
481
+ });
482
+ if (report.eventHistory.status === "redacted" && event.data.type === "assistant_message" && event.data.parts.some((part) => part.text !== void 0)) context.addIssue({
483
+ code: "custom",
484
+ path: [
485
+ "events",
486
+ index,
487
+ "data"
488
+ ],
489
+ message: "redacted event history must redact assistant messages"
490
+ });
491
+ if (report.eventHistory.status === "available" && event.data.type === "assistant_message" && event.data.parts.some((part) => part.redacted === true)) context.addIssue({
492
+ code: "custom",
493
+ path: [
494
+ "events",
495
+ index,
496
+ "data"
497
+ ],
498
+ message: "available event history must expose reasoning"
499
+ });
500
+ if (event.data.type === "tool_calls" && (report.eventHistory.status === "redacted" && event.data.assistant?.parts.some((part) => part.type === "reasoning" && part.text !== void 0) || report.eventHistory.status === "available" && event.data.assistant?.parts.some((part) => part.type === "reasoning" && part.redacted === true))) context.addIssue({
501
+ code: "custom",
502
+ path: [
503
+ "events",
504
+ index,
505
+ "data",
506
+ "assistant"
507
+ ],
508
+ message: "assistant reasoning must match event history visibility"
509
+ });
510
+ }
511
+ }
512
+ const conversationDetailReportSchema = conversationSummaryReportSchema.extend({
513
+ modelUsage: z.array(conversationModelUsageSchema).optional(),
514
+ events: z.array(conversationReportEventSchema),
515
+ eventHistory: conversationEventHistorySchema,
516
+ previousCursor: z.string().min(1).optional(),
517
+ generatedAt: z.string(),
518
+ sentryConversationUrl: z.string().optional(),
519
+ sourceTask: conversationSourceTaskSchema.optional()
520
+ }).strict().superRefine(validateConversationEvents);
521
+ const conversationEventPageSchema = z.object({
522
+ events: z.array(conversationReportEventSchema),
523
+ eventHistory: conversationEventHistorySchema,
524
+ previousCursor: z.string().min(1).optional(),
525
+ generatedAt: z.string()
526
+ }).strict().superRefine(validateConversationEvents);
527
+ const conversationFeedSchema = z.object({
528
+ conversations: z.array(conversationSummaryReportSchema),
529
+ source: z.literal("conversation_index"),
530
+ generatedAt: z.string()
531
+ }).strict();
532
+ const conversationStatsItemSchema = z.object({
533
+ active: z.number(),
534
+ conversations: z.number(),
535
+ durationMs: z.number(),
536
+ failed: z.number(),
537
+ label: z.string(),
538
+ costUsd: z.number().optional(),
539
+ tokens: z.number().optional()
540
+ }).strict();
541
+ /** UTC day (`YYYY-MM-DD`) or hour (`YYYY-MM-DDTHH`) activity bucket key. */
542
+ const conversationMetricBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
543
+ const conversationMetricDaySchema = z.object({
544
+ cachedInputTokens: z.number().optional(),
545
+ conversations: z.number(),
546
+ costUsd: z.number().optional(),
547
+ date: conversationMetricBucketSchema,
548
+ durationMs: z.number(),
549
+ inputTokens: z.number().optional(),
550
+ tokens: z.number().optional()
551
+ }).strict();
552
+ const guardianMetricDaySchema = z.object({
553
+ allow: z.number(),
554
+ ask: z.number(),
555
+ costUsd: z.number().optional(),
556
+ date: conversationMetricBucketSchema,
557
+ deny: z.number(),
558
+ requests: z.number()
559
+ }).strict();
560
+ const guardianStatsSchema = z.object({
561
+ allow: z.number(),
562
+ ask: z.number(),
563
+ costUsd: z.number().optional(),
564
+ deny: z.number(),
565
+ metricDays: z.array(guardianMetricDaySchema),
566
+ metricHours: z.array(guardianMetricDaySchema).optional(),
567
+ metricSixHours: z.array(guardianMetricDaySchema).optional(),
568
+ requests: z.number()
569
+ }).strict();
570
+ const conversationStatsReportSchema = z.object({
571
+ active: z.number(),
572
+ cachedInputTokens: z.number().optional(),
573
+ conversations: z.number(),
574
+ durationMs: z.number(),
575
+ failed: z.number(),
576
+ generatedAt: z.string(),
577
+ guardian: guardianStatsSchema,
578
+ metricDays: z.array(conversationMetricDaySchema),
579
+ metricHours: z.array(conversationMetricDaySchema).optional(),
580
+ metricSixHours: z.array(conversationMetricDaySchema).optional(),
581
+ locations: z.array(conversationStatsItemSchema),
582
+ actors: z.array(conversationStatsItemSchema),
583
+ source: z.literal("conversation_index"),
584
+ costUsd: z.number().optional(),
585
+ inputTokens: z.number().optional(),
586
+ tokens: z.number().optional(),
587
+ windowEnd: z.string(),
588
+ windowStart: z.string()
589
+ }).strict();
590
+ //#endregion
591
+ //#region src/api/reporting-window.ts
592
+ /** Shared UTC day/hour/six-hour windows for dashboard activity series. */
593
+ const HOUR_MS = 36e5;
594
+ const SIX_HOUR_MS = 6 * HOUR_MS;
595
+ const DAY_MS = 24 * HOUR_MS;
596
+ /** Start of the UTC calendar day containing `valueMs`. */
597
+ function startOfUtcDay(valueMs) {
598
+ const date = new Date(valueMs);
599
+ date.setUTCHours(0, 0, 0, 0);
600
+ return date;
601
+ }
602
+ /** Start of the UTC hour containing `valueMs`. */
603
+ function startOfUtcHour(valueMs) {
604
+ const date = new Date(valueMs);
605
+ date.setUTCMinutes(0, 0, 0);
606
+ return date;
607
+ }
608
+ /** Start of the UTC 6-hour bucket containing `valueMs` (00/06/12/18). */
609
+ function startOfUtcSixHour(valueMs) {
610
+ const date = startOfUtcHour(valueMs);
611
+ date.setUTCHours(Math.floor(date.getUTCHours() / 6) * 6, 0, 0, 0);
612
+ return date;
613
+ }
614
+ /** UTC day key `YYYY-MM-DD`. */
615
+ function utcDayKey(value) {
616
+ return (typeof value === "number" ? new Date(value) : value).toISOString().slice(0, 10);
617
+ }
618
+ /** UTC hour key `YYYY-MM-DDTHH`. */
619
+ function utcHourKey(value) {
620
+ return (typeof value === "number" ? new Date(value) : value).toISOString().slice(0, 13);
621
+ }
622
+ /** UTC 6-hour bucket key `YYYY-MM-DDTHH` at 00/06/12/18. */
623
+ function utcSixHourKey(value) {
624
+ return utcHourKey(startOfUtcSixHour(typeof value === "number" ? value : value.getTime()));
625
+ }
626
+ /** Inclusive trailing UTC day window ending on today's UTC day. */
627
+ function trailingUtcDayWindow(nowMs, dayCount) {
628
+ const end = startOfUtcDay(nowMs);
629
+ const start = new Date(end);
630
+ start.setUTCDate(start.getUTCDate() - (dayCount - 1));
631
+ return {
632
+ end,
633
+ start
634
+ };
635
+ }
636
+ /** Inclusive trailing UTC hour window ending on the current UTC hour. */
637
+ function trailingUtcHourWindow(nowMs, hourCount = 24) {
638
+ const end = startOfUtcHour(nowMs);
639
+ return {
640
+ end,
641
+ start: /* @__PURE__ */ new Date(end.getTime() - (hourCount - 1) * HOUR_MS)
642
+ };
643
+ }
644
+ /** Inclusive trailing UTC 6-hour window ending on the current 6h bucket. */
645
+ function trailingUtcSixHourWindow(nowMs, bucketCount = 28) {
646
+ const end = startOfUtcSixHour(nowMs);
647
+ return {
648
+ end,
649
+ start: /* @__PURE__ */ new Date(end.getTime() - (bucketCount - 1) * SIX_HOUR_MS)
650
+ };
651
+ }
652
+ /** Fill a fixed UTC day window from a sparse map. */
653
+ function fillUtcDays(args) {
654
+ const { end, start } = trailingUtcDayWindow(args.nowMs, args.count);
655
+ const items = [];
656
+ for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
657
+ const date = utcDayKey(cursor);
658
+ items.push(args.rows.get(date) ?? args.empty(date));
659
+ }
660
+ return items;
661
+ }
662
+ /** Fill a fixed UTC hour window from a sparse map. */
663
+ function fillUtcHours(args) {
664
+ const hourCount = args.count ?? 24;
665
+ const { end, start } = trailingUtcHourWindow(args.nowMs, hourCount);
666
+ const items = [];
667
+ for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS)) {
668
+ const date = utcHourKey(cursor);
669
+ items.push(args.rows.get(date) ?? args.empty(date));
670
+ }
671
+ return items;
672
+ }
673
+ /** Fill a fixed UTC 6-hour window from a map of known rows. */
674
+ function fillUtcSixHours(args) {
675
+ const bucketCount = args.count ?? 28;
676
+ const { end, start } = trailingUtcSixHourWindow(args.nowMs, bucketCount);
677
+ const items = [];
678
+ for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + SIX_HOUR_MS)) {
679
+ const date = utcSixHourKey(cursor);
680
+ items.push(args.rows.get(date) ?? args.empty(date));
681
+ }
682
+ return items;
683
+ }
684
+ /**
685
+ * Sum hour rows into trailing 6-hour buckets.
686
+ * Adds number fields. Keeps other fields from the first row in the bucket.
687
+ * Sets `date` to the 6-hour bucket key.
688
+ */
689
+ function sumUtcHoursIntoSixHours(args) {
690
+ const bucketCount = args.count ?? 28;
691
+ const bySix = /* @__PURE__ */ new Map();
692
+ for (const hour of args.hours) {
693
+ const key = utcSixHourKey(Date.parse(`${hour.date}:00:00.000Z`));
694
+ const next = {
695
+ ...bySix.get(key) ?? args.empty(key),
696
+ date: key
697
+ };
698
+ for (const [field, value] of Object.entries(hour)) {
699
+ if (field === "date") continue;
700
+ if (typeof value === "number") {
701
+ const prior = next[field];
702
+ next[field] = (typeof prior === "number" ? prior : 0) + value;
703
+ }
704
+ }
705
+ bySix.set(key, next);
706
+ }
707
+ return fillUtcSixHours({
708
+ count: bucketCount,
709
+ empty: args.empty,
710
+ nowMs: args.nowMs,
711
+ rows: bySix
712
+ });
713
+ }
714
+ //#endregion
715
+ //#region src/api/schema/code.ts
716
+ const codeChangeSummarySchema = z.object({
717
+ closed: z.number().int().nonnegative(),
718
+ costUsd: z.number().nonnegative().optional(),
719
+ created: z.number().int().nonnegative(),
720
+ medianCostUsd: z.number().nonnegative().optional(),
721
+ medianMergeTimeMs: z.number().nonnegative().optional(),
722
+ merged: z.number().int().nonnegative(),
723
+ mergeRate: z.number().min(0).max(1).optional(),
724
+ open: z.number().int().nonnegative()
725
+ }).strict();
726
+ /** UTC day (`YYYY-MM-DD`) or hour (`YYYY-MM-DDTHH`) activity bucket key. */
727
+ const codeMetricBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
728
+ const codeActivityDaySchema = z.object({
729
+ closed: z.number().int().nonnegative(),
730
+ created: z.number().int().nonnegative(),
731
+ date: codeMetricBucketSchema,
732
+ merged: z.number().int().nonnegative()
733
+ }).strict();
734
+ const codeRepositorySummarySchema = z.object({
735
+ closed: z.number().int().nonnegative(),
736
+ created: z.number().int().nonnegative(),
737
+ id: z.string().uuid(),
738
+ medianCostUsd: z.number().nonnegative().optional(),
739
+ merged: z.number().int().nonnegative(),
740
+ mergeRate: z.number().min(0).max(1).optional(),
741
+ name: z.string().min(1),
742
+ open: z.number().int().nonnegative(),
743
+ provider: z.string().min(1),
744
+ url: z.string().url().optional()
745
+ }).strict();
746
+ const codeChangeSummaryReportSchema = z.object({
747
+ closedAt: z.string().optional(),
748
+ id: z.string().uuid(),
749
+ mergedAt: z.string().optional(),
750
+ number: z.number().int().positive(),
751
+ openedAt: z.string(),
752
+ provider: z.string().min(1),
753
+ repository: z.string().min(1),
754
+ state: codeChangeStateSchema,
755
+ title: z.string().optional(),
756
+ url: z.string().url().optional()
757
+ }).strict();
758
+ const codeOverviewReportSchema = z.object({
759
+ activityDays: z.array(codeActivityDaySchema),
760
+ activityHours: z.array(codeActivityDaySchema).optional(),
761
+ activitySixHours: z.array(codeActivityDaySchema).optional(),
762
+ changes: z.array(codeChangeSummaryReportSchema),
763
+ generatedAt: z.string(),
764
+ repositories: z.array(codeRepositorySummarySchema),
765
+ summary: codeChangeSummarySchema,
766
+ windowEnd: z.string(),
767
+ windowStart: z.string()
768
+ }).strict();
769
+ /** Person-scoped code activity for one People profile. */
770
+ const codePersonReportSchema = z.object({
771
+ activityDays: z.array(codeActivityDaySchema),
772
+ activityHours: z.array(codeActivityDaySchema).optional(),
773
+ activitySixHours: z.array(codeActivityDaySchema).optional(),
774
+ generatedAt: z.string(),
775
+ summary: codeChangeSummarySchema,
776
+ windowEnd: z.string(),
777
+ windowStart: z.string()
778
+ }).strict();
779
+ //#endregion
780
+ //#region src/api/activity.ts
781
+ const dailyConversationActivitySchema = z.object({
782
+ active: z.number(),
783
+ conversations: z.number(),
784
+ date: z.string(),
785
+ durationMs: z.number(),
786
+ failed: z.number(),
787
+ tokens: z.number().optional()
788
+ }).strict();
789
+ /** Build a zeroed day for conversation activity projections. */
790
+ function emptyActivityDay(date) {
791
+ return {
792
+ active: 0,
793
+ conversations: 0,
794
+ date,
795
+ durationMs: 0,
796
+ failed: 0
797
+ };
798
+ }
799
+ /** Fill a fixed UTC day window from sparse conversation activity. */
800
+ function activityDays(days, nowMs, count) {
801
+ return fillUtcDays({
802
+ count,
803
+ empty: emptyActivityDay,
804
+ nowMs,
805
+ rows: days
806
+ });
807
+ }
808
+ /**
809
+ * Fill the trailing 7-day UTC hour window from known hour rows.
810
+ * 24h charts use the last 24 points. 7d charts sum hours into 6-hour buckets.
811
+ */
812
+ function activityHours(hours, nowMs) {
813
+ return fillUtcHours({
814
+ count: 168,
815
+ empty: emptyActivityDay,
816
+ nowMs,
817
+ rows: hours
818
+ });
819
+ }
820
+ /**
821
+ * Fill trailing 6-hour buckets from hour keys or hour rows.
822
+ * Hour keys must be summed into 6-hour keys first.
823
+ */
824
+ function activitySixHours(hours, nowMs) {
825
+ return sumUtcHoursIntoSixHours({
826
+ empty: emptyActivityDay,
827
+ hours: hours instanceof Map ? activityHours(hours, nowMs) : [...hours],
828
+ nowMs
829
+ });
830
+ }
831
+ //#endregion
832
+ //#region src/api/schema/location.ts
833
+ const locationParamsSchema = z.object({ locationId: z.string().min(1) }).strict();
834
+ const locationSummaryReportSchema = conversationStatsItemSchema.extend({
835
+ id: z.string(),
836
+ firstSeenAt: z.string(),
837
+ kind: juniorDestinationKindSchema,
838
+ lastSeenAt: z.string(),
839
+ provider: z.string(),
840
+ providerDestinationId: z.string(),
841
+ visibility: z.literal("public")
842
+ }).strict();
843
+ const locationActorSummaryReportSchema = conversationStatsItemSchema.extend({ actor: actorIdentitySchema }).strict();
844
+ /** UTC day (`YYYY-MM-DD`) or hour (`YYYY-MM-DDTHH`) activity bucket key. */
845
+ const locationMetricBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
846
+ const locationActivityDayReportSchema = z.object({
847
+ date: locationMetricBucketSchema,
848
+ privateConversations: z.number(),
849
+ publicConversations: z.number()
850
+ }).strict();
851
+ const locationDirectoryReportSchema = z.object({
852
+ activityDays: z.array(locationActivityDayReportSchema),
853
+ activityHours: z.array(locationActivityDayReportSchema).optional(),
854
+ activitySixHours: z.array(locationActivityDayReportSchema).optional(),
855
+ generatedAt: z.string(),
856
+ locations: z.array(locationSummaryReportSchema),
857
+ privateActivity: conversationStatsItemSchema,
858
+ source: z.literal("conversation_index"),
859
+ windowEnd: z.string(),
860
+ windowStart: z.string()
861
+ }).strict();
862
+ const locationDetailReportSchema = locationSummaryReportSchema.extend({
863
+ activityDays: z.array(dailyConversationActivitySchema),
864
+ activityHours: z.array(dailyConversationActivitySchema).optional(),
865
+ activitySixHours: z.array(dailyConversationActivitySchema).optional(),
866
+ actors: z.array(locationActorSummaryReportSchema),
867
+ generatedAt: z.string(),
868
+ recentConversations: z.array(conversationSummaryReportSchema),
869
+ source: z.literal("conversation_index"),
870
+ windowEnd: z.string(),
871
+ windowStart: z.string()
872
+ }).strict();
873
+ //#endregion
874
+ //#region src/api/schema/person.ts
875
+ const personParamsSchema = z.object({ email: z.string().trim().min(1) }).strict();
876
+ const peopleConversationStatsItemSchema = conversationStatsItemSchema.omit({ costUsd: true });
877
+ /** UTC day (`YYYY-MM-DD`) or hour (`YYYY-MM-DDTHH`) activity bucket key. */
878
+ const peopleMetricBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
879
+ const actorActivityDayReportSchema = z.object({
880
+ active: z.number(),
881
+ conversations: z.number(),
882
+ costUsd: z.number().optional(),
883
+ date: peopleMetricBucketSchema,
884
+ durationMs: z.number(),
885
+ failed: z.number(),
886
+ tokens: z.number().optional()
887
+ }).strict();
888
+ const peopleActivityDayReportSchema = z.object({
889
+ activePeople: z.number(),
890
+ conversations: z.number(),
891
+ date: peopleMetricBucketSchema
892
+ }).strict();
893
+ const actorTotalsReportSchema = z.object({
894
+ active: z.number(),
895
+ activeDays: z.number(),
896
+ conversations: z.number(),
897
+ durationMs: z.number(),
898
+ failed: z.number(),
899
+ tokens: z.number().optional()
900
+ }).strict();
901
+ /** Spend and activity for one people-directory range, plus the prior period's spend. */
902
+ const actorWindowMetricsSchema = z.object({
903
+ conversations: z.number().int().nonnegative(),
904
+ costUsd: z.number().finite().nonnegative(),
905
+ durationMs: z.number().finite().nonnegative(),
906
+ priorCostUsd: z.number().finite().nonnegative()
907
+ }).strict();
908
+ /** People-directory ranges that match the dashboard range control. */
909
+ const actorDirectoryWindowsSchema = z.object({
910
+ 1: actorWindowMetricsSchema,
911
+ 7: actorWindowMetricsSchema,
912
+ 30: actorWindowMetricsSchema,
913
+ 90: actorWindowMetricsSchema
914
+ }).strict();
915
+ const identifiedActorSchema = actorIdentitySchema.extend({ email: z.string().min(1) }).strict();
916
+ const actorSummaryReportSchema = actorTotalsReportSchema.extend({
917
+ firstSeenAt: z.string(),
918
+ lastSeenAt: z.string(),
919
+ actor: identifiedActorSchema,
920
+ windows: actorDirectoryWindowsSchema
921
+ }).strict();
922
+ const actorDirectoryReportSchema = z.object({
923
+ activityDays: z.array(peopleActivityDayReportSchema),
924
+ activityHours: z.array(peopleActivityDayReportSchema).optional(),
925
+ activitySixHours: z.array(peopleActivityDayReportSchema).optional(),
926
+ generatedAt: z.string(),
927
+ people: z.array(actorSummaryReportSchema),
928
+ source: z.literal("conversation_index"),
929
+ windowEnd: z.string(),
930
+ windowStart: z.string()
931
+ }).strict();
932
+ const actorProfileReportSchema = z.object({
933
+ activityDays: z.array(actorActivityDayReportSchema),
934
+ activityHours: z.array(actorActivityDayReportSchema).optional(),
935
+ activitySixHours: z.array(actorActivityDayReportSchema).optional(),
936
+ generatedAt: z.string(),
937
+ locations: z.array(peopleConversationStatsItemSchema),
938
+ recentConversations: z.array(conversationSummaryReportSchema),
939
+ actor: identifiedActorSchema,
940
+ source: z.literal("conversation_index"),
941
+ surfaces: z.array(peopleConversationStatsItemSchema),
942
+ totals: actorTotalsReportSchema,
943
+ windowEnd: z.string(),
944
+ windowStart: z.string()
945
+ }).strict();
946
+ const personalSpendReportSchema = z.object({
947
+ generatedAt: z.string(),
948
+ sevenDaysUsd: z.number().finite().nonnegative(),
949
+ source: z.literal("conversation_index"),
950
+ thirtyDaysUsd: z.number().finite().nonnegative(),
951
+ windowEnd: z.string(),
952
+ windowStart: z.string()
953
+ }).strict();
954
+ //#endregion
955
+ //#region src/api/schema/personal-token.ts
956
+ const personalTokenMetadataSchema = z.object({
957
+ id: z.string().uuid(),
958
+ name: z.string(),
959
+ tokenSuffix: z.string(),
960
+ createdAt: z.string().datetime(),
961
+ expiresAt: z.string().datetime(),
962
+ lastUsedAt: z.string().datetime().nullable()
963
+ }).strict();
964
+ const personalTokenListSchema = z.object({ tokens: z.array(personalTokenMetadataSchema) }).strict();
965
+ const createPersonalTokenBodySchema = z.object({ name: z.string().trim().min(1).max(80) }).strict();
966
+ const createdPersonalTokenSchema = personalTokenMetadataSchema.extend({ token: z.string().startsWith("jr_pat_") }).strict();
967
+ const personalTokenParamsSchema = z.object({ id: z.string().uuid() }).strict();
968
+ const revokePersonalTokenResponseSchema = z.object({ revoked: z.literal(true) }).strict();
969
+ //#endregion
970
+ //#region src/api/schema/task.ts
971
+ const taskDestinationSchema = z.object({
972
+ channelId: z.string().min(1),
973
+ label: z.string().min(1),
974
+ teamId: z.string().min(1),
975
+ visibility: z.enum(["private", "public"])
976
+ }).strict();
977
+ /** Task run counts for the dashboard range control (24h/7d/30d/90d). */
978
+ const taskRunWindowsSchema = z.object({
979
+ 1: z.number().int().nonnegative(),
980
+ 7: z.number().int().nonnegative(),
981
+ 30: z.number().int().nonnegative(),
982
+ 90: z.number().int().nonnegative()
983
+ }).strict();
984
+ const taskSummaryBaseSchema = z.object({
985
+ createdAt: z.string().datetime(),
986
+ createdBy: z.string().min(1),
987
+ createdByEmail: z.string().trim().email().optional(),
988
+ destination: taskDestinationSchema,
989
+ id: z.string().min(1),
990
+ instruction: z.string().min(1),
991
+ lastConversationId: z.string().min(1).optional(),
992
+ lastRunAt: z.string().datetime().optional(),
993
+ ownedByViewer: z.boolean(),
994
+ runs: taskRunWindowsSchema,
995
+ outcomes: z.array(taskOutcomeSchema).max(5),
996
+ /** Short display title; falls back from instruction when unset. */
997
+ title: z.string().min(1),
998
+ totalRuns: z.number().int().nonnegative()
999
+ });
1000
+ const scheduledTaskSummarySchema = taskSummaryBaseSchema.extend({
1001
+ kind: z.literal("scheduled"),
1002
+ nextRunAt: z.string().datetime().optional(),
1003
+ schedule: z.string().min(1),
1004
+ status: z.enum([
1005
+ "active",
1006
+ "blocked",
1007
+ "completed"
1008
+ ])
1009
+ }).strict();
1010
+ const eventTaskSummarySchema = taskSummaryBaseSchema.extend({
1011
+ events: z.array(z.string().min(1)).min(1),
1012
+ kind: z.literal("event"),
1013
+ resource: z.string().min(1),
1014
+ source: z.string().min(1),
1015
+ triggerAvailable: z.boolean()
1016
+ }).strict();
1017
+ const taskSummarySchema = z.discriminatedUnion("kind", [scheduledTaskSummarySchema, eventTaskSummarySchema]);
1018
+ /** UTC day (`YYYY-MM-DD`) or hour (`YYYY-MM-DDTHH`) execution bucket key. */
1019
+ const taskMetricBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
1020
+ /** One UTC day/hour of completed task executions stacked by task type. */
1021
+ const taskExecutionDaySchema = z.object({
1022
+ /** Linked conversation spend for executions in this bucket. */
1023
+ costUsd: z.number().finite().nonnegative(),
1024
+ date: taskMetricBucketSchema,
1025
+ event: z.number().int().nonnegative(),
1026
+ scheduled: z.number().int().nonnegative()
1027
+ }).strict();
1028
+ const taskListQuerySchema = z.object({ q: z.string().trim().max(200).optional() }).strict();
1029
+ const taskListSchema = z.object({
1030
+ executionDays: z.array(taskExecutionDaySchema),
1031
+ executionHours: z.array(taskExecutionDaySchema).optional(),
1032
+ executionSixHours: z.array(taskExecutionDaySchema).optional(),
1033
+ tasks: z.array(taskSummarySchema),
1034
+ truncated: z.boolean()
1035
+ }).strict();
1036
+ const taskParamsSchema = z.object({
1037
+ id: z.string().min(1),
1038
+ kind: z.enum(["scheduled", "event"])
1039
+ }).strict();
1040
+ const taskExecutionStatusSchema = z.enum([
1041
+ "blocked",
1042
+ "completed",
1043
+ "failed"
1044
+ ]);
1045
+ const taskExecutionSchema = z.object({
1046
+ conversationId: z.string().min(1).optional(),
1047
+ /** Estimated model cost for the linked conversation, when known. */
1048
+ costUsd: z.number().finite().nonnegative().optional(),
1049
+ /** Cumulative conversation runtime in milliseconds, when known. */
1050
+ durationMs: z.number().finite().nonnegative().optional(),
1051
+ executedAt: z.string().datetime(),
1052
+ executionId: z.string().min(1),
1053
+ status: taskExecutionStatusSchema,
1054
+ title: z.string().min(1).optional(),
1055
+ /** Cumulative conversation token total, when known. */
1056
+ totalTokens: z.number().int().nonnegative().optional()
1057
+ }).strict();
1058
+ /** One UTC day/hour of terminal executions for a single task, stacked by status. */
1059
+ const taskExecutionStatusDaySchema = z.object({
1060
+ blocked: z.number().int().nonnegative(),
1061
+ completed: z.number().int().nonnegative(),
1062
+ date: taskMetricBucketSchema,
1063
+ failed: z.number().int().nonnegative()
1064
+ }).strict();
1065
+ const taskExecutionListSchema = z.object({
1066
+ executionDays: z.array(taskExecutionStatusDaySchema),
1067
+ executionHours: z.array(taskExecutionStatusDaySchema).optional(),
1068
+ executionSixHours: z.array(taskExecutionStatusDaySchema).optional(),
1069
+ executions: z.array(taskExecutionSchema),
1070
+ task: taskSummarySchema,
1071
+ truncated: z.boolean()
1072
+ }).strict();
1073
+ const taskRunSchema = taskExecutionSchema.extend({
1074
+ kind: z.enum(["scheduled", "event"]),
1075
+ taskId: z.string().min(1),
1076
+ taskTitle: z.string().min(1)
1077
+ }).strict();
1078
+ const taskRunListSchema = z.object({
1079
+ runs: z.array(taskRunSchema),
1080
+ truncated: z.boolean()
1081
+ }).strict();
1082
+ //#endregion
1083
+ //#region src/api/schema/workspace.ts
1084
+ const workspaceRepoInputSchema = z.object({
1085
+ provider: z.string(),
1086
+ repo: z.string()
1087
+ }).strict();
1088
+ const workspaceRepoSchema = z.object({
1089
+ provider: z.string(),
1090
+ repo: z.string(),
1091
+ checkoutPath: z.string()
1092
+ }).strict();
1093
+ const workspaceSnapshotSchema = z.object({
1094
+ id: z.string(),
1095
+ generatedAt: z.iso.datetime(),
1096
+ buildDurationMs: z.number().int().nonnegative(),
1097
+ sizeBytes: z.number().int().nonnegative().nullable()
1098
+ }).strict();
1099
+ /** Install-wide baseline Sandbox snapshot used when no Workspace recipe is selected. */
1100
+ const baselineSnapshotSchema = z.object({
1101
+ id: z.string(),
1102
+ generatedAt: z.iso.datetime(),
1103
+ buildDurationMs: z.number().int().nonnegative(),
1104
+ dependencyCount: z.number().int().nonnegative()
1105
+ }).strict();
1106
+ const workspaceSchema = z.object({
1107
+ id: z.string().uuid(),
1108
+ name: z.string(),
1109
+ setupScript: z.string(),
1110
+ repos: z.array(workspaceRepoSchema),
1111
+ snapshot: workspaceSnapshotSchema.nullable()
1112
+ }).strict();
1113
+ const workspaceListSchema = z.object({
1114
+ baselineSnapshot: baselineSnapshotSchema.nullable(),
1115
+ workspaces: z.array(workspaceSchema)
1116
+ }).strict();
1117
+ const workspaceBodySchema = z.object({
1118
+ name: z.string(),
1119
+ setupScript: z.string().optional(),
1120
+ repos: z.array(workspaceRepoInputSchema)
1121
+ }).strict();
1122
+ const workspaceParamsSchema = z.object({ id: z.string().uuid() }).strict();
1123
+ const deleteWorkspaceResponseSchema = z.object({ deleted: z.literal(true) }).strict();
1124
+ //#endregion
1125
+ //#region src/api/schema/stats.ts
1126
+ const statSchema = z.object({
1127
+ count: z.number().int().nonnegative(),
1128
+ date: z.string(),
1129
+ metric: z.string().min(1),
1130
+ name: z.string().min(1),
1131
+ namespace: z.string().min(1)
1132
+ }).strict();
1133
+ const statsReportSchema = z.object({
1134
+ generatedAt: z.string().datetime(),
1135
+ stats: z.array(statSchema),
1136
+ windowEnd: z.string(),
1137
+ windowStart: z.string()
1138
+ }).strict();
1139
+ //#endregion
1140
+ export { sumUtcHoursIntoSixHours as $, actorProfileReportSchema as A, createConversationMessageBodySchema as At, dailyConversationActivitySchema as B, createPersonalTokenBodySchema as C, conversationPendingMessageSchema as Ct, personalTokenParamsSchema as D, conversationStatsReportSchema as Dt, personalTokenMetadataSchema as E, conversationReportEventSchema as Et, locationDirectoryReportSchema as F, codePersonReportSchema as G, codeChangeSummaryReportSchema as H, locationParamsSchema as I, HOUR_MS as J, codeRepositorySummarySchema as K, activityDays as L, personalSpendReportSchema as M, locationActivityDayReportSchema as N, revokePersonalTokenResponseSchema as O, conversationSummaryReportSchema as Ot, locationDetailReportSchema as P, startOfUtcHour as Q, activityHours as R, taskSummarySchema as S, conversationPendingMessageDeliverySchema as St, personalTokenListSchema as T, conversationReportEventDataSchema as Tt, codeChangeSummarySchema as U, codeActivityDaySchema as V, codeOverviewReportSchema as W, fillUtcHours as X, fillUtcDays as Y, fillUtcSixHours as Z, taskListSchema as _, conversationEventsQuerySchema as _t, workspaceBodySchema as a, acceptedConversationMessageSchema as at, taskRunSchema as b, conversationParamsSchema as bt, workspaceRepoSchema as c, cancelConversationPendingMessagesBodySchema as ct, scheduledTaskSummarySchema as d, conversationAttachmentParamsSchema as dt, trailingUtcDayWindow as et, taskExecutionListSchema as f, conversationAuxiliaryCostsSchema as ft, taskListQuerySchema as g, conversationEventPageSchema as gt, taskExecutionStatusSchema as h, conversationEventHistorySchema as ht, deleteWorkspaceResponseSchema as i, utcHourKey as it, personParamsSchema as j, apiErrorSchema as jt, actorDirectoryReportSchema as k, createConversationBodySchema as kt, workspaceSchema as l, cancelConversationPendingMessagesResponseSchema as lt, taskExecutionStatusDaySchema as m, conversationDetailReportSchema as mt, statsReportSchema as n, trailingUtcSixHourWindow as nt, workspaceListSchema as o, archiveConversationBodySchema as ot, taskExecutionSchema as p, conversationDetailQuerySchema as pt, DAY_MS as q, baselineSnapshotSchema as r, utcDayKey as rt, workspaceParamsSchema as s, archiveConversationResponseSchema as st, statSchema as t, trailingUtcHourWindow as tt, eventTaskSummarySchema as u, conversationActivityPreviewSchema as ut, taskParamsSchema as v, conversationFeedQuerySchema as vt, createdPersonalTokenSchema as w, conversationPendingMessagesReportSchema as wt, taskRunWindowsSchema as x, conversationPendingAuthorizationSchema as xt, taskRunListSchema as y, conversationFeedSchema as yt, activitySixHours as z };