agent-relay-server 0.94.6 → 0.95.1

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 (143) hide show
  1. package/docs/openapi.json +1 -1
  2. package/package.json +2 -2
  3. package/public/assets/MessageBubble-CkPnAwxJ.js +3 -0
  4. package/public/assets/{MessageBubble-g4NKZBDI.js.map → MessageBubble-CkPnAwxJ.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-Chydc7yG.js → PlanGraphPanel-DPgW_Ohe.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-Chydc7yG.js.map → PlanGraphPanel-DPgW_Ohe.js.map} +1 -1
  7. package/public/assets/{activity-BXLw6f9y.js → activity-CRebaL8O.js} +2 -2
  8. package/public/assets/{activity-BXLw6f9y.js.map → activity-CRebaL8O.js.map} +1 -1
  9. package/public/assets/{agent-profiles-B6PsZZmM.js → agent-profiles-BFpEQHKo.js} +2 -2
  10. package/public/assets/{agent-profiles-B6PsZZmM.js.map → agent-profiles-BFpEQHKo.js.map} +1 -1
  11. package/public/assets/{agents-B0POygaD.js → agents-7WtV1Pf3.js} +2 -2
  12. package/public/assets/{agents-B0POygaD.js.map → agents-7WtV1Pf3.js.map} +1 -1
  13. package/public/assets/{analytics-B50LtRMU.js → analytics-DpnJh9UQ.js} +3 -3
  14. package/public/assets/{analytics-B50LtRMU.js.map → analytics-DpnJh9UQ.js.map} +1 -1
  15. package/public/assets/{automation-CeYilS-s.js → automation-CjQNCXlO.js} +2 -2
  16. package/public/assets/{automation-CeYilS-s.js.map → automation-CjQNCXlO.js.map} +1 -1
  17. package/public/assets/{badge-CcTIPkUa.js → badge-BbfOskRI.js} +2 -2
  18. package/public/assets/{badge-CcTIPkUa.js.map → badge-BbfOskRI.js.map} +1 -1
  19. package/public/assets/branch-state-badge-BcObk0ca.js +2 -0
  20. package/public/assets/{branch-state-badge-T6t16OU5.js.map → branch-state-badge-BcObk0ca.js.map} +1 -1
  21. package/public/assets/{button-Dvz6HZ1j.js → button-DWiw--lT.js} +2 -2
  22. package/public/assets/{button-Dvz6HZ1j.js.map → button-DWiw--lT.js.map} +1 -1
  23. package/public/assets/{card-xVEUTFuh.js → card-BeqvuYTT.js} +2 -2
  24. package/public/assets/{card-xVEUTFuh.js.map → card-BeqvuYTT.js.map} +1 -1
  25. package/public/assets/channels-B2bftzgH.js +2 -0
  26. package/public/assets/{channels-C0J-VHEa.js.map → channels-B2bftzgH.js.map} +1 -1
  27. package/public/assets/chat-Dcwua_5V.js +2 -0
  28. package/public/assets/chat-Dcwua_5V.js.map +1 -0
  29. package/public/assets/{connectors-P5V_DlvA.js → connectors-CJOJirYT.js} +2 -2
  30. package/public/assets/{connectors-P5V_DlvA.js.map → connectors-CJOJirYT.js.map} +1 -1
  31. package/public/assets/copy-button-CIXy8ks6.js +2 -0
  32. package/public/assets/{copy-button-gB8Wc3dh.js.map → copy-button-CIXy8ks6.js.map} +1 -1
  33. package/public/assets/display-DRiGi1zj.js.map +1 -1
  34. package/public/assets/{dist-DbJ0cYxd.js → dist-BQXmO19g.js} +2 -2
  35. package/public/assets/{dist-DbJ0cYxd.js.map → dist-BQXmO19g.js.map} +1 -1
  36. package/public/assets/{dist-CE9yg7LH.js → dist-BufB2Xy_.js} +2 -2
  37. package/public/assets/{dist-CE9yg7LH.js.map → dist-BufB2Xy_.js.map} +1 -1
  38. package/public/assets/dist-CXkmW1Od.js +2 -0
  39. package/public/assets/{dist-4Joy6mhT.js.map → dist-CXkmW1Od.js.map} +1 -1
  40. package/public/assets/{dist-DoHTwsqW.js → dist-CbxR2pzD.js} +2 -2
  41. package/public/assets/{dist-DoHTwsqW.js.map → dist-CbxR2pzD.js.map} +1 -1
  42. package/public/assets/{dist-Cu5eOAWz.js → dist-CtuS_3Jl.js} +2 -2
  43. package/public/assets/{dist-Cu5eOAWz.js.map → dist-CtuS_3Jl.js.map} +1 -1
  44. package/public/assets/{dist-CVWxY_y8.js → dist-Du_bcq-z.js} +2 -2
  45. package/public/assets/{dist-CVWxY_y8.js.map → dist-Du_bcq-z.js.map} +1 -1
  46. package/public/assets/{dist-BkHh9GoG.js → dist-KxiSP9h9.js} +2 -2
  47. package/public/assets/{dist-BkHh9GoG.js.map → dist-KxiSP9h9.js.map} +1 -1
  48. package/public/assets/dist-LFuRypZd.js +2 -0
  49. package/public/assets/{dist-4O7O9HEE.js.map → dist-LFuRypZd.js.map} +1 -1
  50. package/public/assets/dist-Q6OOS84U.js +2 -0
  51. package/public/assets/{dist-B2WymQRX.js.map → dist-Q6OOS84U.js.map} +1 -1
  52. package/public/assets/{dist-B5OjWLDL.js → dist-eG_93I3z.js} +2 -2
  53. package/public/assets/{dist-B5OjWLDL.js.map → dist-eG_93I3z.js.map} +1 -1
  54. package/public/assets/{dist-XUy-xPl6.js → dist-zTw85jD8.js} +2 -2
  55. package/public/assets/{dist-XUy-xPl6.js.map → dist-zTw85jD8.js.map} +1 -1
  56. package/public/assets/{es2015-Dv7v8EgR.js → es2015-ibwCE_JR.js} +2 -2
  57. package/public/assets/{es2015-Dv7v8EgR.js.map → es2015-ibwCE_JR.js.map} +1 -1
  58. package/public/assets/{formatted-body-impl-B8xoPLk0.js → formatted-body-impl-CGACmUqI.js} +2 -2
  59. package/public/assets/{formatted-body-impl-B8xoPLk0.js.map → formatted-body-impl-CGACmUqI.js.map} +1 -1
  60. package/public/assets/index-CKPsJqiW.css +2 -0
  61. package/public/assets/index-CwhhpGgX.js +23 -0
  62. package/public/assets/index-CwhhpGgX.js.map +1 -0
  63. package/public/assets/{input-CWYjJ4Bn.js → input-DUdtS3nG.js} +2 -2
  64. package/public/assets/{input-CWYjJ4Bn.js.map → input-DUdtS3nG.js.map} +1 -1
  65. package/public/assets/{insights-O02aG6Fa.js → insights-DqXjTYai.js} +2 -2
  66. package/public/assets/{insights-O02aG6Fa.js.map → insights-DqXjTYai.js.map} +1 -1
  67. package/public/assets/{integrations-COYT1FSR.js → integrations-DEgLatDv.js} +2 -2
  68. package/public/assets/{integrations-COYT1FSR.js.map → integrations-DEgLatDv.js.map} +1 -1
  69. package/public/assets/{lib-C6ShgLFg.js → lib-Gp69YB9e.js} +3 -3
  70. package/public/assets/{lib-C6ShgLFg.js.map → lib-Gp69YB9e.js.map} +1 -1
  71. package/public/assets/lucide-react-uFIMC7W7.js +9 -0
  72. package/public/assets/{lucide-react-BMjjWU36.js.map → lucide-react-uFIMC7W7.js.map} +1 -1
  73. package/public/assets/{maintenance-CsaxFb2K.js → maintenance-CcFJlNxt.js} +2 -2
  74. package/public/assets/{maintenance-CsaxFb2K.js.map → maintenance-CcFJlNxt.js.map} +1 -1
  75. package/public/assets/{managed-agents-BkMSa35M.js → managed-agents-CHR4Hx1O.js} +4 -4
  76. package/public/assets/{managed-agents-BkMSa35M.js.map → managed-agents-CHR4Hx1O.js.map} +1 -1
  77. package/public/assets/{markdown-preview-impl-CPUObdGL.js → markdown-preview-impl-BHaUcnfn.js} +2 -2
  78. package/public/assets/{markdown-preview-impl-CPUObdGL.js.map → markdown-preview-impl-BHaUcnfn.js.map} +1 -1
  79. package/public/assets/{memory-Bc9b5aFW.js → memory-Uk0VfqnC.js} +2 -2
  80. package/public/assets/{memory-Bc9b5aFW.js.map → memory-Uk0VfqnC.js.map} +1 -1
  81. package/public/assets/{messages-DDUpkDDo.js → messages-D_juCBfr.js} +2 -2
  82. package/public/assets/{messages-DDUpkDDo.js.map → messages-D_juCBfr.js.map} +1 -1
  83. package/public/assets/{orchestrators-CTiypI_B.js → orchestrators-8IrmgeHV.js} +2 -2
  84. package/public/assets/{orchestrators-CTiypI_B.js.map → orchestrators-8IrmgeHV.js.map} +1 -1
  85. package/public/assets/{overview-DT05JmLC.js → overview-D_DM0QHJ.js} +2 -2
  86. package/public/assets/{overview-DT05JmLC.js.map → overview-D_DM0QHJ.js.map} +1 -1
  87. package/public/assets/{pairs-VlxzegP3.js → pairs-jciDuPLn.js} +2 -2
  88. package/public/assets/{pairs-VlxzegP3.js.map → pairs-jciDuPLn.js.map} +1 -1
  89. package/public/assets/{projects-5xutbu4r.js → projects-C-QHyuMD.js} +2 -2
  90. package/public/assets/{projects-5xutbu4r.js.map → projects-C-QHyuMD.js.map} +1 -1
  91. package/public/assets/{react-dom-D1K8FBqJ.js → react-dom-DF2cuNaf.js} +2 -2
  92. package/public/assets/{react-dom-D1K8FBqJ.js.map → react-dom-DF2cuNaf.js.map} +1 -1
  93. package/public/assets/{registry-dClAc8d-.js → registry-D1EIvc8U.js} +2 -2
  94. package/public/assets/{registry-dClAc8d-.js.map → registry-D1EIvc8U.js.map} +1 -1
  95. package/public/assets/{security-sGs_RWhJ.js → security-C0_Df9yI.js} +2 -2
  96. package/public/assets/{security-sGs_RWhJ.js.map → security-C0_Df9yI.js.map} +1 -1
  97. package/public/assets/{select-AzzgLRfk.js → select-CXFXPZ7Z.js} +2 -2
  98. package/public/assets/{select-AzzgLRfk.js.map → select-CXFXPZ7Z.js.map} +1 -1
  99. package/public/assets/settings-DGPpdFoq.js +6 -0
  100. package/public/assets/{settings-A0LUC7z3.js.map → settings-DGPpdFoq.js.map} +1 -1
  101. package/public/assets/store-d-IbqTaD.js +9 -0
  102. package/public/assets/store-d-IbqTaD.js.map +1 -0
  103. package/public/assets/{tasks-QfihaEd7.js → tasks-B_epVa5b.js} +2 -2
  104. package/public/assets/{tasks-QfihaEd7.js.map → tasks-B_epVa5b.js.map} +1 -1
  105. package/public/assets/teams-D2hATpCD.js +2 -0
  106. package/public/assets/{teams-yi_-_mib.js.map → teams-D2hATpCD.js.map} +1 -1
  107. package/public/assets/{terminal-viewer-impl-BuXn1PG3.js → terminal-viewer-impl-CefeetWa.js} +3 -3
  108. package/public/assets/{terminal-viewer-impl-BuXn1PG3.js.map → terminal-viewer-impl-CefeetWa.js.map} +1 -1
  109. package/public/assets/types-Tv67voFu.js.map +1 -1
  110. package/public/assets/{use-keyboard-viewport-BAtKHKT6.js → use-keyboard-viewport-CeLM-PeW.js} +2 -2
  111. package/public/assets/{use-keyboard-viewport-BAtKHKT6.js.map → use-keyboard-viewport-CeLM-PeW.js.map} +1 -1
  112. package/public/assets/{user-avatar-D5hoY3pJ.js → user-avatar-BOGZ21O8.js} +2 -2
  113. package/public/assets/{user-avatar-D5hoY3pJ.js.map → user-avatar-BOGZ21O8.js.map} +1 -1
  114. package/public/assets/{work-queue-pZe5uRpJ.js → work-queue-C9wBOivX.js} +2 -2
  115. package/public/assets/{work-queue-pZe5uRpJ.js.map → work-queue-C9wBOivX.js.map} +1 -1
  116. package/public/assets/{workspaces-DVh1TmHX.js → workspaces-DKFmnOF8.js} +3 -3
  117. package/public/assets/{workspaces-DVh1TmHX.js.map → workspaces-DKFmnOF8.js.map} +1 -1
  118. package/public/index.html +21 -21
  119. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  120. package/src/agent-busy-health.ts +45 -3
  121. package/src/codex-wham-quota.ts +4 -1
  122. package/src/config-store.ts +16 -5
  123. package/src/config.ts +7 -0
  124. package/src/db/provider-quotas.ts +60 -15
  125. package/src/mcp/index.ts +22 -0
  126. package/src/runtime-tokens.ts +3 -1
  127. package/public/assets/MessageBubble-g4NKZBDI.js +0 -3
  128. package/public/assets/branch-state-badge-T6t16OU5.js +0 -2
  129. package/public/assets/channels-C0J-VHEa.js +0 -2
  130. package/public/assets/chat-KKQrWEE_.js +0 -2
  131. package/public/assets/chat-KKQrWEE_.js.map +0 -1
  132. package/public/assets/copy-button-gB8Wc3dh.js +0 -2
  133. package/public/assets/dist-4Joy6mhT.js +0 -2
  134. package/public/assets/dist-4O7O9HEE.js +0 -2
  135. package/public/assets/dist-B2WymQRX.js +0 -2
  136. package/public/assets/index-D9oZL47o.js +0 -23
  137. package/public/assets/index-D9oZL47o.js.map +0 -1
  138. package/public/assets/index-DcyinRQU.css +0 -2
  139. package/public/assets/lucide-react-BMjjWU36.js +0 -9
  140. package/public/assets/settings-A0LUC7z3.js +0 -6
  141. package/public/assets/store-Bfl3XVmS.js +0 -9
  142. package/public/assets/store-Bfl3XVmS.js.map +0 -1
  143. package/public/assets/teams-yi_-_mib.js +0 -2
@@ -53,6 +53,7 @@ type ProviderQuotaSnapshotRow = {
53
53
 
54
54
  type StoredQuotaState = QuotaState & {
55
55
  _windowUpdatedAt?: Record<string, number>;
56
+ _windowSource?: Record<string, string>;
56
57
  };
57
58
 
58
59
  function cleanKey(value: string): string {
@@ -270,6 +271,7 @@ function parseStoredQuotaState(value: string, fallback: QuotaState): StoredQuota
270
271
  return {
271
272
  ...publicQuotaState(quota),
272
273
  ...(quota._windowUpdatedAt && typeof quota._windowUpdatedAt === "object" ? { _windowUpdatedAt: quota._windowUpdatedAt } : {}),
274
+ ...(quota._windowSource && typeof quota._windowSource === "object" ? { _windowSource: quota._windowSource } : {}),
273
275
  };
274
276
  }
275
277
 
@@ -284,15 +286,37 @@ function storedQuotaWindowSampleTimes(quota: StoredQuotaState): Map<string, numb
284
286
  return times;
285
287
  }
286
288
 
287
- function quotaWithWindowSampleTimes(quota: QuotaState, times: Map<string, number>): StoredQuotaState {
289
+ // Source priority for per-window precedence: "ingest" (WHAM/API) beats "probe" (agent self-report).
290
+ const QUOTA_SOURCE_PRIORITY: Record<string, number> = { ingest: 3, header: 2, probe: 1, statusline: 0 };
291
+ function quotaSourcePriority(source: string): number {
292
+ return QUOTA_SOURCE_PRIORITY[source] ?? 1;
293
+ }
294
+
295
+ function storedQuotaWindowSources(quota: StoredQuotaState): Map<string, string> {
296
+ const sources = new Map<string, string>();
297
+ const rawSources = quota._windowSource && typeof quota._windowSource === "object" ? quota._windowSource : {};
298
+ for (const window of quota.windows) {
299
+ const key = quotaWindowKey(window);
300
+ const value = rawSources[key];
301
+ if (typeof value === "string") sources.set(key, value);
302
+ }
303
+ return sources;
304
+ }
305
+
306
+ function quotaWithWindowSampleTimes(quota: QuotaState, times: Map<string, number>, sources?: Map<string, string>): StoredQuotaState {
288
307
  const windowUpdatedAt: Record<string, number> = {};
308
+ const windowSource: Record<string, string> = {};
289
309
  for (const window of quota.windows) {
290
- const timestamp = times.get(quotaWindowKey(window));
291
- if (timestamp !== undefined) windowUpdatedAt[quotaWindowKey(window)] = timestamp;
310
+ const key = quotaWindowKey(window);
311
+ const timestamp = times.get(key);
312
+ if (timestamp !== undefined) windowUpdatedAt[key] = timestamp;
313
+ const src = sources?.get(key);
314
+ if (src !== undefined) windowSource[key] = src;
292
315
  }
293
- return Object.keys(windowUpdatedAt).length > 0
294
- ? { ...quota, _windowUpdatedAt: windowUpdatedAt }
295
- : quota;
316
+ const hasUpdatedAt = Object.keys(windowUpdatedAt).length > 0;
317
+ const hasSrc = Object.keys(windowSource).length > 0;
318
+ if (!hasUpdatedAt && !hasSrc) return quota;
319
+ return { ...quota, ...(hasUpdatedAt ? { _windowUpdatedAt: windowUpdatedAt } : {}), ...(hasSrc ? { _windowSource: windowSource } : {}) };
296
320
  }
297
321
 
298
322
  function quotaWindowSampleTimes(provider: string, accountKey: string, fallback?: StoredQuotaState): Map<string, number> {
@@ -327,11 +351,14 @@ function mergeQuotaWindows(existing: StoredQuotaState | undefined, incoming: Quo
327
351
  } {
328
352
  if (!existing) {
329
353
  const times = new Map(incoming.windows.map((window) => [quotaWindowKey(window), incoming.updatedAt]));
330
- return { quota: quotaWithWindowSampleTimes(incoming, times), acceptedIncomingWindow: true };
354
+ const sources = new Map(incoming.windows.map((window) => [quotaWindowKey(window), incoming.source]));
355
+ return { quota: quotaWithWindowSampleTimes(incoming, times, sources), acceptedIncomingWindow: true };
331
356
  }
332
357
  const existingTimes = quotaWindowSampleTimes(provider, accountKey, existing);
358
+ const existingSources = storedQuotaWindowSources(existing);
333
359
  const incomingByKey = new Map(incoming.windows.map((window) => [quotaWindowKey(window), window]));
334
360
  const mergedTimes = new Map<string, number>();
361
+ const mergedSources = new Map<string, string>();
335
362
  let acceptedIncomingWindow = false;
336
363
  let updatedAt = existing.updatedAt;
337
364
  let source = existing.source;
@@ -339,22 +366,39 @@ function mergeQuotaWindows(existing: StoredQuotaState | undefined, incoming: Quo
339
366
  const key = quotaWindowKey(window);
340
367
  const incomingWindow = incomingByKey.get(key);
341
368
  const existingUpdatedAt = existingTimes.get(key) ?? existing.updatedAt;
369
+ const existingSource = existingSources.get(key) ?? existing.source;
342
370
  if (!incomingWindow) {
343
- mergedTimes.set(key, existingUpdatedAt);
344
- return window;
371
+ mergedTimes.set(key, existingUpdatedAt); mergedSources.set(key, existingSource); return window;
372
+ }
373
+ // Per-window source precedence is symmetric in BOTH directions (#712, #716):
374
+ // - A higher-priority existing value is kept even against a newer lower-priority reading.
375
+ // - A higher-priority incoming value (e.g. authoritative WHAM `ingest`) overrides the stored
376
+ // value outright, bypassing the timestamp + regression guards below. Those guards exist to
377
+ // reject a noisy lower-or-equal source's improbable swing (a wedged probe self-report) — they
378
+ // must NOT block authoritative data correcting a stale probe that pinned the window high.
379
+ const existingPriority = quotaSourcePriority(existingSource);
380
+ const incomingPriority = quotaSourcePriority(incoming.source);
381
+ if (existingPriority > incomingPriority) {
382
+ mergedTimes.set(key, existingUpdatedAt); mergedSources.set(key, existingSource); return window;
383
+ }
384
+ if (incomingPriority > existingPriority) {
385
+ acceptedIncomingWindow = true;
386
+ updatedAt = Math.max(updatedAt, incoming.updatedAt);
387
+ source = incoming.source;
388
+ mergedTimes.set(key, incoming.updatedAt); mergedSources.set(key, incoming.source);
389
+ return incomingWindow;
345
390
  }
391
+ // Same-priority sources: prefer the newer reading and guard against an improbable regression.
346
392
  if (incoming.updatedAt < existingUpdatedAt) {
347
- mergedTimes.set(key, existingUpdatedAt);
348
- return window;
393
+ mergedTimes.set(key, existingUpdatedAt); mergedSources.set(key, existingSource); return window;
349
394
  }
350
395
  if (quotaWindowUtilizationRegressed(window, incomingWindow)) {
351
- mergedTimes.set(key, existingUpdatedAt);
352
- return window;
396
+ mergedTimes.set(key, existingUpdatedAt); mergedSources.set(key, existingSource); return window;
353
397
  }
354
398
  acceptedIncomingWindow = true;
355
399
  updatedAt = Math.max(updatedAt, incoming.updatedAt);
356
400
  source = incoming.source;
357
- mergedTimes.set(key, incoming.updatedAt);
401
+ mergedTimes.set(key, incoming.updatedAt); mergedSources.set(key, incoming.source);
358
402
  return incomingWindow;
359
403
  });
360
404
  const existingKeys = new Set(existing.windows.map(quotaWindowKey));
@@ -365,8 +409,9 @@ function mergeQuotaWindows(existing: StoredQuotaState | undefined, incoming: Quo
365
409
  updatedAt = Math.max(updatedAt, incoming.updatedAt);
366
410
  source = incoming.source;
367
411
  mergedTimes.set(quotaWindowKey(window), incoming.updatedAt);
412
+ mergedSources.set(quotaWindowKey(window), incoming.source);
368
413
  }
369
- return { quota: quotaWithWindowSampleTimes({ windows, source, updatedAt }, mergedTimes), acceptedIncomingWindow };
414
+ return { quota: quotaWithWindowSampleTimes({ windows, source, updatedAt }, mergedTimes, mergedSources), acceptedIncomingWindow };
370
415
  }
371
416
 
372
417
  function rowToSnapshot(row: ProviderQuotaSnapshotRow): ProviderQuotaSnapshot {
package/src/mcp/index.ts CHANGED
@@ -39,6 +39,23 @@ const TOOLS: ToolDefinition[] = [
39
39
  ...NTFY_TOOLS,
40
40
  ];
41
41
 
42
+ // Tool group membership (#551). Each tool belongs to exactly one group; toolGroups in the token
43
+ // constraints lists which groups are enabled (absent = all). This is the surface/eager layer on
44
+ // top of scope-gating — scope enforcement at tools/call stays authoritative.
45
+ export const RELAY_TOOL_GROUPS: Record<string, readonly string[]> = {
46
+ core: ["relay_whoami", "relay_send_message", "relay_reply", "relay_get_message", "relay_get_thread", "relay_find_agents"],
47
+ memory: ["relay_recall", "relay_compact_and_resume"],
48
+ artifacts: ["relay_upload_artifact", "relay_attach_artifact"],
49
+ workspace: ["relay_workspace_status", "relay_workspace_ready", "relay_workspace_deps", "relay_workspace_list", "relay_workspace_claim", "relay_workspace_release", "relay_workspace_land", "relay_merge_pause", "relay_merge_pauses", "relay_merge_renew", "relay_merge_resume"],
50
+ "spawn-lifecycle": ["relay_spawn_agent", "relay_spawn_targets", "relay_my_agents", "relay_shutdown_agent", "relay_agent_action", "relay_agent_status", "relay_agent_crash_report", "relay_schedule_timer", "relay_list_timers", "relay_cancel_timer"],
51
+ plans: ["relay_plan_create", "relay_plan_add_node", "relay_plan_update_node", "relay_plan_add_edge", "relay_plan_remove_node", "relay_plan_remove_edge", "relay_plan_delete", "relay_plan_get"],
52
+ teams: ["relay_team_get", "relay_team_set_brief", "relay_team_claim", "relay_team_dissolve"],
53
+ blackboard: ["relay_blackboard_write", "relay_blackboard_get", "relay_blackboard_read", "relay_blackboard_search", "relay_blackboard_retract"],
54
+ project: ["relay_project_list", "relay_project_get", "relay_project_add_root", "relay_project_write_entry", "relay_project_read", "relay_project_search", "relay_project_retract", "relay_project_add_edge", "relay_project_remove_edge", "relay_project_promote_entry", "relay_project_ingest_claudemd"],
55
+ issues: ["relay_issue_ref_upsert", "relay_issue_ref_resolve", "relay_issue_ref_get", "relay_issue_ref_list", "relay_issue_ref_update", "relay_issue_ref_delete", "relay_issue_association_associate", "relay_issue_association_list_issues_for_entity", "relay_issue_association_list_entities_for_issue", "relay_issue_association_remove", "relay_issue_activity_record", "relay_issue_activity_by_issue", "relay_issue_activity_by_agent", "relay_issue_lifecycle_reopen"],
56
+ subscriptions: ["relay_subscribe", "relay_unsubscribe", "relay_list_subscriptions", "relay_why_notified", "relay_notification_preview", "relay_notify_ntfy"],
57
+ };
58
+
42
59
  export async function postMcp(req: Request): Promise<Response> {
43
60
  const parsed = await parseJsonRpcRequest(req);
44
61
  if (!parsed.ok) return Response.json(jsonRpcError(null, -32700, parsed.error), { status: parsed.status });
@@ -164,8 +181,13 @@ async function callTool(auth: McpAuthContext, params: unknown): Promise<Record<s
164
181
  }
165
182
 
166
183
  function visibleTools(auth: McpAuthContext): Array<Record<string, unknown>> {
184
+ const enabledGroups = auth.component?.constraints?.toolGroups;
185
+ const allowedNames = enabledGroups
186
+ ? new Set(enabledGroups.flatMap((g) => RELAY_TOOL_GROUPS[g] ?? []))
187
+ : null;
167
188
  return TOOLS
168
189
  .filter((tool) => hasAnyScope(auth, tool.requiredScopes))
190
+ .filter((tool) => !allowedNames || allowedNames.has(tool.name))
169
191
  .map(({ name, description, alwaysLoad, ...tool }) => ({
170
192
  name,
171
193
  description,
@@ -1,6 +1,6 @@
1
1
  import { createToken, getTokenProfile, hardenStaleRevocation, revokeToken } from "./token-db";
2
2
  import { verifyComponentTokenAllowExpired } from "./security";
3
- import { spawnGrantForProfile } from "./config-store";
3
+ import { spawnGrantForProfile, toolGroupsForProfile } from "./config-store";
4
4
  import type { TokenRecord } from "./types";
5
5
 
6
6
  // Scopes that turn an agent's runtime token into a spawn-capable one (#221). Appended to the
@@ -112,6 +112,7 @@ export function issueRunnerRuntimeToken(input: {
112
112
  projectId?: string;
113
113
  }): RuntimeTokenResult {
114
114
  const grant = spawnGrantForProfile(input.profile, input.agentInitiated);
115
+ const toolGroups = toolGroupsForProfile(input.profile);
115
116
  const subject = input.policyName
116
117
  ? `runner:policy:${input.policyName}`
117
118
  : input.spawnRequestId
@@ -131,6 +132,7 @@ export function issueRunnerRuntimeToken(input: {
131
132
  ...(input.spawnedBy ? { spawnedBy: input.spawnedBy } : {}),
132
133
  ...(input.teamId ? { teamId: input.teamId } : {}),
133
134
  ...(input.projectId ? { projectId: input.projectId } : {}),
135
+ ...(toolGroups ? { toolGroups } : {}),
134
136
  },
135
137
  createdBy: input.createdBy ?? "runtime",
136
138
  });
@@ -1,3 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{B as t,En as n,Et as r,Gn as i,I as a,Jt as o,Ln as s,Rn as c,Rt as l,Tt as u,Yn as d,Yt as f,_n as p,a as m,an as h,b as g,c as _,ct as v,dt as y,g as b,hn as x,i as S,jn as C,m as w,mn as ee,nn as T,on as te,or as E,pn as D,qn as O,r as k,vn as A,y as j,yn as M,z as ne}from"./lucide-react-BMjjWU36.js";import{g as N,r as re,t as P}from"./store-Bfl3XVmS.js";import{E as F,H as ie,N as I,P as L,R,S as ae,V as oe,_ as se,d as ce,f as le,k as z,q as B,rt as V,v as ue}from"./display-DRiGi1zj.js";import{t as H}from"./types-Tv67voFu.js";import{a as de,i as fe,o as pe,t as U,w as W}from"./index-D9oZL47o.js";import{t as me}from"./user-avatar-D5hoY3pJ.js";var G=e(E(),1),he={online:`came online`,offline:`went offline`,shutdown:`shut down`,restarted:`restarted`,"compaction-requested":`compaction requested`,compacting:`compaction started`,compacted:`context compacted`,"compaction-stalled":`compaction stalled — may need manual intervention`,"clear-requested":`clear requested`,"clearing-context":`clear started`,"context-cleared":`context cleared`,"clear-stalled":`context clear stalled — may need manual intervention`,"shutting-down":`shutting down`},ge=new Set(Object.keys(he)),_e=3e3;function K(e){return new Date(e.occurredAt??e.createdAt).getTime()}function ve(e){if(e.kind!==`session`)return null;let t=e.payload?.session;return!t||t.type!==`narration`&&t.type!==`reasoning`&&t.type!==`tool`?null:{id:e.id,kind:t.type,label:typeof t.label==`string`?t.label:void 0,text:e.body,ts:K(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function ye(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`notice`)return null;let n=typeof t.label==`string`&&t.label?t.label:`compacted`;return{id:`notice-${e.id}`,status:n,timestamp:K(e)}}function be(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`relay-injection`)return null;let n=t.relayInjection&&typeof t.relayInjection==`object`&&!Array.isArray(t.relayInjection)?t.relayInjection:{},r=typeof n.category==`string`&&[`memory`,`instructions`,`tools`,`comms`,`knowledge`,`context`].includes(n.category)?n.category:`context`,i=typeof n.timestamp==`number`&&Number.isFinite(n.timestamp)?n.timestamp:K(e),a=n.detail&&typeof n.detail==`object`&&!Array.isArray(n.detail)?n.detail:{};return{id:e.id,category:r,summary:typeof n.summary==`string`&&n.summary.trim()?n.summary:e.body,detail:a,agentId:typeof n.agentId==`string`&&n.agentId?n.agentId:e.from,timestamp:i}}function xe(e,t){let n=e.trim();for(let e of t){let t=e.trim();if(t){if(n===t)break;n.startsWith(`${t}\n\n`)&&(n=n.slice(t.length+2).trimStart())}}return n.trim()||e.trim()}function Se(e){return e.kind===`system`&&e.from===`system`}var Ce=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function q(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function we(e){let t=e.filter(e=>ge.has(e.status)).slice().sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let e of t)n.some(t=>t.id===e.id)||n.some(t=>t.status===e.status&&Math.abs(t.timestamp-e.timestamp)<=_e)||n.push(e);return n}function Te(e,t,n,r=[],i){let a=[];for(let e of r){let t=e.entries.reduce((e,t)=>Math.min(e,B(t.originalCreatedAt)),1/0),n=Number.isFinite(t)?t-1:e.importedAt;a.push({ts:n,entry:{type:`import-boundary`,history:e,timestamp:n}});for(let t of e.entries)a.push({ts:B(t.originalCreatedAt),entry:{type:`imported-message`,history:e,entry:t}})}if(n){let e=new Date(n).getTime();Number.isFinite(e)&&a.push({ts:e,entry:{type:`created`,timestamp:e}})}if(i?.spawnedBy){let e=n?new Date(n).getTime():0,t=Number.isFinite(e)?e:0;a.push({ts:t,entry:{type:`agent-action`,direction:`spawned-by`,agentId:i.spawnedBy.agentId,provider:i.spawnedBy.provider,status:`ready`,timestamp:t}})}let o=i?.spawnedBy?.agentId,s=null,c=1/0;for(let t of e){if(t.kind===`session`||Se(t)||F(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!z(t).trim())continue;let e=K(t);e<c&&(c=e,s=t.id)}let l=new Map,u=new Map,d=new Map;for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type===`narration`&&typeof e.turnId==`string`){let n=u.get(e.turnId)??[];n.push({id:t.id,body:t.body.trim()}),u.set(e.turnId,n)}else if(e?.type===`response`&&typeof e.turnId==`string`){let n=l.get(e.turnId)??[];n.push(t.body.trim()),l.set(e.turnId,n)}}let f=new Map;for(let[e,t]of l){let n=(u.get(e)??[]).map(e=>e.body);f.set(e,t.map(e=>xe(e,n)))}for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type!==`response`||typeof e.turnId!=`string`)continue;let n=xe(t.body,(u.get(e.turnId)??[]).map(e=>e.body));n&&n!==t.body&&d.set(t.id,n)}let p=new Set;for(let[e,t]of f){let n=u.get(e)??[];for(let e of t)for(let t=n.length-1;t>=0;t--){let r=n[t];if(!p.has(r.id)&&ie(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(Se(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(Ce.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=K(t);if(!r){a.push({ts:i,entry:{type:`notice`,msg:t}});continue}let o=e===`agent.ready`?`ready`:e===`agent.exited`?`exited`:`failed`,s=m.get(r);if(s)s.entry.status=o,typeof n.reason==`string`&&(s.entry.reason=n.reason),s.entry.timestamp=i,s.ts=i;else{let e={ts:i,entry:{type:`agent-action`,direction:`spawned-child`,agentId:r,provider:typeof n.provider==`string`?n.provider:void 0,status:o,reason:typeof n.reason==`string`?n.reason:void 0,timestamp:i}};m.set(r,e),a.push(e)}continue}a.push({ts:K(t),entry:{type:`notice`,msg:t}});continue}let e=ye(t);if(e){h.push(e);continue}let n=ve(t);if(n){if(n.kind===`narration`&&p.has(n.id))continue;a.push({ts:n.ts,entry:{type:`activity`,steps:[n],timestamp:n.ts}});continue}let r=be(t);if(r){a.push({ts:r.timestamp,entry:{type:`relay-injection`,event:r}});continue}if(t.kind===`session`){let e=t.payload?.session;if(e?.type===`response`&&typeof e.turnId==`string`){let e=d.get(t.id);if(e&&e!==t.body){a.push({ts:K(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let i=t.id===s?`initial-prompt`:`message`;a.push({ts:K(t),entry:{type:i,msg:t}})}for(let e of we([...t,...h]))a.push({ts:e.timestamp,entry:{type:`status`,event:e}});let g={created:0,date:1,"import-boundary":2,"imported-message":3,"initial-prompt":4,message:4,activity:4,notice:4,"agent-action":4,"relay-injection":4,status:5};a.sort((e,t)=>{let n=e.ts-t.ts;return Math.abs(n)<3e3&&g[e.entry.type]-g[t.entry.type]||n});let _=[],v=``;for(let{ts:e,entry:t}of a){if(t.type===`created`){_.push(t);continue}let n=q(e);if(n!==v&&(_.push({type:`date`,date:n,timestamp:e}),v=n),t.type===`activity`){let e=_[_.length-1];if(e&&e.type===`activity`&&Oe(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function Ee(e){return e.type===`message`?`msg-${e.msg.id}`:e.type===`initial-prompt`?`initprompt-${e.msg.id}`:e.type===`notice`?`notice-${e.msg.id}`:e.type===`relay-injection`?`relay-injection-${e.event.id}`:e.type===`agent-action`?`agent-action-${e.direction}-${e.agentId}`:e.type===`activity`?`act-${e.steps[0]?.id??e.timestamp}`:e.type===`import-boundary`?`import-${e.history.id}`:e.type===`imported-message`?`import-msg-${e.history.id}-${e.entry.originalMessageId}-${e.entry.position}`:e.type===`status`?`status-${e.event.id}`:e.type===`date`?`date-${e.date}`:`created-${e.timestamp}`}function De(e){return e.type===`message`||e.type===`initial-prompt`||e.type===`notice`?(e.msg.subject?`${e.msg.subject} `:``)+z(e.msg):e.type===`imported-message`?z(e.entry.message):e.type===`activity`?e.steps.map(e=>[e.label,e.text].filter(Boolean).join(` `)).join(`
2
- `):e.type===`relay-injection`?`${e.event.category} ${e.event.summary}\n${JSON.stringify(e.event.detail)}`:``}function Oe(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function ke(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Ae(e,t){if(t.startsWith(`/`))return t;let n=`${e.replace(/\/+$/,``)}/${t}`.split(`/`),r=[];for(let e of n)!e||e===`.`||(e===`..`?r.pop():r.push(e));return`/`+r.join(`/`)}function je(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function Me(e,t){return e.filter(e=>e.status===`online`&&R(t,e.baseDir)).sort((e,t)=>I(t.baseDir).length-I(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function Ne(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function Pe(){return typeof window<`u`&&!!window.getSelection()?.toString()}function Fe(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var Ie=[`👍`,`❤️`,`✅`,`👀`];function Le(e){let t=new Map;for(let n of e.reactions||[]){let e=L(n.emoji),r=t.get(e)??{emoji:e,count:0,mine:!1,actors:[]};r.count+=1,r.mine=r.mine||n.actorId===`user`,r.actors.push(n.actorId),t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count||e.emoji.localeCompare(t.emoji))}function J(e){return F(e)}function Re(e,t){let n=e.readBy||[],r=e.resolvedToAgent||t||e.to,i=r?n.includes(r):!1,a=n.some(e=>e!==V);if(i||a){let e=i?r:n.find(e=>e!==V);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:M}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:M};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:T};if(e.deliveryStatus===`failed`||e.deliveryStatus===`dead`){let t=e.deliveryPoisonReason||e.deliveryLastError||e.deliveryStatus;return{label:e.deliveryStatus,title:t,tone:`danger`,icon:D}}return{label:`sent`,title:`Accepted by Relay`,tone:`muted`,icon:A}}function ze(e){let t=B(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,B(t.updatedAt||t.createdAt)),t)}function Be(e){return e?e.messages.reduce((e,t)=>Math.max(e,ze(t)),0):0}function Ve(e,t,n){return(e-t)*n}function He(e){if(!e)return 0;let t=0;for(let n of e.messages)ae(n)&&(t=Math.max(t,B(n.createdAt)));return t}function Y(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function Ue(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function We(e,t,n,r){if(e?.teamId)return{teamId:e.teamId};let i=[...t];n&&!i.some(e=>e.id===n.id)&&i.push(n);let a=i.filter(e=>e.threadId).reverse(),o=a.find(e=>!!r[re(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var X=O(),Ge={online:`text-emerald-400`,offline:`text-zinc-400`,shutdown:`text-zinc-400`,restarted:`text-blue-400`,"compaction-requested":`text-zinc-400`,compacting:`text-amber-400`,compacted:`text-amber-400`,"compaction-stalled":`text-red-400`,"clear-requested":`text-zinc-400`,"clearing-context":`text-amber-400`,"context-cleared":`text-amber-400`,"clear-stalled":`text-red-400`,"shutting-down":`text-zinc-400`};function Ke(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===q(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===q(o.getTime())?`Yesterday`:a.toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`,year:a.getFullYear()===t.getFullYear()?void 0:`numeric`})}function qe({event:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,X.jsx)(h,{className:i(`w-2 h-2 fill-current`,Ge[e.status]||`text-zinc-400`)}),(0,X.jsx)(`span`,{children:he[e.status]||e.status}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var Je={"branch.landed":u,"context.warning":w,"agent.context_threshold":w,"agent.resume_budget_exhausted":w,"agent.rate_limit_resume":t},Ye={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function Xe(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function Z({agentId:e,fallbackLabel:t,className:n,noIcon:r}){let a=P(t=>t.agentsById[e])||null,o=P(e=>e.openInboxThread),s=P(e=>e.switchView),c=a?ce(a):t||e;return(0,X.jsxs)(`button`,{type:`button`,className:i(`inline-flex max-w-full items-center gap-1 rounded px-1 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,n),onClick:t=>{t.stopPropagation(),o(e),s(`chat`)},title:`Open chat for ${c}`,children:[!r&&(0,X.jsx)(W,{agent:a,className:`w-4 h-4 text-[10px]`}),(0,X.jsx)(`span`,{className:`max-w-[160px] truncate`,children:c})]})}function Ze({msg:e}){let t=e.payload??{},n=$e(e),r=typeof t.sha==`string`?t.sha:``,i=r?r.slice(0,7):``,a=typeof t.author==`string`?t.author:``,o=typeof t.branch==`string`?t.branch:``,s=typeof t.base==`string`?t.base:``,c=t.pushed;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex max-w-full flex-wrap items-center justify-center gap-x-1.5 gap-y-0.5 rounded-full border border-emerald-600/35 bg-emerald-500/10 px-2.5 py-1 text-xs text-emerald-700 dark:border-emerald-500/25 dark:text-emerald-300/90`,children:[(0,X.jsx)(u,{className:`h-3 w-3 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,X.jsx)(`span`,{className:`text-emerald-700 dark:text-emerald-300`,children:`branch landed`}),o&&s&&(0,X.jsxs)(`span`,{className:`font-mono text-emerald-700/80 dark:text-emerald-200/70`,title:`${o} → ${s}`,children:[o,(0,X.jsx)(`span`,{className:`opacity-50`,children:` → `}),s]}),i&&(0,X.jsx)(`span`,{className:`rounded bg-emerald-500/15 px-1 font-mono text-emerald-800 dark:text-emerald-200`,title:r,children:i}),a&&(0,X.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-700/80 dark:text-emerald-300/80`,children:[(0,X.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,X.jsx)(Z,{agentId:a,className:`text-emerald-700 hover:text-emerald-900 dark:text-emerald-300/90 dark:hover:text-emerald-100`})]}),c===!1&&(0,X.jsx)(`span`,{className:`text-amber-600 dark:text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),n&&(0,X.jsxs)(`span`,{className:`max-w-[220px] truncate text-emerald-700/70 dark:text-emerald-300/70`,title:n,children:[`· because `,n]}),(0,X.jsx)(`span`,{className:`text-emerald-700/60 dark:text-emerald-300/50`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Qe({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,X.jsx)(Ze,{msg:e});let n=Je[t]??a,r=Ye[t]??Xe(t),i=$e(e);return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-2.5 py-1 text-xs text-muted-foreground`,children:[(0,X.jsx)(n,{className:`h-3 w-3`}),(0,X.jsx)(`span`,{children:r}),i&&(0,X.jsxs)(`span`,{className:`max-w-[220px] truncate text-muted-foreground/80`,title:i,children:[`· because `,i]}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function $e(e){let t=e.payload?.routing;if(!t||typeof t!=`object`||Array.isArray(t))return``;let n=t.reason;return typeof n==`string`?n:``}var et={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},tt={"spawned-child-ready":ne,"spawned-child-exited":v,"spawned-child-failed":D,"spawned-by-ready":c,"spawned-by-exited":c,"spawned-by-failed":c},nt={"spawned-child-ready":`text-emerald-400`,"spawned-child-exited":`text-zinc-400`,"spawned-child-failed":`text-red-400`,"spawned-by-ready":`text-blue-400`,"spawned-by-exited":`text-blue-400`,"spawned-by-failed":`text-blue-400`};function rt({entry:e}){let t=`${e.direction}-${e.status}`,n=et[e.direction]?.[e.status]??e.direction,r=tt[t]??a,o=nt[t]??`text-muted-foreground`,s=e.status===`failed`;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:i(`flex items-center gap-1.5 rounded-full border bg-muted/30 px-2.5 py-1 text-xs`,s?`border-red-500/30`:`border-border`),children:[(0,X.jsx)(r,{className:i(`h-3 w-3 shrink-0`,o)}),(0,X.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,X.jsx)(Z,{agentId:e.agentId}),e.reason&&s&&(0,X.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var it={memory:n,instructions:l,tools:m,comms:a,knowledge:C,context:f},at={memory:`border-emerald-500/25 bg-emerald-500/10 text-emerald-300`,instructions:`border-sky-500/25 bg-sky-500/10 text-sky-300`,tools:`border-amber-500/25 bg-amber-500/10 text-amber-300`,comms:`border-violet-500/25 bg-violet-500/10 text-violet-300`,knowledge:`border-cyan-500/25 bg-cyan-500/10 text-cyan-300`,context:`border-zinc-500/25 bg-zinc-500/10 text-zinc-300`};function ot(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function st({entry:e}){let[t,n]=(0,G.useState)(!1),r=e.event,a=it[r.category]??j;return(0,X.jsx)(`div`,{className:`flex justify-center py-2 my-1`,children:(0,X.jsxs)(`div`,{className:i(`w-full max-w-[85%] md:max-w-[75%] rounded-lg border px-2.5 py-1.5 text-xs shadow-sm`,at[r.category]??at.context),children:[(0,X.jsxs)(`button`,{type:`button`,className:`flex w-full min-w-0 items-center gap-1.5 text-left`,onClick:()=>n(e=>!e),children:[(0,X.jsx)(a,{className:`h-3.5 w-3.5 shrink-0`}),(0,X.jsx)(`span`,{className:`shrink-0 font-medium`,children:r.category}),(0,X.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-foreground/80`,children:r.summary}),(0,X.jsx)(`span`,{className:`shrink-0 text-muted-foreground/60`,children:Y(r.timestamp)}),(0,X.jsx)(x,{className:i(`h-3.5 w-3.5 shrink-0 transition-transform`,t&&`rotate-90`)})]}),t&&(0,X.jsx)(`pre`,{className:`mt-2 max-h-72 overflow-auto rounded-md border border-border/60 bg-background/75 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground whitespace-pre-wrap break-words`,children:ot(r.detail)})]})})}function ct({blockedLabel:e,onInterrupt:t}){return e?(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-red-500/30 px-4`,children:[(0,X.jsx)(D,{className:`w-3.5 h-3.5 text-red-400`}),(0,X.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-foreground/10 px-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.2s_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.4s_infinite]`})]}),(0,X.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,X.jsxs)(`button`,{onClick:t,title:`Interrupt`,className:`ml-1 flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs text-muted-foreground hover:text-red-300 hover:bg-red-500/10 transition-colors`,children:[(0,X.jsx)(te,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var Q=`agent-relay:chat-hide-tools`,$=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(Q)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===Q&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(Q,t?`on`:`off`)}catch{}n()}}})();function lt(){return[(0,G.useSyncExternalStore)($.subscribe,$.get,()=>!1),$.toggle]}function ut({steps:e,showReasoning:t,issueRepo:r}){let[a,o]=lt(),s=t?e:e.filter(e=>e.kind!==`reasoning`);if(!s.length)return null;let c=s.filter(e=>e.kind===`tool`).length;return(0,X.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,X.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[s.map(e=>e.kind===`narration`?(0,X.jsx)(U,{text:e.text,issueRepo:r,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,X.jsx)(n,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,X.jsx)(U,{text:e.text,issueRepo:r,className:`italic break-words min-w-0`})]},e.id):a?null:(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,X.jsx)(b,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,X.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,X.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,X.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),c>0&&(0,X.jsxs)(`button`,{onClick:o,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,X.jsx)(x,{className:i(`w-3 h-3 shrink-0 transition-transform`,!a&&`rotate-90`)}),(0,X.jsx)(`span`,{children:a?`show ${c} tool step${c===1?``:`s`}`:`hide tool steps`})]})]})})}function dt({date:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:Ke(e)}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function ft({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function pt({history:e}){let t=e.sourceAgentLabel||e.sourcePeerId,n=e.entries.length;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-dashed border-border bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground`,children:[(0,X.jsx)(r,{className:`h-3 w-3`}),(0,X.jsxs)(`span`,{children:[`forked history from `,t]}),(0,X.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[n,` `,n===1?`entry`:`entries`]})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function mt({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,a=z(r),o=e.originalFrom===V;return(0,X.jsx)(`div`,{className:i(`flex mb-3 opacity-80`,o?`justify-end`:`justify-start`),children:(0,X.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,X.jsxs)(`div`,{className:i(`rounded-2xl border border-dashed px-3.5 py-2 text-sm select-text`,o?`border-primary/25 bg-primary/10 text-foreground rounded-br-sm`:`border-border bg-card/70 rounded-bl-sm`),children:[(0,X.jsxs)(`div`,{className:i(`mb-1 text-[10px] uppercase tracking-normal`,o?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,o?`you`:t||e.originalFrom]}),(0,X.jsx)(U,{text:a,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,X.jsxs)(`p`,{className:i(`mt-1 flex items-center justify-end gap-1.5 text-xs`,o?`text-primary/60`:`text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,X.jsx)(`span`,{children:Y(e.originalCreatedAt)})]})]})})})}function ht({msg:e,issueRepo:t}){let n=z(e),r=Y(e.occurredAt??e.createdAt);return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,X.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,X.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,X.jsx)(j,{className:`h-3.5 w-3.5`}),(0,X.jsx)(`span`,{children:`Initial prompt`}),(0,X.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,X.jsx)(U,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function gt({scrollEl:e,timeline:t}){let[n,r]=(0,G.useState)(!0),[a,o]=(0,G.useState)(null),[s,c]=(0,G.useState)(null),[l,u]=(0,G.useState)(!1),d=(0,G.useMemo)(()=>{for(let e=t.length-1;e>=0;e--){let n=t[e];if(!(!n||n.type!==`message`&&n.type!==`initial-prompt`)&&n.msg.from===`user`)return{id:n.msg.id,body:z(n.msg)}}return null},[t]);if((0,G.useEffect)(()=>{if(!d||!e){r(!0);return}let t=null,n=null,i=()=>{let i=e.querySelector(`[data-msg-id="${d.id}"]`);if(!i){t?.disconnect(),t=null,n=null,r(!1);return}let a=i.getBoundingClientRect(),o=e.getBoundingClientRect();u(a.top<o.top),i!==n&&(t?.disconnect(),n=i,t=new IntersectionObserver(([e])=>{e&&r(e.isIntersecting)},{root:e,threshold:0}),t.observe(i))};return i(),e.addEventListener(`scroll`,i,{passive:!0}),()=>{t?.disconnect(),e.removeEventListener(`scroll`,i)}},[d?.id,e]),n||!d||!d.body.trim())return null;let f=a?.id===d.id?a.value:!1,m=s?.id===d.id?s.value:!1;function h(){!e||!d||e.querySelector(`[data-msg-id="${d.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let g=l?`↑`:`↓`;return m?(0,X.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,X.jsxs)(`button`,{type:`button`,className:`w-full flex items-center justify-center gap-1.5 py-1 text-[11px] text-primary/60 hover:text-primary transition-colors`,onClick:()=>c({id:d.id,value:!1}),children:[(0,X.jsx)(`span`,{children:`Your prompt`}),(0,X.jsx)(p,{className:`w-3 h-3`})]})}):(0,X.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,X.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,X.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:h,children:[g,` scroll to original`]}),(0,X.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>c({id:d.id,value:!0}),title:`Minimize`,children:(0,X.jsx)(ee,{className:`w-3 h-3`})})]}),(0,X.jsx)(`p`,{className:i(`text-sm text-foreground leading-snug cursor-pointer`,!f&&`line-clamp-2`),onClick:()=>o({id:d.id,value:!f}),children:d.body})]})}function _t(){return(0,G.useSyncExternalStore)(e=>N.subscribe(e),()=>N.getPlayingKey(),()=>null)}function vt({msg:e,peer:t}){return(0,X.jsx)(ht,{msg:e,issueRepo:P(e=>e.agentsById[t]?.issueRepo)})}function yt({agent:e,onClick:t}){let n=!!(t&&e);return(0,X.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:i(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,X.jsx)(W,{agent:e})})}function bt({agentId:e,onOpen:t}){let n=P(t=>t.agentsById[e]??null);return(0,X.jsx)(yt,{agent:n,onClick:n?()=>t(n):void 0})}function xt({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[a,s]=(0,G.useState)(null),[c,u]=(0,G.useState)(null),[f,p]=(0,G.useState)(!1),[m,h]=(0,G.useState)(!1);(0,G.useEffect)(()=>{let t=!1,n=null;async function r(){p(!0),u(null),s(null);try{let r=await d(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),s(n)}catch(e){t||u(e.message)}finally{t||p(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function g(){if(!a)return;let e=document.createElement(`a`);e.href=a,e.download=r,document.body.appendChild(e),e.click(),e.remove()}return n?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`button`,{type:`button`,onClick:()=>a&&h(!0),disabled:!a,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:a?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`img`,{src:a,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,X.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,X.jsx)(k,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,X.jsxs)(`span`,{className:i(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,c?`text-red-400`:`text-muted-foreground`),children:[f?(0,X.jsx)(y,{className:`h-4 w-4 animate-spin`}):(0,X.jsx)(D,{className:`h-4 w-4`}),c||`Loading image`]})}),a&&(0,X.jsx)(fe,{open:m,onOpenChange:h,children:(0,X.jsxs)(de,{className:`max-w-[95vw] max-h-[95vh] w-auto p-0 bg-black/95 border-zinc-800 gap-0 overflow-hidden`,showCloseButton:!1,children:[(0,X.jsx)(pe,{className:`sr-only`,children:r}),(0,X.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,X.jsx)(`img`,{src:a,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,X.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,X.jsx)(`button`,{type:`button`,onClick:g,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,X.jsx)(o,{className:`w-4 h-4`})}),(0,X.jsx)(`button`,{type:`button`,onClick:()=>h(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,X.jsx)(S,{className:`w-4 h-4`})})]})]})]})})]}):(0,X.jsxs)(`button`,{type:`button`,onClick:g,disabled:!a,className:i(`mt-2 flex w-full items-center gap-2 rounded-md border px-2.5 py-2 text-left text-xs transition-colors disabled:cursor-default disabled:opacity-70`,t?`border-primary-foreground/20 bg-primary-foreground/10 hover:bg-primary-foreground/15`:`border-border bg-background hover:bg-muted`),children:[f?(0,X.jsx)(y,{className:`h-4 w-4 shrink-0 animate-spin`}):c?(0,X.jsx)(D,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,X.jsx)(l,{className:`h-4 w-4 shrink-0`}),(0,X.jsx)(`span`,{className:i(`min-w-0 flex-1 truncate`,c&&`text-red-400`),children:c||r}),(0,X.jsx)(o,{className:`h-3.5 w-3.5 shrink-0`})]})}function St({open:e,onToggle:t,onReact:n}){return(0,X.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,X.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:i(`inline-flex h-5 w-6 items-center justify-center rounded-full border border-border bg-popover text-muted-foreground shadow-sm transition hover:bg-muted hover:text-foreground`,e?`opacity-100`:`opacity-0 pointer-events-none md:group-hover/msg:opacity-100 md:group-hover/msg:pointer-events-auto`),children:(0,X.jsx)(g,{className:`h-3 w-3`})}),e&&(0,X.jsx)(`div`,{className:`absolute bottom-full left-0 z-30 mb-1 flex gap-0.5 rounded-full border border-border bg-popover p-0.5 shadow-md`,children:Ie.map(e=>(0,X.jsx)(`button`,{type:`button`,title:`React ${e}`,onClick:()=>n(e),className:`inline-flex h-6 w-7 items-center justify-center rounded-full text-xs transition-colors hover:bg-muted`,children:e},e))})]})}function Ct({msg:e,peer:t}){let[n,r]=(0,G.useState)(!1),a=P(e=>e.agentsById),o=P(e=>e.openAgentDetail),l=e.from===t,u=(l?e.to:e.from)||``,d=a[l?t:u]?.issueRepo??a[t]?.issueRepo,f=!u||u===`broadcast`||u.includes(`:`),p=z(e),m=Y(e.occurredAt??e.createdAt),h=l?s:c,g=a[e.from??``]??null;function _(e){e.stopPropagation(),g&&o(g)}return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,X.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>r(e=>!e),children:[(0,X.jsx)(x,{className:i(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,n&&`rotate-90`)}),(0,X.jsx)(`button`,{type:`button`,title:g?g.label||g.name||g.id:void 0,disabled:!g,onClick:_,className:i(`shrink-0 transition-opacity`,g?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,X.jsx)(W,{agent:g,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,X.jsx)(h,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,X.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,l?`to`:`from`]}),f?(0,X.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:le(u,a)}):(0,X.jsx)(Z,{agentId:u,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!n&&(0,X.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:p}),(0,X.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:m})]}),n&&(0,X.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,X.jsx)(U,{text:p,rawBody:e.body,issueRepo:d,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var wt=(0,G.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:a,onPreviewReferencedPathEnd:o}){if(!H(e.from)&&!H(e.to))return(0,X.jsx)(Ct,{msg:e,peer:t});let s=e.kind===`session`?e.payload?.session:void 0;if(s?.type===`prompt`&&s?.origin===`provider`)return(0,X.jsx)(vt,{msg:e,peer:t});let c=H(e.from),l=P(e=>e.reactToMessage),u=P(e=>e.voiceTtsEnabled),d=_t(),f=P(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),p=P(e=>e.agentsById[t]?.issueRepo),m=P(e=>e.usersById),h=P(e=>e.users.length>1),g=c?oe(e.from,m):void 0,v=P(e=>e.openAgentDetail),[y,b]=(0,G.useState)(!1),x=(0,G.useRef)(null),S=(0,G.useRef)(null),C=(0,G.useRef)(!1),w=z(e),ee=Y(e.occurredAt??e.createdAt),T=Fe(e),E=Le(e),D=c?Re(e,t):null,O=D?.icon,k=d===String(e.id),A=u&&!c&&!J(e)&&w.trim().length>0;function j(t){t.stopPropagation(),k?N.bargeIn():N.speak(e.body,String(e.id))}(0,G.useEffect)(()=>{if(!y)return;function e(e){Pe()||x.current&&!x.current.contains(e.target)&&b(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[y]);function M(e){return Ae(f||`/`,e)}function ne(e,t){let n=M(e);r?.(n,t)}function re(e,t,n){let r=M(e);a?.(r,t,n)}function F(t){l(e,t),b(!1)}function ie(e){e.button===0&&(S.current={x:e.clientX,y:e.clientY},C.current=!1)}function I(e){let t=S.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(C.current=!0)}function L(t){if(!(J(e)||c)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(C.current||Pe()){C.current=!1;return}b(e=>!e)}}let R=n&&!J(e);return(0,X.jsxs)(`div`,{"data-msg-id":e.id,className:i(`group/msg flex mb-3 items-end`,c?`justify-end`:`justify-start`,R&&`gap-1.5`),children:[!c&&R&&(0,X.jsx)(bt,{agentId:t,onOpen:v}),(0,X.jsxs)(`div`,{ref:x,className:i(`relative`,R?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[A&&(0,X.jsx)(`button`,{type:`button`,title:k?`Stop playback`:`Play aloud`,onClick:j,className:i(`absolute -top-2 -right-2 z-20 inline-flex h-6 w-6 items-center justify-center rounded-full border bg-popover shadow-sm transition`,k?`border-primary/50 text-primary opacity-100`:`border-border text-muted-foreground opacity-70 hover:bg-muted hover:text-foreground hover:opacity-100 [@media(hover:hover)]:md:opacity-0 [@media(hover:hover)]:md:group-hover/msg:opacity-100`),children:k?(0,X.jsx)(te,{className:`h-3.5 w-3.5 animate-pulse`}):(0,X.jsx)(_,{className:`h-3.5 w-3.5`})}),(0,X.jsxs)(`div`,{className:i(`rounded-2xl px-3.5 py-2 text-sm select-text`,!c&&!J(e)&&`cursor-pointer`,c?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:ie,onPointerMove:I,onClick:L,children:[c&&h&&(0,X.jsx)(`p`,{className:i(`text-[11px] font-semibold mb-0.5 text-right`,se(e.from)),children:ue(e.from,m)}),e.subject&&(0,X.jsx)(`p`,{className:i(`text-xs font-semibold mb-1`,c?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,X.jsx)(U,{text:w,rawBody:e.body,issueRepo:p,className:`leading-relaxed`,onPrimary:c,onOpenPath:ne,onPreviewPath:re,onPreviewPathEnd:o,resolvePathTitle:(e,t)=>`${M(e)}${t?`:${t}`:``}`}),T.map(t=>(0,X.jsx)(xt,{attachment:t,outbound:c},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,X.jsxs)(`p`,{className:i(`text-xs mt-1 flex items-center gap-1.5`,c?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,X.jsx)(`span`,{children:ee}),D&&O&&(0,X.jsxs)(`span`,{className:i(`inline-flex items-center gap-1`,D.tone===`ok`&&`text-emerald-300`,D.tone===`warn`&&`text-amber-200`,D.tone===`danger`&&`text-red-200`),title:D.title,children:[(0,X.jsx)(O,{className:`h-3 w-3`}),D.label]})]})]}),!J(e)&&E.length>0&&(0,X.jsxs)(`div`,{className:i(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,c?`justify-end pr-2`:`justify-start pl-2`),children:[!c&&(0,X.jsx)(St,{open:y,onToggle:()=>b(e=>!e),onReact:F}),E.map(e=>(0,X.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>F(e.emoji),className:i(`inline-flex h-5 items-center gap-0.5 rounded-full border px-1.5 text-[11px] shadow-sm transition-colors`,e.mine?`border-primary/40 bg-primary/10 text-primary`:`border-border bg-background hover:bg-muted text-foreground`),children:[(0,X.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,X.jsx)(`span`,{children:e.count})]},e.emoji))]}),!J(e)&&!c&&E.length===0&&(0,X.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,X.jsx)(St,{open:y,onToggle:()=>b(e=>!e),onReact:F})})]}),c&&R&&(0,X.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,X.jsx)(me,{user:g,address:e.from,distinct:h})})]})});export{Te as C,Be as S,De as T,Me as _,ft as a,Ue as b,mt as c,st as d,qe as f,He as g,ke as h,ct as i,ht as l,Ve as m,ut as n,dt as o,gt as p,rt as r,pt as s,wt as t,Qe as u,je as v,Ee as w,Ne as x,We as y};
3
- //# sourceMappingURL=MessageBubble-g4NKZBDI.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{Dt as t,Gn as n,Jn as r,a as i,an as a,fn as o,m as s,or as c,qn as l}from"./lucide-react-BMjjWU36.js";import{t as u}from"./store-Bfl3XVmS.js";var d=e(c(),1);function f(e){let t=u(e=>e.showError),[n,i]=(0,d.useState)(!1),[a,o]=(0,d.useState)(null),[s,c]=(0,d.useState)(!1);async function l(){if(!(!e||s)){c(!0);try{o(await r(`POST`,`/agents/`+encodeURIComponent(e)+`/terminal-session`)),i(!0)}catch(e){t(`Terminal Failed`,e.message)}finally{c(!1)}}}function f(t){if(t){i(!0);return}i(!1);let n=a;o(null),e&&n?.mode===`guest`&&r(`DELETE`,`/agents/`+encodeURIComponent(e)+`/terminal-session/`+encodeURIComponent(n.session)).catch(()=>{})}return{terminalOpen:n,terminalTarget:a,terminalOpening:s,openTerminal:l,closeTerminal:f}}var p=l(),m={idle:{label:`idle`,tip:`Branch worktree — nothing to land yet.`,className:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`,Icon:a},changes:{label:`changes`,tip:`Unlanded work in this branch — use "Mark workspace ready" to land it.`,className:`bg-amber-500/10 text-amber-400 border-amber-500/20`,Icon:t},ready:{label:`ready`,tip:`Handed off — the relay auto-merge will land it (~2 min sweep).`,className:`bg-blue-500/10 text-blue-400 border-blue-500/20`,Icon:o},steward:{label:`steward`,tip:`Under reconciliation — a steward is landing it. No action needed.`,className:`bg-orange-500/10 text-orange-400 border-orange-500/20`,Icon:i},blocked:{label:`blocked`,tip:`Escalated — the auto-merge/steward path is stuck. Needs human attention.`,className:`bg-red-500/10 text-red-400 border-red-500/20`,Icon:s}};function h({state:e,onClick:t,iconOnly:r=!1,className:i}){let a=m[e],{Icon:o}=a,s=!!t,c=s?`${a.tip} Click to open this workspace.`:a.tip;return(0,p.jsxs)(`span`,{role:s?`button`:void 0,tabIndex:s?0:void 0,title:c,onClick:t,onKeyDown:s?e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),t?.(e))}:void 0,className:n(`inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium leading-none`,a.className,s&&`cursor-pointer hover:brightness-125 focus:outline-none focus:ring-1 focus:ring-current`,i),children:[(0,p.jsx)(o,{className:`h-2.5 w-2.5 shrink-0`}),!r&&(0,p.jsx)(`span`,{children:a.label})]})}export{f as n,h as t};
2
- //# sourceMappingURL=branch-state-badge-T6t16OU5.js.map
@@ -1,2 +0,0 @@
1
- import{$ as e,Ln as t,Rn as n,Wt as r,qn as i,zn as a}from"./lucide-react-BMjjWU36.js";import{l as o,t as s}from"./store-Bfl3XVmS.js";import{J as c,K as l,Y as u,c as d,s as f}from"./display-DRiGi1zj.js";import{t as p}from"./badge-CcTIPkUa.js";import{t as m}from"./button-Dvz6HZ1j.js";import{a as h,o as g,r as _,t as v}from"./card-xVEUTFuh.js";var y=i();function b({direction:e}){return e===`inbound`?(0,y.jsx)(n,{className:`w-3 h-3`}):e===`outbound`?(0,y.jsx)(t,{className:`w-3 h-3`}):(0,y.jsx)(a,{className:`w-3 h-3`})}function x({channel:t}){let n=o(),i=s(e=>e.openChannelDetail),a=d(t),f=t.status!==`offline`;return(0,y.jsxs)(v,{className:`${f?``:`opacity-60`} hover:border-zinc-600 transition-colors`,children:[(0,y.jsx)(h,{className:`pb-2 pt-4 px-4`,children:(0,y.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,y.jsx)(`div`,{className:`p-1.5 rounded-md ${f?`bg-blue-500/10`:`bg-zinc-800`}`,children:(0,y.jsx)(e,{className:`w-4 h-4 ${f?`text-blue-400`:`text-zinc-500`}`})}),(0,y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,y.jsx)(g,{className:`text-sm font-medium truncate`,children:t.name||t.id}),(0,y.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:[t.type,` · `,t.transport]})]}),(0,y.jsx)(p,{className:`text-[10px] shrink-0 ${c(a.tone)}`,children:a.label})]})}),(0,y.jsxs)(_,{className:`px-4 pb-4 space-y-2.5`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,y.jsx)(b,{direction:t.direction}),(0,y.jsx)(`span`,{className:`capitalize`,children:t.direction}),t.target&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`span`,{children:`·`}),(0,y.jsx)(`span`,{className:`truncate text-foreground`,children:t.target})]})]}),t.targetHealth&&t.targetHealth.status!==`ok`&&(0,y.jsx)(`div`,{className:`text-xs px-2 py-1 rounded ${t.targetHealth.status===`error`?`bg-red-500/10 text-red-400`:`bg-yellow-500/10 text-yellow-400`}`,children:t.targetHealth.detail}),u(t.capabilities).length>0&&(0,y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:u(t.capabilities).map(e=>(0,y.jsx)(p,{variant:`secondary`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))}),t.tags.length>0&&(0,y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:t.tags.map(e=>(0,y.jsx)(p,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))}),(0,y.jsxs)(`div`,{className:`flex items-center justify-between pt-0.5`,children:[(0,y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:l(n,t.lastSeen)}),(0,y.jsxs)(m,{size:`sm`,variant:`outline`,className:`h-7 text-xs gap-1`,onClick:()=>i(t),children:[(0,y.jsx)(r,{className:`w-3 h-3`}),`Details`]})]})]})]})}function S(){let e=s(e=>e.channels),t=e.filter(f).length,n=e.filter(e=>e.targetHealth?.status===`error`).length,r=e.filter(e=>e.targetHealth?.status===`warning`).length;return(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Channels`}),(0,y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Inbound / outbound message integrations`})]}),(0,y.jsxs)(`div`,{className:`flex items-center gap-2 ml-auto`,children:[t>0&&(0,y.jsxs)(p,{className:`text-xs bg-emerald-500/15 text-emerald-400 border-emerald-500/30`,children:[t,` ready`]}),r>0&&(0,y.jsxs)(p,{className:`text-xs bg-yellow-500/15 text-yellow-400 border-yellow-500/30`,children:[r,` warning`]}),n>0&&(0,y.jsxs)(p,{className:`text-xs bg-red-500/15 text-red-400 border-red-500/30`,children:[n,` error`]})]})]}),e.length===0?(0,y.jsx)(`div`,{className:`text-center py-16 text-muted-foreground text-sm`,children:`No channels registered.`}):(0,y.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4`,children:e.map(e=>(0,y.jsx)(x,{channel:e},e.id))})]})}export{S as ChannelsView};
2
- //# sourceMappingURL=channels-C0J-VHEa.js.map