@sentry/junior 0.112.0 → 0.114.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 (59) hide show
  1. package/dist/{agent-hooks-6MVTPKP4.js → agent-hooks-WNBUY4OB.js} +8 -8
  2. package/dist/api/conversations/cursor.d.ts +17 -0
  3. package/dist/api/conversations/detail.d.ts +40 -18
  4. package/dist/api/conversations/event-list.d.ts +115 -0
  5. package/dist/api/conversations/event-page.d.ts +18 -0
  6. package/dist/api/conversations/events.d.ts +6 -2
  7. package/dist/api/conversations/projection.d.ts +6 -1
  8. package/dist/api/schema/conversation.d.ts +228 -51
  9. package/dist/api/schema.d.ts +2 -2
  10. package/dist/api/schema.js +7 -1
  11. package/dist/api.js +461 -139
  12. package/dist/app.d.ts +2 -0
  13. package/dist/app.js +33 -24
  14. package/dist/{catalog-runtime-UEO25P2J.js → catalog-runtime-6O4M6JGA.js} +5 -5
  15. package/dist/chat/config.d.ts +1 -1
  16. package/dist/chat/conversations/history.d.ts +86 -0
  17. package/dist/chat/conversations/projection.d.ts +20 -1
  18. package/dist/chat/pi/transcript.d.ts +2 -0
  19. package/dist/chat/services/context-budget.d.ts +7 -2
  20. package/dist/chat/services/context-compaction.d.ts +28 -1
  21. package/dist/chat/services/conversation-memory.d.ts +1 -0
  22. package/dist/chat/services/provider-error.d.ts +40 -0
  23. package/dist/chat/services/provider-retry.d.ts +3 -6
  24. package/dist/chat/services/turn-router.d.ts +1 -0
  25. package/dist/chat/task-execution/state.d.ts +2 -2
  26. package/dist/chat/task-execution/store.d.ts +1 -1
  27. package/dist/chat/tools/sandbox/edit-file.d.ts +1 -1
  28. package/dist/chat/tools/sandbox/text-edits.d.ts +1 -0
  29. package/dist/{chunk-CSS7JHEM.js → chunk-4FUEG3QY.js} +1 -1
  30. package/dist/{chunk-AU2JVUDF.js → chunk-5CZ7RETL.js} +1 -1
  31. package/dist/{chunk-SKEMI4IF.js → chunk-6QWPVTMO.js} +200 -52
  32. package/dist/{chunk-AWNDKI5K.js → chunk-ABPSDO6M.js} +20 -15
  33. package/dist/{chunk-QIALGHRN.js → chunk-FIGAF6KL.js} +34 -2
  34. package/dist/{chunk-TZU3R5OC.js → chunk-K2W4CK7K.js} +1 -1
  35. package/dist/{chunk-2FJ6WEYV.js → chunk-O4GT7LYB.js} +1 -1
  36. package/dist/{chunk-ZHP4KNF7.js → chunk-OSKEC4XU.js} +1 -1
  37. package/dist/{chunk-IV2O4HQJ.js → chunk-PM3PX42K.js} +1 -1
  38. package/dist/{chunk-NDQL4ESR.js → chunk-RD7EJI7H.js} +2 -2
  39. package/dist/{chunk-JE23YR3X.js → chunk-S4QDH23A.js} +75 -43
  40. package/dist/{chunk-GJG67YFS.js → chunk-TLGM5X2M.js} +2 -2
  41. package/dist/{chunk-VBSVNOLA.js → chunk-VNNBSKCO.js} +5 -5
  42. package/dist/{chunk-4EJO4HIC.js → chunk-W6RDUAO3.js} +1 -1
  43. package/dist/{chunk-GR4IB6OQ.js → chunk-WV4UJBAS.js} +431 -96
  44. package/dist/{chunk-66IP6WED.js → chunk-XLFBQJUO.js} +4 -4
  45. package/dist/{chunk-X3SP5RDW.js → chunk-YU6PO42Q.js} +1 -1
  46. package/dist/{chunk-PK4ETCUQ.js → chunk-ZGXH3REA.js} +226 -215
  47. package/dist/cli/chat.js +19 -19
  48. package/dist/cli/check.js +6 -6
  49. package/dist/cli/plugins.js +11 -11
  50. package/dist/cli/snapshot-warmup.js +8 -8
  51. package/dist/cli/upgrade.js +5 -5
  52. package/dist/{db-P5H5RVQV.js → db-4VLP7KBF.js} +5 -5
  53. package/dist/instrumentation.js +2 -2
  54. package/dist/nitro.js +2 -2
  55. package/dist/{runner-B4ZDUO3R.js → runner-IPXLWQOF.js} +12 -13
  56. package/dist/{skills-GWTOZ3XV.js → skills-QCNZISNF.js} +6 -6
  57. package/dist/{validation-QFIC6XH6.js → validation-I2BW3UHD.js} +6 -6
  58. package/dist/version.js +1 -1
  59. package/package.json +6 -6
package/dist/api.js CHANGED
@@ -5,7 +5,10 @@ import {
5
5
  apiErrorSchema,
6
6
  archiveConversationBodySchema,
7
7
  archiveConversationResponseSchema,
8
+ conversationDetailQuerySchema,
8
9
  conversationDetailReportSchema,
10
+ conversationEventPageSchema,
11
+ conversationEventsQuerySchema,
9
12
  conversationFeedQuerySchema,
10
13
  conversationFeedSchema,
11
14
  conversationParamsSchema,
@@ -15,13 +18,13 @@ import {
15
18
  locationDirectoryReportSchema,
16
19
  locationParamsSchema,
17
20
  personParamsSchema
18
- } from "./chunk-JE23YR3X.js";
21
+ } from "./chunk-S4QDH23A.js";
19
22
  import {
20
23
  buildSentryConversationUrl,
21
24
  formatSlackConversationRedactedLabel,
22
25
  readHealthReport,
23
26
  resolveSlackConversationContextFromThreadId
24
- } from "./chunk-2FJ6WEYV.js";
27
+ } from "./chunk-O4GT7LYB.js";
25
28
  import {
26
29
  healthReportSchema,
27
30
  pluginOperationalReportFeedSchema,
@@ -34,12 +37,12 @@ import {
34
37
  hasAgentTurnUsage
35
38
  } from "./chunk-MU6HHZEN.js";
36
39
  import "./chunk-PDO5BLNM.js";
37
- import "./chunk-NDQL4ESR.js";
40
+ import "./chunk-RD7EJI7H.js";
38
41
  import {
39
42
  decodeStoredConversationEvent,
40
43
  getDb,
41
44
  getSqlExecutor
42
- } from "./chunk-QIALGHRN.js";
45
+ } from "./chunk-FIGAF6KL.js";
43
46
  import {
44
47
  juniorConversationEvents,
45
48
  juniorConversations,
@@ -47,7 +50,7 @@ import {
47
50
  juniorUsers
48
51
  } from "./chunk-JQFJO5WH.js";
49
52
  import "./chunk-4ZNGQH7C.js";
50
- import "./chunk-PK4ETCUQ.js";
53
+ import "./chunk-ZGXH3REA.js";
51
54
  import {
52
55
  juniorDestinations
53
56
  } from "./chunk-VFUK3X5B.js";
@@ -55,11 +58,11 @@ import {
55
58
  canExposeConversationPayload,
56
59
  parseSlackThreadId
57
60
  } from "./chunk-6Y5L4BOM.js";
58
- import "./chunk-CSS7JHEM.js";
61
+ import "./chunk-4FUEG3QY.js";
59
62
  import "./chunk-42WRQLJ6.js";
60
63
  import "./chunk-6GWA276C.js";
61
- import "./chunk-AU2JVUDF.js";
62
- import "./chunk-IV2O4HQJ.js";
64
+ import "./chunk-5CZ7RETL.js";
65
+ import "./chunk-PM3PX42K.js";
63
66
  import "./chunk-MLKGABMK.js";
64
67
 
65
68
  // src/api.ts
@@ -156,9 +159,6 @@ var archive_default = defineApiRoute({
156
159
  }
157
160
  });
158
161
 
159
- // src/api/conversations/detail.ts
160
- import { and as and5, asc as asc2, eq as eq6, getTableColumns, inArray as inArray3, sql as sql3 } from "drizzle-orm";
161
-
162
162
  // src/chat/pi/sql-model-usage.ts
163
163
  import { and as and2, eq as eq2, sql } from "drizzle-orm";
164
164
  var message = sql`${juniorConversationEvents.payload}->'message'`;
@@ -275,14 +275,74 @@ async function readConversationModelUsageFromSql(executor, options) {
275
275
  });
276
276
  }
277
277
 
278
- // src/api/conversations/events.ts
278
+ // src/api/conversations/cursor.ts
279
+ import { createHmac, timingSafeEqual } from "crypto";
279
280
  import { z } from "zod";
281
+ var CURSOR_CONTEXT = "junior-conversation-report-cursor";
282
+ var conversationCursorPayloadSchema = z.object({
283
+ conversationId: z.string().min(1),
284
+ seq: z.number().int().min(-1),
285
+ version: z.literal(1)
286
+ }).strict();
287
+ function cursorSecret() {
288
+ const secret = process.env.JUNIOR_SECRET?.trim();
289
+ if (!secret) {
290
+ throw new Error("Cannot sign conversation cursor without JUNIOR_SECRET");
291
+ }
292
+ return secret;
293
+ }
294
+ function signature(payload) {
295
+ return createHmac("sha256", cursorSecret()).update(`${CURSOR_CONTEXT}:${payload}`).digest("base64url");
296
+ }
297
+ function encodeConversationCursor(payload) {
298
+ const encoded = Buffer.from(
299
+ JSON.stringify({ ...payload, version: 1 }),
300
+ "utf8"
301
+ ).toString("base64url");
302
+ return `${encoded}.${signature(encoded)}`;
303
+ }
304
+ function decodeConversationCursor(args) {
305
+ const [encoded, actualSignature, extra] = args.cursor.split(".");
306
+ if (!encoded || !actualSignature || extra !== void 0) return void 0;
307
+ const expected = Buffer.from(signature(encoded));
308
+ const actual = Buffer.from(actualSignature);
309
+ if (expected.length !== actual.length || !timingSafeEqual(expected, actual)) {
310
+ return void 0;
311
+ }
312
+ try {
313
+ const parsed = conversationCursorPayloadSchema.parse(
314
+ JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"))
315
+ );
316
+ if (parsed.conversationId !== args.conversationId) {
317
+ return void 0;
318
+ }
319
+ return { seq: parsed.seq };
320
+ } catch {
321
+ return void 0;
322
+ }
323
+ }
324
+
325
+ // src/api/conversations/event-page.ts
326
+ import {
327
+ and as and3,
328
+ asc,
329
+ desc,
330
+ eq as eq3,
331
+ getTableColumns,
332
+ inArray,
333
+ lt,
334
+ sql as sql2
335
+ } from "drizzle-orm";
336
+
337
+ // src/api/conversations/events.ts
338
+ import { z as z2 } from "zod";
280
339
  var conversationReportSourceEventTypes = [
281
340
  "message",
282
341
  "message_handled",
283
342
  "agent_step",
284
343
  "tool_execution_started",
285
344
  "turn_started",
345
+ "turn_routed",
286
346
  "turn_completed",
287
347
  "turn_failed",
288
348
  "compaction",
@@ -290,31 +350,33 @@ var conversationReportSourceEventTypes = [
290
350
  "subagent_started",
291
351
  "subagent_ended"
292
352
  ];
293
- var reportingAssistantMessageSchema = z.object({
294
- role: z.literal("assistant"),
295
- content: z.array(z.unknown())
353
+ var reportingAssistantMessageSchema = z2.object({
354
+ role: z2.literal("assistant"),
355
+ content: z2.array(z2.unknown())
296
356
  }).passthrough();
297
- var reportingToolCallPartSchema = z.object({
298
- type: z.literal("toolCall"),
299
- id: z.string().min(1),
300
- name: z.string().min(1),
301
- arguments: z.unknown()
357
+ var reportingToolCallPartSchema = z2.object({
358
+ type: z2.literal("toolCall"),
359
+ id: z2.string().min(1),
360
+ name: z2.string().min(1),
361
+ arguments: z2.unknown()
302
362
  }).passthrough();
303
- var reportingToolResultMessageSchema = z.object({
304
- role: z.literal("toolResult"),
305
- toolCallId: z.string().min(1),
306
- content: z.array(z.unknown()),
307
- details: z.unknown().optional(),
308
- isError: z.boolean().optional()
363
+ var reportingToolResultMessageSchema = z2.object({
364
+ role: z2.literal("toolResult"),
365
+ toolCallId: z2.string().min(1),
366
+ toolName: z2.string().min(1).optional(),
367
+ name: z2.string().min(1).optional(),
368
+ content: z2.array(z2.unknown()),
369
+ details: z2.unknown().optional(),
370
+ isError: z2.boolean().optional()
309
371
  }).passthrough();
310
- var reportingToolResultDetailsSchema = z.object({
311
- ok: z.boolean().optional(),
312
- status: z.string().optional()
372
+ var reportingToolResultDetailsSchema = z2.object({
373
+ ok: z2.boolean().optional(),
374
+ status: z2.string().optional()
313
375
  }).passthrough();
314
- var reportingTextPartSchema = z.object({ type: z.literal("text"), text: z.string() }).passthrough();
315
- var reportingMediaPartSchema = z.object({
316
- type: z.enum(["image", "audio"]),
317
- mimeType: z.string().min(1).optional()
376
+ var reportingTextPartSchema = z2.object({ type: z2.literal("text"), text: z2.string() }).passthrough();
377
+ var reportingMediaPartSchema = z2.object({
378
+ type: z2.enum(["image", "audio"]),
379
+ mimeType: z2.string().min(1).optional()
318
380
  }).passthrough();
319
381
  function sanitizeModelContentPart(value) {
320
382
  const text = reportingTextPartSchema.safeParse(value);
@@ -343,6 +405,9 @@ function reportToolCalls(args) {
343
405
  {
344
406
  toolCallId: call.data.id,
345
407
  name: call.data.name,
408
+ status: "running",
409
+ startedAt: new Date(args.createdAtMs).toISOString(),
410
+ startedSeq: args.seq,
346
411
  ...args.canExposePayload && call.data.arguments !== void 0 ? { input: call.data.arguments } : {}
347
412
  }
348
413
  ];
@@ -357,13 +422,37 @@ function reportToolResult(args) {
357
422
  );
358
423
  const outcome = message2.data.isError === true || details.success && (details.data.ok === false || details.data.status === "error") ? "error" : "completed";
359
424
  const output = modelVisibleToolOutput(message2.data.content);
425
+ const name = message2.data.toolName ?? message2.data.name ?? args.start?.name;
426
+ if (!name) return void 0;
360
427
  return {
361
- type: "tool_result",
362
- toolCallId: message2.data.toolCallId,
363
- outcome,
364
- ...args.canExposePayload && output !== void 0 ? { output } : {}
428
+ type: "tool_calls",
429
+ calls: [
430
+ {
431
+ toolCallId: message2.data.toolCallId,
432
+ name,
433
+ status: outcome,
434
+ ...args.start ? {
435
+ startedAt: new Date(args.start.createdAtMs).toISOString(),
436
+ startedSeq: args.start.seq
437
+ } : {},
438
+ ...args.canExposePayload && output !== void 0 ? { output } : {}
439
+ }
440
+ ]
365
441
  };
366
442
  }
443
+ function conversationReportToolResultIds(events) {
444
+ return [
445
+ ...new Set(
446
+ events.flatMap((event) => {
447
+ if (event.data.type !== "agent_step") return [];
448
+ const result = reportingToolResultMessageSchema.safeParse(
449
+ event.data.message
450
+ );
451
+ return result.success ? [result.data.toolCallId] : [];
452
+ })
453
+ )
454
+ ];
455
+ }
367
456
  function reportEventData(args) {
368
457
  const { data } = args;
369
458
  switch (data.type) {
@@ -386,6 +475,16 @@ function reportEventData(args) {
386
475
  turnId: data.turnId,
387
476
  state: "started"
388
477
  };
478
+ case "turn_routed":
479
+ return {
480
+ type: "turn_routed",
481
+ turnId: data.turnId,
482
+ modelProfile: data.modelProfile,
483
+ modelId: data.modelId,
484
+ reasoningLevel: data.reasoningLevel,
485
+ ...data.confidence !== void 0 ? { confidence: data.confidence } : {},
486
+ source: data.source
487
+ };
389
488
  case "turn_completed":
390
489
  return {
391
490
  type: "turn_lifecycle",
@@ -400,44 +499,105 @@ function reportEventData(args) {
400
499
  failureKind: data.failureCode === "delivery_failed" ? "delivery" : "agent"
401
500
  };
402
501
  case "compaction":
403
- return { type: "compaction" };
502
+ return {
503
+ type: "compaction",
504
+ modelProfile: data.modelProfile,
505
+ modelId: data.modelId,
506
+ ...data.details ? { details: data.details } : {}
507
+ };
404
508
  default:
405
509
  return void 0;
406
510
  }
407
511
  }
408
- function projectConversationReportEvents(args) {
512
+ function projectConversationReportEventPage(args) {
409
513
  const subagentStarts = /* @__PURE__ */ new Map();
514
+ for (const event of args.subagentStartEvents ?? []) {
515
+ if (event.data.type === "subagent_started") {
516
+ subagentStarts.set(event.data.subagentInvocationId, {
517
+ createdAtMs: event.createdAtMs,
518
+ data: event.data,
519
+ seq: event.seq
520
+ });
521
+ }
522
+ }
523
+ const toolStarts = /* @__PURE__ */ new Map();
524
+ for (const event of args.toolStartEvents ?? []) {
525
+ if (event.data.type === "tool_execution_started") {
526
+ const current = toolStarts.get(event.data.toolCallId);
527
+ if (!current || event.seq < current.seq) {
528
+ toolStarts.set(event.data.toolCallId, {
529
+ createdAtMs: event.createdAtMs,
530
+ name: event.data.toolName,
531
+ seq: event.seq
532
+ });
533
+ }
534
+ }
535
+ }
410
536
  const projected = [];
411
537
  for (const event of args.events) {
412
538
  let data;
413
539
  if (event.data.type === "agent_step") {
414
540
  const reportArgs = {
415
541
  canExposePayload: args.canExposePayload,
416
- message: event.data.message
542
+ createdAtMs: event.createdAtMs,
543
+ message: event.data.message,
544
+ seq: event.seq
417
545
  };
418
- data = reportToolCalls(reportArgs) ?? reportToolResult(reportArgs);
546
+ const result = reportingToolResultMessageSchema.safeParse(
547
+ event.data.message
548
+ );
549
+ const start = result.success ? toolStarts.get(result.data.toolCallId) : void 0;
550
+ data = reportToolCalls(reportArgs) ?? reportToolResult({
551
+ canExposePayload: args.canExposePayload,
552
+ message: event.data.message,
553
+ ...start && start.seq < event.seq ? { start } : {}
554
+ });
419
555
  } else if (event.data.type === "tool_execution_started") {
556
+ toolStarts.set(event.data.toolCallId, {
557
+ createdAtMs: event.createdAtMs,
558
+ name: event.data.toolName,
559
+ seq: event.seq
560
+ });
420
561
  data = {
421
- type: "tool_started",
422
- toolCallId: event.data.toolCallId,
423
- name: event.data.toolName
562
+ type: "tool_calls",
563
+ calls: [
564
+ {
565
+ toolCallId: event.data.toolCallId,
566
+ name: event.data.toolName,
567
+ status: "running",
568
+ startedAt: new Date(event.createdAtMs).toISOString(),
569
+ startedSeq: event.seq
570
+ }
571
+ ]
424
572
  };
425
573
  } else if (event.data.type === "subagent_started") {
426
- subagentStarts.set(event.data.subagentInvocationId, event.seq);
574
+ subagentStarts.set(event.data.subagentInvocationId, {
575
+ createdAtMs: event.createdAtMs,
576
+ data: event.data,
577
+ seq: event.seq
578
+ });
427
579
  data = {
428
- type: "subagent_started",
580
+ type: "subagent",
581
+ startedSeq: event.seq,
582
+ startedAt: new Date(event.createdAtMs).toISOString(),
429
583
  childConversationId: event.data.childConversationId,
430
584
  subagentKind: event.data.subagentKind,
585
+ status: "running",
431
586
  ...event.data.parentToolCallId ? { parentToolCallId: event.data.parentToolCallId } : {}
432
587
  };
433
588
  } else if (event.data.type === "subagent_ended") {
434
- const startedSeq = subagentStarts.get(event.data.subagentInvocationId);
435
- if (startedSeq !== void 0) {
589
+ const started = subagentStarts.get(event.data.subagentInvocationId);
590
+ if (started && started.seq < event.seq) {
436
591
  data = {
437
- type: "subagent_ended",
438
- startedSeq,
439
- outcome: event.data.outcome
592
+ type: "subagent",
593
+ startedSeq: started.seq,
594
+ startedAt: new Date(started.createdAtMs).toISOString(),
595
+ childConversationId: started.data.childConversationId,
596
+ subagentKind: started.data.subagentKind,
597
+ ...started.data.parentToolCallId ? { parentToolCallId: started.data.parentToolCallId } : {},
598
+ status: event.data.outcome === "success" ? "completed" : event.data.outcome
440
599
  };
600
+ subagentStarts.delete(event.data.subagentInvocationId);
441
601
  }
442
602
  } else if (event.data.type === "handoff") {
443
603
  data = {
@@ -465,8 +625,116 @@ function projectConversationReportEvents(args) {
465
625
  return projected;
466
626
  }
467
627
 
628
+ // src/api/conversations/event-page.ts
629
+ var conversationEventColumns = getTableColumns(juniorConversationEvents);
630
+ var MIN_SCAN_SIZE = 64;
631
+ async function readConversationEventRows(executor, args) {
632
+ return executor.db().select({
633
+ ...conversationEventColumns,
634
+ // Replacement history is model context, never dashboard report data.
635
+ payload: sql2`case
636
+ when ${juniorConversationEvents.type} in ('compaction', 'handoff')
637
+ then jsonb_set(
638
+ ${juniorConversationEvents.payload},
639
+ '{replacementHistory}',
640
+ '[]'::jsonb
641
+ )
642
+ else ${juniorConversationEvents.payload}
643
+ end`
644
+ }).from(juniorConversationEvents).where(
645
+ and3(
646
+ eq3(juniorConversationEvents.conversationId, args.conversationId),
647
+ args.beforeSeq === void 0 ? void 0 : lt(juniorConversationEvents.seq, args.beforeSeq),
648
+ inArray(
649
+ juniorConversationEvents.type,
650
+ args.types ?? [...conversationReportSourceEventTypes]
651
+ ),
652
+ args.subagentInvocationIds === void 0 ? void 0 : inArray(
653
+ sql2`${juniorConversationEvents.payload}->>'subagentInvocationId'`,
654
+ args.subagentInvocationIds
655
+ ),
656
+ args.toolCallIds === void 0 ? void 0 : inArray(
657
+ sql2`${juniorConversationEvents.payload}->>'toolCallId'`,
658
+ args.toolCallIds
659
+ )
660
+ )
661
+ ).orderBy(
662
+ args.direction === "forward" ? asc(juniorConversationEvents.seq) : desc(juniorConversationEvents.seq)
663
+ ).limit(args.limit);
664
+ }
665
+ function decodeConversationEventRow(row) {
666
+ return decodeStoredConversationEvent({
667
+ schemaVersion: row.schemaVersion,
668
+ seq: row.seq,
669
+ historyVersion: row.historyVersion,
670
+ ...row.idempotencyKey ? { idempotencyKey: row.idempotencyKey } : {},
671
+ createdAtMs: row.createdAt.getTime(),
672
+ type: row.type,
673
+ payload: row.payload
674
+ });
675
+ }
676
+ async function projectConversationEventRows(executor, args) {
677
+ const events = args.rows.map(decodeConversationEventRow).sort((left, right) => left.seq - right.seq);
678
+ const endedInvocationIds = [
679
+ ...new Set(
680
+ events.flatMap(
681
+ (event) => event.data.type === "subagent_ended" ? [event.data.subagentInvocationId] : []
682
+ )
683
+ )
684
+ ];
685
+ const subagentStartRows = endedInvocationIds.length === 0 ? [] : await readConversationEventRows(executor, {
686
+ conversationId: args.conversationId,
687
+ direction: "forward",
688
+ limit: endedInvocationIds.length,
689
+ subagentInvocationIds: endedInvocationIds,
690
+ types: ["subagent_started"]
691
+ });
692
+ const toolResultIds = conversationReportToolResultIds(events);
693
+ const toolStartRows = toolResultIds.length === 0 ? [] : await readConversationEventRows(executor, {
694
+ conversationId: args.conversationId,
695
+ direction: "forward",
696
+ limit: toolResultIds.length,
697
+ toolCallIds: toolResultIds,
698
+ types: ["tool_execution_started"]
699
+ });
700
+ return projectConversationReportEventPage({
701
+ canExposePayload: args.canExposePayload,
702
+ events,
703
+ subagentStartEvents: subagentStartRows.map(decodeConversationEventRow),
704
+ toolStartEvents: toolStartRows.map(decodeConversationEventRow)
705
+ });
706
+ }
707
+ async function readConversationEventPage(executor, args) {
708
+ const scanSize = Math.max(args.limit + 1, MIN_SCAN_SIZE);
709
+ const rows = [];
710
+ let beforeSeq = args.beforeSeq;
711
+ let projected = [];
712
+ while (projected.length <= args.limit) {
713
+ const batch = await readConversationEventRows(executor, {
714
+ beforeSeq,
715
+ conversationId: args.conversationId,
716
+ direction: "backward",
717
+ limit: scanSize
718
+ });
719
+ if (batch.length === 0) break;
720
+ rows.push(...batch);
721
+ projected = await projectConversationEventRows(executor, {
722
+ canExposePayload: args.canExposePayload,
723
+ conversationId: args.conversationId,
724
+ rows
725
+ });
726
+ if (projected.length > args.limit || batch.length < scanSize) break;
727
+ beforeSeq = batch.at(-1).seq;
728
+ }
729
+ const events = projected.slice(-args.limit);
730
+ return {
731
+ events,
732
+ ...projected.length > events.length && events[0] ? { previousSeq: events[0].seq } : {}
733
+ };
734
+ }
735
+
468
736
  // src/api/conversations/list.ts
469
- import { and as and4, asc, desc, eq as eq5, isNull as isNull2 } from "drizzle-orm";
737
+ import { and as and5, asc as asc2, desc as desc2, eq as eq6, isNull as isNull2 } from "drizzle-orm";
470
738
 
471
739
  // src/api/conversations/shared.ts
472
740
  function slackStatsLocationLabel(input) {
@@ -566,6 +834,15 @@ function channelNameRedactedFromConversation(conversation, canViewPrivateContent
566
834
  }
567
835
  return !canViewPrivateContent;
568
836
  }
837
+ function conversationEventHistory(args) {
838
+ if (args.transcriptPurgedAtMs !== void 0) {
839
+ return {
840
+ status: "expired",
841
+ expiredAt: new Date(args.transcriptPurgedAtMs).toISOString()
842
+ };
843
+ }
844
+ return args.canExposePayload ? { status: "available" } : { status: "redacted", reason: "non_public_conversation" };
845
+ }
569
846
  function conversationSummaryFromStoredConversation(args) {
570
847
  const { conversation, durationMs, usage: usage3 } = args;
571
848
  const canViewPrivateContent = args.access?.canViewPrivateContent ?? false;
@@ -610,7 +887,7 @@ function conversationSummaryFromStoredConversation(args) {
610
887
  }
611
888
 
612
889
  // src/api/conversations/access.ts
613
- import { eq as eq3, inArray } from "drizzle-orm";
890
+ import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
614
891
  import { alias } from "drizzle-orm/pg-core";
615
892
  var rootConversation = alias(juniorConversations, "access_root_conversation");
616
893
  var rootDestination = alias(juniorDestinations, "access_root_destination");
@@ -630,17 +907,17 @@ async function readConversationAccessFromSql(db, conversationIds, verifiedViewer
630
907
  rootEmailVerified: rootIdentity.emailVerified
631
908
  }).from(juniorConversations).leftJoin(
632
909
  rootConversation,
633
- eq3(
910
+ eq4(
634
911
  rootConversation.conversationId,
635
912
  juniorConversations.rootConversationId
636
913
  )
637
914
  ).leftJoin(
638
915
  rootDestination,
639
- eq3(rootDestination.id, rootConversation.destinationId)
916
+ eq4(rootDestination.id, rootConversation.destinationId)
640
917
  ).leftJoin(
641
918
  rootIdentity,
642
- eq3(rootIdentity.id, rootConversation.actorIdentityId)
643
- ).where(inArray(juniorConversations.conversationId, [...conversationIds]));
919
+ eq4(rootIdentity.id, rootConversation.actorIdentityId)
920
+ ).where(inArray2(juniorConversations.conversationId, [...conversationIds]));
644
921
  return new Map(
645
922
  rows.map((row) => {
646
923
  const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
@@ -664,7 +941,7 @@ async function readConversationAccessFromSql(db, conversationIds, verifiedViewer
664
941
  }
665
942
 
666
943
  // src/api/conversations/usage.ts
667
- import { and as and3, eq as eq4, inArray as inArray2, isNull, sql as sql2 } from "drizzle-orm";
944
+ import { and as and4, eq as eq5, inArray as inArray3, isNull, sql as sql3 } from "drizzle-orm";
668
945
  import { alias as alias2 } from "drizzle-orm/pg-core";
669
946
  var usage2 = juniorConversations.usage;
670
947
  var metricRootConversation = alias2(
@@ -678,10 +955,10 @@ var componentFields = [
678
955
  "cacheCreationTokens"
679
956
  ];
680
957
  function summedUsageNumber(field) {
681
- return sql2`sum((${usage2}->>${field})::double precision)::double precision`;
958
+ return sql3`sum((${usage2}->>${field})::double precision)::double precision`;
682
959
  }
683
960
  function summedCostNumber(field) {
684
- return sql2`round(
961
+ return sql3`round(
685
962
  sum((${usage2}->'cost'->>${field})::numeric),
686
963
  12
687
964
  )::double precision`;
@@ -711,7 +988,7 @@ function usageFromAggregate(row) {
711
988
  }
712
989
  async function readRootConversationMetricsFromSql(db, rootConversationIds) {
713
990
  if (rootConversationIds.length === 0) return /* @__PURE__ */ new Map();
714
- const hasComponents = sql2`coalesce(
991
+ const hasComponents = sql3`coalesce(
715
992
  ${usage2}->>'inputTokens',
716
993
  ${usage2}->>'outputTokens',
717
994
  ${usage2}->>'cachedInputTokens',
@@ -719,12 +996,12 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
719
996
  ) is not null`;
720
997
  const rows = await db.select({
721
998
  rootConversationId: juniorConversations.rootConversationId,
722
- durationMs: sql2`coalesce(sum(${juniorConversations.durationMs}), 0)::double precision`,
999
+ durationMs: sql3`coalesce(sum(${juniorConversations.durationMs}), 0)::double precision`,
723
1000
  inputTokens: summedUsageNumber("inputTokens"),
724
1001
  outputTokens: summedUsageNumber("outputTokens"),
725
1002
  cachedInputTokens: summedUsageNumber("cachedInputTokens"),
726
1003
  cacheCreationTokens: summedUsageNumber("cacheCreationTokens"),
727
- totalOnlyTokens: sql2`sum(
1004
+ totalOnlyTokens: sql3`sum(
728
1005
  case
729
1006
  when not (${hasComponents})
730
1007
  then (${usage2}->>'totalTokens')::double precision
@@ -738,19 +1015,19 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
738
1015
  costTotal: summedCostNumber("total")
739
1016
  }).from(juniorConversations).innerJoin(
740
1017
  metricRootConversation,
741
- and3(
742
- eq4(
1018
+ and4(
1019
+ eq5(
743
1020
  metricRootConversation.conversationId,
744
1021
  juniorConversations.rootConversationId
745
1022
  ),
746
1023
  isNull(metricRootConversation.parentConversationId),
747
- eq4(
1024
+ eq5(
748
1025
  metricRootConversation.rootConversationId,
749
1026
  metricRootConversation.conversationId
750
1027
  )
751
1028
  )
752
1029
  ).where(
753
- inArray2(juniorConversations.rootConversationId, [...rootConversationIds])
1030
+ inArray3(juniorConversations.rootConversationId, [...rootConversationIds])
754
1031
  ).groupBy(juniorConversations.rootConversationId);
755
1032
  return new Map(
756
1033
  rows.flatMap((row) => {
@@ -782,22 +1059,22 @@ async function conversationRows(db, limit, actorEmail) {
782
1059
  userDisplayName: juniorUsers.displayName
783
1060
  }).from(juniorConversations).leftJoin(
784
1061
  juniorDestinations,
785
- eq5(juniorDestinations.id, juniorConversations.destinationId)
1062
+ eq6(juniorDestinations.id, juniorConversations.destinationId)
786
1063
  ).leftJoin(
787
1064
  juniorIdentities,
788
- eq5(juniorIdentities.id, juniorConversations.actorIdentityId)
789
- ).leftJoin(juniorUsers, eq5(juniorUsers.id, juniorIdentities.userId)).where(
790
- and4(
1065
+ eq6(juniorIdentities.id, juniorConversations.actorIdentityId)
1066
+ ).leftJoin(juniorUsers, eq6(juniorUsers.id, juniorIdentities.userId)).where(
1067
+ and5(
791
1068
  isNull2(juniorConversations.parentConversationId),
792
1069
  isNull2(juniorConversations.archivedAt),
793
- actorEmail ? and4(
794
- eq5(juniorIdentities.emailNormalized, actorEmail),
795
- eq5(juniorIdentities.emailVerified, true)
1070
+ actorEmail ? and5(
1071
+ eq6(juniorIdentities.emailNormalized, actorEmail),
1072
+ eq6(juniorIdentities.emailVerified, true)
796
1073
  ) : void 0
797
1074
  )
798
1075
  ).orderBy(
799
- desc(juniorConversations.lastActivityAt),
800
- asc(juniorConversations.conversationId)
1076
+ desc2(juniorConversations.lastActivityAt),
1077
+ asc2(juniorConversations.conversationId)
801
1078
  ).limit(limit);
802
1079
  }
803
1080
  function conversationFromRow(row) {
@@ -845,11 +1122,11 @@ async function readConversationRecordFromSql(conversationId) {
845
1122
  userDisplayName: juniorUsers.displayName
846
1123
  }).from(juniorConversations).leftJoin(
847
1124
  juniorDestinations,
848
- eq5(juniorDestinations.id, juniorConversations.destinationId)
1125
+ eq6(juniorDestinations.id, juniorConversations.destinationId)
849
1126
  ).leftJoin(
850
1127
  juniorIdentities,
851
- eq5(juniorIdentities.id, juniorConversations.actorIdentityId)
852
- ).leftJoin(juniorUsers, eq5(juniorUsers.id, juniorIdentities.userId)).where(eq5(juniorConversations.conversationId, conversationId)).limit(1);
1128
+ eq6(juniorIdentities.id, juniorConversations.actorIdentityId)
1129
+ ).leftJoin(juniorUsers, eq6(juniorUsers.id, juniorIdentities.userId)).where(eq6(juniorConversations.conversationId, conversationId)).limit(1);
853
1130
  const row = rows[0];
854
1131
  return row ? {
855
1132
  conversation: conversationFromRow(row),
@@ -914,35 +1191,11 @@ var list_default = defineApiRoute({
914
1191
  });
915
1192
 
916
1193
  // src/api/conversations/detail.ts
917
- var conversationEventColumns = getTableColumns(juniorConversationEvents);
918
- async function readConversationReportEventRows(executor, conversationId) {
919
- return executor.db().select({
920
- ...conversationEventColumns,
921
- // Replacement history is model context, never dashboard report data.
922
- payload: sql3`case
923
- when ${juniorConversationEvents.type} in ('compaction', 'handoff')
924
- then jsonb_set(
925
- ${juniorConversationEvents.payload},
926
- '{replacementHistory}',
927
- '[]'::jsonb
928
- )
929
- else ${juniorConversationEvents.payload}
930
- end`
931
- }).from(juniorConversationEvents).where(
932
- and5(
933
- eq6(juniorConversationEvents.conversationId, conversationId),
934
- inArray3(juniorConversationEvents.type, [
935
- ...conversationReportSourceEventTypes
936
- ])
937
- )
938
- ).orderBy(asc2(juniorConversationEvents.seq));
939
- }
940
1194
  function projectConversationDetail(args) {
941
1195
  const { conversation } = args;
942
1196
  const conversationId = conversation.conversationId;
943
1197
  const transcriptPurgedAtMs = conversation.transcriptPurgedAtMs;
944
1198
  const canExposePayload = args.access?.canViewPrivateContent ?? false;
945
- const events = transcriptPurgedAtMs === void 0 ? args.events : [];
946
1199
  const modelUsage = transcriptPurgedAtMs === void 0 ? args.modelUsage : [];
947
1200
  const sentryConversationUrl = buildSentryConversationUrl(conversationId);
948
1201
  return {
@@ -953,15 +1206,18 @@ function projectConversationDetail(args) {
953
1206
  ...args.locationId ? { locationId: args.locationId } : {},
954
1207
  usage: args.usage
955
1208
  }),
956
- events: projectConversationReportEvents({ canExposePayload, events }),
1209
+ events: args.events,
1210
+ ...args.previousSeq !== void 0 ? {
1211
+ previousCursor: encodeConversationCursor({
1212
+ conversationId,
1213
+ seq: args.previousSeq
1214
+ })
1215
+ } : {},
957
1216
  ...modelUsage.length > 0 ? { modelUsage } : {},
958
- eventHistory: transcriptPurgedAtMs !== void 0 ? {
959
- status: "expired",
960
- expiredAt: new Date(transcriptPurgedAtMs).toISOString()
961
- } : canExposePayload ? { status: "available" } : {
962
- status: "redacted",
963
- reason: "non_public_conversation"
964
- },
1217
+ eventHistory: conversationEventHistory({
1218
+ canExposePayload,
1219
+ ...transcriptPurgedAtMs === void 0 ? {} : { transcriptPurgedAtMs }
1220
+ }),
965
1221
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
966
1222
  ...sentryConversationUrl ? { sentryConversationUrl } : {}
967
1223
  };
@@ -971,13 +1227,12 @@ async function readConversationDetailFromSql(conversationId, options) {
971
1227
  if (!record) return void 0;
972
1228
  const executor = getSqlExecutor();
973
1229
  const includeDescendantMetrics = record.rootConversationId === conversationId;
974
- const [accessByConversation, eventRows, modelUsage, metricsByRoot] = await Promise.all([
1230
+ const [accessByConversation, modelUsage, metricsByRoot] = await Promise.all([
975
1231
  readConversationAccessFromSql(
976
1232
  getDb(),
977
1233
  [conversationId],
978
1234
  options.verifiedViewerEmail
979
1235
  ),
980
- readConversationReportEventRows(executor, conversationId),
981
1236
  record.conversation.transcriptPurgedAtMs === void 0 ? readConversationModelUsageFromSql(executor, {
982
1237
  conversationId,
983
1238
  includeDescendants: includeDescendantMetrics
@@ -987,29 +1242,28 @@ async function readConversationDetailFromSql(conversationId, options) {
987
1242
  includeDescendantMetrics ? [conversationId] : []
988
1243
  )
989
1244
  ]);
990
- const events = eventRows.map(
991
- (row) => decodeStoredConversationEvent({
992
- schemaVersion: row.schemaVersion,
993
- seq: row.seq,
994
- historyVersion: row.historyVersion,
995
- ...row.idempotencyKey ? { idempotencyKey: row.idempotencyKey } : {},
996
- createdAtMs: row.createdAt.getTime(),
997
- type: row.type,
998
- payload: row.payload
999
- })
1000
- );
1245
+ const access = accessByConversation.get(conversationId);
1246
+ const page = record.conversation.transcriptPurgedAtMs === void 0 ? await readConversationEventPage(executor, {
1247
+ canExposePayload: access?.canViewPrivateContent ?? false,
1248
+ conversationId,
1249
+ limit: options.limit
1250
+ }) : { events: [] };
1001
1251
  const metrics = metricsByRoot.get(conversationId);
1002
1252
  return projectConversationDetail({
1003
1253
  ...record,
1004
- access: accessByConversation.get(conversationId),
1254
+ access,
1005
1255
  durationMs: metrics?.durationMs ?? record.durationMs,
1006
- events,
1256
+ events: page.events,
1007
1257
  modelUsage,
1258
+ ...page.previousSeq === void 0 ? {} : { previousSeq: page.previousSeq },
1008
1259
  usage: metrics?.usage ?? record.usage ?? void 0
1009
1260
  });
1010
1261
  }
1011
1262
  async function readConversationDetail(conversationId, options = {}) {
1012
- const report = await readConversationDetailFromSql(conversationId, options);
1263
+ const report = await readConversationDetailFromSql(conversationId, {
1264
+ ...options,
1265
+ limit: options.limit ?? 500
1266
+ });
1013
1267
  return report ? conversationDetailReportSchema.parse(report) : void 0;
1014
1268
  }
1015
1269
  var detail_default = defineApiRoute({
@@ -1021,11 +1275,73 @@ var detail_default = defineApiRoute({
1021
1275
  conversationParamsSchema,
1022
1276
  c.req.param()
1023
1277
  );
1278
+ const query = parseQuery(conversationDetailQuerySchema, c.req.query());
1024
1279
  const verifiedViewerEmail = c.get("verifiedViewerEmail");
1025
- const report = await readConversationDetail(
1026
- conversationId,
1027
- verifiedViewerEmail ? { verifiedViewerEmail } : {}
1280
+ const report = await readConversationDetail(conversationId, {
1281
+ ...query,
1282
+ ...verifiedViewerEmail ? { verifiedViewerEmail } : {}
1283
+ });
1284
+ if (!report) throwApiError(404, "Conversation not found.");
1285
+ return report;
1286
+ }
1287
+ });
1288
+
1289
+ // src/api/conversations/event-list.ts
1290
+ async function readConversationEvents(conversationId, beforeValue, options = {}) {
1291
+ const record = await readConversationRecordFromSql(conversationId);
1292
+ if (!record) return void 0;
1293
+ const before = decodeConversationCursor({
1294
+ conversationId,
1295
+ cursor: beforeValue
1296
+ });
1297
+ if (!before) throwApiError(400, "Invalid conversation cursor.");
1298
+ const accessByConversation = await readConversationAccessFromSql(
1299
+ getDb(),
1300
+ [conversationId],
1301
+ options.verifiedViewerEmail
1302
+ );
1303
+ const access = accessByConversation.get(conversationId);
1304
+ const canExposePayload = access?.canViewPrivateContent ?? false;
1305
+ const transcriptPurgedAtMs = record.conversation.transcriptPurgedAtMs;
1306
+ const page = transcriptPurgedAtMs === void 0 ? await readConversationEventPage(getSqlExecutor(), {
1307
+ beforeSeq: before.seq,
1308
+ canExposePayload,
1309
+ conversationId,
1310
+ limit: options.limit ?? 500
1311
+ }) : { events: [] };
1312
+ return conversationEventPageSchema.parse({
1313
+ events: page.events,
1314
+ eventHistory: conversationEventHistory({
1315
+ canExposePayload,
1316
+ ...transcriptPurgedAtMs === void 0 ? {} : { transcriptPurgedAtMs }
1317
+ }),
1318
+ ...page.previousSeq === void 0 ? {} : {
1319
+ previousCursor: encodeConversationCursor({
1320
+ conversationId,
1321
+ seq: page.previousSeq
1322
+ })
1323
+ },
1324
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
1325
+ });
1326
+ }
1327
+ var event_list_default = defineApiRoute({
1328
+ method: "get",
1329
+ path: "/:conversationId/events",
1330
+ responseSchema: conversationEventPageSchema,
1331
+ handler: async (c) => {
1332
+ const { conversationId } = parseParams(
1333
+ conversationParamsSchema,
1334
+ c.req.param()
1028
1335
  );
1336
+ const { before, limit } = parseQuery(
1337
+ conversationEventsQuerySchema,
1338
+ c.req.query()
1339
+ );
1340
+ const verifiedViewerEmail = c.get("verifiedViewerEmail");
1341
+ const report = await readConversationEvents(conversationId, before, {
1342
+ limit,
1343
+ ...verifiedViewerEmail ? { verifiedViewerEmail } : {}
1344
+ });
1029
1345
  if (!report) throwApiError(404, "Conversation not found.");
1030
1346
  return report;
1031
1347
  }
@@ -1325,7 +1641,13 @@ var stats_default = defineApiRoute({
1325
1641
  });
1326
1642
 
1327
1643
  // src/api/conversations/routes.ts
1328
- var routes = [list_default, stats_default, archive_default, detail_default];
1644
+ var routes = [
1645
+ list_default,
1646
+ stats_default,
1647
+ archive_default,
1648
+ event_list_default,
1649
+ detail_default
1650
+ ];
1329
1651
  function createConversationRoutes() {
1330
1652
  const app = new Hono();
1331
1653
  registerApiRoutes(app, routes);
@@ -1336,7 +1658,7 @@ function createConversationRoutes() {
1336
1658
  import { Hono as Hono2 } from "hono";
1337
1659
 
1338
1660
  // src/api/locations/query.ts
1339
- import { and as and7, asc as asc3, desc as desc2, eq as eq8, gte as gte2, isNull as isNull4, sql as sql6 } from "drizzle-orm";
1661
+ import { and as and7, asc as asc3, desc as desc3, eq as eq8, gte as gte2, isNull as isNull4, sql as sql6 } from "drizzle-orm";
1340
1662
  import { alias as alias4 } from "drizzle-orm/pg-core";
1341
1663
 
1342
1664
  // src/api/conversations/reporting.ts
@@ -1622,7 +1944,7 @@ async function recentLocationRows(db, locationId) {
1622
1944
  isNull4(juniorConversations.archivedAt)
1623
1945
  )
1624
1946
  ).orderBy(
1625
- desc2(juniorConversations.lastActivityAt),
1947
+ desc3(juniorConversations.lastActivityAt),
1626
1948
  asc3(juniorConversations.conversationId)
1627
1949
  ).limit(RECENT_LIMIT);
1628
1950
  }
@@ -1803,7 +2125,7 @@ import { Hono as Hono3 } from "hono";
1803
2125
  import { and as and9, eq as eq10, gte as gte3, sql as sql8 } from "drizzle-orm";
1804
2126
 
1805
2127
  // src/api/people/shared.ts
1806
- import { and as and8, asc as asc4, desc as desc3, eq as eq9, isNull as isNull5, notExists, or, sql as sql7 } from "drizzle-orm";
2128
+ import { and as and8, asc as asc4, desc as desc4, eq as eq9, isNull as isNull5, notExists, or, sql as sql7 } from "drizzle-orm";
1807
2129
  import { alias as alias5 } from "drizzle-orm/pg-core";
1808
2130
  var RECENT_LIMIT2 = 25;
1809
2131
  var ACTIVITY_DAYS2 = 365;
@@ -1937,7 +2259,7 @@ async function recentActorRows(email) {
1937
2259
  ).where(
1938
2260
  and8(verifiedActorWhere(email), isNull5(juniorConversations.archivedAt))
1939
2261
  ).orderBy(
1940
- desc3(juniorConversations.lastActivityAt),
2262
+ desc4(juniorConversations.lastActivityAt),
1941
2263
  asc4(juniorConversations.conversationId)
1942
2264
  ).limit(RECENT_LIMIT2);
1943
2265
  }
@@ -2257,7 +2579,7 @@ function readDescriptionText(home) {
2257
2579
  }
2258
2580
  }
2259
2581
  async function readSkillReports() {
2260
- const { discoverSkills } = await import("./skills-GWTOZ3XV.js");
2582
+ const { discoverSkills } = await import("./skills-QCNZISNF.js");
2261
2583
  const skills = await discoverSkills();
2262
2584
  return skillReportsSchema.parse(
2263
2585
  skills.map((skill) => ({
@@ -2267,7 +2589,7 @@ async function readSkillReports() {
2267
2589
  );
2268
2590
  }
2269
2591
  async function readPluginReports() {
2270
- const { pluginCatalogRuntime } = await import("./catalog-runtime-UEO25P2J.js");
2592
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-6O4M6JGA.js");
2271
2593
  return pluginReportsSchema.parse(
2272
2594
  pluginCatalogRuntime.getProviders().map((plugin) => ({
2273
2595
  name: plugin.manifest.name
@@ -2277,7 +2599,7 @@ async function readPluginReports() {
2277
2599
  async function readRuntimeInfoReport() {
2278
2600
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
2279
2601
  import("./discovery-RMHYSRL7.js"),
2280
- import("./catalog-runtime-UEO25P2J.js"),
2602
+ import("./catalog-runtime-6O4M6JGA.js"),
2281
2603
  readPluginReports(),
2282
2604
  readSkillReports()
2283
2605
  ]);
@@ -2293,7 +2615,7 @@ async function readRuntimeInfoReport() {
2293
2615
  }
2294
2616
  async function readPluginOperationalReportFeed() {
2295
2617
  const nowMs = Date.now();
2296
- const { getPluginOperationalReports } = await import("./agent-hooks-6MVTPKP4.js");
2618
+ const { getPluginOperationalReports } = await import("./agent-hooks-WNBUY4OB.js");
2297
2619
  return pluginOperationalReportFeedSchema.parse({
2298
2620
  source: "plugins",
2299
2621
  generatedAt: new Date(nowMs).toISOString(),