agent-relay-server 0.102.2 → 0.104.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 (128) hide show
  1. package/docs/openapi.json +1 -1
  2. package/package.json +4 -2
  3. package/public/assets/MessageBubble-BpiTbbnp.js +4 -0
  4. package/public/assets/{MessageBubble-Dppo7pil.js.map → MessageBubble-BpiTbbnp.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-DO5OY2qa.js → PlanGraphPanel-k8Aa98g5.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-DO5OY2qa.js.map → PlanGraphPanel-k8Aa98g5.js.map} +1 -1
  7. package/public/assets/{activity-BhuOs5ha.js → activity-CxKi5Erb.js} +2 -2
  8. package/public/assets/{activity-BhuOs5ha.js.map → activity-CxKi5Erb.js.map} +1 -1
  9. package/public/assets/agent-profiles-DMZXdN6K.js +2 -0
  10. package/public/assets/agent-profiles-DMZXdN6K.js.map +1 -0
  11. package/public/assets/agents-BrvpH3gn.js +2 -0
  12. package/public/assets/agents-BrvpH3gn.js.map +1 -0
  13. package/public/assets/{analytics-BxGRljQc.js → analytics-1fvh-9ok.js} +2 -2
  14. package/public/assets/{analytics-BxGRljQc.js.map → analytics-1fvh-9ok.js.map} +1 -1
  15. package/public/assets/automation-BCgX5WOH.js +2 -0
  16. package/public/assets/automation-BCgX5WOH.js.map +1 -0
  17. package/public/assets/{branch-state-badge-olhanssg.js → branch-state-badge-DYA7bU0i.js} +2 -2
  18. package/public/assets/{branch-state-badge-olhanssg.js.map → branch-state-badge-DYA7bU0i.js.map} +1 -1
  19. package/public/assets/{channels-yHkm1dux.js → channels-CK80oJYG.js} +2 -2
  20. package/public/assets/{channels-yHkm1dux.js.map → channels-CK80oJYG.js.map} +1 -1
  21. package/public/assets/chat-D_2PEz06.js +2 -0
  22. package/public/assets/chat-D_2PEz06.js.map +1 -0
  23. package/public/assets/{connectors-DpR0V2hy.js → connectors-ChGyht5m.js} +2 -2
  24. package/public/assets/{connectors-DpR0V2hy.js.map → connectors-ChGyht5m.js.map} +1 -1
  25. package/public/assets/display-D1xB8NJZ.js +3 -0
  26. package/public/assets/display-D1xB8NJZ.js.map +1 -0
  27. package/public/assets/{formatted-body-impl-BTeCfK4I.js → formatted-body-impl-BJ4WCF5J.js} +2 -2
  28. package/public/assets/{formatted-body-impl-BTeCfK4I.js.map → formatted-body-impl-BJ4WCF5J.js.map} +1 -1
  29. package/public/assets/index-BMO_Sblt.css +2 -0
  30. package/public/assets/index-CN7QZlMb.js +23 -0
  31. package/public/assets/index-CN7QZlMb.js.map +1 -0
  32. package/public/assets/{insights-C4aYlgsY.js → insights-BCZRV0hX.js} +2 -2
  33. package/public/assets/{insights-C4aYlgsY.js.map → insights-BCZRV0hX.js.map} +1 -1
  34. package/public/assets/{integrations-CEmYa5mW.js → integrations-C7UGs00U.js} +2 -2
  35. package/public/assets/{integrations-CEmYa5mW.js.map → integrations-C7UGs00U.js.map} +1 -1
  36. package/public/assets/maintenance-ChYno3Fm.js +2 -0
  37. package/public/assets/{maintenance-DVx3SiC_.js.map → maintenance-ChYno3Fm.js.map} +1 -1
  38. package/public/assets/{managed-agents-DUyOTdz1.js → managed-agents-DjxZQNIR.js} +4 -4
  39. package/public/assets/managed-agents-DjxZQNIR.js.map +1 -0
  40. package/public/assets/{markdown-preview-impl-D3hYfzGD.js → markdown-preview-impl-DFa5HF1H.js} +2 -2
  41. package/public/assets/{markdown-preview-impl-D3hYfzGD.js.map → markdown-preview-impl-DFa5HF1H.js.map} +1 -1
  42. package/public/assets/{memory-2IfPgcnN.js → memory-CTw6kadT.js} +2 -2
  43. package/public/assets/{memory-2IfPgcnN.js.map → memory-CTw6kadT.js.map} +1 -1
  44. package/public/assets/{messages-CkOwABhw.js → messages-Cjr816D_.js} +2 -2
  45. package/public/assets/{messages-CkOwABhw.js.map → messages-Cjr816D_.js.map} +1 -1
  46. package/public/assets/{orchestrators-CEKO3eQ1.js → orchestrators-CdmFKA7K.js} +2 -2
  47. package/public/assets/{orchestrators-CEKO3eQ1.js.map → orchestrators-CdmFKA7K.js.map} +1 -1
  48. package/public/assets/overview-DBOnjfpP.js +2 -0
  49. package/public/assets/{overview-D9BxevAq.js.map → overview-DBOnjfpP.js.map} +1 -1
  50. package/public/assets/{pairs-CqT4D1uL.js → pairs-BkcdKdF7.js} +2 -2
  51. package/public/assets/{pairs-CqT4D1uL.js.map → pairs-BkcdKdF7.js.map} +1 -1
  52. package/public/assets/{projects-C_zwR-Fn.js → projects-ClKbDQB1.js} +2 -2
  53. package/public/assets/{projects-C_zwR-Fn.js.map → projects-ClKbDQB1.js.map} +1 -1
  54. package/public/assets/registry-Bsf3RtOO.js +2 -0
  55. package/public/assets/registry-Bsf3RtOO.js.map +1 -0
  56. package/public/assets/{security-8a5_4U3S.js → security-Iyu5bhJw.js} +2 -2
  57. package/public/assets/{security-8a5_4U3S.js.map → security-Iyu5bhJw.js.map} +1 -1
  58. package/public/assets/{select-s4BE-T62.js → select-Bi6tNJDx.js} +2 -2
  59. package/public/assets/{select-s4BE-T62.js.map → select-Bi6tNJDx.js.map} +1 -1
  60. package/public/assets/settings-CbHp2F9r.js +6 -0
  61. package/public/assets/settings-CbHp2F9r.js.map +1 -0
  62. package/public/assets/store-zeyDiSKE.js +9 -0
  63. package/public/assets/store-zeyDiSKE.js.map +1 -0
  64. package/public/assets/{tasks-Bcr17zR3.js → tasks-CPlf-5Tr.js} +2 -2
  65. package/public/assets/{tasks-Bcr17zR3.js.map → tasks-CPlf-5Tr.js.map} +1 -1
  66. package/public/assets/teams-D2uUNhlY.js +2 -0
  67. package/public/assets/{teams-B_HSkU9T.js.map → teams-D2uUNhlY.js.map} +1 -1
  68. package/public/assets/{terminal-viewer-impl-Ctp4csJ3.js → terminal-viewer-impl-uRzbrlXy.js} +2 -2
  69. package/public/assets/{terminal-viewer-impl-Ctp4csJ3.js.map → terminal-viewer-impl-uRzbrlXy.js.map} +1 -1
  70. package/public/assets/types-DorDDvEb.js +2 -0
  71. package/public/assets/types-DorDDvEb.js.map +1 -0
  72. package/public/assets/{user-avatar-RliaJcaG.js → user-avatar-GFWMuAGK.js} +2 -2
  73. package/public/assets/{user-avatar-RliaJcaG.js.map → user-avatar-GFWMuAGK.js.map} +1 -1
  74. package/public/assets/{work-queue-C0hpmlv8.js → work-queue-B30SNmuq.js} +2 -2
  75. package/public/assets/{work-queue-C0hpmlv8.js.map → work-queue-B30SNmuq.js.map} +1 -1
  76. package/public/assets/{workspaces-QXbQx_AG.js → workspaces-CSpmgbPT.js} +3 -3
  77. package/public/assets/{workspaces-QXbQx_AG.js.map → workspaces-CSpmgbPT.js.map} +1 -1
  78. package/public/index.html +5 -5
  79. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  80. package/runner/plugins/claude/monitors/relay-monitor.provisioned.mjs +238 -16
  81. package/runner/src/config.ts +8 -3
  82. package/src/automations/validation.ts +3 -3
  83. package/src/cli/orchestrator.ts +7 -5
  84. package/src/cli/provider.ts +26 -10
  85. package/src/cli/upgrade.ts +5 -4
  86. package/src/commands-db.ts +1 -1
  87. package/src/config-store.ts +3 -3
  88. package/src/config.ts +3 -3
  89. package/src/context-advisory.ts +3 -3
  90. package/src/db/provider-quotas.ts +11 -2
  91. package/src/db/provisioning-registry.ts +49 -61
  92. package/src/managed-policy.ts +7 -2
  93. package/src/mcp/tools-spawn.ts +2 -2
  94. package/src/mcp-team-template-tools.ts +2 -2
  95. package/src/provider-catalog-store.ts +1 -1
  96. package/src/recipe-validator.ts +4 -2
  97. package/src/routes/agent-profiles.ts +2 -2
  98. package/src/routes/agent-sessions.ts +18 -23
  99. package/src/routes/provider-config.ts +1 -1
  100. package/src/spawn-targets.ts +2 -2
  101. package/src/upgrade.ts +120 -44
  102. package/src/workspace-phase.ts +1 -0
  103. package/public/assets/MessageBubble-Dppo7pil.js +0 -4
  104. package/public/assets/agent-profiles-CT-vbfzd.js +0 -2
  105. package/public/assets/agent-profiles-CT-vbfzd.js.map +0 -1
  106. package/public/assets/agents-CLcgi8AD.js +0 -2
  107. package/public/assets/agents-CLcgi8AD.js.map +0 -1
  108. package/public/assets/automation-CE1i1zpw.js +0 -2
  109. package/public/assets/automation-CE1i1zpw.js.map +0 -1
  110. package/public/assets/chat-DHdFZvAg.js +0 -2
  111. package/public/assets/chat-DHdFZvAg.js.map +0 -1
  112. package/public/assets/display-DRiGi1zj.js +0 -3
  113. package/public/assets/display-DRiGi1zj.js.map +0 -1
  114. package/public/assets/index-CKhh9XRZ.css +0 -2
  115. package/public/assets/index-DeDosfVE.js +0 -23
  116. package/public/assets/index-DeDosfVE.js.map +0 -1
  117. package/public/assets/maintenance-DVx3SiC_.js +0 -2
  118. package/public/assets/managed-agents-DUyOTdz1.js.map +0 -1
  119. package/public/assets/overview-D9BxevAq.js +0 -2
  120. package/public/assets/registry-BLjwVXCW.js +0 -2
  121. package/public/assets/registry-BLjwVXCW.js.map +0 -1
  122. package/public/assets/settings-BR30UpbJ.js +0 -6
  123. package/public/assets/settings-BR30UpbJ.js.map +0 -1
  124. package/public/assets/store-DNbkrqbU.js +0 -9
  125. package/public/assets/store-DNbkrqbU.js.map +0 -1
  126. package/public/assets/teams-B_HSkU9T.js +0 -2
  127. package/public/assets/types-Tv67voFu.js +0 -2
  128. package/public/assets/types-Tv67voFu.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  // Auto-split from routes.ts (#299). Domain: agent-sessions.
2
- import { RELAY_TOKEN_HEADER, isRecord } from "agent-relay-sdk";
2
+ import { RELAY_TOKEN_HEADER, isRecord, isSpawnProvider } from "agent-relay-sdk";
3
3
  import { VALID_AGENT_ACTIONS, agentControlActionIcon, auditEvent, authAuditMetadata, authorizeAgentRoute, authorizeRoute, canViewAgentRoute, cleanAttachmentRefs, dashboardAttribution, emitCommand, error, json, metaString, parseBody, requestUserAddress, requestUserId, spawnRequestId, type AgentControlAction, type Handler } from "./_shared";
4
4
  import { arbitrateDrive, currentDriver, drivingMessage, releaseDrive, type DriveArbitration } from "../agent-drive-arbiter";
5
5
  import { ValidationError, getAgent, getAgentTimeline, getOrchestrator, markReady, mergeAgentMeta, sendMessage, withResolvedProvisioning } from "../db";
@@ -18,10 +18,9 @@ import { authContextFromRequest } from "../services/auth-context";
18
18
  import { ShutdownAuthError, ShutdownTargetError, shutdownAgent } from "../services/shutdown-agent";
19
19
  import { type AgentCard, type SpawnApprovalMode } from "../types";
20
20
  import { type ProviderEffort } from "agent-relay-sdk/provider-catalog";
21
+ import { getManifest } from "agent-relay-providers";
21
22
  import { relayToken } from "../config";
22
23
 
23
- const CLAUDE_RESUME_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
24
-
25
24
  // 409 when a second human tries to drive an agent another user is already driving (#394). The
26
25
  // blocked driver learns who holds the wheel so the UI can show "X is driving" + offer "request".
27
26
  function driveBlockedResponse(arb: Extract<DriveArbitration, { allowed: false }>): Response {
@@ -61,7 +60,7 @@ function agentIsControlEligible(agent: AgentCard): boolean {
61
60
 
62
61
  function agentCanReceiveControlAction(agent: AgentCard, action: AgentControlAction): boolean {
63
62
  if (!agentIsControlEligible(agent)) return false;
64
- if (action === "resume") return agentRuntimeProvider(agent) === "claude" && (agent.status === "offline" || agent.status === "stale");
63
+ if (action === "resume") return getManifest(agentRuntimeProvider(agent) ?? "")?.resume?.supported === true && (agent.status === "offline" || agent.status === "stale");
65
64
  // Interrupt only makes sense while the provider is mid-turn, and only if the
66
65
  // provider advertises it can be interrupted from the dashboard.
67
66
  if (action === "interrupt") return agent.providerCapabilities?.liveSession?.interrupt === true && agent.status === "busy";
@@ -109,11 +108,11 @@ function restartSpawnParamsForAgent(
109
108
  const requestedBy = opts.resumeId ? "dashboard-resume" : "dashboard-restart";
110
109
  if (policy) {
111
110
  const params = { ...buildManagedSpawnParams(policy.value, requestId, { createdBy: "managed-agent" }), agentId: agent.id, requestedBy };
112
- return opts.resumeId ? withClaudeResumeParams(params, opts.resumeId, agent.id) : params;
111
+ return opts.resumeId ? withResumeParams(params, opts.resumeId, agent.id) : params;
113
112
  }
114
113
 
115
114
  const provider = metaString(agent.meta, "provider");
116
- if (provider !== "claude" && provider !== "codex") return undefined;
115
+ if (!isSpawnProvider(provider)) return undefined;
117
116
  const cwd = metaString(agent.meta, "cwd") ?? orchestrator.baseDir;
118
117
  const label = metaString(agent.meta, "label") ?? agent.label;
119
118
  const approvalMode = metaString(agent.meta, "approvalMode") as SpawnApprovalMode | undefined;
@@ -155,48 +154,44 @@ function restartSpawnParamsForAgent(
155
154
  requestedBy,
156
155
  requestedAt: Date.now(),
157
156
  });
158
- return opts.resumeId ? withClaudeResumeParams(params, opts.resumeId, agent.id) : params;
157
+ return opts.resumeId ? withResumeParams(params, opts.resumeId, agent.id) : params;
159
158
  }
160
159
 
161
160
  function spawnRequestIdForRestart(): string {
162
161
  return generateSpawnRequestId();
163
162
  }
164
163
 
165
- function withClaudeResumeParams(params: Record<string, unknown>, resumeId: string, agentId: string): Record<string, unknown> {
164
+ function withResumeParams(params: Record<string, unknown>, resumeId: string, agentId: string): Record<string, unknown> {
166
165
  return {
167
166
  ...params,
168
- providerArgs: providerArgsWithClaudeResume(recordStringArray(params.providerArgs), resumeId),
167
+ providerArgs: providerArgsWithResume(metaStringArray(params as Record<string, unknown>, "providerArgs"), resumeId),
169
168
  resumeOfAgentId: agentId,
170
169
  claudeResumeId: resumeId,
171
170
  };
172
171
  }
173
172
 
174
- function providerArgsWithClaudeResume(args: string[], resumeId: string): string[] {
173
+ function providerArgsWithResume(args: string[], resumeId: string): string[] {
175
174
  const cleaned: string[] = [];
176
175
  for (let i = 0; i < args.length; i += 1) {
177
176
  const arg = args[i];
178
177
  if (!arg) continue;
179
- if (arg === "--resume") {
180
- i += 1;
181
- continue;
182
- }
178
+ if (arg === "--resume") { i += 1; continue; }
183
179
  if (arg.startsWith("--resume=")) continue;
184
180
  cleaned.push(arg);
185
181
  }
186
182
  return [...cleaned, "--resume", resumeId];
187
183
  }
188
184
 
189
- function recordStringArray(value: unknown): string[] {
190
- return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string" && item.trim().length > 0) : [];
191
- }
192
-
193
- function latestClaudeResumeIdForAgent(agent: AgentCard): string | undefined {
185
+ function latestResumeIdForAgent(agent: AgentCard): string | undefined {
186
+ const provider = agentRuntimeProvider(agent);
187
+ const resume = getManifest(provider ?? "")?.resume as { supported: boolean; idPattern?: string } | undefined;
188
+ if (!provider || !resume?.supported) return undefined;
189
+ const re = resume.idPattern ? new RegExp(`^${resume.idPattern}$`, "i") : undefined;
194
190
  for (const entry of getAgentTimeline(agent.id, { limit: 50 })) {
195
191
  const metadata = entry.metadata;
196
192
  if (!metadata) continue;
197
- const provider = metaString(metadata, "provider");
198
193
  const resumeId = metaString(metadata, "claudeResumeId");
199
- if (provider === "claude" && resumeId && CLAUDE_RESUME_ID_RE.test(resumeId)) return resumeId;
194
+ if (metaString(metadata, "provider") === provider && resumeId && (!re || re.test(resumeId))) return resumeId;
200
195
  }
201
196
  return undefined;
202
197
  }
@@ -270,9 +265,9 @@ export const postAgentAction: Handler = async (req, params) => {
270
265
  const metaTmuxSession = typeof agent.meta?.tmuxSession === "string" ? agent.meta.tmuxSession : undefined;
271
266
  const metaPolicyName = typeof agent.meta?.policyName === "string" ? agent.meta.policyName : undefined;
272
267
  const metaSpawnRequestId = typeof agent.meta?.spawnRequestId === "string" ? agent.meta.spawnRequestId : undefined;
273
- const resumeId = action === "resume" ? latestClaudeResumeIdForAgent(agent) : undefined;
268
+ const resumeId = action === "resume" ? latestResumeIdForAgent(agent) : undefined;
274
269
  if (action === "resume" && !orchestrator) return error("no online orchestrator available to resume agent", 409);
275
- if (action === "resume" && !resumeId) return error("no Claude resume id recorded for agent", 422);
270
+ if (action === "resume" && !resumeId) return error("no resume id recorded for agent", 422);
276
271
  const denied = authorizeRoute(req, {
277
272
  scope: "agent:write",
278
273
  resource: { agentId: agent.id, orchestratorId: orchestrator?.id, policyName: metaPolicyName, spawnRequestId: metaSpawnRequestId },
@@ -29,7 +29,7 @@ export const getProviderConfigsRoute: Handler = (req) => {
29
29
  migrateLocalProviderConfigs();
30
30
  const entries = listProviderConfigEntries(host);
31
31
  return json(Object.fromEntries(VALID_PROVIDER_CONFIGS.map((provider) => {
32
- return [provider, providerConfigPublic(entries[provider])];
32
+ return [provider, providerConfigPublic(entries[provider] ?? getProviderConfigEntry(provider, host))];
33
33
  })));
34
34
  };
35
35
 
@@ -5,7 +5,7 @@ import { getRoutingPolicy } from "./routing-policy-store";
5
5
  import { isPathWithinBase } from "./utils";
6
6
  import { McpNotFoundError } from "./mcp-errors";
7
7
  import { DEFAULT_QUOTA_PREFER_SLACK_AT, DEFAULT_QUOTA_TARGET_UTILIZATION, quotaPaceMetrics } from "agent-relay-sdk/provider-quota";
8
- import type { ProviderQuotaRoutingConfig } from "agent-relay-sdk";
8
+ import { isSpawnProvider, type ProviderQuotaRoutingConfig } from "agent-relay-sdk";
9
9
  import type { Orchestrator, ProviderCatalogSummary, ProviderQuotaBurnRole, ProviderQuotaBurnWindow, ProviderQuotaRecord, QuotaState, SpawnProvider } from "./types";
10
10
 
11
11
  // #308 — spawn discovery + target selection. Home for the live capability matrix that
@@ -159,7 +159,7 @@ export function providerQuotaAdvisories(now = Date.now()): Map<SpawnProvider, Sp
159
159
  const policy = getRoutingPolicy();
160
160
  const byProvider = new Map<SpawnProvider, ProviderQuotaRecord[]>();
161
161
  for (const record of listProviderQuotas({ historyLimit: 0, now }).quotas) {
162
- if (record.provider !== "claude" && record.provider !== "codex") continue;
162
+ if (!isSpawnProvider(record.provider)) continue;
163
163
  const provider = record.provider;
164
164
  byProvider.set(provider, [...(byProvider.get(provider) ?? []), record]);
165
165
  }
package/src/upgrade.ts CHANGED
@@ -1,17 +1,18 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
+ import { getAllManifests, type ProviderManifest } from "agent-relay-providers";
4
5
  import { VERSION, cliRelayUrl, relayAuthHeaders } from "./config";
5
6
  import type { RuntimeContracts, RuntimePackageMetadata } from "./contracts";
6
7
  import { defaultRuntimePrefix, runtimeBinPath } from "./runtime-prefix";
7
8
  import { resolveLocalOrchestratorId } from "./upgrade-local-id";
8
9
  import { defaultInstallIo, packageName, verifyAndRepairInstall, type InstallIo, type VerifyInstall } from "./upgrade-install-verify";
9
- import { errMessage, runInstallWithRetry } from "agent-relay-sdk";
10
+ import { errMessage, runInstallWithRetry, type SpawnProvider } from "agent-relay-sdk";
10
11
  import { shellEscape as shellQuote } from "agent-relay-sdk/shell-utils";
11
12
 
12
13
  export { resolveLocalOrchestratorId } from "./upgrade-local-id";
13
14
 
14
- export type UpgradeProvider = "auto" | "all" | "codex" | "claude" | "orchestrator";
15
+ export type UpgradeProvider = "auto" | "all" | SpawnProvider | "orchestrator";
15
16
 
16
17
  type UpgradeOptions = {
17
18
  targetVersion?: string;
@@ -65,6 +66,8 @@ export type UpgradeSnapshot = {
65
66
  health?: { status?: string; restartRequired?: boolean };
66
67
  }>;
67
68
  packageManager: "runtime-npm" | "bun" | "npm" | "none";
69
+ installedPackages?: Record<string, InstalledPackage | undefined>;
70
+ availableCommands?: Record<string, boolean>;
68
71
  };
69
72
 
70
73
  type UpgradeAction = {
@@ -83,7 +86,7 @@ type UpgradeAction = {
83
86
 
84
87
  type UpgradePlan = {
85
88
  targetVersion: string;
86
- providers: { codex: boolean; claude: boolean; orchestrator: boolean };
89
+ providers: Record<string, boolean>;
87
90
  snapshot: UpgradeSnapshot;
88
91
  actions: UpgradeAction[];
89
92
  warnings: string[];
@@ -105,12 +108,18 @@ export async function detectUpgradeSnapshot(options: UpgradeOptions = {}): Promi
105
108
  const npmPackages = commandExists("npm", runtimePrefix) ? npmGlobalPackages() : new Map<string, string>();
106
109
  const codexCopiedPackage = readPackageVersion(join(homeDir(), ".agent-relay", "codex", "package", "package.json"));
107
110
  const claudePluginInstalls = readClaudePluginInstalls(join(homeDir(), ".claude", "plugins", "installed_plugins.json"));
111
+ const anyKnownPackage = (packages: Map<string, string>) => knownUpgradePackages().some((name) => packages.has(name));
112
+ const installedPackages = Object.fromEntries(knownUpgradePackages().map((name) => [
113
+ name,
114
+ installedPackage(name, runtimePrefix, runtimePackages, bunPackages, npmPackages),
115
+ ]));
116
+ const availableCommands = Object.fromEntries(knownUpgradeCommands().map((command) => [command, commandExists(command, runtimePrefix)]));
108
117
 
109
118
  const packageManager = commandExists("npm", runtimePrefix)
110
119
  ? "runtime-npm"
111
- : bunPackages.has("agent-relay-server") || bunPackages.has("agent-relay-runner") || bunPackages.has("agent-relay-codex") || bunPackages.has("agent-relay-plugin") || bunPackages.has("agent-relay-orchestrator")
120
+ : anyKnownPackage(bunPackages)
112
121
  ? "bun"
113
- : npmPackages.has("agent-relay-server") || npmPackages.has("agent-relay-runner") || npmPackages.has("agent-relay-codex") || npmPackages.has("agent-relay-plugin") || npmPackages.has("agent-relay-orchestrator")
122
+ : anyKnownPackage(npmPackages)
114
123
  ? "npm"
115
124
  : commandExists("bun", runtimePrefix)
116
125
  ? "bun"
@@ -130,14 +139,16 @@ export async function detectUpgradeSnapshot(options: UpgradeOptions = {}): Promi
130
139
  ? { version: codexCopiedPackage, source: "copied", path: join(homeDir(), ".agent-relay", "codex", "package") }
131
140
  : undefined,
132
141
  claudePluginInstalls,
133
- hasCodexCommand: commandExists("codex-relay", runtimePrefix) || commandExists("agent-relay-runner", runtimePrefix),
134
- hasOrchestratorCommand: commandExists("agent-relay-orchestrator", runtimePrefix),
135
- hasClaudeCommand: commandExists("claude", runtimePrefix),
142
+ hasCodexCommand: providerCommandDetected("codex", availableCommands),
143
+ hasOrchestratorCommand: availableCommands["agent-relay-orchestrator"] === true,
144
+ hasClaudeCommand: availableCommands.claude === true,
136
145
  hasSystemdUserService: hasSystemdUserService("agent-relay.service"),
137
146
  hasSystemdUserOrchestratorService: hasSystemdUserService("agent-relay-orchestrator.service"),
138
147
  runningServerVersion: await runningServerVersion(),
139
148
  runningOrchestrators: await runningOrchestrators(),
140
149
  packageManager,
150
+ installedPackages,
151
+ availableCommands,
141
152
  };
142
153
  }
143
154
 
@@ -145,45 +156,50 @@ export function createUpgradePlan(snapshot: UpgradeSnapshot, options: UpgradeOpt
145
156
  const targetVersion = options.targetVersion ?? snapshot.targetVersion;
146
157
  const requestedProviders = options.providers?.length ? options.providers : ["auto"];
147
158
  const providerSet = new Set(requestedProviders);
148
- const codexRequested = providerSet.has("all") || providerSet.has("codex") || (providerSet.has("auto") && isCodexDetected(snapshot));
149
- const claudeRequested = providerSet.has("all") || providerSet.has("claude") || (providerSet.has("auto") && isClaudeRelayDetected(snapshot));
159
+ const selectedProviders = Object.fromEntries(upgradableProviderManifests().map((manifest) => [
160
+ manifest.id,
161
+ providerSet.has("all") || providerSet.has(manifest.id) || (providerSet.has("auto") && isProviderDetected(snapshot, manifest)),
162
+ ]));
150
163
  const orchestratorRequested = providerSet.has("all") || providerSet.has("orchestrator") || (providerSet.has("auto") && isOrchestratorDetected(snapshot));
151
- const runnerRequested = codexRequested || claudeRequested;
164
+ const runnerRequested = upgradableProviderManifests().some((manifest) =>
165
+ selectedProviders[manifest.id] && manifest.upgrade?.packages.includes("agent-relay-runner"),
166
+ );
152
167
  const actions: UpgradeAction[] = [];
153
168
  const warnings: string[] = [];
154
- const packages: string[] = [];
169
+ const packages = new Set<string>();
155
170
  let serverPackageUpdated = false;
156
171
  let orchestratorPackageUpdated = false;
157
172
 
158
173
  if (packageNeedsUpgrade(snapshot.serverPackage, targetVersion)) {
159
- packages.push(`agent-relay-server@${targetVersion}`);
174
+ packages.add(`agent-relay-server@${targetVersion}`);
160
175
  serverPackageUpdated = true;
161
176
  }
162
- if (runnerRequested && packageNeedsUpgrade(snapshot.runnerPackage, targetVersion)) {
163
- packages.push(`agent-relay-runner@${targetVersion}`);
164
- }
165
- if (codexRequested && (snapshot.packageManager === "runtime-npm" || snapshot.codexPackage) && packageNeedsUpgrade(snapshot.codexPackage, targetVersion)) {
166
- packages.push(`agent-relay-codex@${targetVersion}`);
167
- }
168
- if (claudeRequested && (snapshot.packageManager === "runtime-npm" || snapshot.claudeGlobalPackage) && packageNeedsUpgrade(snapshot.claudeGlobalPackage, targetVersion)) {
169
- packages.push(`agent-relay-plugin@${targetVersion}`);
177
+ for (const manifest of upgradableProviderManifests()) {
178
+ if (!selectedProviders[manifest.id]) continue;
179
+ for (const providerPackage of manifest.upgrade?.packages ?? []) {
180
+ const installed = installedUpgradePackage(snapshot, providerPackage);
181
+ if ((snapshot.packageManager === "runtime-npm" || installed) && packageNeedsUpgrade(installed, targetVersion)) {
182
+ packages.add(`${providerPackage}@${targetVersion}`);
183
+ }
184
+ }
170
185
  }
171
186
  if (orchestratorRequested && packageNeedsUpgrade(snapshot.orchestratorPackage, targetVersion)) {
172
- packages.push(`agent-relay-orchestrator@${targetVersion}`);
187
+ packages.add(`agent-relay-orchestrator@${targetVersion}`);
173
188
  orchestratorPackageUpdated = true;
174
189
  }
175
190
 
176
191
  if (snapshot.packageManager === "none") {
177
- if (packages.length > 0) warnings.push("No supported global package manager found. Install Bun or npm, then rerun `agent-relay upgrade`.");
178
- } else if (packages.length > 0) {
192
+ if (packages.size > 0) warnings.push("No supported global package manager found. Install Bun or npm, then rerun `agent-relay upgrade`.");
193
+ } else if (packages.size > 0) {
194
+ const packageList = sortUpgradeSpecs([...packages]);
179
195
  // --prefer-online: revalidate the packument so a just-published version is
180
196
  // visible to this host's npm cache right away, avoiding the post-publish
181
197
  // ETARGET race (#211). bun add always hits the network for the spec.
182
198
  const command = snapshot.packageManager === "runtime-npm"
183
- ? ["npm", "install", "--prefer-online", "--prefix", snapshot.runtimePrefix, ...packages]
199
+ ? ["npm", "install", "--prefer-online", "--prefix", snapshot.runtimePrefix, ...packageList]
184
200
  : snapshot.packageManager === "bun"
185
- ? ["bun", "add", "-g", ...packages]
186
- : ["npm", "install", "--prefer-online", "-g", ...packages];
201
+ ? ["bun", "add", "-g", ...packageList]
202
+ : ["npm", "install", "--prefer-online", "-g", ...packageList];
187
203
  actions.push({
188
204
  label: snapshot.packageManager === "runtime-npm" ? "Upgrade runtime packages" : "Upgrade global packages",
189
205
  command,
@@ -194,7 +210,7 @@ export function createUpgradePlan(snapshot: UpgradeSnapshot, options: UpgradeOpt
194
210
  // can read actual versions from (and it's the systemd-managed deploy that
195
211
  // strands hosts on a silent no-op). Global bun/npm installs are left as-is.
196
212
  verifyInstall: snapshot.packageManager === "runtime-npm"
197
- ? { prefix: snapshot.runtimePrefix, targetVersion, packages: packages.map(packageName) }
213
+ ? { prefix: snapshot.runtimePrefix, targetVersion, packages: packageList.map(packageName) }
198
214
  : undefined,
199
215
  });
200
216
  if (snapshot.packageManager === "runtime-npm") {
@@ -215,16 +231,13 @@ export function createUpgradePlan(snapshot: UpgradeSnapshot, options: UpgradeOpt
215
231
  warnings.push(`Legacy Claude Code plugin install(s) ${formatClaudePlugins(snapshot.claudePluginInstalls)} are not upgraded by the Phase 3.5 runner upgrade. Claude lifecycle now uses agent-relay-runner; refresh shims with \`agent-relay provider wrap claude\`.`);
216
232
  }
217
233
 
218
- if (!codexRequested && providerSet.has("auto") && !isCodexDetected(snapshot)) {
219
- warnings.push("Codex provider not detected; skipping Codex integration upgrade.");
220
- }
221
-
222
- if (claudeRequested) {
223
- if (!snapshot.hasClaudeCommand) {
224
- warnings.push("Claude Code command not detected; skipping Claude plugin upgrade.");
234
+ for (const manifest of upgradableProviderManifests()) {
235
+ if (!selectedProviders[manifest.id] && providerSet.has("auto") && !isProviderDetected(snapshot, manifest)) {
236
+ warnings.push(`${manifest.label} provider not detected; skipping ${manifest.label} integration upgrade.`);
237
+ }
238
+ if (selectedProviders[manifest.id] && !providerCommandDetected(manifest.id, snapshot.availableCommands)) {
239
+ warnings.push(`${manifest.label} command not detected; ${manifest.label} integration may remain unusable until the provider CLI is installed.`);
225
240
  }
226
- } else if (providerSet.has("auto") && !isClaudeRelayDetected(snapshot)) {
227
- warnings.push("Claude runner not detected; skipping Claude runner upgrade.");
228
241
  }
229
242
 
230
243
  if (!orchestratorRequested && providerSet.has("auto") && !isOrchestratorDetected(snapshot)) {
@@ -271,7 +284,7 @@ export function createUpgradePlan(snapshot: UpgradeSnapshot, options: UpgradeOpt
271
284
 
272
285
  return {
273
286
  targetVersion,
274
- providers: { codex: codexRequested, claude: claudeRequested, orchestrator: orchestratorRequested },
287
+ providers: { ...selectedProviders, orchestrator: orchestratorRequested },
275
288
  snapshot: { ...snapshot, targetVersion },
276
289
  actions,
277
290
  warnings,
@@ -415,7 +428,7 @@ export function formatUpgradePlan(plan: UpgradePlan, options: { dryRun?: boolean
415
428
  `- systemd user service: ${plan.snapshot.hasSystemdUserService ? "yes" : "no"}`,
416
429
  `- orchestrator systemd user service: ${plan.snapshot.hasSystemdUserOrchestratorService ? "yes" : "no"}`,
417
430
  "",
418
- `Providers: codex=${plan.providers.codex ? "yes" : "no"}, claude=${plan.providers.claude ? "yes" : "no"}, orchestrator=${plan.providers.orchestrator ? "yes" : "no"}`,
431
+ `Providers: ${formatProviderSelection(plan.providers)}`,
419
432
  "",
420
433
  "Actions:",
421
434
  ];
@@ -431,12 +444,43 @@ export function formatUpgradePlan(plan: UpgradePlan, options: { dryRun?: boolean
431
444
  return lines.join("\n");
432
445
  }
433
446
 
434
- function isCodexDetected(snapshot: UpgradeSnapshot): boolean {
435
- return Boolean(snapshot.runnerPackage || snapshot.codexPackage || snapshot.hasCodexCommand);
447
+ function upgradableProviderManifests(): ProviderManifest[] {
448
+ return getAllManifests().filter((manifest) => (manifest.upgrade?.packages.length ?? 0) > 0);
449
+ }
450
+
451
+ function knownUpgradePackages(): string[] {
452
+ return uniqueStrings([
453
+ "agent-relay-server",
454
+ "agent-relay-orchestrator",
455
+ ...upgradableProviderManifests().flatMap((manifest) => manifest.upgrade?.packages ?? []),
456
+ ]);
457
+ }
458
+
459
+ function knownUpgradeCommands(): string[] {
460
+ return uniqueStrings([
461
+ "agent-relay-orchestrator",
462
+ ...upgradableProviderManifests().flatMap((manifest) => manifest.upgrade?.detectCommands ?? []),
463
+ ]);
464
+ }
465
+
466
+ function installedUpgradePackage(snapshot: UpgradeSnapshot, name: string): InstalledPackage | undefined {
467
+ return snapshot.installedPackages?.[name] ??
468
+ (name === "agent-relay-runner" ? snapshot.runnerPackage : undefined) ??
469
+ (name === "agent-relay-codex" ? snapshot.codexPackage : undefined) ??
470
+ (name === "agent-relay-plugin" ? snapshot.claudeGlobalPackage : undefined) ??
471
+ (name === "agent-relay-orchestrator" ? snapshot.orchestratorPackage : undefined) ??
472
+ (name === "agent-relay-server" ? snapshot.serverPackage : undefined);
473
+ }
474
+
475
+ function providerCommandDetected(provider: string, availableCommands: Record<string, boolean> | undefined): boolean {
476
+ const detectCommands = upgradableProviderManifests().find((manifest) => manifest.id === provider)?.upgrade?.detectCommands ?? [];
477
+ return detectCommands.some((command: string) => availableCommands?.[command] === true);
436
478
  }
437
479
 
438
- function isClaudeRelayDetected(snapshot: UpgradeSnapshot): boolean {
439
- return Boolean(snapshot.runnerPackage || snapshot.hasClaudeCommand);
480
+ function isProviderDetected(snapshot: UpgradeSnapshot, manifest: ProviderManifest): boolean {
481
+ const detectPackages = manifest.upgrade?.detectPackages ?? manifest.upgrade?.packages ?? [];
482
+ return detectPackages.some((name: string) => Boolean(installedUpgradePackage(snapshot, name))) ||
483
+ providerCommandDetected(manifest.id, snapshot.availableCommands);
440
484
  }
441
485
 
442
486
  function isOrchestratorDetected(snapshot: UpgradeSnapshot): boolean {
@@ -587,7 +631,7 @@ function commandExists(command: string, runtimePrefix = defaultRuntimePrefix({ h
587
631
  join(homeDir(), ".local", "bin", command),
588
632
  join(homeDir(), ".bun", "bin", command),
589
633
  join(homeDir(), ".npm-global", "bin", command),
590
- join(homeDir(), ".agent-relay", "codex", "bin", command),
634
+ ...providerShimFallbackPaths(command),
591
635
  ].some((path) => existsSync(path));
592
636
  }
593
637
 
@@ -616,6 +660,38 @@ function uniqueStrings(values: string[]): string[] {
616
660
  return [...new Set(values.filter(Boolean))];
617
661
  }
618
662
 
663
+ function providerShimFallbackPaths(command: string): string[] {
664
+ const root = join(homeDir(), ".agent-relay");
665
+ return uniqueStrings(upgradableProviderManifests().flatMap((manifest) =>
666
+ (manifest.shim?.extraBinPaths ?? [])
667
+ .filter((path: string) => path.split("/").at(-1) === command)
668
+ .map((path: string) => join(root, path)),
669
+ ));
670
+ }
671
+
672
+ function formatProviderSelection(providers: Record<string, boolean>): string {
673
+ return Object.entries(providers)
674
+ .map(([provider, enabled]) => `${provider}=${enabled ? "yes" : "no"}`)
675
+ .join(", ");
676
+ }
677
+
678
+ function sortUpgradeSpecs(specs: string[]): string[] {
679
+ return [...specs].sort((left, right) => {
680
+ const leftName = packageName(left);
681
+ const rightName = packageName(right);
682
+ const leftRank = upgradePackageRank(leftName);
683
+ const rightRank = upgradePackageRank(rightName);
684
+ return leftRank === rightRank ? leftName.localeCompare(rightName) : leftRank - rightRank;
685
+ });
686
+ }
687
+
688
+ function upgradePackageRank(name: string): number {
689
+ if (name === "agent-relay-server") return 0;
690
+ if (name === "agent-relay-runner") return 1;
691
+ if (name === "agent-relay-orchestrator") return 3;
692
+ return 2;
693
+ }
694
+
619
695
  function formatPackage(pkg: InstalledPackage | undefined): string {
620
696
  if (!pkg) return "not detected";
621
697
  const path = pkg.path ? ` at ${pkg.path}` : "";
@@ -327,6 +327,7 @@ export function worktreeMcpInstructions(workspace: Pick<WorkspaceRecord, "branch
327
327
  const base = workspace.baseRef ? `\`${workspace.baseRef}\`` : "the base branch";
328
328
  return [
329
329
  `You are in an isolated git worktree on branch ${branch}, based on ${base} — NOT the main checkout. ${base} moves under you as other agents land in parallel; that's expected.`,
330
+ "Your shell's working directory is already this worktree — run commands directly without prefixing `cd`.",
330
331
  "Changes reach the base via: commit your work, then call `relay_workspace_ready`. Relay rebases onto the latest base, lands, and pushes for you.",
331
332
  "Do NOT push, rebase, merge, resolve conflicts, or `cd` into the main checkout — Relay (and a steward, spawned only if a clean auto-merge isn't possible) own all of that.",
332
333
  "After `ready` the status is `ready` (a normal, healthy hand-off state, not a stall). Stop your turn and go idle; Relay wakes you with `landed-success` when your branch lands and refreshes, or `landed-failure` if landing fatally fails.",
@@ -1,4 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{$t as t,An as n,B as r,Cn as i,Dt as a,Fn as o,Hn as s,L as c,Ot as l,Qn as u,Qt as d,Sn as f,Un as p,V as m,Vt as h,Xn as g,_n as _,a as v,b as y,c as ee,dr as b,er as x,ft as S,g as C,hn as te,i as ne,ln as w,lt as T,m as E,on as D,r as re,un as O,vn as ie,x as k,xn as ae,yn as A}from"./lucide-react-BYZuAhQs.js";import{r as j,t as M,v as N}from"./store-DNbkrqbU.js";import{E as P,H as oe,N as F,P as I,R as se,S as ce,V as le,_ as ue,d as de,f as fe,k as L,q as R,rt as z,v as pe}from"./display-DRiGi1zj.js";import{t as B}from"./types-Tv67voFu.js";import{D as V,a as me,i as he,l as ge,t as H}from"./index-DeDosfVE.js";import{t as _e}from"./user-avatar-RliaJcaG.js";var U=e(b(),1),ve={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`},ye=new Set(Object.keys(ve)),be=3e3;function W(e){return new Date(e.occurredAt??e.createdAt).getTime()}function xe(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:W(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function Se(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:W(e)}}function Ce(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:W(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 we(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`prompt-resolution`)return null;let n=t.promptResolution&&typeof t.promptResolution==`object`&&!Array.isArray(t.promptResolution)?t.promptResolution:{},r=n.kind===`questions`||n.kind===`plan`||n.kind===`command`||n.kind===`tool`?n.kind:`tool`,i=typeof n.title==`string`&&n.title.trim()?n.title:`Prompt resolved`,a=typeof n.decisionLabel==`string`&&n.decisionLabel.trim()?n.decisionLabel:typeof t.label==`string`&&t.label.trim()?t.label:`Resolved`,o=n.answers&&typeof n.answers==`object`&&!Array.isArray(n.answers)?n.answers:{};return{id:e.id,title:i,kind:r,body:typeof n.promptBody==`string`?n.promptBody:typeof n.body==`string`?n.body:e.body,toolName:typeof n.toolName==`string`&&n.toolName.trim()?n.toolName:i,decisionLabel:a,questions:Te(n.questions,o,a),timestamp:W(e)}}function Te(e,t,n){let r=(Array.isArray(e)?e:[]).map((e,r)=>{let i=e&&typeof e==`object`&&!Array.isArray(e)?e:{},a=typeof i.question==`string`&&i.question.trim()?i.question.trim():typeof i.header==`string`&&i.header.trim()?i.header.trim():`Question ${r+1}`,o=t[a]??t[String(i.question??``)]??t[String(i.header??``)];return{question:a,answer:typeof o==`string`&&o.trim()?o.trim():n}});return r.length?r:Object.entries(t).map(([e,t])=>({question:e,answer:t}))}function Ee(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 De(e){return e.kind===`system`&&e.from===`system`}var Oe=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function G(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function ke(e){let t=e.filter(e=>ye.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)<=be)||n.push(e);return n}function Ae(e,t,n,r=[],i){let a=[];for(let e of r){let t=e.entries.reduce((e,t)=>Math.min(e,R(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:R(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`||De(t)||P(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!L(t).trim())continue;let e=W(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=>Ee(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=Ee(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)&&oe(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(De(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(Oe.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=W(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:W(t),entry:{type:`notice`,msg:t}});continue}let e=Se(t);if(e){h.push(e);continue}let n=xe(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=Ce(t);if(r){a.push({ts:r.timestamp,entry:{type:`relay-injection`,event:r}});continue}let i=we(t);if(i){a.push({ts:i.timestamp,entry:{type:`prompt-resolution`,event:i}});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:W(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let o=t.id===s?`initial-prompt`:`message`;a.push({ts:W(t),entry:{type:o,msg:t}})}for(let e of ke([...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,"prompt-resolution":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=G(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`&&Ne(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function je(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===`prompt-resolution`?`prompt-resolution-${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 Me(e){return e.type===`message`||e.type===`initial-prompt`||e.type===`notice`?(e.msg.subject?`${e.msg.subject} `:``)+L(e.msg):e.type===`imported-message`?L(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)}`:e.type===`prompt-resolution`?[e.event.title,e.event.decisionLabel,e.event.body,...e.event.questions.map(e=>`${e.question} ${e.answer}`)].filter(Boolean).join(`
3
- `):``}function Ne(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function Pe(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Fe(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 Ie(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function Le(e,t){return e.filter(e=>e.status===`online`&&se(t,e.baseDir)).sort((e,t)=>F(t.baseDir).length-F(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function Re(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function ze(){return typeof window<`u`&&!!window.getSelection()?.toString()}function Be(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var Ve=[`👍`,`❤️`,`✅`,`👀`];function He(e){let t=new Map;for(let n of e.reactions||[]){let e=I(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 K(e){return P(e)}function Ue(e,t){let n=e.readBy||[],r=e.resolvedToAgent||t||e.to,a=r?n.includes(r):!1,o=n.some(e=>e!==z);if(a||o){let e=a?r:n.find(e=>e!==z);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:i}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:i};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:D};if(e.deliveryStatus===`failed`||e.deliveryStatus===`dead`){let t=e.deliveryPoisonReason||e.deliveryLastError||e.deliveryStatus;return{label:e.deliveryStatus,title:t,tone:`danger`,icon:_}}return{label:`sent`,title:`Accepted by Relay`,tone:`muted`,icon:f}}function We(e){let t=R(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,R(t.updatedAt||t.createdAt)),t)}function Ge(e){return e?e.messages.reduce((e,t)=>Math.max(e,We(t)),0):0}function Ke(e,t,n){return(e-t)*n}function qe(e){if(!e)return 0;let t=0;for(let n of e.messages)ce(n)&&(t=Math.max(t,R(n.createdAt)));return t}function q(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function Je(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function Ye(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[j(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var J=u(),Xe={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 Ze(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===G(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===G(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,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,J.jsx)(w,{className:g(`w-2 h-2 fill-current`,Xe[e.status]||`text-zinc-400`)}),(0,J.jsx)(`span`,{children:ve[e.status]||e.status}),(0,J.jsx)(`span`,{className:`text-muted-foreground/60`,children:q(e.timestamp)})]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var $e={"branch.landed":a,"context.warning":E,"agent.context_threshold":E,"agent.resume_budget_exhausted":E,"agent.rate_limit_resume":m},et={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function tt(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function Y({agentId:e,fallbackLabel:t,className:n,noIcon:r}){let i=M(t=>t.agentsById[e])||null,a=M(e=>e.openInboxThread),o=M(e=>e.switchView),s=i?de(i):t||e;return(0,J.jsxs)(`button`,{type:`button`,className:g(`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(),a(e),o(`chat`)},title:`Open chat for ${s}`,children:[!r&&(0,J.jsx)(V,{agent:i,className:`w-4 h-4 text-[10px]`}),(0,J.jsx)(`span`,{className:`max-w-[160px] truncate`,children:s})]})}function nt({msg:e}){let t=e.payload??{},n=it(e),r=typeof t.sha==`string`?t.sha:``,i=r?r.slice(0,7):``,o=typeof t.author==`string`?t.author:``,s=typeof t.branch==`string`?t.branch:``,c=typeof t.base==`string`?t.base:``,l=t.pushed;return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.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,J.jsx)(a,{className:`h-3 w-3 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,J.jsx)(`span`,{className:`text-emerald-700 dark:text-emerald-300`,children:`branch landed`}),s&&c&&(0,J.jsxs)(`span`,{className:`font-mono text-emerald-700/80 dark:text-emerald-200/70`,title:`${s} → ${c}`,children:[s,(0,J.jsx)(`span`,{className:`opacity-50`,children:` → `}),c]}),i&&(0,J.jsx)(`span`,{className:`rounded bg-emerald-500/15 px-1 font-mono text-emerald-800 dark:text-emerald-200`,title:r,children:i}),o&&(0,J.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-700/80 dark:text-emerald-300/80`,children:[(0,J.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,J.jsx)(Y,{agentId:o,className:`text-emerald-700 hover:text-emerald-900 dark:text-emerald-300/90 dark:hover:text-emerald-100`})]}),l===!1&&(0,J.jsx)(`span`,{className:`text-amber-600 dark:text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),n&&(0,J.jsxs)(`span`,{className:`max-w-[220px] truncate text-emerald-700/70 dark:text-emerald-300/70`,title:n,children:[`· because `,n]}),(0,J.jsx)(`span`,{className:`text-emerald-700/60 dark:text-emerald-300/50`,children:q(e.occurredAt??e.createdAt)})]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function rt({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,J.jsx)(nt,{msg:e});let n=$e[t]??c,r=et[t]??tt(t),i=it(e);return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.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,J.jsx)(n,{className:`h-3 w-3`}),(0,J.jsx)(`span`,{children:r}),i&&(0,J.jsxs)(`span`,{className:`max-w-[220px] truncate text-muted-foreground/80`,title:i,children:[`· because `,i]}),(0,J.jsx)(`span`,{className:`text-muted-foreground/60`,children:q(e.occurredAt??e.createdAt)})]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function it(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 at={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},ot={"spawned-child-ready":r,"spawned-child-exited":T,"spawned-child-failed":_,"spawned-by-ready":p,"spawned-by-exited":p,"spawned-by-failed":p},st={"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 ct({entry:e}){let t=`${e.direction}-${e.status}`,n=at[e.direction]?.[e.status]??e.direction,r=ot[t]??c,i=st[t]??`text-muted-foreground`,a=e.status===`failed`;return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.jsxs)(`div`,{className:g(`flex items-center gap-1.5 rounded-full border bg-muted/30 px-2.5 py-1 text-xs`,a?`border-red-500/30`:`border-border`),children:[(0,J.jsx)(r,{className:g(`h-3 w-3 shrink-0`,i)}),(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,J.jsx)(Y,{agentId:e.agentId}),e.reason&&a&&(0,J.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,J.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:q(e.timestamp)})]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var lt={memory:n,instructions:h,tools:v,comms:c,knowledge:o,context:t},ut={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 dt(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function ft({entry:e}){let[t,n]=(0,U.useState)(!1),r=e.event,i=lt[r.category]??y;return(0,J.jsx)(`div`,{className:`flex justify-center py-2 my-1`,children:(0,J.jsxs)(`div`,{className:g(`w-full max-w-[85%] md:max-w-[75%] rounded-lg border px-2.5 py-1.5 text-xs shadow-sm`,ut[r.category]??ut.context),children:[(0,J.jsxs)(`button`,{type:`button`,className:`flex w-full min-w-0 items-center gap-1.5 text-left`,onClick:()=>n(e=>!e),children:[(0,J.jsx)(i,{className:`h-3.5 w-3.5 shrink-0`}),(0,J.jsx)(`span`,{className:`shrink-0 font-medium`,children:r.category}),(0,J.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-foreground/80`,children:r.summary}),(0,J.jsx)(`span`,{className:`shrink-0 text-muted-foreground/60`,children:q(r.timestamp)}),(0,J.jsx)(A,{className:g(`h-3.5 w-3.5 shrink-0 transition-transform`,t&&`rotate-90`)})]}),t&&(0,J.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:dt(r.detail)})]})})}function pt({blockedLabel:e,onInterrupt:t}){return e?(0,J.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,J.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,J.jsx)(_,{className:`w-3.5 h-3.5 text-red-400`}),(0,J.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,J.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,J.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,J.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,J.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,J.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,J.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,J.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,J.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,J.jsx)(O,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var X=`agent-relay:chat-hide-tools`,Z=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(X)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===X&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(X,t?`on`:`off`)}catch{}n()}}})();function mt(){return[(0,U.useSyncExternalStore)(Z.subscribe,Z.get,()=>!1),Z.toggle]}function ht({steps:e,showReasoning:t,issueRepo:r}){let[i,a]=mt(),o=t?e:e.filter(e=>e.kind!==`reasoning`);if(!o.length)return null;let s=o.filter(e=>e.kind===`tool`).length;return(0,J.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,J.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[o.map(e=>e.kind===`narration`?(0,J.jsx)(H,{text:e.text,issueRepo:r,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,J.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,J.jsx)(n,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,J.jsx)(H,{text:e.text,issueRepo:r,className:`italic break-words min-w-0`})]},e.id):i?null:(0,J.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,J.jsx)(C,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,J.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,J.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,J.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),s>0&&(0,J.jsxs)(`button`,{onClick:a,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,J.jsx)(A,{className:g(`w-3 h-3 shrink-0 transition-transform`,!i&&`rotate-90`)}),(0,J.jsx)(`span`,{children:i?`show ${s} tool step${s===1?``:`s`}`:`hide tool steps`})]})]})})}function gt({entry:e}){let{event:t}=e,n=t.kind===`questions`,r=n?t.title:t.kind===`plan`?`Plan prompt`:`${t.toolName} permission`;return(0,J.jsx)(`div`,{className:`flex justify-center py-1.5`,children:(0,J.jsxs)(`div`,{className:`w-full max-w-2xl rounded-md border border-border bg-muted/20 px-3 py-2 text-sm`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,J.jsx)(te,{className:`h-3.5 w-3.5 text-emerald-500`}),(0,J.jsx)(`span`,{className:`font-medium text-foreground`,children:r}),(0,J.jsx)(`span`,{children:t.decisionLabel}),(0,J.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/60`,children:q(t.timestamp)})]}),n&&t.questions.length>0?(0,J.jsx)(`div`,{className:`mt-2 space-y-1.5`,children:t.questions.map((e,t)=>(0,J.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.question}),(0,J.jsx)(`div`,{className:`text-sm text-foreground`,children:e.answer})]},`${e.question}-${t}`))}):t.body.trim()?(0,J.jsx)(`div`,{className:`mt-2 max-h-48 overflow-auto rounded border border-border/70 bg-background/40 px-2 py-1.5 text-sm`,children:(0,J.jsx)(H,{text:t.body})}):null]})})}function _t({date:e}){return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:Ze(e)}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function vt({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function yt({history:e}){let t=e.sourceAgentLabel||e.sourcePeerId,n=e.entries.length;return(0,J.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,J.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,J.jsx)(l,{className:`h-3 w-3`}),(0,J.jsxs)(`span`,{children:[`forked history from `,t]}),(0,J.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[n,` `,n===1?`entry`:`entries`]})]}),(0,J.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function bt({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,i=L(r),a=e.originalFrom===z;return(0,J.jsx)(`div`,{className:g(`flex mb-3 opacity-80`,a?`justify-end`:`justify-start`),children:(0,J.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,J.jsxs)(`div`,{className:g(`rounded-2xl border border-dashed px-3.5 py-2 text-sm select-text`,a?`border-primary/25 bg-primary/10 text-foreground rounded-br-sm`:`border-border bg-card/70 rounded-bl-sm`),children:[(0,J.jsxs)(`div`,{className:g(`mb-1 text-[10px] uppercase tracking-normal`,a?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,a?`you`:t||e.originalFrom]}),(0,J.jsx)(H,{text:i,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,J.jsxs)(`p`,{className:g(`mt-1 flex items-center justify-end gap-1.5 text-xs`,a?`text-primary/60`:`text-muted-foreground`),children:[(0,J.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,J.jsx)(`span`,{children:q(e.originalCreatedAt)})]})]})})})}function Q({msg:e,issueRepo:t}){let n=L(e),r=q(e.occurredAt??e.createdAt);return(0,J.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,J.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,J.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,J.jsx)(y,{className:`h-3.5 w-3.5`}),(0,J.jsx)(`span`,{children:`Initial prompt`}),(0,J.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,J.jsx)(H,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function xt({scrollEl:e,timeline:t}){let[n,r]=(0,U.useState)(!0),[i,a]=(0,U.useState)(null),[o,s]=(0,U.useState)(null),[c,l]=(0,U.useState)(!1),u=(0,U.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:L(n.msg)}}return null},[t]);if((0,U.useEffect)(()=>{if(!u||!e){r(!0);return}let t=null,n=null,i=()=>{let i=e.querySelector(`[data-msg-id="${u.id}"]`);if(!i){t?.disconnect(),t=null,n=null,r(!1);return}let a=i.getBoundingClientRect(),o=e.getBoundingClientRect();l(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)}},[u?.id,e]),n||!u||!u.body.trim())return null;let d=i?.id===u.id?i.value:!1,f=o?.id===u.id?o.value:!1;function p(){!e||!u||e.querySelector(`[data-msg-id="${u.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let m=c?`↑`:`↓`;return f?(0,J.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,J.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:()=>s({id:u.id,value:!1}),children:[(0,J.jsx)(`span`,{children:`Your prompt`}),(0,J.jsx)(ae,{className:`w-3 h-3`})]})}):(0,J.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,J.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,J.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:p,children:[m,` scroll to original`]}),(0,J.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>s({id:u.id,value:!0}),title:`Minimize`,children:(0,J.jsx)(ie,{className:`w-3 h-3`})})]}),(0,J.jsx)(`p`,{className:g(`text-sm text-foreground leading-snug cursor-pointer`,!d&&`line-clamp-2`),onClick:()=>a({id:u.id,value:!d}),children:u.body})]})}function St(){return(0,U.useSyncExternalStore)(e=>N.subscribe(e),()=>N.getPlayingKey(),()=>null)}function Ct({msg:e,peer:t}){return(0,J.jsx)(Q,{msg:e,issueRepo:M(e=>e.agentsById[t]?.issueRepo)})}function wt({agent:e,onClick:t}){let n=!!(t&&e);return(0,J.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:g(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,J.jsx)(V,{agent:e})})}function Tt({agentId:e,onOpen:t}){let n=M(t=>t.agentsById[e]??null);return(0,J.jsx)(wt,{agent:n,onClick:n?()=>t(n):void 0})}function Et({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[i,a]=(0,U.useState)(null),[o,s]=(0,U.useState)(null),[c,l]=(0,U.useState)(!1),[u,f]=(0,U.useState)(!1);(0,U.useEffect)(()=>{let t=!1,n=null;async function r(){l(!0),s(null),a(null);try{let r=await x(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),a(n)}catch(e){t||s(e.message)}finally{t||l(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function p(){if(!i)return;let e=document.createElement(`a`);e.href=i,e.download=r,document.body.appendChild(e),e.click(),e.remove()}return n?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{type:`button`,onClick:()=>i&&f(!0),disabled:!i,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:i?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`img`,{src:i,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,J.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,J.jsx)(re,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,J.jsxs)(`span`,{className:g(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,o?`text-red-400`:`text-muted-foreground`),children:[c?(0,J.jsx)(S,{className:`h-4 w-4 animate-spin`}):(0,J.jsx)(_,{className:`h-4 w-4`}),o||`Loading image`]})}),i&&(0,J.jsx)(he,{open:u,onOpenChange:f,children:(0,J.jsxs)(me,{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,J.jsx)(ge,{className:`sr-only`,children:r}),(0,J.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,J.jsx)(`img`,{src:i,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,J.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,J.jsx)(`button`,{type:`button`,onClick:p,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,J.jsx)(d,{className:`w-4 h-4`})}),(0,J.jsx)(`button`,{type:`button`,onClick:()=>f(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,J.jsx)(ne,{className:`w-4 h-4`})})]})]})]})})]}):(0,J.jsxs)(`button`,{type:`button`,onClick:p,disabled:!i,className:g(`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:[c?(0,J.jsx)(S,{className:`h-4 w-4 shrink-0 animate-spin`}):o?(0,J.jsx)(_,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,J.jsx)(h,{className:`h-4 w-4 shrink-0`}),(0,J.jsx)(`span`,{className:g(`min-w-0 flex-1 truncate`,o&&`text-red-400`),children:o||r}),(0,J.jsx)(d,{className:`h-3.5 w-3.5 shrink-0`})]})}function $({open:e,onToggle:t,onReact:n}){return(0,J.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,J.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:g(`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,J.jsx)(k,{className:`h-3 w-3`})}),e&&(0,J.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:Ve.map(e=>(0,J.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 Dt({msg:e,peer:t}){let[n,r]=(0,U.useState)(!1),i=M(e=>e.agentsById),a=M(e=>e.openAgentDetail),o=e.from===t,c=(o?e.to:e.from)||``,l=i[o?t:c]?.issueRepo??i[t]?.issueRepo,u=!c||c===`broadcast`||c.includes(`:`),d=L(e),f=q(e.occurredAt??e.createdAt),m=o?s:p,h=i[e.from??``]??null;function _(e){e.stopPropagation(),h&&a(h)}return(0,J.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,J.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>r(e=>!e),children:[(0,J.jsx)(A,{className:g(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,n&&`rotate-90`)}),(0,J.jsx)(`button`,{type:`button`,title:h?h.label||h.name||h.id:void 0,disabled:!h,onClick:_,className:g(`shrink-0 transition-opacity`,h?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,J.jsx)(V,{agent:h,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,J.jsx)(m,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,J.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,o?`to`:`from`]}),u?(0,J.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:fe(c,i)}):(0,J.jsx)(Y,{agentId:c,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!n&&(0,J.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:d}),(0,J.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:f})]}),n&&(0,J.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,J.jsx)(H,{text:d,rawBody:e.body,issueRepo:l,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var Ot=(0,U.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:i,onPreviewReferencedPathEnd:a}){if(!B(e.from)&&!B(e.to))return(0,J.jsx)(Dt,{msg:e,peer:t});let o=e.kind===`session`?e.payload?.session:void 0;if(o?.type===`prompt`&&o?.origin===`provider`)return(0,J.jsx)(Ct,{msg:e,peer:t});let s=B(e.from),c=M(e=>e.reactToMessage),l=M(e=>e.voiceTtsEnabled),u=St(),d=M(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),f=M(e=>e.agentsById[t]?.issueRepo),p=M(e=>e.usersById),m=M(e=>e.users.length>1),h=s?le(e.from,p):void 0,_=M(e=>e.openAgentDetail),[v,y]=(0,U.useState)(!1),b=(0,U.useRef)(null),x=(0,U.useRef)(null),S=(0,U.useRef)(!1),C=L(e),te=q(e.occurredAt??e.createdAt),ne=Be(e),w=He(e),T=s?Ue(e,t):null,E=T?.icon,D=u===String(e.id),re=l&&!s&&!K(e)&&C.trim().length>0;function ie(t){t.stopPropagation(),D?N.bargeIn():N.speak(e.body,String(e.id))}(0,U.useEffect)(()=>{if(!v)return;function e(e){ze()||b.current&&!b.current.contains(e.target)&&y(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[v]);function k(e){return Fe(d||`/`,e)}function ae(e,t){let n=k(e);r?.(n,t)}function A(e,t,n){let r=k(e);i?.(r,t,n)}function j(t){c(e,t),y(!1)}function P(e){e.button===0&&(x.current={x:e.clientX,y:e.clientY},S.current=!1)}function oe(e){let t=x.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(S.current=!0)}function F(t){if(!(K(e)||s)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(S.current||ze()){S.current=!1;return}y(e=>!e)}}let I=n&&!K(e);return(0,J.jsxs)(`div`,{"data-msg-id":e.id,className:g(`group/msg flex mb-3 items-end`,s?`justify-end`:`justify-start`,I&&`gap-1.5`),children:[!s&&I&&(0,J.jsx)(Tt,{agentId:t,onOpen:_}),(0,J.jsxs)(`div`,{ref:b,className:g(`relative`,I?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[re&&(0,J.jsx)(`button`,{type:`button`,title:D?`Stop playback`:`Play aloud`,onClick:ie,className:g(`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`,D?`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:D?(0,J.jsx)(O,{className:`h-3.5 w-3.5 animate-pulse`}):(0,J.jsx)(ee,{className:`h-3.5 w-3.5`})}),(0,J.jsxs)(`div`,{className:g(`rounded-2xl px-3.5 py-2 text-sm select-text`,!s&&!K(e)&&`cursor-pointer`,s?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:P,onPointerMove:oe,onClick:F,children:[s&&m&&(0,J.jsx)(`p`,{className:g(`text-[11px] font-semibold mb-0.5 text-right`,ue(e.from)),children:pe(e.from,p)}),e.subject&&(0,J.jsx)(`p`,{className:g(`text-xs font-semibold mb-1`,s?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,J.jsx)(H,{text:C,rawBody:e.body,issueRepo:f,className:`leading-relaxed`,onPrimary:s,onOpenPath:ae,onPreviewPath:A,onPreviewPathEnd:a,resolvePathTitle:(e,t)=>`${k(e)}${t?`:${t}`:``}`}),ne.map(t=>(0,J.jsx)(Et,{attachment:t,outbound:s},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,J.jsxs)(`p`,{className:g(`text-xs mt-1 flex items-center gap-1.5`,s?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,J.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,J.jsx)(`span`,{children:te}),T&&E&&(0,J.jsxs)(`span`,{className:g(`inline-flex items-center gap-1`,T.tone===`ok`&&`text-emerald-300`,T.tone===`warn`&&`text-amber-200`,T.tone===`danger`&&`text-red-200`),title:T.title,children:[(0,J.jsx)(E,{className:`h-3 w-3`}),T.label]})]})]}),!K(e)&&w.length>0&&(0,J.jsxs)(`div`,{className:g(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,s?`justify-end pr-2`:`justify-start pl-2`),children:[!s&&(0,J.jsx)($,{open:v,onToggle:()=>y(e=>!e),onReact:j}),w.map(e=>(0,J.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>j(e.emoji),className:g(`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,J.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,J.jsx)(`span`,{children:e.count})]},e.emoji))]}),!K(e)&&!s&&w.length===0&&(0,J.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,J.jsx)($,{open:v,onToggle:()=>y(e=>!e),onReact:j})})]}),s&&I&&(0,J.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,J.jsx)(_e,{user:h,address:e.from,distinct:m})})]})});export{Ge as C,Me as E,Re as S,je as T,qe as _,vt as a,Ye as b,bt as c,gt as d,ft as f,Pe as g,Ke as h,pt as i,Q as l,xt as m,ht as n,_t as o,Qe as p,ct as r,yt as s,Ot as t,rt as u,Le as v,Ae as w,Je as x,Ie as y};
4
- //# sourceMappingURL=MessageBubble-Dppo7pil.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{B as t,Gt as n,Kt as r,Qn as i,Qt as a,W as o,dr as s,f as c,ft as l,h as u,rn as d}from"./lucide-react-BYZuAhQs.js";import{t as f}from"./store-DNbkrqbU.js";import{a as p}from"./types-Tv67voFu.js";import{t as m}from"./badge-BLar6FjP.js";import{t as h}from"./button-BrIB69qd.js";import{a as g,c as _,i as v,l as y,o as b,s as x}from"./index-DeDosfVE.js";var S=e(s(),1),C=i();function w(e){return e.provider===`claude`||e.provider===`codex`?e.provider:`codex`}function T(e){if(Array.isArray(e))return e.map(T);if(e&&typeof e==`object`){let t={};for(let[n,r]of Object.entries(e))n===`files`&&Array.isArray(r)?t[n]=r.map(e=>{if(e&&typeof e==`object`&&typeof e.content==`string`){let t=e.content;return{...e,content:`<${t.length} chars elided>`}}return T(e)}):t[n]=T(r);return t}return e}function E({profile:e,open:t,onOpenChange:n}){let r=f(e=>e.apiCall),[i,o]=(0,S.useState)(()=>w(e)),[s,c]=(0,S.useState)(!1),[u,d]=(0,S.useState)(null),[m,E]=(0,S.useState)(null),D=(0,S.useCallback)(async t=>{c(!0),d(null);try{E((await r(`GET`,`/agent-profiles/${encodeURIComponent(e.name)}/resolved?provider=${t}`)).profile)}catch(e){E(null),d(p(e))}finally{c(!1)}},[r,e.name]);(0,S.useEffect)(()=>{if(t){let t=w(e);o(t),D(t)}},[t,e,D]);function O(e){e!==i&&(o(e),D(e))}function k(){if(!m)return;let t=new Blob([JSON.stringify(m,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`${e.name}.${i}.resolved.json`,document.body.appendChild(r),r.click(),r.remove(),URL.revokeObjectURL(n)}let A=m?JSON.stringify(T(m),null,2):``;return(0,C.jsx)(v,{open:t,onOpenChange:n,children:(0,C.jsxs)(g,{className:`max-w-3xl`,children:[(0,C.jsxs)(_,{children:[(0,C.jsxs)(y,{className:`font-mono text-sm`,children:[e.name,` — resolved projection`]}),(0,C.jsxs)(b,{children:[`The fully-resolved agent-profile projection (`,(0,C.jsx)(`code`,{children:`withResolvedProvisioning`}),`) for the selected provider. File contents are elided below; download the full JSON for the complete bundle.`]})]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,C.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Provider`}),(0,C.jsx)(`div`,{className:`flex items-center gap-1`,children:[`claude`,`codex`].map(e=>(0,C.jsx)(h,{variant:e===i?`default`:`outline`,size:`sm`,className:`h-7 px-3 text-xs`,disabled:s,onClick:()=>O(e),children:e},e))}),(0,C.jsx)(`div`,{className:`flex-1`}),(0,C.jsxs)(h,{size:`sm`,className:`h-7 gap-1 text-xs`,disabled:s||!m,onClick:k,children:[(0,C.jsx)(a,{className:`h-3.5 w-3.5`}),`Download full JSON`]})]}),(0,C.jsx)(`div`,{className:`min-h-[16rem] overflow-auto rounded-md border border-border bg-muted/30 p-3`,children:s?(0,C.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,C.jsx)(l,{className:`h-3.5 w-3.5 animate-spin`}),`Resolving projection…`]}):u?(0,C.jsx)(`div`,{className:`text-xs text-destructive`,children:u}):m?(0,C.jsx)(`pre`,{className:`max-h-[60vh] overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed`,children:A}):(0,C.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`No projection available.`})}),(0,C.jsx)(x,{children:(0,C.jsx)(h,{variant:`outline`,size:`sm`,onClick:()=>n(!1),children:`Close`})})]})})}var D={host:`text-emerald-400 bg-emerald-500/10`,minimal:`text-amber-400 bg-amber-500/10`,isolated:`text-red-400 bg-red-500/10`,vanilla:`text-fuchsia-400 bg-fuchsia-500/10`};function O({relay:e}){return(0,C.jsx)(`div`,{className:`flex items-center gap-1`,children:[{key:`ctx`,on:e.context},{key:`skl`,on:e.skills},{key:`plg`,on:e.plugins},{key:`stl`,on:e.statusLine}].map(e=>(0,C.jsx)(`span`,{className:`inline-block h-1.5 w-1.5 rounded-full ${e.on?`bg-emerald-400`:`bg-muted-foreground/30`}`,title:`${e.key}: ${e.on?`on`:`off`}`},e.key))})}function k({profile:e}){let t=f(e=>e.openProfileModal),i=f(e=>e.deleteProfile),a=e.builtIn===!0,[s,c]=(0,S.useState)(!1);return(0,C.jsxs)(`div`,{className:`group flex flex-col gap-3 rounded-lg border border-border bg-card p-4`,children:[(0,C.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,C.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,C.jsx)(`span`,{className:`text-base leading-none`,"aria-hidden":!0,children:e.icon?.trim()||`•`}),(0,C.jsx)(`span`,{className:`font-mono text-sm font-medium`,children:e.name}),a&&(0,C.jsx)(m,{variant:`secondary`,className:`text-[10px]`,children:`Built-in`}),e.overridden&&(0,C.jsx)(m,{variant:`outline`,className:`text-[10px] border-amber-500/30 bg-amber-500/10 text-amber-400`,children:`Overridden`})]}),e.description&&(0,C.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground line-clamp-2`,children:e.description})]}),(0,C.jsxs)(`div`,{className:`flex shrink-0 items-center gap-0.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity`,children:[(0,C.jsx)(h,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`View`,onClick:()=>t(`view`,e),children:(0,C.jsx)(r,{className:`h-3.5 w-3.5`})}),(0,C.jsx)(h,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`Edit`,onClick:()=>t(`edit`,e),children:(0,C.jsx)(o,{className:`h-3.5 w-3.5`})}),(0,C.jsx)(h,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`Duplicate`,onClick:()=>t(`duplicate`,e),children:(0,C.jsx)(d,{className:`h-3.5 w-3.5`})}),(0,C.jsx)(h,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`Resolved projection`,onClick:()=>c(!0),children:(0,C.jsx)(n,{className:`h-3.5 w-3.5`})}),(!a||e.overridden)&&(0,C.jsx)(h,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7 text-destructive`,title:a?`Reset to default`:`Delete`,onClick:()=>i(e),children:(0,C.jsx)(u,{className:`h-3.5 w-3.5`})})]})]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 text-[10px]`,children:[(0,C.jsx)(m,{variant:`outline`,className:D[e.base]||``,children:e.base}),(0,C.jsx)(m,{variant:`outline`,children:e.provider||`any`}),(0,C.jsxs)(m,{variant:`outline`,children:[`fs: `,e.permissions.filesystem]}),e.permissions.mode&&(0,C.jsx)(m,{variant:`outline`,children:e.permissions.mode})]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-1 text-[10px] text-muted-foreground`,children:[(0,C.jsxs)(`span`,{className:`flex items-center gap-1`,children:[`Relay `,(0,C.jsx)(O,{relay:e.relay})]}),(0,C.jsxs)(`span`,{children:[`MCP: `,e.mcp.mode]}),(0,C.jsxs)(`span`,{children:[`Hooks: `,e.hooks.mode]}),e.instructions.globalInstructions===`ignore`&&(0,C.jsx)(`span`,{className:`text-amber-400`,children:`global: ignore`}),Object.keys(e.env||{}).length>0&&(0,C.jsxs)(`span`,{children:[Object.keys(e.env).length,` env vars`]})]}),(0,C.jsx)(E,{profile:e,open:s,onOpenChange:c})]})}function A(){let e=f(e=>e.agentProfiles),n=f(e=>e.openProfileModal),r=e.filter(e=>e.builtIn),i=e.filter(e=>!e.builtIn);return(0,C.jsxs)(`div`,{className:`space-y-4`,children:[(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-2 text-lg font-semibold`,children:[(0,C.jsx)(c,{className:`h-5 w-5 text-primary`}),`Agent Profiles`]}),(0,C.jsx)(m,{variant:`outline`,children:e.length}),(0,C.jsx)(`div`,{className:`flex-1`}),(0,C.jsxs)(h,{size:`sm`,className:`gap-1`,onClick:()=>n(`create`),children:[(0,C.jsx)(t,{className:`h-3.5 w-3.5`}),`Create Profile`]})]}),r.length>0&&(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Built-in`}),(0,C.jsx)(`div`,{className:`grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3`,children:r.map(e=>(0,C.jsx)(k,{profile:e},e.name))})]}),i.length>0&&(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Custom`}),(0,C.jsx)(`div`,{className:`grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3`,children:i.map(e=>(0,C.jsx)(k,{profile:e},e.name))})]}),e.length===0&&(0,C.jsx)(`div`,{className:`py-12 text-center text-sm text-muted-foreground`,children:`No agent profiles found. Create one to configure agent behavior.`})]})}export{A as AgentProfilesView};
2
- //# sourceMappingURL=agent-profiles-CT-vbfzd.js.map