@sentry/junior 0.194.0 → 0.196.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 (97) hide show
  1. package/dist/{agent-hooks-IDX764FD.js → agent-hooks-IQLRR4RC.js} +13 -13
  2. package/dist/api/activity.d.ts +9 -1
  3. package/dist/api/code/overview.d.ts +12 -0
  4. package/dist/api/locations/detail.d.ts +8 -0
  5. package/dist/api/locations/list.d.ts +5 -0
  6. package/dist/api/people/code.d.ts +6 -0
  7. package/dist/api/people/shared.d.ts +9 -1
  8. package/dist/api/reporting-window.d.ts +39 -1
  9. package/dist/api/schema/code.d.ts +12 -0
  10. package/dist/api/schema/conversation.d.ts +25 -0
  11. package/dist/api/schema/location.d.ts +13 -0
  12. package/dist/api/schema/person.d.ts +14 -0
  13. package/dist/api/schema/task.d.ts +12 -0
  14. package/dist/api/schema.js +3 -3
  15. package/dist/api.js +244 -65
  16. package/dist/app.d.ts +8 -2
  17. package/dist/app.js +166 -70
  18. package/dist/{catalog-runtime-MICXEBLK.js → catalog-runtime-EM7V2F4I.js} +4 -4
  19. package/dist/chat/agent/handoff.d.ts +73 -0
  20. package/dist/chat/config.d.ts +3 -2
  21. package/dist/chat/event-tasks/store.d.ts +27 -17
  22. package/dist/chat/model-profile.d.ts +12 -0
  23. package/dist/chat/no-reply.d.ts +4 -3
  24. package/dist/chat/resource-events/notification.d.ts +2 -1
  25. package/dist/chat/services/automated-turn-limit.d.ts +110 -0
  26. package/dist/chat/services/subscribed-decision.d.ts +8 -0
  27. package/dist/chat/slack/automated-turn-limit-notice.d.ts +38 -0
  28. package/dist/chat/tasks/execution-stats.d.ts +2 -1
  29. package/dist/chat/tasks/read.d.ts +5 -2
  30. package/dist/chat/tools/types.d.ts +6 -2
  31. package/dist/{chunk-U76RWMFR.js → chunk-5XSEOJPC.js} +87 -14
  32. package/dist/{chunk-OEQOAONV.js → chunk-6LQNW2CJ.js} +7 -7
  33. package/dist/{chunk-GFBR4S3Q.js → chunk-7NL7T6VU.js} +1 -1
  34. package/dist/{chunk-CFGBKPWQ.js → chunk-7TUDDW3Y.js} +3 -3
  35. package/dist/{chunk-RFE7DCZK.js → chunk-B5WJBVHY.js} +2 -2
  36. package/dist/{chunk-S7GX44BU.js → chunk-BXIVMNLR.js} +1 -1
  37. package/dist/{chunk-QMEF4Z7R.js → chunk-CNI74T7U.js} +6 -6
  38. package/dist/{chunk-X76JVHQ4.js → chunk-CTS72G4B.js} +1 -1
  39. package/dist/{chunk-G35QGPO2.js → chunk-DFWJJOW3.js} +2 -6
  40. package/dist/{chunk-INTBMGNX.js → chunk-EEUFKVCD.js} +22 -22
  41. package/dist/{chunk-H4DCWLTR.js → chunk-EFNUCRB5.js} +8 -8
  42. package/dist/{chunk-V4HXV5MY.js → chunk-EQBHN4JK.js} +1 -1
  43. package/dist/{chunk-JOI3DHML.js → chunk-ES7KCEND.js} +1 -1
  44. package/dist/{chunk-WWXJUURQ.js → chunk-G6YRPYDC.js} +1 -1
  45. package/dist/{chunk-WMJS5DDV.js → chunk-GZ336GZ5.js} +148 -19
  46. package/dist/{chunk-IME5OW4Y.js → chunk-I7GEGEHZ.js} +1 -1
  47. package/dist/{chunk-2NL3Y47F.js → chunk-J357NJQ5.js} +5 -5
  48. package/dist/{chunk-53IEEFFP.js → chunk-KJGH3KWA.js} +3 -3
  49. package/dist/{chunk-ELCYG6UU.js → chunk-KZX7LORG.js} +3 -3
  50. package/dist/{chunk-YSLIB7ER.js → chunk-LBN67OZR.js} +83 -7
  51. package/dist/{chunk-73JEAQRT.js → chunk-LCAM2P7H.js} +4 -4
  52. package/dist/{chunk-VOB2DKO6.js → chunk-LGXI6PWX.js} +24 -13
  53. package/dist/{chunk-P2P6MUQ4.js → chunk-LSPUMNZK.js} +2 -2
  54. package/dist/{chunk-AWZS5SVX.js → chunk-N2MSPOGG.js} +8 -8
  55. package/dist/{chunk-CCTYK5RH.js → chunk-NE2UQMC7.js} +10 -7
  56. package/dist/{chunk-D4YV5TDV.js → chunk-NHJU2ZAL.js} +11 -0
  57. package/dist/{chunk-G4RARFNT.js → chunk-OVWAO5KY.js} +1194 -726
  58. package/dist/{chunk-XRDSML3K.js → chunk-P3LE2CSJ.js} +2 -2
  59. package/dist/{chunk-KNIAWMBU.js → chunk-PI6VXVBK.js} +1 -1
  60. package/dist/{chunk-XLWZRHX5.js → chunk-PIZJBSGZ.js} +23 -29
  61. package/dist/{chunk-GY5SEFVL.js → chunk-QAINJHI4.js} +5 -5
  62. package/dist/{chunk-XND3J6AT.js → chunk-RAWYH7TW.js} +1 -1
  63. package/dist/{chunk-ENWIHU54.js → chunk-RFNMWONZ.js} +6 -6
  64. package/dist/{chunk-E53C73ML.js → chunk-S74KAE77.js} +4 -4
  65. package/dist/{chunk-7ANA7PBB.js → chunk-SR5FS2JP.js} +3 -3
  66. package/dist/{chunk-F2KSURTJ.js → chunk-VKLQ2M7V.js} +9 -9
  67. package/dist/{chunk-NWWDFHXP.js → chunk-VRHZXY5X.js} +1 -1
  68. package/dist/{chunk-6H2MKVV5.js → chunk-VSOO3Y6M.js} +1 -1
  69. package/dist/{chunk-NPO24LAN.js → chunk-VVU7GHIZ.js} +9 -9
  70. package/dist/{chunk-IOGDKPVU.js → chunk-VXAQTJSR.js} +1 -1
  71. package/dist/{chunk-ADEACKAH.js → chunk-XNXKRWWI.js} +11 -4
  72. package/dist/cli/chat.js +35 -35
  73. package/dist/cli/check.js +5 -5
  74. package/dist/cli/plugins.js +14 -14
  75. package/dist/cli/snapshot-create.js +10 -10
  76. package/dist/cli/upgrade.js +7 -7
  77. package/dist/db/schema/event-tasks.d.ts +21 -0
  78. package/dist/db/schema.d.ts +19 -0
  79. package/dist/{db-3IEVINAY.js → db-YTM7ZXPK.js} +8 -8
  80. package/dist/instrumentation.js +3 -3
  81. package/dist/nitro.js +7 -7
  82. package/dist/{oauth-callback-server-N7L2BB4L.js → oauth-callback-server-OXW4KQLQ.js} +31 -31
  83. package/dist/{runner-PTTZV3WU.js → runner-RJY5RNJO.js} +23 -23
  84. package/dist/{skills-POMWS2RR.js → skills-WZV6NLFY.js} +5 -5
  85. package/dist/spawn-J7SQJLYF.js +42 -0
  86. package/dist/task-runner-SMUQ5464.js +36 -0
  87. package/dist/{validation-U6LOMXR7.js → validation-XS5ZHV3W.js} +5 -5
  88. package/dist/version.js +1 -1
  89. package/dist/{work-FHA3BS4L.js → work-LJMSDEY3.js} +23 -23
  90. package/dist/worker-NMFZ7A2N.js +24 -0
  91. package/migrations/0038_event_task_status.sql +5 -0
  92. package/migrations/meta/0038_snapshot.json +3323 -0
  93. package/migrations/meta/_journal.json +8 -1
  94. package/package.json +4 -4
  95. package/dist/spawn-R75MXXKE.js +0 -42
  96. package/dist/task-runner-OQLRHADB.js +0 -36
  97. package/dist/worker-GR4UNVVP.js +0 -24
package/dist/api.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  DAY_MS,
3
3
  HOUR_MS,
4
+ WINDOW_SEVEN_DAY_HOURS,
4
5
  acceptedConversationMessageSchema,
5
6
  activityDays,
6
7
  activityHours,
8
+ activitySixHours,
7
9
  actorDirectoryReportSchema,
8
10
  actorProfileReportSchema,
9
11
  apiErrorSchema,
@@ -31,6 +33,7 @@ import {
31
33
  deleteWorkspaceResponseSchema,
32
34
  fillUtcDays,
33
35
  fillUtcHours,
36
+ fillUtcSixHours,
34
37
  locationDetailReportSchema,
35
38
  locationDirectoryReportSchema,
36
39
  locationParamsSchema,
@@ -39,20 +42,23 @@ import {
39
42
  personalTokenListSchema,
40
43
  personalTokenParamsSchema,
41
44
  revokePersonalTokenResponseSchema,
45
+ startOfUtcHour,
42
46
  statsReportSchema,
47
+ sumUtcHoursIntoSixHours,
43
48
  taskExecutionListSchema,
44
49
  taskListSchema,
45
50
  taskParamsSchema,
46
51
  taskRunListSchema,
47
52
  trailingUtcDayWindow,
48
53
  trailingUtcHourWindow,
54
+ trailingUtcSixHourWindow,
49
55
  utcDayKey,
50
56
  utcHourKey,
51
57
  workspaceBodySchema,
52
58
  workspaceListSchema,
53
59
  workspaceParamsSchema,
54
60
  workspaceSchema
55
- } from "./chunk-YSLIB7ER.js";
61
+ } from "./chunk-LBN67OZR.js";
56
62
  import {
57
63
  appendAndEnqueueWebMessage,
58
64
  conversationArchiveTimes,
@@ -72,12 +78,12 @@ import {
72
78
  resolveSlackConversationContextFromThreadId,
73
79
  viewerConversationMembership,
74
80
  webActorFromEmail
75
- } from "./chunk-H4DCWLTR.js";
81
+ } from "./chunk-EFNUCRB5.js";
76
82
  import {
77
83
  buildSentryConversationUrl,
78
84
  buildSentryEventUrl,
79
85
  getWebAuthorization
80
- } from "./chunk-XND3J6AT.js";
86
+ } from "./chunk-RAWYH7TW.js";
81
87
  import {
82
88
  conversationActiveDaysColumn,
83
89
  conversationAggregateColumns,
@@ -91,7 +97,7 @@ import {
91
97
  readTaskExecutionSummaries,
92
98
  readTaskExecutions,
93
99
  readTaskRuns
94
- } from "./chunk-VOB2DKO6.js";
100
+ } from "./chunk-LGXI6PWX.js";
95
101
  import {
96
102
  healthReportSchema,
97
103
  pluginOperationalReportFeedSchema,
@@ -106,6 +112,7 @@ import {
106
112
  getEventTask,
107
113
  getResourceEventCatalog,
108
114
  isListedScheduledTask,
115
+ listDeletedEventTasksCreatedBy,
109
116
  listEventTasksCreatedBy,
110
117
  listPublicEventTasksForTeams,
111
118
  listPublicScheduledTasksForTeams,
@@ -114,24 +121,24 @@ import {
114
121
  readScheduledTask,
115
122
  readStats,
116
123
  saveScheduledTask
117
- } from "./chunk-WMJS5DDV.js";
124
+ } from "./chunk-GZ336GZ5.js";
118
125
  import {
119
126
  parseSlackThreadId
120
- } from "./chunk-IOGDKPVU.js";
127
+ } from "./chunk-VXAQTJSR.js";
121
128
  import {
122
129
  cancelHumanFacingPendingMessages,
123
130
  getConversation
124
- } from "./chunk-E53C73ML.js";
131
+ } from "./chunk-S74KAE77.js";
125
132
  import "./chunk-DA2KGZZI.js";
126
133
  import {
127
134
  agentTurnUsageSchema,
128
135
  fallbackShortTitle,
129
136
  hasAgentTurnUsage,
130
137
  renderJuniorNativeConversationEvent
131
- } from "./chunk-RFE7DCZK.js";
138
+ } from "./chunk-B5WJBVHY.js";
132
139
  import {
133
140
  getCachedSnapshot
134
- } from "./chunk-ELCYG6UU.js";
141
+ } from "./chunk-KZX7LORG.js";
135
142
  import "./chunk-PDO5BLNM.js";
136
143
  import {
137
144
  getVercelConversationWorkQueue
@@ -157,7 +164,7 @@ import {
157
164
  updateWorkspace,
158
165
  withSlackRetries,
159
166
  workspaceRepoCheckoutPath
160
- } from "./chunk-CCTYK5RH.js";
167
+ } from "./chunk-NE2UQMC7.js";
161
168
  import "./chunk-3Y47VMHV.js";
162
169
  import {
163
170
  getConversationStore,
@@ -166,7 +173,7 @@ import {
166
173
  locationFromRow,
167
174
  parseSessionSource,
168
175
  resolveRootConversationId
169
- } from "./chunk-ADEACKAH.js";
176
+ } from "./chunk-XNXKRWWI.js";
170
177
  import {
171
178
  conversationReadColumns,
172
179
  juniorApiTokens,
@@ -178,23 +185,23 @@ import {
178
185
  juniorIdentities,
179
186
  juniorSchedulerTasks,
180
187
  juniorUsers
181
- } from "./chunk-XLWZRHX5.js";
188
+ } from "./chunk-PIZJBSGZ.js";
182
189
  import {
183
190
  create,
184
191
  hash
185
- } from "./chunk-7ANA7PBB.js";
186
- import "./chunk-V4HXV5MY.js";
192
+ } from "./chunk-SR5FS2JP.js";
193
+ import "./chunk-EQBHN4JK.js";
187
194
  import {
188
195
  decodeStoredConversationEvent
189
- } from "./chunk-GFBR4S3Q.js";
196
+ } from "./chunk-7NL7T6VU.js";
190
197
  import {
191
198
  juniorDestinations
192
199
  } from "./chunk-VFUK3X5B.js";
193
- import "./chunk-U76RWMFR.js";
194
- import "./chunk-D4YV5TDV.js";
195
- import "./chunk-JOI3DHML.js";
196
- import "./chunk-WWXJUURQ.js";
197
- import "./chunk-S7GX44BU.js";
200
+ import "./chunk-5XSEOJPC.js";
201
+ import "./chunk-NHJU2ZAL.js";
202
+ import "./chunk-ES7KCEND.js";
203
+ import "./chunk-G6YRPYDC.js";
204
+ import "./chunk-BXIVMNLR.js";
198
205
  import "./chunk-CEMMLV5L.js";
199
206
  import {
200
207
  parseSlackChannelId,
@@ -206,9 +213,9 @@ import "./chunk-TXKUKMVO.js";
206
213
  import {
207
214
  logException,
208
215
  logWarn
209
- } from "./chunk-X76JVHQ4.js";
216
+ } from "./chunk-CTS72G4B.js";
210
217
  import "./chunk-PEQXYSSE.js";
211
- import "./chunk-IME5OW4Y.js";
218
+ import "./chunk-I7GEGEHZ.js";
212
219
 
213
220
  // src/api.ts
214
221
  import { Hono as Hono9 } from "hono";
@@ -2057,7 +2064,7 @@ async function readConversationFeed(options = {}) {
2057
2064
  }
2058
2065
 
2059
2066
  // src/chat/tasks/read.ts
2060
- import { and as and9, eq as eq9, or as or4 } from "drizzle-orm";
2067
+ import { and as and9, desc as desc4, eq as eq9, inArray as inArray6, or as or4 } from "drizzle-orm";
2061
2068
 
2062
2069
  // src/chat/scheduled-tasks/personal.ts
2063
2070
  import { and as and8, desc as desc3, eq as eq8, inArray as inArray5, lt as lt2, notInArray, or as or3, sql as sql8 } from "drizzle-orm";
@@ -2360,7 +2367,7 @@ async function resolveViewerTaskCandidate(user, kind, id) {
2360
2367
  };
2361
2368
  }
2362
2369
  const task = await getEventTask(db, id);
2363
- if (!task) return void 0;
2370
+ if (!task || task.status === "deleted") return void 0;
2364
2371
  const ownedByViewer = eventTaskBelongsToUser(task, user);
2365
2372
  const destinations = await destinationDetails([task.destination]);
2366
2373
  const destination = destinations.get(destinationKey(task.destination));
@@ -2408,6 +2415,26 @@ async function taskSummaryForCandidate(candidate) {
2408
2415
  createdByEmail
2409
2416
  );
2410
2417
  }
2418
+ function emptyTaskExecutionDay(date) {
2419
+ return { costUsd: 0, date, event: 0, scheduled: 0 };
2420
+ }
2421
+ function emptyTaskExecutionStatusDay(date) {
2422
+ return { blocked: 0, completed: 0, date, failed: 0 };
2423
+ }
2424
+ function taskExecutionSixHours(hours, nowMs = Date.now()) {
2425
+ return sumUtcHoursIntoSixHours({
2426
+ empty: emptyTaskExecutionDay,
2427
+ hours,
2428
+ nowMs
2429
+ });
2430
+ }
2431
+ function taskExecutionStatusSixHours(hours, nowMs = Date.now()) {
2432
+ return sumUtcHoursIntoSixHours({
2433
+ empty: emptyTaskExecutionStatusDay,
2434
+ hours,
2435
+ nowMs
2436
+ });
2437
+ }
2411
2438
  async function readViewerTasks(user) {
2412
2439
  const db = getDb();
2413
2440
  const identityIds = new Set(user.identities.map((identity) => identity.id));
@@ -2499,26 +2526,94 @@ async function readViewerTasks(user) {
2499
2526
  return {
2500
2527
  executionDays,
2501
2528
  executionHours,
2529
+ executionSixHours: taskExecutionSixHours(executionHours),
2502
2530
  tasks,
2503
2531
  truncated: ownedCandidates.length > TASK_LIST_LIMIT || publicCandidates.length > TASK_LIST_LIMIT
2504
2532
  };
2505
2533
  }
2506
- async function readViewerTaskRuns(user) {
2507
- const taskList = await readViewerTasks(user);
2508
- const taskTitles = new Map(
2509
- taskList.tasks.map((task) => [`${task.kind}:${task.id}`, task.title])
2534
+ async function readDeletedOwnedScheduledTasks(user) {
2535
+ const identityIds = user.identities.map((identity) => identity.id);
2536
+ if (identityIds.length === 0) return [];
2537
+ const rows = await getDb().select({
2538
+ creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
2539
+ id: juniorSchedulerTasks.id,
2540
+ record: juniorSchedulerTasks.record,
2541
+ title: juniorSchedulerTasks.title
2542
+ }).from(juniorSchedulerTasks).where(
2543
+ and9(
2544
+ eq9(juniorSchedulerTasks.status, "deleted"),
2545
+ inArray6(juniorSchedulerTasks.creatorIdentityId, identityIds)
2546
+ )
2547
+ ).orderBy(
2548
+ desc4(juniorSchedulerTasks.createdAtMs),
2549
+ desc4(juniorSchedulerTasks.id)
2550
+ ).limit(TASK_EXECUTION_LIST_LIMIT);
2551
+ return rows.map(parseScheduledTaskRow).filter((task) => task?.status === "deleted");
2552
+ }
2553
+ async function readDeletedOwnedEventTasks(user) {
2554
+ return await listDeletedEventTasksCreatedBy(
2555
+ getDb(),
2556
+ user,
2557
+ TASK_EXECUTION_LIST_LIMIT
2510
2558
  );
2559
+ }
2560
+ function taskTitleForRun(run, taskTitles) {
2561
+ return taskTitles.get(`${run.kind}:${run.taskId}`) ?? run.title?.trim() ?? "Untitled task";
2562
+ }
2563
+ function addDeletedTaskRun(args, taskTitles, tasks) {
2564
+ const key = `${args.kind}:${args.taskId}`;
2565
+ if (taskTitles.has(key)) return;
2566
+ taskTitles.set(key, args.title);
2567
+ tasks.push({ kind: args.kind, taskId: args.taskId });
2568
+ }
2569
+ async function readViewerTaskRuns(user) {
2570
+ const [taskList, deletedScheduled, deletedEvent] = await Promise.all([
2571
+ readViewerTasks(user),
2572
+ readDeletedOwnedScheduledTasks(user),
2573
+ readDeletedOwnedEventTasks(user)
2574
+ ]);
2575
+ const taskTitles = /* @__PURE__ */ new Map();
2576
+ const tasks = [];
2577
+ for (const task of taskList.tasks) {
2578
+ taskTitles.set(`${task.kind}:${task.id}`, task.title);
2579
+ tasks.push({ kind: task.kind, taskId: task.id });
2580
+ }
2581
+ for (const task of deletedScheduled) {
2582
+ const instruction = displayText(task.task.text, "Untitled scheduled task");
2583
+ addDeletedTaskRun(
2584
+ {
2585
+ kind: "scheduled",
2586
+ taskId: task.id,
2587
+ title: taskDisplayTitle(
2588
+ task.title,
2589
+ instruction,
2590
+ "Untitled scheduled task"
2591
+ )
2592
+ },
2593
+ taskTitles,
2594
+ tasks
2595
+ );
2596
+ }
2597
+ for (const task of deletedEvent) {
2598
+ const instruction = displayText(task.task.text, "Untitled event task");
2599
+ addDeletedTaskRun(
2600
+ {
2601
+ kind: "event",
2602
+ taskId: task.id,
2603
+ title: taskDisplayTitle(task.title, instruction, "Untitled event task")
2604
+ },
2605
+ taskTitles,
2606
+ tasks
2607
+ );
2608
+ }
2511
2609
  const runs = await readTaskRuns({
2512
2610
  limit: TASK_EXECUTION_LIST_LIMIT + 1,
2513
- tasks: taskList.tasks.map((task) => ({
2514
- kind: task.kind,
2515
- taskId: task.id
2516
- }))
2611
+ tasks
2517
2612
  });
2518
2613
  return {
2519
2614
  runs: runs.slice(0, TASK_EXECUTION_LIST_LIMIT).map((run) => ({
2520
2615
  ...run,
2521
- taskTitle: taskTitles.get(`${run.kind}:${run.taskId}`) ?? "Untitled task"
2616
+ taskTitle: taskTitleForRun(run, taskTitles)
2522
2617
  })),
2523
2618
  truncated: runs.length > TASK_EXECUTION_LIST_LIMIT
2524
2619
  };
@@ -2551,6 +2646,7 @@ async function readViewerTaskExecutions(user, kind, id) {
2551
2646
  return {
2552
2647
  executionDays,
2553
2648
  executionHours,
2649
+ executionSixHours: taskExecutionStatusSixHours(executionHours),
2554
2650
  executions: executions.slice(0, TASK_EXECUTION_LIST_LIMIT),
2555
2651
  task,
2556
2652
  truncated: executions.length > TASK_EXECUTION_LIST_LIMIT
@@ -2612,7 +2708,7 @@ async function deleteViewerTask(user, kind, id) {
2612
2708
  }
2613
2709
  }
2614
2710
  const task = await getEventTask(getDb(), id);
2615
- if (!task || !eventTaskBelongsToUser(task, user)) {
2711
+ if (!task || task.status === "deleted" || !eventTaskBelongsToUser(task, user)) {
2616
2712
  throw new ViewerTaskNotFoundError();
2617
2713
  }
2618
2714
  await deleteEventTask(getDb(), id);
@@ -3011,15 +3107,7 @@ function statsWindow(nowMs) {
3011
3107
  return { end, start };
3012
3108
  }
3013
3109
  var HOUR_MS2 = 60 * 60 * 1e3;
3014
- var WINDOW_HOURS = 24;
3015
- function startOfUtcHour(valueMs) {
3016
- const date = new Date(valueMs);
3017
- date.setUTCMinutes(0, 0, 0);
3018
- return date;
3019
- }
3020
- function utcHourKey2(value) {
3021
- return value.toISOString().slice(0, 13);
3022
- }
3110
+ var WINDOW_HOURS = WINDOW_SEVEN_DAY_HOURS;
3023
3111
  function metricPoint(date, row) {
3024
3112
  return {
3025
3113
  conversations: row?.conversations ?? 0,
@@ -3044,13 +3132,33 @@ function metricDays(rows, endMs) {
3044
3132
  }
3045
3133
  return days;
3046
3134
  }
3135
+ function emptyMetricDay(date) {
3136
+ return { conversations: 0, date, durationMs: 0 };
3137
+ }
3138
+ function emptyGuardianDay(date) {
3139
+ return { allow: 0, ask: 0, date, deny: 0, requests: 0 };
3140
+ }
3141
+ function sumMetricHoursIntoSixHours(hours, endMs) {
3142
+ return sumUtcHoursIntoSixHours({
3143
+ empty: emptyMetricDay,
3144
+ hours,
3145
+ nowMs: endMs
3146
+ });
3147
+ }
3148
+ function sumGuardianHoursIntoSixHours(hours, endMs) {
3149
+ return sumUtcHoursIntoSixHours({
3150
+ empty: emptyGuardianDay,
3151
+ hours,
3152
+ nowMs: endMs
3153
+ });
3154
+ }
3047
3155
  function metricHours(rows, endMs) {
3048
3156
  const byHour = new Map(rows.map((row) => [row.date, row]));
3049
3157
  const end = startOfUtcHour(endMs);
3050
3158
  const start = new Date(end.getTime() - (WINDOW_HOURS - 1) * HOUR_MS2);
3051
3159
  const hours = [];
3052
3160
  for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS2)) {
3053
- const date = utcHourKey2(cursor);
3161
+ const date = utcHourKey(cursor);
3054
3162
  hours.push(metricPoint(date, byHour.get(date)));
3055
3163
  }
3056
3164
  return hours;
@@ -3094,7 +3202,7 @@ function guardianStats(dayRows, hourRows, endMs) {
3094
3202
  const hourStart = new Date(hourEnd.getTime() - (WINDOW_HOURS - 1) * HOUR_MS2);
3095
3203
  const metricHours2 = [];
3096
3204
  for (const cursor = new Date(hourStart); cursor.getTime() <= hourEnd.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS2)) {
3097
- const date = utcHourKey2(cursor);
3205
+ const date = utcHourKey(cursor);
3098
3206
  metricHours2.push(guardianPoint(date, byHour.get(date)));
3099
3207
  }
3100
3208
  return {
@@ -3103,6 +3211,7 @@ function guardianStats(dayRows, hourRows, endMs) {
3103
3211
  deny,
3104
3212
  metricDays: metricDays2,
3105
3213
  metricHours: metricHours2,
3214
+ metricSixHours: sumGuardianHoursIntoSixHours(metricHours2, endMs),
3106
3215
  requests,
3107
3216
  ...costUsd !== void 0 ? { costUsd } : void 0
3108
3217
  };
@@ -3281,7 +3390,13 @@ async function readConversationStatsFromSql() {
3281
3390
  generatedAt: new Date(nowMs).toISOString(),
3282
3391
  guardian: guardianStats(guardian.dayRows, guardian.hourRows, nowMs),
3283
3392
  metricDays: metricDays(metricRows, nowMs),
3284
- metricHours: metricHours(metricHourRows, nowMs),
3393
+ ...(() => {
3394
+ const hours = metricHours(metricHourRows, nowMs);
3395
+ return {
3396
+ metricHours: hours,
3397
+ metricSixHours: sumMetricHoursIntoSixHours(hours, nowMs)
3398
+ };
3399
+ })(),
3285
3400
  locations: statsItems(locations),
3286
3401
  actors: statsItems(actors),
3287
3402
  source: "conversation_index",
@@ -3515,7 +3630,7 @@ function createConversationRoutes(options) {
3515
3630
  import { Hono as Hono2 } from "hono";
3516
3631
 
3517
3632
  // src/api/code/overview.ts
3518
- import { desc as desc4, eq as eq11, gte as gte2, or as or5, sql as sql10 } from "drizzle-orm";
3633
+ import { desc as desc5, eq as eq11, gte as gte2, or as or5, sql as sql10 } from "drizzle-orm";
3519
3634
  import { z as z5 } from "zod";
3520
3635
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
3521
3636
  var WINDOW_DAYS2 = 30;
@@ -3624,7 +3739,7 @@ async function readCodeWindows(args) {
3624
3739
  const activityHourEnd = new Date(args.nowMs);
3625
3740
  activityHourEnd.setUTCMinutes(0, 0, 0);
3626
3741
  const activityHourStart = new Date(
3627
- activityHourEnd.getTime() - 23 * (DAY_MS2 / 24)
3742
+ activityHourEnd.getTime() - (7 * 24 - 1) * (DAY_MS2 / 24)
3628
3743
  );
3629
3744
  const [summaryResult, activityResult, activityHourResult] = await Promise.all([
3630
3745
  db.execute(sql10`
@@ -3780,9 +3895,15 @@ async function readCodeWindows(args) {
3780
3895
  open: 0
3781
3896
  }
3782
3897
  );
3898
+ const activityHours3 = z5.array(activityDaySchema).parse(queryRows(activityHourResult));
3783
3899
  return {
3784
3900
  activityDays: z5.array(activityDaySchema).parse(queryRows(activityResult)),
3785
- activityHours: z5.array(activityDaySchema).parse(queryRows(activityHourResult)),
3901
+ activityHours: activityHours3,
3902
+ activitySixHours: sumUtcHoursIntoSixHours({
3903
+ empty: (date) => ({ closed: 0, created: 0, date, merged: 0 }),
3904
+ hours: activityHours3,
3905
+ nowMs: args.nowMs
3906
+ }),
3786
3907
  summary: {
3787
3908
  ...summary,
3788
3909
  mergeRate: mergeRate(summary.merged, summary.closed)
@@ -3875,11 +3996,12 @@ async function readCodeOverview(nowMs = Date.now()) {
3875
3996
  gte2(changes.closedAt, windows.windowStart),
3876
3997
  eq11(changes.state, "open")
3877
3998
  )
3878
- ).orderBy(desc4(changes.updatedAt)).limit(25)
3999
+ ).orderBy(desc5(changes.updatedAt)).limit(25)
3879
4000
  ]);
3880
4001
  return codeOverviewReportSchema.parse({
3881
4002
  activityDays: windows.activityDays,
3882
4003
  activityHours: windows.activityHours,
4004
+ activitySixHours: windows.activitySixHours,
3883
4005
  changes: recentChanges.map((change) => ({
3884
4006
  ...change,
3885
4007
  closedAt: change.closedAt?.toISOString(),
@@ -3908,6 +4030,7 @@ async function readPersonCodeOverview(args) {
3908
4030
  return codePersonReportSchema.parse({
3909
4031
  activityDays: windows.activityDays,
3910
4032
  activityHours: windows.activityHours,
4033
+ activitySixHours: windows.activitySixHours,
3911
4034
  generatedAt: windows.windowEnd.toISOString(),
3912
4035
  summary: windows.summary,
3913
4036
  windowEnd: windows.windowEnd.toISOString(),
@@ -3929,7 +4052,7 @@ function createCodeRoutes() {
3929
4052
  import { Hono as Hono3 } from "hono";
3930
4053
 
3931
4054
  // src/api/locations/query.ts
3932
- import { and as and11, asc as asc3, desc as desc5, eq as eq12, gte as gte3, isNull as isNull5, sql as sql11 } from "drizzle-orm";
4055
+ import { and as and11, asc as asc3, desc as desc6, eq as eq12, gte as gte3, isNull as isNull5, sql as sql11 } from "drizzle-orm";
3933
4056
  import { alias as alias4 } from "drizzle-orm/pg-core";
3934
4057
 
3935
4058
  // src/api/conversations/reporting.ts
@@ -4162,15 +4285,29 @@ function directoryActivityDays(rows, nowMs) {
4162
4285
  }
4163
4286
  function directoryActivityHours(rows, nowMs) {
4164
4287
  return fillUtcHours({
4288
+ count: WINDOW_SEVEN_DAY_HOURS,
4289
+ empty: emptyLocationActivityDay,
4290
+ nowMs,
4291
+ rows: accumulateLocationActivity(rows)
4292
+ });
4293
+ }
4294
+ function directoryActivitySixHours(rows, nowMs) {
4295
+ const hours = fillUtcHours({
4296
+ count: WINDOW_SEVEN_DAY_HOURS,
4165
4297
  empty: emptyLocationActivityDay,
4166
4298
  nowMs,
4167
4299
  rows: accumulateLocationActivity(rows)
4168
4300
  });
4301
+ return sumUtcHoursIntoSixHours({
4302
+ empty: emptyLocationActivityDay,
4303
+ hours,
4304
+ nowMs
4305
+ });
4169
4306
  }
4170
4307
  async function readLocationDirectoryFromSql() {
4171
4308
  const nowMs = Date.now();
4172
4309
  const { end, start } = trailingUtcDayWindow(nowMs, ACTIVITY_DAYS2);
4173
- const hourWindow = trailingUtcHourWindow(nowMs);
4310
+ const hourWindow = trailingUtcHourWindow(nowMs, WINDOW_SEVEN_DAY_HOURS);
4174
4311
  const [rows, activity] = await Promise.all([
4175
4312
  directoryRows(getDb()),
4176
4313
  directoryActivityRows(getDb(), start, hourWindow.start)
@@ -4188,6 +4325,7 @@ async function readLocationDirectoryFromSql() {
4188
4325
  return {
4189
4326
  activityDays: directoryActivityDays(activity.dayRows, nowMs),
4190
4327
  activityHours: directoryActivityHours(activity.hourRows, nowMs),
4328
+ activitySixHours: directoryActivitySixHours(activity.hourRows, nowMs),
4191
4329
  generatedAt: new Date(nowMs).toISOString(),
4192
4330
  locations: locations.sort(
4193
4331
  (left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt) || right.conversations - left.conversations || left.label.localeCompare(right.label)
@@ -4230,14 +4368,14 @@ async function recentLocationRows(db, locationId) {
4230
4368
  juniorIdentities,
4231
4369
  eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
4232
4370
  ).leftJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).where(publicLocationWhere(locationId)).orderBy(
4233
- desc5(juniorConversations.lastActivityAt),
4371
+ desc6(juniorConversations.lastActivityAt),
4234
4372
  asc3(juniorConversations.conversationId)
4235
4373
  ).limit(RECENT_LIMIT);
4236
4374
  }
4237
4375
  async function readLocationDetailFromSql(locationId, options = {}) {
4238
4376
  const nowMs = Date.now();
4239
4377
  const { end, start } = trailingUtcDayWindow(nowMs, ACTIVITY_DAYS2);
4240
- const hourWindow = trailingUtcHourWindow(nowMs);
4378
+ const hourWindow = trailingUtcHourWindow(nowMs, WINDOW_SEVEN_DAY_HOURS);
4241
4379
  const where = publicLocationWhere(locationId);
4242
4380
  const activityDate = sql11`TO_CHAR(
4243
4381
  ${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
@@ -4376,6 +4514,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
4376
4514
  ...location,
4377
4515
  activityDays: activity,
4378
4516
  activityHours: hourlyActivity,
4517
+ activitySixHours: activitySixHours(hourlyActivity, nowMs),
4379
4518
  actors: actors.sort(
4380
4519
  (left, right) => right.conversations - left.conversations || left.label.localeCompare(right.label)
4381
4520
  ),
@@ -4461,7 +4600,7 @@ async function readPeopleCode(email) {
4461
4600
  import { and as and13, eq as eq14, gte as gte4, sql as sql13 } from "drizzle-orm";
4462
4601
 
4463
4602
  // src/api/people/shared.ts
4464
- import { and as and12, asc as asc4, desc as desc6, eq as eq13, isNull as isNull6, notExists, or as or6, sql as sql12 } from "drizzle-orm";
4603
+ import { and as and12, asc as asc4, desc as desc7, eq as eq13, isNull as isNull6, notExists, or as or6, sql as sql12 } from "drizzle-orm";
4465
4604
  import { alias as alias5 } from "drizzle-orm/pg-core";
4466
4605
  var RECENT_LIMIT2 = 25;
4467
4606
  var ACTIVITY_DAYS3 = 365;
@@ -4552,11 +4691,20 @@ function activityDays2(days, nowMs) {
4552
4691
  }
4553
4692
  function activityHours2(hours, nowMs) {
4554
4693
  return fillUtcHours({
4694
+ count: WINDOW_SEVEN_DAY_HOURS,
4555
4695
  empty: emptyActivityDay,
4556
4696
  nowMs,
4557
4697
  rows: hours
4558
4698
  });
4559
4699
  }
4700
+ function activitySixHours2(hours, nowMs) {
4701
+ const series = hours instanceof Map ? activityHours2(hours, nowMs) : [...hours];
4702
+ return sumUtcHoursIntoSixHours({
4703
+ empty: emptyActivityDay,
4704
+ hours: series,
4705
+ nowMs
4706
+ });
4707
+ }
4560
4708
  function statsItems2(map) {
4561
4709
  return [...map.values()].sort(
4562
4710
  (left, right) => right.conversations - left.conversations || right.durationMs - left.durationMs || left.label.localeCompare(right.label)
@@ -4596,7 +4744,7 @@ async function recentActorRows(email) {
4596
4744
  juniorDestinations,
4597
4745
  eq13(juniorDestinations.id, juniorConversations.destinationId)
4598
4746
  ).where(verifiedActorWhere(email)).orderBy(
4599
- desc6(juniorConversations.lastActivityAt),
4747
+ desc7(juniorConversations.lastActivityAt),
4600
4748
  asc4(juniorConversations.conversationId)
4601
4749
  ).limit(RECENT_LIMIT2);
4602
4750
  }
@@ -4624,6 +4772,14 @@ function directoryActivityDays2(rows, nowMs) {
4624
4772
  }
4625
4773
  function directoryActivityHours2(rows, nowMs) {
4626
4774
  return fillUtcHours({
4775
+ count: WINDOW_SEVEN_DAY_HOURS,
4776
+ empty: emptyDirectoryDay,
4777
+ nowMs,
4778
+ rows: new Map(rows.map((row) => [row.date, row]))
4779
+ });
4780
+ }
4781
+ function directoryActivitySixHours2(rows, nowMs) {
4782
+ return fillUtcSixHours({
4627
4783
  empty: emptyDirectoryDay,
4628
4784
  nowMs,
4629
4785
  rows: new Map(rows.map((row) => [row.date, row]))
@@ -4709,17 +4865,24 @@ async function readPeopleListFromSql() {
4709
4865
  ${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
4710
4866
  'YYYY-MM-DD"T"HH24'
4711
4867
  )`;
4712
- const hourWindow = trailingUtcHourWindow(nowMs);
4868
+ const hourWindow = trailingUtcHourWindow(nowMs, WINDOW_SEVEN_DAY_HOURS);
4869
+ const sixHourWindow = trailingUtcSixHourWindow(nowMs);
4713
4870
  const dayMetricStart = trailingUtcDayWindow(nowMs, DAY_METRIC_LOOKBACK).start;
4714
4871
  const hourMetricStart = trailingUtcHourWindow(
4715
4872
  nowMs,
4716
4873
  HOUR_METRIC_LOOKBACK
4717
4874
  ).start;
4718
4875
  const metricsJoin = peopleTreeMetricsJoin();
4876
+ const activitySixHour = sql13`TO_CHAR(
4877
+ date_trunc('day', ${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC')
4878
+ + (FLOOR(EXTRACT(HOUR FROM ${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC') / 6) * INTERVAL '6 hours'),
4879
+ 'YYYY-MM-DD"T"HH24'
4880
+ )`;
4719
4881
  const [
4720
4882
  rows,
4721
4883
  activityRows,
4722
4884
  activityHourRows,
4885
+ activitySixHourRows,
4723
4886
  dayMetricRows,
4724
4887
  hourMetricRows
4725
4888
  ] = await Promise.all([
@@ -4761,6 +4924,19 @@ async function readPeopleListFromSql() {
4761
4924
  gte4(juniorConversations.lastActivityAt, hourWindow.start)
4762
4925
  )
4763
4926
  ).groupBy(activityHour),
4927
+ getDb().select({
4928
+ activePeople: sql13`COUNT(DISTINCT ${juniorUsers.id})::int`,
4929
+ conversations: sql13`COUNT(*)::int`,
4930
+ date: activitySixHour
4931
+ }).from(juniorConversations).innerJoin(
4932
+ juniorIdentities,
4933
+ eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
4934
+ ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).where(
4935
+ and13(
4936
+ verifiedActorWhere(),
4937
+ gte4(juniorConversations.lastActivityAt, sixHourWindow.start)
4938
+ )
4939
+ ).groupBy(activitySixHour),
4764
4940
  getDb().select({
4765
4941
  email: juniorUsers.primaryEmailNormalized,
4766
4942
  date: activityDate,
@@ -4845,6 +5021,7 @@ async function readPeopleListFromSql() {
4845
5021
  return {
4846
5022
  activityDays: directoryActivityDays2(activityRows, nowMs),
4847
5023
  activityHours: directoryActivityHours2(activityHourRows, nowMs),
5024
+ activitySixHours: directoryActivitySixHours2(activitySixHourRows, nowMs),
4848
5025
  generatedAt: new Date(nowMs).toISOString(),
4849
5026
  people: people.sort(
4850
5027
  (left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt) || right.conversations - left.conversations || left.actor.email.localeCompare(right.actor.email)
@@ -4871,7 +5048,7 @@ async function readPeoplePluginReports(args) {
4871
5048
  source: "plugins"
4872
5049
  });
4873
5050
  }
4874
- const { getPluginProfileReports } = await import("./agent-hooks-IDX764FD.js");
5051
+ const { getPluginProfileReports } = await import("./agent-hooks-IQLRR4RC.js");
4875
5052
  return pluginOperationalReportFeedSchema.parse({
4876
5053
  generatedAt: new Date(nowMs).toISOString(),
4877
5054
  reports: await getPluginProfileReports({
@@ -4893,6 +5070,7 @@ function emptyProfile(email, nowMs) {
4893
5070
  return {
4894
5071
  activityDays: activityDays2(/* @__PURE__ */ new Map(), nowMs),
4895
5072
  activityHours: activityHours2(/* @__PURE__ */ new Map(), nowMs),
5073
+ activitySixHours: activitySixHours2(/* @__PURE__ */ new Map(), nowMs),
4896
5074
  generatedAt: new Date(nowMs).toISOString(),
4897
5075
  locations: [],
4898
5076
  recentConversations: [],
@@ -4958,7 +5136,7 @@ async function readPeopleProfileFromSql(email, options = {}) {
4958
5136
  'YYYY-MM-DD"T"HH24'
4959
5137
  )`;
4960
5138
  const channel = sql14`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
4961
- const hourWindow = trailingUtcHourWindow(nowMs);
5139
+ const hourWindow = trailingUtcHourWindow(nowMs, 7 * 24);
4962
5140
  const [totalsRows, dayRows, hourRows, locationRows, surfaceRows, recentRows] = await Promise.all([
4963
5141
  getDb().select({
4964
5142
  email: juniorUsers.primaryEmailNormalized,
@@ -5067,6 +5245,7 @@ async function readPeopleProfileFromSql(email, options = {}) {
5067
5245
  return {
5068
5246
  activityDays: activityDays2(days, nowMs),
5069
5247
  activityHours: activityHours2(hours, nowMs),
5248
+ activitySixHours: activitySixHours2(hours, nowMs),
5070
5249
  generatedAt: new Date(nowMs).toISOString(),
5071
5250
  locations: statsItems2(locations),
5072
5251
  recentConversations: recentRows.map(
@@ -5239,7 +5418,7 @@ import { Hono as Hono5 } from "hono";
5239
5418
 
5240
5419
  // src/personal-tokens/store.ts
5241
5420
  import { createHash, randomBytes, randomUUID } from "crypto";
5242
- import { and as and16, desc as desc7, eq as eq17, gt, isNull as isNull7 } from "drizzle-orm";
5421
+ import { and as and16, desc as desc8, eq as eq17, gt, isNull as isNull7 } from "drizzle-orm";
5243
5422
  var TOKEN_PREFIX = "jr_pat_";
5244
5423
  var TOKEN_SUFFIX_LENGTH = 8;
5245
5424
  var DEFAULT_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
@@ -5281,7 +5460,7 @@ async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
5281
5460
  isNull7(juniorApiTokens.revokedAt),
5282
5461
  gt(juniorApiTokens.expiresAt, now)
5283
5462
  )
5284
- ).orderBy(desc7(juniorApiTokens.createdAt));
5463
+ ).orderBy(desc8(juniorApiTokens.createdAt));
5285
5464
  return rows.map(metadata);
5286
5465
  }
5287
5466
  async function revokePersonalToken(args) {
@@ -5703,7 +5882,7 @@ function readDescriptionText(home) {
5703
5882
  }
5704
5883
  }
5705
5884
  async function readSkillReports() {
5706
- const { discoverSkills } = await import("./skills-POMWS2RR.js");
5885
+ const { discoverSkills } = await import("./skills-WZV6NLFY.js");
5707
5886
  const skills = await discoverSkills();
5708
5887
  return skillReportsSchema.parse(
5709
5888
  skills.map((skill) => ({
@@ -5713,7 +5892,7 @@ async function readSkillReports() {
5713
5892
  );
5714
5893
  }
5715
5894
  async function readPlugins() {
5716
- const { pluginCatalogRuntime } = await import("./catalog-runtime-MICXEBLK.js");
5895
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-EM7V2F4I.js");
5717
5896
  return pluginsSchema.parse(
5718
5897
  pluginCatalogRuntime.getProviders().map((plugin) => ({
5719
5898
  configKeys: plugin.manifest.configKeys ?? [],
@@ -5726,7 +5905,7 @@ async function readPlugins() {
5726
5905
  async function readRuntimeInfoReport() {
5727
5906
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
5728
5907
  import("./discovery-DWVDM7UK.js"),
5729
- import("./catalog-runtime-MICXEBLK.js"),
5908
+ import("./catalog-runtime-EM7V2F4I.js"),
5730
5909
  readPlugins(),
5731
5910
  readSkillReports()
5732
5911
  ]);
@@ -5742,7 +5921,7 @@ async function readRuntimeInfoReport() {
5742
5921
  }
5743
5922
  async function readPluginOperationalReportFeed() {
5744
5923
  const nowMs = Date.now();
5745
- const { getPluginOperationalReports } = await import("./agent-hooks-IDX764FD.js");
5924
+ const { getPluginOperationalReports } = await import("./agent-hooks-IQLRR4RC.js");
5746
5925
  return pluginOperationalReportFeedSchema.parse({
5747
5926
  source: "plugins",
5748
5927
  generatedAt: new Date(nowMs).toISOString(),