agent-relay-server 0.114.0 → 0.115.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 (145) hide show
  1. package/docs/openapi.json +39 -1
  2. package/package.json +3 -3
  3. package/public/assets/MessageBubble-Dy37JuVw.js +4 -0
  4. package/public/assets/{MessageBubble-CxqPFLGP.js.map → MessageBubble-Dy37JuVw.js.map} +1 -1
  5. package/public/assets/PlanGraphPanel-C17_n4Ff.js +2 -0
  6. package/public/assets/PlanGraphPanel-C17_n4Ff.js.map +1 -0
  7. package/public/assets/{activity-Dw15HMdi.js → activity-G-s2N4eU.js} +2 -2
  8. package/public/assets/{activity-Dw15HMdi.js.map → activity-G-s2N4eU.js.map} +1 -1
  9. package/public/assets/{agent-profiles-DNtXbS77.js → agent-profiles-v4CcpJWT.js} +2 -2
  10. package/public/assets/{agent-profiles-DNtXbS77.js.map → agent-profiles-v4CcpJWT.js.map} +1 -1
  11. package/public/assets/agents-CuEoaCLs.js +2 -0
  12. package/public/assets/{agents-DOwnLE42.js.map → agents-CuEoaCLs.js.map} +1 -1
  13. package/public/assets/{analytics-CRwxJWuV.js → analytics-Dvg0J33b.js} +3 -3
  14. package/public/assets/{analytics-CRwxJWuV.js.map → analytics-Dvg0J33b.js.map} +1 -1
  15. package/public/assets/{automation-BQk8XQEj.js → automation-wXSbBEei.js} +2 -2
  16. package/public/assets/{automation-BQk8XQEj.js.map → automation-wXSbBEei.js.map} +1 -1
  17. package/public/assets/{badge-oaCc6hVH.js → badge-BhUZ1cAb.js} +2 -2
  18. package/public/assets/{badge-oaCc6hVH.js.map → badge-BhUZ1cAb.js.map} +1 -1
  19. package/public/assets/branch-state-badge-YzkNCHyZ.js +2 -0
  20. package/public/assets/{branch-state-badge-JDaHO2fG.js.map → branch-state-badge-YzkNCHyZ.js.map} +1 -1
  21. package/public/assets/{button-Cx0NiToX.js → button-C-V4oij1.js} +2 -2
  22. package/public/assets/{button-Cx0NiToX.js.map → button-C-V4oij1.js.map} +1 -1
  23. package/public/assets/{card-DkHdS68K.js → card-DAkf5Kzw.js} +2 -2
  24. package/public/assets/{card-DkHdS68K.js.map → card-DAkf5Kzw.js.map} +1 -1
  25. package/public/assets/{channels-wQha9YA6.js → channels-Vl9YHoGK.js} +2 -2
  26. package/public/assets/{channels-wQha9YA6.js.map → channels-Vl9YHoGK.js.map} +1 -1
  27. package/public/assets/chat-yiXwg4kh.js +2 -0
  28. package/public/assets/{chat-BTmgzO_g.js.map → chat-yiXwg4kh.js.map} +1 -1
  29. package/public/assets/{connectors-BF-XDm0s.js → connectors-C33KsouZ.js} +2 -2
  30. package/public/assets/{connectors-BF-XDm0s.js.map → connectors-C33KsouZ.js.map} +1 -1
  31. package/public/assets/{copy-button-CsCBPQzj.js → copy-button-BStzXgtd.js} +2 -2
  32. package/public/assets/{copy-button-CsCBPQzj.js.map → copy-button-BStzXgtd.js.map} +1 -1
  33. package/public/assets/{dist-BJnh7VkB.js → dist-CBMWGhWc.js} +2 -2
  34. package/public/assets/{dist-BJnh7VkB.js.map → dist-CBMWGhWc.js.map} +1 -1
  35. package/public/assets/{dist-Pak9TL_I.js → dist-CDZZxxJq.js} +2 -2
  36. package/public/assets/{dist-Pak9TL_I.js.map → dist-CDZZxxJq.js.map} +1 -1
  37. package/public/assets/{dist-AbnkNPcD.js → dist-CQ0Z-TDi.js} +2 -2
  38. package/public/assets/{dist-AbnkNPcD.js.map → dist-CQ0Z-TDi.js.map} +1 -1
  39. package/public/assets/{dist-REUlCFee.js → dist-ChDX_t12.js} +2 -2
  40. package/public/assets/{dist-REUlCFee.js.map → dist-ChDX_t12.js.map} +1 -1
  41. package/public/assets/{dist-DLOrqIs-.js → dist-CmFeEXMe.js} +2 -2
  42. package/public/assets/{dist-DLOrqIs-.js.map → dist-CmFeEXMe.js.map} +1 -1
  43. package/public/assets/{dist-DBti5--U.js → dist-Cs8X0P1d.js} +2 -2
  44. package/public/assets/{dist-DBti5--U.js.map → dist-Cs8X0P1d.js.map} +1 -1
  45. package/public/assets/dist-D2jvo5oA.js +2 -0
  46. package/public/assets/{dist-QY_EIkcd.js.map → dist-D2jvo5oA.js.map} +1 -1
  47. package/public/assets/{dist-1g1lCjVb.js → dist-DV83j9tm.js} +2 -2
  48. package/public/assets/{dist-1g1lCjVb.js.map → dist-DV83j9tm.js.map} +1 -1
  49. package/public/assets/{dist-DJpDTmGg.js → dist-DyNJNwpi.js} +2 -2
  50. package/public/assets/{dist-DJpDTmGg.js.map → dist-DyNJNwpi.js.map} +1 -1
  51. package/public/assets/dist-mm7c7nBt.js +2 -0
  52. package/public/assets/{dist-DjJMNrsj.js.map → dist-mm7c7nBt.js.map} +1 -1
  53. package/public/assets/dist-y03IwOrd.js +2 -0
  54. package/public/assets/{dist-C7VlX6hz.js.map → dist-y03IwOrd.js.map} +1 -1
  55. package/public/assets/{es2015-GhJvD7eR.js → es2015-VnZ2kVIz.js} +2 -2
  56. package/public/assets/{es2015-GhJvD7eR.js.map → es2015-VnZ2kVIz.js.map} +1 -1
  57. package/public/assets/{formatted-body-impl-2ZWd80_S.js → formatted-body-impl-CfnhWZAX.js} +2 -2
  58. package/public/assets/{formatted-body-impl-2ZWd80_S.js.map → formatted-body-impl-CfnhWZAX.js.map} +1 -1
  59. package/public/assets/index-4XRZ-n_A.js +23 -0
  60. package/public/assets/index-4XRZ-n_A.js.map +1 -0
  61. package/public/assets/{input-CPfrBmej.js → input-CtLT7WXi.js} +2 -2
  62. package/public/assets/{input-CPfrBmej.js.map → input-CtLT7WXi.js.map} +1 -1
  63. package/public/assets/{insights-DwS0svZy.js → insights-C5Ft13cw.js} +2 -2
  64. package/public/assets/{insights-DwS0svZy.js.map → insights-C5Ft13cw.js.map} +1 -1
  65. package/public/assets/{integrations-De1_UHQE.js → integrations-DR3pboEG.js} +2 -2
  66. package/public/assets/{integrations-De1_UHQE.js.map → integrations-DR3pboEG.js.map} +1 -1
  67. package/public/assets/{lib-Bi-xeh6t.js → lib-BLoevhQO.js} +3 -3
  68. package/public/assets/{lib-Bi-xeh6t.js.map → lib-BLoevhQO.js.map} +1 -1
  69. package/public/assets/lucide-react-Dc3ZwCBi.js +9 -0
  70. package/public/assets/{lucide-react-De5edQpl.js.map → lucide-react-Dc3ZwCBi.js.map} +1 -1
  71. package/public/assets/{maintenance-B5qrcsDt.js → maintenance-Ddl6-McO.js} +2 -2
  72. package/public/assets/{maintenance-B5qrcsDt.js.map → maintenance-Ddl6-McO.js.map} +1 -1
  73. package/public/assets/{managed-agents-BGMWAUfG.js → managed-agents-pLThsagU.js} +4 -4
  74. package/public/assets/{managed-agents-BGMWAUfG.js.map → managed-agents-pLThsagU.js.map} +1 -1
  75. package/public/assets/{markdown-preview-impl-DsZ4Ek80.js → markdown-preview-impl-CiENso5E.js} +2 -2
  76. package/public/assets/{markdown-preview-impl-DsZ4Ek80.js.map → markdown-preview-impl-CiENso5E.js.map} +1 -1
  77. package/public/assets/memory-CSzdP2o2.js +2 -0
  78. package/public/assets/{memory-CouN7Y4r.js.map → memory-CSzdP2o2.js.map} +1 -1
  79. package/public/assets/{messages-D9mYFxhU.js → messages-1ton_JT5.js} +2 -2
  80. package/public/assets/{messages-D9mYFxhU.js.map → messages-1ton_JT5.js.map} +1 -1
  81. package/public/assets/{orchestrators-B_SD_mhI.js → orchestrators-C2kC07Qm.js} +2 -2
  82. package/public/assets/{orchestrators-B_SD_mhI.js.map → orchestrators-C2kC07Qm.js.map} +1 -1
  83. package/public/assets/{overview-C8hVsCqz.js → overview-CXc2vQRQ.js} +2 -2
  84. package/public/assets/{overview-C8hVsCqz.js.map → overview-CXc2vQRQ.js.map} +1 -1
  85. package/public/assets/{pairs-B6vWKXnX.js → pairs-DLfFKNEf.js} +2 -2
  86. package/public/assets/{pairs-B6vWKXnX.js.map → pairs-DLfFKNEf.js.map} +1 -1
  87. package/public/assets/{projects-C2gHOdEY.js → projects-TM20JuNI.js} +2 -2
  88. package/public/assets/{projects-C2gHOdEY.js.map → projects-TM20JuNI.js.map} +1 -1
  89. package/public/assets/{prompt-settings-D4SXk0af.js → prompt-settings-DWYbD9TA.js} +2 -2
  90. package/public/assets/{prompt-settings-D4SXk0af.js.map → prompt-settings-DWYbD9TA.js.map} +1 -1
  91. package/public/assets/{react-dom-FNIdlE_z.js → react-dom-cLkVFBsS.js} +2 -2
  92. package/public/assets/{react-dom-FNIdlE_z.js.map → react-dom-cLkVFBsS.js.map} +1 -1
  93. package/public/assets/{registry-CMPhWcx3.js → registry-BWRVKBhU.js} +2 -2
  94. package/public/assets/{registry-CMPhWcx3.js.map → registry-BWRVKBhU.js.map} +1 -1
  95. package/public/assets/{security-C1fE4DVg.js → security-DcNNqoA4.js} +2 -2
  96. package/public/assets/{security-C1fE4DVg.js.map → security-DcNNqoA4.js.map} +1 -1
  97. package/public/assets/{select-D9j1MBVi.js → select-DkpcyiTY.js} +2 -2
  98. package/public/assets/{select-D9j1MBVi.js.map → select-DkpcyiTY.js.map} +1 -1
  99. package/public/assets/settings-C9-w25pF.js +6 -0
  100. package/public/assets/{settings-CduSwUr9.js.map → settings-C9-w25pF.js.map} +1 -1
  101. package/public/assets/{store-Bk6Lku_S.js → store-BZ2N51To.js} +5 -5
  102. package/public/assets/store-BZ2N51To.js.map +1 -0
  103. package/public/assets/{tasks-Bi456f7f.js → tasks-DuH_JQJM.js} +2 -2
  104. package/public/assets/{tasks-Bi456f7f.js.map → tasks-DuH_JQJM.js.map} +1 -1
  105. package/public/assets/{teams-ZEXvcAz_.js → teams-CQZ6a8A5.js} +2 -2
  106. package/public/assets/{teams-ZEXvcAz_.js.map → teams-CQZ6a8A5.js.map} +1 -1
  107. package/public/assets/{terminal-viewer-impl-tktfofs3.js → terminal-viewer-impl-B1A49Vs2.js} +3 -3
  108. package/public/assets/{terminal-viewer-impl-tktfofs3.js.map → terminal-viewer-impl-B1A49Vs2.js.map} +1 -1
  109. package/public/assets/types-DSwhOFcJ.js.map +1 -1
  110. package/public/assets/{use-keyboard-viewport-wzkGlTqU.js → use-keyboard-viewport-DucYmqmP.js} +2 -2
  111. package/public/assets/{use-keyboard-viewport-wzkGlTqU.js.map → use-keyboard-viewport-DucYmqmP.js.map} +1 -1
  112. package/public/assets/{user-avatar-_Dq16BWV.js → user-avatar-C3eL_il0.js} +2 -2
  113. package/public/assets/{user-avatar-_Dq16BWV.js.map → user-avatar-C3eL_il0.js.map} +1 -1
  114. package/public/assets/{work-queue-Bk8g7t9K.js → work-queue-IfxOcGe5.js} +2 -2
  115. package/public/assets/{work-queue-Bk8g7t9K.js.map → work-queue-IfxOcGe5.js.map} +1 -1
  116. package/public/assets/workspaces-gPEVu-L5.js +3 -0
  117. package/public/assets/{workspaces-D2bYW3zl.js.map → workspaces-gPEVu-L5.js.map} +1 -1
  118. package/public/index.html +20 -20
  119. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  120. package/scripts/orchestrator-spawn-smoke.ts +30 -13
  121. package/src/config-store.ts +15 -3
  122. package/src/db/migrations.ts +2 -2
  123. package/src/db/plans.ts +11 -0
  124. package/src/db/schema.ts +1 -1
  125. package/src/mcp/index.ts +1 -1
  126. package/src/mcp-plan-tools.ts +3 -0
  127. package/src/routes/index.ts +2 -1
  128. package/src/routes/plans.ts +12 -2
  129. package/src/services/plan-graph.ts +8 -1
  130. package/public/assets/MessageBubble-CxqPFLGP.js +0 -4
  131. package/public/assets/PlanGraphPanel-gQ_lb6zP.js +0 -2
  132. package/public/assets/PlanGraphPanel-gQ_lb6zP.js.map +0 -1
  133. package/public/assets/agents-DOwnLE42.js +0 -2
  134. package/public/assets/branch-state-badge-JDaHO2fG.js +0 -2
  135. package/public/assets/chat-BTmgzO_g.js +0 -2
  136. package/public/assets/dist-C7VlX6hz.js +0 -2
  137. package/public/assets/dist-DjJMNrsj.js +0 -2
  138. package/public/assets/dist-QY_EIkcd.js +0 -2
  139. package/public/assets/index-D4mb_LKw.js +0 -23
  140. package/public/assets/index-D4mb_LKw.js.map +0 -1
  141. package/public/assets/lucide-react-De5edQpl.js +0 -9
  142. package/public/assets/memory-CouN7Y4r.js +0 -2
  143. package/public/assets/settings-CduSwUr9.js +0 -6
  144. package/public/assets/store-Bk6Lku_S.js.map +0 -1
  145. package/public/assets/workspaces-D2bYW3zl.js +0 -3
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import { spawnSync } from "node:child_process";
2
3
  import { hostname } from "node:os";
3
4
  import { RELAY_TOKEN_HEADER } from "agent-relay-sdk";
4
5
 
@@ -16,7 +17,7 @@ type Agent = {
16
17
  status: string;
17
18
  ready: boolean;
18
19
  tags?: string[];
19
- meta?: { cwd?: string; provider?: string };
20
+ meta?: { cwd?: string; provider?: string; workspace?: { repoRoot?: string; sourceCwd?: string } };
20
21
  createdAt?: number;
21
22
  };
22
23
 
@@ -25,10 +26,9 @@ type ApprovalMode = "open" | "guarded" | "read-only";
25
26
  const args = process.argv.slice(2);
26
27
  let relayUrl = process.env.AGENT_RELAY_URL || "http://127.0.0.1:4850";
27
28
  let orchestratorId = process.env.AGENT_RELAY_SMOKE_ORCHESTRATOR || "";
28
- // Default cwd is resolved from the selected orchestrator's baseDir below, not
29
- // the local process.cwd() the chosen orchestrator may be on a different host
30
- // (e.g. macOS macmini with /Users/admin/projects) where a local Linux path
31
- // fails cwd containment.
29
+ // Default cwd is resolved to the local git repo root below. For remote
30
+ // orchestrators, pass --cwd or AGENT_RELAY_SMOKE_CWD with a repo path on that
31
+ // host so isolated workspace creation has a valid source repository.
32
32
  let cwd = process.env.AGENT_RELAY_SMOKE_CWD || "";
33
33
  let timeoutMs = Number(process.env.AGENT_RELAY_SMOKE_TIMEOUT_MS || 90_000);
34
34
  let providers = (process.env.AGENT_RELAY_SMOKE_PROVIDERS || "codex,claude").split(",").filter(Boolean);
@@ -83,11 +83,24 @@ async function waitFor<T>(label: string, fn: () => Promise<T | null>): Promise<T
83
83
  throw new Error(`${label} timed out after ${timeoutMs}ms`);
84
84
  }
85
85
 
86
+ function localRepoRoot(): string | null {
87
+ const result = spawnSync("git", ["rev-parse", "--show-toplevel"], {
88
+ cwd: process.cwd(),
89
+ encoding: "utf8",
90
+ });
91
+ if (result.status !== 0) return null;
92
+ return result.stdout.trim() || null;
93
+ }
94
+
86
95
  function findSpawnedAgent(agents: Agent[], provider: string, label: string, startedAt: number): Agent | null {
87
96
  return agents
88
97
  .filter((agent) => agent.ready && agent.status !== "offline")
89
98
  .filter((agent) => agent.label === label)
90
- .filter((agent) => agent.meta?.cwd === cwd)
99
+ .filter((agent) =>
100
+ agent.meta?.cwd === cwd ||
101
+ agent.meta?.workspace?.sourceCwd === cwd ||
102
+ agent.meta?.workspace?.repoRoot === cwd
103
+ )
91
104
  .filter((agent) => (agent.tags || []).includes(provider))
92
105
  .filter((agent) => (agent.tags || []).includes("dashboard-spawned"))
93
106
  .filter((agent) => !agent.createdAt || agent.createdAt >= startedAt - 5_000)
@@ -118,8 +131,8 @@ const orchestrators = await api<Orchestrator[]>("GET", "/orchestrators");
118
131
  // Default selection prefers the orchestrator on the same host as the relay (the
119
132
  // gate runs there): a local spawn is faster and avoids cross-host teardown
120
133
  // flakiness. Fall back to any online orchestrator. An explicit --orchestrator
121
- // always wins — pair it with --cwd (or rely on the baseDir default below) to
122
- // target a remote host such as a macOS macmini.
134
+ // always wins — pair it with --cwd to target a remote host such as a macOS
135
+ // macmini.
123
136
  const onlineOrchestrators = orchestrators.filter((orch) => orch.status === "online");
124
137
  const localOrchestrator = onlineOrchestrators.find((orch) => orch.id === hostname());
125
138
  const orchestrator = orchestratorId
@@ -129,13 +142,17 @@ if (!orchestrator) throw new Error(orchestratorId ? `orchestrator not found: ${o
129
142
  if (orchestrator.status !== "online") throw new Error(`orchestrator ${orchestrator.id} is ${orchestrator.status}`);
130
143
 
131
144
  // Resolve the spawn cwd against the chosen orchestrator's own base directory so
132
- // the smoke works regardless of which host runs it. An explicit --cwd / env
133
- // override still wins (and is subject to the orchestrator's containment check).
145
+ // the smoke exercises isolated workspace creation from a real git repository.
146
+ // An explicit --cwd / env override still wins (and is subject to the
147
+ // orchestrator's containment check).
134
148
  if (!cwd) {
135
- if (!orchestrator.baseDir) {
136
- throw new Error(`orchestrator ${orchestrator.id} did not report a baseDir; pass --cwd or set AGENT_RELAY_SMOKE_CWD`);
149
+ if (orchestrator.id !== hostname()) {
150
+ throw new Error(`orchestrator ${orchestrator.id} is remote; pass --cwd or set AGENT_RELAY_SMOKE_CWD to a git repo on that host`);
151
+ }
152
+ cwd = localRepoRoot() || "";
153
+ if (!cwd) {
154
+ throw new Error("could not resolve the local git repo root; pass --cwd or set AGENT_RELAY_SMOKE_CWD");
137
155
  }
138
- cwd = orchestrator.baseDir;
139
156
  }
140
157
  console.log(`using cwd ${cwd} on ${orchestrator.id} (base ${orchestrator.baseDir})`);
141
158
 
@@ -67,14 +67,14 @@ const WORKER_TOOL_GROUPS = ["core", "workspace", "memory", "artifacts", "blackbo
67
67
 
68
68
  function builtInAgentProfiles(): AgentProfile[] {
69
69
  return [
70
- agentProfileDefaults({ name: DEFAULT_SPAWN_PROFILE_NAME, icon: "🤖", description: "Relay-aware spawned agent with bundled Relay context, skills, plugins, and status integration.", base: "host", mcp: { mode: "none" }, relay: { tools: { groups: WORKER_TOOL_GROUPS } } }),
70
+ agentProfileDefaults({ name: DEFAULT_SPAWN_PROFILE_NAME, icon: "🤖", description: "Relay-aware spawned agent with bundled Relay context, skills, plugins, and status integration.", base: "minimal", instructions: { append: [], repoInstructions: "allow", globalInstructions: "allow" }, sharedMcp: { policy: "all" }, hostAssets: { skills: true, plugins: true }, relay: { context: true, skills: true, plugins: true, statusLine: true, mcp: true, tools: { groups: WORKER_TOOL_GROUPS } }, permissions: { filesystem: "host" } }),
71
71
  agentProfileDefaults({ name: "minimal", icon: "▫️", description: "Repo-focused spawned agent with Relay affordances disabled and host/global extras avoided where supported.", base: "minimal" }),
72
72
  agentProfileDefaults({ name: "isolated-research", icon: "🔬", description: "Strict profile for autonomous research runs: repo context only, no Relay prompt surface, no global extras where supported.", base: "isolated" }),
73
73
  agentProfileDefaults({ name: "vanilla", icon: "🫥", description: "Zero host bleed (#552): isolated provider home with host plugins, skills, hooks, MCP, and the CLAUDE.md/AGENTS.md cascade (repo + global) all suppressed at launch. Relay provisions any surface explicitly per profile.", base: "vanilla" }),
74
74
  agentProfileDefaults({ name: "lean-worker", icon: "🪶", description: "Lean worker profile (#570): vanilla host-dependency drop with only Relay context/MCP restored and Project knowledge injected from the spawn cwd.", base: "vanilla", relay: { context: true, skills: false, plugins: false, statusLine: false, mcp: true, tools: { groups: WORKER_TOOL_GROUPS } }, projectInstructions: { policy: "all" } }),
75
- agentProfileDefaults({ name: "coordinator", icon: "🧭", description: "Relay-aware coordination lead for spawning worker teams, maintaining shared state, and driving review and release.", base: "host", instructions: { append: [renderTemplate("profile.coordinator.charter")], repoInstructions: "allow", globalInstructions: "allow" }, maxSpawnedAgents: 8 }),
75
+ agentProfileDefaults({ name: "coordinator", icon: "🧭", description: "Relay-aware coordination lead for spawning worker teams, maintaining shared state, and driving review and release.", base: "minimal", instructions: { append: [renderTemplate("profile.coordinator.charter")], repoInstructions: "allow", globalInstructions: "allow" }, sharedMcp: { policy: "all" }, hostAssets: { skills: true, plugins: true }, relay: { context: true, skills: true, plugins: true, statusLine: true, mcp: true }, permissions: { filesystem: "host" }, maxSpawnedAgents: 8 }),
76
76
  agentProfileDefaults({ name: "ops-assistant", icon: "🛠️", description: "Relay-aware ops lieutenant for a coordinator: runs tests, releases, smoke probes, gates, and host checks, then reports crisp outcomes back up.", provider: "codex", base: "host", instructions: { append: [renderTemplate("profile.ops-assistant.brief")], repoInstructions: "allow", globalInstructions: "allow" }, notifications: { responseMode: "results-only" }, permissions: { mode: "open", filesystem: "host" } }),
77
- agentProfileDefaults({ name: "worker", icon: "🔨", description: "Relay-aware focused implementer with open approval posture and no delegated spawn capability.", base: "host", instructions: { system: renderTemplate("profile.worker.system"), append: [], repoInstructions: "allow", globalInstructions: "allow" }, mcp: { mode: "none" }, permissions: { mode: "open", filesystem: "host" }, relay: { tools: { groups: WORKER_TOOL_GROUPS } } }),
77
+ agentProfileDefaults({ name: "worker", icon: "🔨", description: "Relay-aware focused implementer with open approval posture and no delegated spawn capability.", base: "minimal", instructions: { system: renderTemplate("profile.worker.system"), append: [], repoInstructions: "allow", globalInstructions: "allow" }, sharedMcp: { policy: "all" }, hostAssets: { skills: true, plugins: true }, relay: { context: true, skills: true, plugins: true, statusLine: true, mcp: true, tools: { groups: WORKER_TOOL_GROUPS } }, permissions: { mode: "open", filesystem: "host" } }),
78
78
  agentProfileDefaults({ name: "reviewer", icon: "🔍", description: "Relay-aware read-only reviewer for audit and review passes without file writes.", base: "host", mcp: { mode: "none" }, permissions: { mode: "read-only", filesystem: "host" }, relay: { tools: { groups: WORKER_TOOL_GROUPS } } }),
79
79
  ].map((profile) => ({ ...profile, builtIn: true }));
80
80
  }
@@ -272,6 +272,16 @@ function cleanAgentProfileSharedMcp(value: unknown): AgentProfile["sharedMcp"] {
272
272
  return { policy: cleanEnum(policy, "sharedMcp.policy", SHARED_MCP_POLICY_NAMES) as NonNullable<AgentProfile["sharedMcp"]>["policy"] };
273
273
  }
274
274
 
275
+ function cleanAgentProfileHostAssets(value: unknown): AgentProfile["hostAssets"] {
276
+ if (value === undefined || value === null || value === false) return undefined;
277
+ if (!isRecord(value)) throw new ValidationError("hostAssets must be an object");
278
+ const hostAssets = {
279
+ ...(value.skills === undefined ? {} : { skills: cleanBoolean(value.skills, "hostAssets.skills") }),
280
+ ...(value.plugins === undefined ? {} : { plugins: cleanBoolean(value.plugins, "hostAssets.plugins") }),
281
+ };
282
+ return Object.keys(hostAssets).length ? hostAssets : undefined;
283
+ }
284
+
275
285
  function cleanAgentProfileNotifications(value: unknown): AgentProfile["notifications"] {
276
286
  if (value === undefined || value === null) return undefined;
277
287
  if (!isRecord(value)) throw new ValidationError("notifications must be an object");
@@ -306,6 +316,7 @@ function agentProfileDefaults(input: Pick<AgentProfile, "name" | "base"> & Omit<
306
316
  ...(input.projectSkills ? { projectSkills: input.projectSkills } : {}),
307
317
  ...(input.projectSettings ? { projectSettings: input.projectSettings } : {}),
308
318
  ...(input.sharedMcp ? { sharedMcp: input.sharedMcp } : {}),
319
+ ...(input.hostAssets ? { hostAssets: input.hostAssets } : {}),
309
320
  ...(input.notifications ? { notifications: input.notifications } : {}),
310
321
  relay: {
311
322
  context: input.relay?.context ?? !isolated,
@@ -389,6 +400,7 @@ function validateAgentProfile(key: string, value: unknown, opts: { allowBuiltIn?
389
400
  projectSkills: cleanAgentProfileProjectSkills(value.projectSkills),
390
401
  projectSettings: cleanAgentProfileProjectSettings(value.projectSettings),
391
402
  sharedMcp: cleanAgentProfileSharedMcp(value.sharedMcp),
403
+ hostAssets: cleanAgentProfileHostAssets(value.hostAssets),
392
404
  notifications: cleanAgentProfileNotifications(value.notifications),
393
405
  relay: {
394
406
  context: relay.context === undefined ? defaults.relay.context : cleanBoolean(relay.context, "relay.context"),
@@ -444,11 +444,11 @@ export function applyMigrations(): void {
444
444
  created_by TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL
445
445
  )
446
446
  `);
447
- const planCols = getDb().query("PRAGMA table_info(plans)").all() as any[];
448
- const planColNames = planCols.map((c: any) => c.name);
447
+ const planColNames = (getDb().query("PRAGMA table_info(plans)").all() as any[]).map((c: any) => c.name);
449
448
  if (!planColNames.includes("team_id")) {
450
449
  getDb().run("ALTER TABLE plans ADD COLUMN team_id TEXT");
451
450
  }
451
+ if (!planColNames.includes("archived")) getDb().run("ALTER TABLE plans ADD COLUMN archived INTEGER NOT NULL DEFAULT 0");
452
452
  getDb().run("CREATE UNIQUE INDEX IF NOT EXISTS idx_plans_thread_channel ON plans(thread_id, coalesce(channel, ''))");
453
453
  getDb().run("CREATE INDEX IF NOT EXISTS idx_plans_updated ON plans(updated_at)");
454
454
  getDb().run("CREATE INDEX IF NOT EXISTS idx_plans_team ON plans(team_id)");
package/src/db/plans.ts CHANGED
@@ -8,6 +8,7 @@ interface PlanRow {
8
8
  thread_id: number;
9
9
  team_id: string | null;
10
10
  channel: string | null;
11
+ archived: number;
11
12
  version: number;
12
13
  title: string | null;
13
14
  objective: string | null;
@@ -52,6 +53,7 @@ function rowToPlan(row: PlanRow): Plan {
52
53
  threadId: String(row.thread_id),
53
54
  ...(row.team_id ? { teamId: row.team_id } : {}),
54
55
  ...(row.channel ? { channel: row.channel } : {}),
56
+ archived: Boolean(row.archived),
55
57
  version: row.version,
56
58
  ...(row.title ? { title: row.title } : {}),
57
59
  ...(row.objective ? { objective: row.objective } : {}),
@@ -189,6 +191,15 @@ export function replacePlan(input: Plan, changedBy?: string): Plan {
189
191
  return getPlan(input.id)!;
190
192
  }
191
193
 
194
+ export function setPlanArchived(id: string, archived: boolean): Plan {
195
+ const existing = getPlan(id);
196
+ if (!existing) throw new ValidationError(`plan ${id} not found`);
197
+ if (existing.archived === archived) return existing;
198
+ const now = Date.now();
199
+ getDb().query("UPDATE plans SET archived = ?, updated_at = ? WHERE id = ?").run(archived ? 1 : 0, now, id);
200
+ return getPlan(id)!;
201
+ }
202
+
192
203
  export function deletePlan(id: string, changedBy?: string): boolean {
193
204
  const existing = getPlan(id);
194
205
  if (!existing) return false;
package/src/db/schema.ts CHANGED
@@ -304,7 +304,7 @@ export function initDb(path: string = "agent-relay.db"): Database {
304
304
  CREATE INDEX IF NOT EXISTS idx_project_edges_to ON project_edges(to_project, kind);
305
305
  CREATE TABLE IF NOT EXISTS plans (
306
306
  id TEXT PRIMARY KEY, thread_id INTEGER NOT NULL, team_id TEXT, channel TEXT, version INTEGER NOT NULL DEFAULT 1,
307
- title TEXT, objective TEXT, nodes TEXT NOT NULL DEFAULT '[]', edges TEXT NOT NULL DEFAULT '[]',
307
+ archived INTEGER NOT NULL DEFAULT 0, title TEXT, objective TEXT, nodes TEXT NOT NULL DEFAULT '[]', edges TEXT NOT NULL DEFAULT '[]',
308
308
  created_by TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL
309
309
  );
310
310
  CREATE UNIQUE INDEX IF NOT EXISTS idx_plans_thread_channel ON plans(thread_id, coalesce(channel, ''));
package/src/mcp/index.ts CHANGED
@@ -54,7 +54,7 @@ export const RELAY_TOOL_GROUPS: Record<string, readonly string[]> = {
54
54
  artifacts: ["relay_upload_artifact", "relay_attach_artifact"],
55
55
  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"],
56
56
  "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"],
57
- 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"],
57
+ 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_archive", "relay_plan_delete", "relay_plan_get"],
58
58
  tasks: ["relay_task_create", "relay_task_get", "relay_task_list", "relay_task_update", "relay_task_set_status", "relay_task_set_stage", "relay_task_record_gate", "relay_task_add_dependency", "relay_task_remove_dependency", "relay_task_add_ref", "relay_task_remove_ref", "relay_task_assign_agent", "relay_task_history", "relay_task_memory_read", "relay_task_memory_replace_working_state", "relay_task_memory_append_ruled_out", "relay_task_memory_append_decision", "relay_task_dispatch", "relay_task_comment", "relay_task_close_bridge", "relay_release_readiness"],
59
59
  teams: ["relay_team_get", "relay_team_set_brief", "relay_team_claim", "relay_team_dissolve"],
60
60
  blackboard: ["relay_blackboard_write", "relay_blackboard_get", "relay_blackboard_read", "relay_blackboard_search", "relay_blackboard_retract"],
@@ -4,6 +4,7 @@ import { authContextFromMcp } from "./services/auth-context";
4
4
  import {
5
5
  addPlanEdge,
6
6
  addPlanNode,
7
+ archivePlanGraph,
7
8
  bindPlanNodeToTask,
8
9
  createPlan,
9
10
  deletePlanGraph,
@@ -98,6 +99,7 @@ export const PLAN_TOOLS = [
98
99
  { name: "relay_plan_add_edge", description: "Add a dependency edge to a plan DAG; rejects cycles.", requiredScopes: ["plans:write"], inputSchema: { type: "object", properties: { planId: { type: "string" }, from: { type: "string" }, to: { type: "string" } }, required: ["planId", "from", "to"], additionalProperties: false } },
99
100
  { name: "relay_plan_remove_node", description: "Remove a node and its connected edges from a plan DAG.", requiredScopes: ["plans:write"], inputSchema: { type: "object", properties: { planId: { type: "string" }, nodeId: { type: "string" } }, required: ["planId", "nodeId"], additionalProperties: false } },
100
101
  { name: "relay_plan_remove_edge", description: "Remove a dependency edge from a plan DAG.", requiredScopes: ["plans:write"], inputSchema: { type: "object", properties: { planId: { type: "string" }, from: { type: "string" }, to: { type: "string" } }, required: ["planId", "from", "to"], additionalProperties: false } },
102
+ { name: "relay_plan_archive", description: "Soft-archive or unarchive a persisted plan DAG without deleting its history.", requiredScopes: ["plans:write"], inputSchema: { type: "object", properties: { planId: { type: "string" }, archived: { type: "boolean", default: true } }, required: ["planId"], additionalProperties: false } },
101
103
  { name: "relay_plan_delete", description: "Delete a persisted plan DAG and archive its latest version.", requiredScopes: ["plans:write"], inputSchema: { type: "object", properties: { planId: { type: "string" } }, required: ["planId"], additionalProperties: false } },
102
104
  {
103
105
  name: "relay_plan_bind_node",
@@ -135,6 +137,7 @@ export function relayPlanTool(auth: McpAuthLike, name: string, args: Record<stri
135
137
  if (name === "relay_plan_add_edge") return addPlanEdge(stringArg(args.planId, "planId"), { from: args.from, to: args.to }, ctx) as unknown as Record<string, unknown>;
136
138
  if (name === "relay_plan_remove_node") return removePlanNode(stringArg(args.planId, "planId"), stringArg(args.nodeId, "nodeId"), ctx) as unknown as Record<string, unknown>;
137
139
  if (name === "relay_plan_remove_edge") return removePlanEdge(stringArg(args.planId, "planId"), { from: args.from, to: args.to }, ctx) as unknown as Record<string, unknown>;
140
+ if (name === "relay_plan_archive") return archivePlanGraph(stringArg(args.planId, "planId"), args.archived !== false, ctx) as unknown as Record<string, unknown>;
138
141
  if (name === "relay_plan_delete") return deletePlanGraph(stringArg(args.planId, "planId"), ctx);
139
142
  if (name === "relay_plan_bind_node") {
140
143
  return bindPlanNodeToTask(
@@ -33,7 +33,7 @@ import { getHostDirectories, postAgent, postAgentSpawn, postRouteAdvice } from "
33
33
  import { getInsightsConfigRoute, getInsightsObservationsRoute, postInsightsObservationRoute, putInsightsConfigRoute } from "./insights";
34
34
  import { getOrchestratorDirectories, getOrchestratorFileRead, getOrchestratorFileStat, getOrchestratorFilesList, getOrchestratorLogs, getOrchestratorProviders, getOrchestratorSessions, getOrchestratorTerminal, getOrchestratorVersion, getOrchestratorWorkspaceProbe, postOrchestratorCreateDirectory, postOrchestratorTerminalInput, postOrchestratorTerminalResize } from "./orchestrator-proxy";
35
35
  import { getPairById, getPairs, postAcceptPair, postHangupPair, postPair, postPairMessage, postRejectPair } from "./pairs";
36
- import { getPlanByIdRoute, getPlansRoute } from "./plans";
36
+ import { getPlanByIdRoute, getPlansRoute, patchPlanArchiveRoute } from "./plans";
37
37
  import { getBlackboardEntryRoute, getBlackboardRoute } from "./blackboard";
38
38
  import { deleteIssueAssociationRoute, getIssueAssociationEntityIssuesRoute, getIssueAssociationIssueEntitiesRoute, postIssueAssociationRoute } from "./issue-associations";
39
39
  import { getAgentIssueActivityRoute, getIssueActivityAgentsRoute, postIssueActivityRoute } from "./issue-activity";
@@ -384,6 +384,7 @@ const routes: Route[] = [
384
384
  route("POST", "/api/pairs/:id/messages", postPairMessage),
385
385
  route("GET", "/api/plans", getPlansRoute),
386
386
  route("GET", "/api/plans/:id", getPlanByIdRoute),
387
+ route("PATCH", "/api/plans/:id/archive", patchPlanArchiveRoute),
387
388
  route("GET", "/api/blackboard", getBlackboardRoute),
388
389
  route("GET", "/api/blackboard/:id", getBlackboardEntryRoute),
389
390
  route("POST", "/api/issue-associations", postIssueAssociationRoute),
@@ -1,6 +1,7 @@
1
- import { getPlanGraph } from "../services/plan-graph";
1
+ import { archivePlanGraph, getPlanGraph } from "../services/plan-graph";
2
+ import { authContextFromRequest } from "../services/auth-context";
2
3
  import { cleanString } from "../validation";
3
- import { error, json, parseQueryInt, type Handler } from "./_shared";
4
+ import { error, json, parseBody, parseQueryInt, type Handler } from "./_shared";
4
5
 
5
6
  export const getPlansRoute: Handler = (req) => {
6
7
  const url = new URL(req.url);
@@ -32,3 +33,12 @@ export const getPlanByIdRoute: Handler = (_req, params) => {
32
33
  const plan = getPlanGraph({ planId: id });
33
34
  return plan ? json(plan) : error("plan not found", 404);
34
35
  };
36
+
37
+ export const patchPlanArchiveRoute: Handler = async (req, params) => {
38
+ const id = cleanString(params.id, "id", { required: true, max: 120 })!;
39
+ const parsed = await parseBody<{ archived?: unknown }>(req);
40
+ if (!parsed.ok) return error(parsed.error);
41
+ const archived = parsed.body?.archived;
42
+ if (typeof archived !== "boolean") return error("archived must be a boolean");
43
+ return json(archivePlanGraph(id, archived, authContextFromRequest(req)));
44
+ };
@@ -1,5 +1,5 @@
1
1
  import { isRecord } from "agent-relay-sdk";
2
- import { addTaskDependency, createPlanRow, deletePlan, getAgent, getEntry, getPlan, getPlanByTeam, getPlanByThread, getTaskDetail, listPlansWithBoundOwner, planThreadExists, removeTaskDependency, replacePlan, ValidationError } from "../db";
2
+ import { addTaskDependency, createPlanRow, deletePlan, getAgent, getEntry, getPlan, getPlanByTeam, getPlanByThread, getTaskDetail, listPlansWithBoundOwner, planThreadExists, removeTaskDependency, replacePlan, setPlanArchived, ValidationError } from "../db";
3
3
  import { associateIssue, planNodeIssueEntityId, removeAssociation } from "../db/issue-associations";
4
4
  import { resolveIssueRefFromString } from "../db/issue-refs";
5
5
  import { emitRelayEvent } from "../events";
@@ -394,6 +394,13 @@ export function deletePlanGraph(planId: string, ctx: AuthContext): { id: string;
394
394
  return { id: plan.id, deleted: true };
395
395
  }
396
396
 
397
+ export function archivePlanGraph(planId: string, archived: boolean, ctx: AuthContext): Plan {
398
+ const actor = actorId(ctx);
399
+ const plan = setPlanArchived(planId, archived);
400
+ emitPlan("plan.changed", plan, actor);
401
+ return plan;
402
+ }
403
+
397
404
  export function updateBoundPlanNodesForAgent(agentId: string, status: PlanStatus, actor = "server"): Plan[] {
398
405
  const updated: Plan[] = [];
399
406
  for (const plan of listPlansWithBoundOwner(agentId)) {
@@ -1,4 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{At as t,En as n,Gn as r,H as i,Kn as a,Nn as o,Qn as s,R as c,Rn as l,S as u,Sn as d,Tn as f,Ut as p,V as m,_ as h,a as g,bn as _,cn as v,dn as y,en as b,er as x,h as S,kt as C,l as ee,nr as te,o as ne,pn as re,pr as w,pt as T,r as E,tn as D,ut as O,vn as k,wn as A,x as j,xn as ie}from"./lucide-react-De5edQpl.js";import{r as M,t as N,y as P}from"./store-Bk6Lku_S.js";import{o as F}from"./types-DSwhOFcJ.js";import{E as I,H as ae,N as L,P as R,R as oe,S as se,V as ce,_ as le,d as ue,f as de,k as z,q as B,rt as V,v as fe}from"./display-_5kFrHJh.js";import{O as H,n as pe,o as me,s as U,t as he}from"./index-D4mb_LKw.js";import{t as ge}from"./user-avatar-_Dq16BWV.js";var W=e(w(),1),_e={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`},ve=new Set(Object.keys(_e)),ye=3e3;function G(e){return new Date(e.occurredAt??e.createdAt).getTime()}function be(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:G(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function xe(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:G(e)}}function Se(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:G(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 Ce(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:we(n.questions,o,a),timestamp:G(e)}}function we(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 Te(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 Ee(e){return e.kind===`system`&&e.from===`system`}var De=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function K(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function Oe(e){let t=e.filter(e=>ve.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)<=ye)||n.push(e);return n}function ke(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`||Ee(t)||I(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!z(t).trim())continue;let e=G(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=>Te(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=Te(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)&&ae(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(Ee(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(De.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=G(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:G(t),entry:{type:`notice`,msg:t}});continue}let e=xe(t);if(e){h.push(e);continue}let n=be(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=Se(t);if(r){a.push({ts:r.timestamp,entry:{type:`relay-injection`,event:r}});continue}let i=Ce(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:G(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let o=t.id===s?`initial-prompt`:`message`;a.push({ts:G(t),entry:{type:o,msg:t}})}for(let e of Oe([...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=K(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`&&Me(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function Ae(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 je(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)}`: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 Me(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function Ne(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Pe(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 Fe(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function Ie(e,t){return e.filter(e=>e.status===`online`&&oe(t,e.baseDir)).sort((e,t)=>L(t.baseDir).length-L(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function Le(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function Re(){return typeof window<`u`&&!!window.getSelection()?.toString()}function ze(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var Be=[`👍`,`❤️`,`✅`,`👀`];function Ve(e){let t=new Map;for(let n of e.reactions||[]){let e=R(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 q(e){return I(e)}function He(e,t){let r=e.readBy||[],i=e.resolvedToAgent||t||e.to,a=i?r.includes(i):!1,o=r.some(e=>e!==V);if(a||o){let e=a?i:r.find(e=>e!==V);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:n}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:n};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:v};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 Ue(e){let t=B(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,B(t.updatedAt||t.createdAt)),t)}function We(e){return e?e.messages.reduce((e,t)=>Math.max(e,Ue(t)),0):0}function Ge(e,t,n){return(e-t)*n}function Ke(e){if(!e)return 0;let t=0;for(let n of e.messages)se(n)&&(t=Math.max(t,B(n.createdAt)));return t}function J(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function qe(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function Je(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[M(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var Y=x(),Ye={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 Xe(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===K(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===K(o.getTime())?`Yesterday`:a.toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`,year:a.getFullYear()===t.getFullYear()?void 0:`numeric`})}function Ze({event:e}){return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,Y.jsx)(y,{className:s(`w-2 h-2 fill-current`,Ye[e.status]||`text-zinc-400`)}),(0,Y.jsx)(`span`,{children:_e[e.status]||e.status}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60`,children:J(e.timestamp)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var Qe={"branch.landed":C,"context.warning":S,"agent.context_threshold":S,"agent.resume_budget_exhausted":S,"agent.rate_limit_resume":i},$e={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function et(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function X({agentId:e,fallbackLabel:t,className:n,noIcon:r}){let i=N(t=>t.agentsById[e])||null,a=N(e=>e.openInboxThread),o=N(e=>e.switchView),c=i?ue(i):t||e;return(0,Y.jsxs)(`button`,{type:`button`,className:s(`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 ${c}`,children:[!r&&(0,Y.jsx)(H,{agent:i,className:`w-4 h-4 text-[10px]`}),(0,Y.jsx)(`span`,{className:`max-w-[160px] truncate`,children:c})]})}function tt({msg:e}){let t=e.payload??{},n=rt(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,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.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,Y.jsx)(C,{className:`h-3 w-3 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,Y.jsx)(`span`,{className:`text-emerald-700 dark:text-emerald-300`,children:`branch landed`}),o&&s&&(0,Y.jsxs)(`span`,{className:`font-mono text-emerald-700/80 dark:text-emerald-200/70`,title:`${o} → ${s}`,children:[o,(0,Y.jsx)(`span`,{className:`opacity-50`,children:` → `}),s]}),i&&(0,Y.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,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-700/80 dark:text-emerald-300/80`,children:[(0,Y.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,Y.jsx)(X,{agentId:a,className:`text-emerald-700 hover:text-emerald-900 dark:text-emerald-300/90 dark:hover:text-emerald-100`})]}),c===!1&&(0,Y.jsx)(`span`,{className:`text-amber-600 dark:text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),n&&(0,Y.jsxs)(`span`,{className:`max-w-[220px] truncate text-emerald-700/70 dark:text-emerald-300/70`,title:n,children:[`· because `,n]}),(0,Y.jsx)(`span`,{className:`text-emerald-700/60 dark:text-emerald-300/50`,children:J(e.occurredAt??e.createdAt)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function nt({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,Y.jsx)(tt,{msg:e});let n=Qe[t]??c,r=$e[t]??et(t),i=rt(e);return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.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,Y.jsx)(n,{className:`h-3 w-3`}),(0,Y.jsx)(`span`,{children:r}),i&&(0,Y.jsxs)(`span`,{className:`max-w-[220px] truncate text-muted-foreground/80`,title:i,children:[`· because `,i]}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60`,children:J(e.occurredAt??e.createdAt)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function rt(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 it={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},at={"spawned-child-ready":m,"spawned-child-exited":O,"spawned-child-failed":_,"spawned-by-ready":a,"spawned-by-exited":a,"spawned-by-failed":a},ot={"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 st({entry:e}){let t=`${e.direction}-${e.status}`,n=it[e.direction]?.[e.status]??e.direction,r=at[t]??c,i=ot[t]??`text-muted-foreground`,a=e.status===`failed`;return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:s(`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,Y.jsx)(r,{className:s(`h-3 w-3 shrink-0`,i)}),(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,Y.jsx)(X,{agentId:e.agentId}),e.reason&&a&&(0,Y.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:J(e.timestamp)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var ct={memory:o,instructions:p,tools:ne,comms:c,knowledge:l,context:D},lt={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 ut(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function dt({entry:e}){let[t,n]=(0,W.useState)(!1),r=e.event,i=ct[r.category]??j;return(0,Y.jsx)(`div`,{className:`flex justify-center py-2 my-1`,children:(0,Y.jsxs)(`div`,{className:s(`w-full max-w-[85%] md:max-w-[75%] rounded-lg border px-2.5 py-1.5 text-xs shadow-sm`,lt[r.category]??lt.context),children:[(0,Y.jsxs)(`button`,{type:`button`,className:`flex w-full min-w-0 items-center gap-1.5 text-left`,onClick:()=>n(e=>!e),children:[(0,Y.jsx)(i,{className:`h-3.5 w-3.5 shrink-0`}),(0,Y.jsx)(`span`,{className:`shrink-0 font-medium`,children:r.category}),(0,Y.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-foreground/80`,children:r.summary}),(0,Y.jsx)(`span`,{className:`shrink-0 text-muted-foreground/60`,children:J(r.timestamp)}),(0,Y.jsx)(d,{className:s(`h-3.5 w-3.5 shrink-0 transition-transform`,t&&`rotate-90`)})]}),t&&(0,Y.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:ut(r.detail)})]})})}function ft({blockedLabel:e,onInterrupt:t}){return e?(0,Y.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,Y.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,Y.jsx)(_,{className:`w-3.5 h-3.5 text-red-400`}),(0,Y.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,Y.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,Y.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,Y.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,Y.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,Y.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,Y.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,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,Y.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,Y.jsx)(re,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var Z=`agent-relay:chat-hide-tools`,Q=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(Z)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===Z&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(Z,t?`on`:`off`)}catch{}n()}}})();function pt(){return[(0,W.useSyncExternalStore)(Q.subscribe,Q.get,()=>!1),Q.toggle]}function mt({steps:e,showReasoning:t,issueRepo:n}){let[r,i]=pt(),a=t?e:e.filter(e=>e.kind!==`reasoning`);if(!a.length)return null;let c=a.filter(e=>e.kind===`tool`).length;return(0,Y.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,Y.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[a.map(e=>e.kind===`narration`?(0,Y.jsx)(U,{text:e.text,issueRepo:n,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,Y.jsx)(o,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,Y.jsx)(U,{text:e.text,issueRepo:n,className:`italic break-words min-w-0`})]},e.id):r?null:(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,Y.jsx)(h,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,Y.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,Y.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,Y.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),c>0&&(0,Y.jsxs)(`button`,{onClick:i,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,Y.jsx)(d,{className:s(`w-3 h-3 shrink-0 transition-transform`,!r&&`rotate-90`)}),(0,Y.jsx)(`span`,{children:r?`show ${c} tool step${c===1?``:`s`}`:`hide tool steps`})]})]})})}function ht({entry:e}){let{event:t}=e,n=t.kind===`questions`,r=n?t.title:t.kind===`plan`?`Plan prompt`:`${t.toolName} permission`;return(0,Y.jsx)(`div`,{className:`flex justify-center py-1.5`,children:(0,Y.jsxs)(`div`,{className:`w-full max-w-2xl rounded-md border border-border bg-muted/20 px-3 py-2 text-sm`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,Y.jsx)(k,{className:`h-3.5 w-3.5 text-emerald-500`}),(0,Y.jsx)(`span`,{className:`font-medium text-foreground`,children:r}),(0,Y.jsx)(`span`,{children:t.decisionLabel}),(0,Y.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/60`,children:J(t.timestamp)})]}),n&&t.questions.length>0?(0,Y.jsx)(`div`,{className:`mt-2 space-y-1.5`,children:t.questions.map((e,t)=>(0,Y.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.question}),(0,Y.jsx)(`div`,{className:`text-sm text-foreground`,children:e.answer})]},`${e.question}-${t}`))}):t.body.trim()?(0,Y.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,Y.jsx)(U,{text:t.body})}):null]})})}function gt({date:e}){return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:Xe(e)}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function _t({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function vt({history:e}){let n=e.sourceAgentLabel||e.sourcePeerId,r=e.entries.length;return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.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,Y.jsx)(t,{className:`h-3 w-3`}),(0,Y.jsxs)(`span`,{children:[`forked history from `,n]}),(0,Y.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[r,` `,r===1?`entry`:`entries`]})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function yt({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,i=z(r),a=e.originalFrom===V;return(0,Y.jsx)(`div`,{className:s(`flex mb-3 opacity-80`,a?`justify-end`:`justify-start`),children:(0,Y.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,Y.jsxs)(`div`,{className:s(`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,Y.jsxs)(`div`,{className:s(`mb-1 text-[10px] uppercase tracking-normal`,a?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,a?`you`:t||e.originalFrom]}),(0,Y.jsx)(U,{text:i,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,Y.jsxs)(`p`,{className:s(`mt-1 flex items-center justify-end gap-1.5 text-xs`,a?`text-primary/60`:`text-muted-foreground`),children:[(0,Y.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,Y.jsx)(`span`,{children:J(e.originalCreatedAt)})]})]})})})}function $({msg:e,issueRepo:t}){let n=z(e),r=J(e.occurredAt??e.createdAt);return(0,Y.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,Y.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,Y.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,Y.jsx)(j,{className:`h-3.5 w-3.5`}),(0,Y.jsx)(`span`,{children:`Initial prompt`}),(0,Y.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,Y.jsx)(U,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function bt({scrollEl:e,timeline:t}){let[n,r]=(0,W.useState)(!0),[i,a]=(0,W.useState)(null),[o,c]=(0,W.useState)(null),[l,u]=(0,W.useState)(!1),d=(0,W.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,W.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=i?.id===d.id?i.value:!1,p=o?.id===d.id?o.value:!1;function m(){!e||!d||e.querySelector(`[data-msg-id="${d.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let h=l?`↑`:`↓`;return p?(0,Y.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,Y.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,Y.jsx)(`span`,{children:`Your prompt`}),(0,Y.jsx)(A,{className:`w-3 h-3`})]})}):(0,Y.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,Y.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,Y.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:m,children:[h,` scroll to original`]}),(0,Y.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>c({id:d.id,value:!0}),title:`Minimize`,children:(0,Y.jsx)(ie,{className:`w-3 h-3`})})]}),(0,Y.jsx)(`p`,{className:s(`text-sm text-foreground leading-snug cursor-pointer`,!f&&`line-clamp-2`),onClick:()=>a({id:d.id,value:!f}),children:d.body})]})}function xt(){return(0,W.useSyncExternalStore)(e=>P.subscribe(e),()=>P.getPlayingKey(),()=>null)}function St({msg:e,peer:t}){return(0,Y.jsx)($,{msg:e,issueRepo:N(e=>e.agentsById[t]?.issueRepo)})}function Ct({agent:e,onClick:t}){let n=!!(t&&e);return(0,Y.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:s(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,Y.jsx)(H,{agent:e})})}function wt({agentId:e,onOpen:t}){let n=N(t=>t.agentsById[e]??null);return(0,Y.jsx)(Ct,{agent:n,onClick:n?()=>t(n):void 0})}function Tt({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[i,a]=(0,W.useState)(null),[o,c]=(0,W.useState)(null),[l,u]=(0,W.useState)(!1),[d,f]=(0,W.useState)(!1);(0,W.useEffect)(()=>{let t=!1,n=null;async function r(){u(!0),c(null),a(null);try{let r=await te(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),a(n)}catch(e){t||c(e.message)}finally{t||u(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function m(){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,Y.jsxs)(Y.Fragment,{children:[(0,Y.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,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`img`,{src:i,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,Y.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,Y.jsx)(E,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,Y.jsxs)(`span`,{className:s(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,o?`text-red-400`:`text-muted-foreground`),children:[l?(0,Y.jsx)(T,{className:`h-4 w-4 animate-spin`}):(0,Y.jsx)(_,{className:`h-4 w-4`}),o||`Loading image`]})}),i&&(0,Y.jsx)(he,{open:d,onOpenChange:f,children:(0,Y.jsxs)(pe,{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,Y.jsx)(me,{className:`sr-only`,children:r}),(0,Y.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,Y.jsx)(`img`,{src:i,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,Y.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,Y.jsx)(`button`,{type:`button`,onClick:m,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,Y.jsx)(b,{className:`w-4 h-4`})}),(0,Y.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,Y.jsx)(g,{className:`w-4 h-4`})})]})]})]})})]}):(0,Y.jsxs)(`button`,{type:`button`,onClick:m,disabled:!i,className:s(`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:[l?(0,Y.jsx)(T,{className:`h-4 w-4 shrink-0 animate-spin`}):o?(0,Y.jsx)(_,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,Y.jsx)(p,{className:`h-4 w-4 shrink-0`}),(0,Y.jsx)(`span`,{className:s(`min-w-0 flex-1 truncate`,o&&`text-red-400`),children:o||r}),(0,Y.jsx)(b,{className:`h-3.5 w-3.5 shrink-0`})]})}function Et({open:e,onToggle:t,onReact:n}){return(0,Y.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,Y.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:s(`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,Y.jsx)(u,{className:`h-3 w-3`})}),e&&(0,Y.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:Be.map(e=>(0,Y.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,i]=(0,W.useState)(!1),o=N(e=>e.agentsById),c=N(e=>e.openAgentDetail),l=e.from===t,u=(l?e.to:e.from)||``,f=o[l?t:u]?.issueRepo??o[t]?.issueRepo,p=!u||u===`broadcast`||u.includes(`:`),m=z(e),h=J(e.occurredAt??e.createdAt),g=l?r:a,_=o[e.from??``]??null;function v(e){e.stopPropagation(),_&&c(_)}return(0,Y.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,Y.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>i(e=>!e),children:[(0,Y.jsx)(d,{className:s(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,n&&`rotate-90`)}),(0,Y.jsx)(`button`,{type:`button`,title:_?_.label||_.name||_.id:void 0,disabled:!_,onClick:v,className:s(`shrink-0 transition-opacity`,_?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,Y.jsx)(H,{agent:_,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,Y.jsx)(g,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,Y.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,l?`to`:`from`]}),p?(0,Y.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:de(u,o)}):(0,Y.jsx)(X,{agentId:u,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!n&&(0,Y.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:m}),(0,Y.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:h})]}),n&&(0,Y.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,Y.jsx)(U,{text:m,rawBody:e.body,issueRepo:f,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var Ot=(0,W.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:i,onPreviewReferencedPathEnd:a}){if(!F(e.from)&&!F(e.to))return(0,Y.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,Y.jsx)(St,{msg:e,peer:t});let c=F(e.from),l=N(e=>e.reactToMessage),u=N(e=>e.voiceTtsEnabled),d=xt(),f=N(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),p=N(e=>e.agentsById[t]?.issueRepo),m=N(e=>e.usersById),h=N(e=>e.users.length>1),g=c?ce(e.from,m):void 0,_=N(e=>e.openAgentDetail);N(e=>e.openTaskDetailById);let[v,y]=(0,W.useState)(!1),b=(0,W.useRef)(null),x=(0,W.useRef)(null),S=(0,W.useRef)(!1),C=z(e),te=J(e.occurredAt??e.createdAt),ne=ze(e),w=Ve(e),T=c?He(e,t):null,E=T?.icon,D=d===String(e.id),O=u&&!c&&!q(e)&&C.trim().length>0;function k(t){t.stopPropagation(),D?P.bargeIn():P.speak(e.body,String(e.id))}(0,W.useEffect)(()=>{if(!v)return;function e(e){Re()||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 A(e){return Pe(f||`/`,e)}function j(e,t){let n=A(e);r?.(n,t)}function ie(e,t,n){let r=A(e);i?.(r,t,n)}function M(t){l(e,t),y(!1)}function I(e){e.button===0&&(x.current={x:e.clientX,y:e.clientY},S.current=!1)}function ae(e){let t=x.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(S.current=!0)}function L(t){if(!(q(e)||c)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(S.current||Re()){S.current=!1;return}y(e=>!e)}}let R=n&&!q(e);return(0,Y.jsxs)(`div`,{"data-msg-id":e.id,className:s(`group/msg flex mb-3 items-end`,c?`justify-end`:`justify-start`,R&&`gap-1.5`),children:[!c&&R&&(0,Y.jsx)(wt,{agentId:t,onOpen:_}),(0,Y.jsxs)(`div`,{ref:b,className:s(`relative`,R?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[O&&(0,Y.jsx)(`button`,{type:`button`,title:D?`Stop playback`:`Play aloud`,onClick:k,className:s(`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,Y.jsx)(re,{className:`h-3.5 w-3.5 animate-pulse`}):(0,Y.jsx)(ee,{className:`h-3.5 w-3.5`})}),(0,Y.jsxs)(`div`,{className:s(`rounded-2xl px-3.5 py-2 text-sm select-text`,!c&&!q(e)&&`cursor-pointer`,c?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:I,onPointerMove:ae,onClick:L,children:[c&&h&&(0,Y.jsx)(`p`,{className:s(`text-[11px] font-semibold mb-0.5 text-right`,le(e.from)),children:fe(e.from,m)}),e.subject&&(0,Y.jsx)(`p`,{className:s(`text-xs font-semibold mb-1`,c?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,Y.jsx)(U,{text:C,rawBody:e.body,issueRepo:p,className:`leading-relaxed`,onPrimary:c,onOpenPath:j,onPreviewPath:ie,onPreviewPathEnd:a,resolvePathTitle:(e,t)=>`${A(e)}${t?`:${t}`:``}`}),ne.map(t=>(0,Y.jsx)(Tt,{attachment:t,outbound:c},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,Y.jsxs)(`p`,{className:s(`text-xs mt-1 flex items-center gap-1.5`,c?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,Y.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,Y.jsx)(`span`,{children:te}),T&&E&&(0,Y.jsxs)(`span`,{className:s(`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,Y.jsx)(E,{className:`h-3 w-3`}),T.label]})]})]}),!q(e)&&w.length>0&&(0,Y.jsxs)(`div`,{className:s(`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,Y.jsx)(Et,{open:v,onToggle:()=>y(e=>!e),onReact:M}),w.map(e=>(0,Y.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>M(e.emoji),className:s(`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,Y.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,Y.jsx)(`span`,{children:e.count})]},e.emoji))]}),!q(e)&&!c&&w.length===0&&(0,Y.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,Y.jsx)(Et,{open:v,onToggle:()=>y(e=>!e),onReact:M})})]}),c&&R&&(0,Y.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,Y.jsx)(ge,{user:g,address:e.from,distinct:h})})]})});export{We as C,je as E,Le as S,Ae as T,Ke as _,_t as a,Je as b,yt as c,ht as d,dt as f,Ne as g,Ge as h,ft as i,$ as l,bt as m,mt as n,gt as o,Ze as p,st as r,vt as s,Ot as t,nt as u,Ie as v,ke as w,qe as x,Fe as y};
4
- //# sourceMappingURL=MessageBubble-CxqPFLGP.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{Mt as t,Qn as n,er as r,mt as i,pr as a,tr as o,wn as s,xn as c}from"./lucide-react-De5edQpl.js";import{i as l,r as u,t as d}from"./store-Bk6Lku_S.js";import{d as f,g as p}from"./index-D4mb_LKw.js";var m=e(a(),1),h=`(max-width: 767px)`;function g(e){if(typeof window>`u`)return()=>{};let t=window.matchMedia(h);return t.addEventListener(`change`,e),()=>t.removeEventListener(`change`,e)}function _(){return(0,m.useSyncExternalStore)(g,()=>typeof window<`u`?window.matchMedia(h).matches:!1,()=>!1)}var v=r(),y=196,b=84,x=52,S=16,C=14,w=[`landed`,`in-progress`,`pending`,`blocked`],T={landed:{label:`landed`,dot:`bg-emerald-400`,accent:`border-l-emerald-400`,text:`text-emerald-300`,wire:`#34d399`},"in-progress":{label:`in progress`,dot:`bg-sky-400`,accent:`border-l-sky-400`,text:`text-sky-300`,wire:`#38bdf8`},pending:{label:`pending`,dot:`bg-amber-400`,accent:`border-l-amber-400`,text:`text-amber-300`,wire:`#fbbf24`},blocked:{label:`blocked`,dot:`bg-red-400`,accent:`border-l-red-400`,text:`text-red-300`,wire:`#f87171`}};function E(e){return e?e.label||(e.policyName?`policy:${e.policyName}`:e.agentId||``):``}function D(e){let t=new Map(e.nodes.map(e=>[e.id,e])),n=new Map(e.nodes.map((e,t)=>[e.id,t])),r=new Map,i=new Map(e.nodes.map(e=>[e.id,0]));for(let n of e.edges)!t.has(n.from)||!t.has(n.to)||(r.set(n.from,[...r.get(n.from)??[],n.to]),i.set(n.to,(i.get(n.to)??0)+1));let a=new Map(e.nodes.map(e=>[e.id,0])),o=e.nodes.filter(e=>(i.get(e.id)??0)===0).map(e=>e.id),s=new Set;for(;o.length;){let e=o.shift();s.add(e);let t=a.get(e)??0;for(let n of r.get(e)??[])a.set(n,Math.max(a.get(n)??0,t+1)),i.set(n,(i.get(n)??0)-1),(i.get(n)??0)===0&&o.push(n)}let c=Math.max(0,...Array.from(a.values()))+1;for(let t of e.nodes)s.has(t.id)||a.set(t.id,c++);let l=new Map;for(let t of e.nodes){let e=a.get(t.id)??0;l.set(e,[...l.get(e)??[],t])}let u=[...l.entries()].sort(([e],[t])=>e-t),d=Math.max(1,...u.map(([,e])=>e.length)),f=b+S,p=[];u.forEach(([e,t],r)=>{let i=[...t].sort((e,t)=>(e.lane||``).localeCompare(t.lane||``)||(n.get(e.id)??0)-(n.get(t.id)??0)),a=(d-i.length)*f/2;i.forEach((t,n)=>{p.push({node:t,layer:e,x:C+r*(y+x),y:C+a+n*f})})});let m=u.length;return{nodes:p,width:Math.max(320,C*2+m*y+Math.max(0,m-1)*x),height:Math.max(b+C*2,C*2+d*b+Math.max(0,d-1)*S)}}function O(e,t){let n=e.x+y,r=e.y+b/2,i=t.x,a=t.y+b/2,o=n+Math.max(20,(i-n)/2);return`M ${n} ${r} C ${o} ${r}, ${o} ${a}, ${i} ${a}`}function k({threadId:e,teamId:r,channel:i}){let a=r?l(r,i):e?u(e,i):``,o=d(e=>r?e.plansByTeam[a]:a?e.plansByThread[a]:null),h=d(e=>e.fetchPlan),g=d(e=>e.planCollapsed),x=d(e=>e.setPlanCollapsed),S=d(e=>e.issueRefsById),C=d(e=>e.deliverableTasks),k=d(e=>e.openTaskDetailById),A=_(),j=g??A;(0,m.useEffect)(()=>{if(r){h({teamId:r,channel:i});return}e&&h({threadId:e,channel:i})},[i,h,r,e]);let M=(0,m.useMemo)(()=>o?D(o):null,[o]),N=(0,m.useMemo)(()=>new Map(M?.nodes.map(e=>[e.node.id,e])??[]),[M]),P=(0,m.useMemo)(()=>{if(!o)return[];let e=new Map;for(let t of o.nodes)e.set(t.status,(e.get(t.status)??0)+1);return w.filter(t=>e.has(t)).map(t=>({status:t,count:e.get(t)??0}))},[o]);if(!o||!M)return null;let F=o.nodes.length,I=P.find(e=>e.status===`landed`)?.count??0,L=`${F} node${F===1?``:`s`}${I>0?` · ${I} landed`:``}`;return(0,v.jsxs)(`section`,{className:`shrink-0 border-b border-border bg-card/45 px-3 py-2`,children:[(0,v.jsxs)(`button`,{type:`button`,onClick:()=>x(!j),"aria-expanded":!j,"aria-label":j?`Expand plan graph`:`Collapse plan graph`,className:n(`flex w-full min-w-0 items-center gap-2 text-left`,!j&&`mb-2`),children:[(0,v.jsx)(`span`,{className:`flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted/60`,children:(0,v.jsx)(t,{className:`h-3 w-3 text-muted-foreground`})}),(0,v.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,v.jsx)(`div`,{className:`truncate text-[13px] font-semibold leading-tight text-foreground`,children:o.title||`Plan`}),(0,v.jsx)(`div`,{className:`truncate text-[11px] leading-tight text-muted-foreground`,children:j?L:o.objective||L})]}),P.length>0&&(0,v.jsx)(`div`,{className:`hidden shrink-0 items-center gap-2.5 sm:flex`,children:P.map(({status:e,count:t})=>(0,v.jsxs)(`span`,{className:`flex items-center gap-1 text-[10px] text-muted-foreground`,children:[(0,v.jsx)(`span`,{className:n(`h-1.5 w-1.5 rounded-full`,T[e].dot)}),(0,v.jsx)(`span`,{className:n(`font-medium tabular-nums`,T[e].text),children:t}),(0,v.jsx)(`span`,{children:T[e].label})]},e))}),(0,v.jsxs)(`span`,{className:`shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium tabular-nums text-muted-foreground`,children:[`v`,o.version]}),(0,v.jsx)(`span`,{className:`flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted/60 hover:text-foreground`,children:j?(0,v.jsx)(s,{className:`h-3.5 w-3.5`}):(0,v.jsx)(c,{className:`h-3.5 w-3.5`})})]}),j?null:o.nodes.length===0?(0,v.jsx)(`div`,{className:`rounded-md border border-dashed border-border px-3 py-3 text-center text-xs text-muted-foreground`,children:`No nodes yet — the plan graph fills in as the team is composed.`}):(0,v.jsx)(`div`,{className:`max-h-[min(46vh,360px)] overflow-auto`,children:(0,v.jsxs)(`div`,{className:`relative`,style:{width:M.width,height:M.height},children:[(0,v.jsxs)(`svg`,{className:`pointer-events-none absolute inset-0`,width:M.width,height:M.height,"aria-hidden":`true`,children:[(0,v.jsx)(`defs`,{children:w.map(e=>(0,v.jsx)(`marker`,{id:`plan-arrow-${e}`,viewBox:`0 0 8 8`,refX:`6.5`,refY:`4`,markerWidth:`6`,markerHeight:`6`,orient:`auto-start-reverse`,children:(0,v.jsx)(`path`,{d:`M0 0 L8 4 L0 8 z`,fill:T[e].wire})},e))}),o.edges.map(e=>{let t=N.get(e.from),n=N.get(e.to);if(!t||!n)return null;let r=T[t.node.status];return(0,v.jsx)(`path`,{d:O(t,n),stroke:r.wire,strokeOpacity:.7,strokeWidth:2,fill:`none`,strokeLinecap:`round`,markerEnd:`url(#plan-arrow-${t.node.status})`},`${e.from}->${e.to}`)})]}),M.nodes.map(({node:e,x:t,y:r})=>{let i=T[e.status],a=E(e.ownerRef),o=e.refs?.issueId?S[e.refs.issueId]:null,s=e.refs?.taskId?parseInt(e.refs.taskId,10):null,c=s==null?void 0:C.find(e=>e.id===s)?.title;return(0,v.jsxs)(`article`,{className:n(`group absolute flex flex-col justify-between rounded-md border border-l-[3px] bg-background/95 p-2`,`shadow-sm transition-all hover:-translate-y-px hover:border-border hover:shadow-md hover:bg-background`,i.accent),style:{left:t,top:r,width:y,height:b},title:e.scopeBlurb||e.label,children:[(0,v.jsx)(`div`,{className:`truncate text-xs font-semibold leading-tight text-foreground`,children:e.label}),(e.scopeBlurb||e.id)&&(0,v.jsx)(`div`,{className:`truncate text-[10px] leading-tight text-muted-foreground`,children:e.scopeBlurb||e.id}),(o||s!=null)&&(0,v.jsxs)(`div`,{className:`flex min-w-0 flex-wrap gap-1`,children:[o&&(0,v.jsx)(p,{issueRef:o,compact:!0,className:`max-w-full`}),s!=null&&(0,v.jsx)(f,{id:s,title:c,onClick:()=>k(s),className:`max-w-full`})]}),(0,v.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-1.5`,children:[(0,v.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5`,children:[(0,v.jsx)(`span`,{className:n(`h-1.5 w-1.5 shrink-0 rounded-full`,i.dot)}),(0,v.jsx)(`span`,{className:n(`text-[10px] font-medium`,i.text),children:i.label})]}),(0,v.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[a&&(0,v.jsx)(`span`,{className:`truncate text-[10px] text-muted-foreground`,children:a}),e.lane&&(0,v.jsx)(`span`,{className:`shrink-0 rounded-sm bg-muted/70 px-1 py-px text-[9px] font-medium uppercase tracking-wide text-muted-foreground`,children:e.lane})]})]})]},e.id)})]})})]})}function A({agentId:e}){let t=d(e=>e.openTaskDetailById),r=d(e=>e.sessionTasksCollapsed),a=d(e=>e.setSessionTasksCollapsed),[l,u]=(0,m.useState)([]);return(0,m.useEffect)(()=>{o(`GET`,`/task-entities?createdBy=`+encodeURIComponent(e)).then(e=>u(e)).catch(()=>{})},[e]),l.length===0?null:(0,v.jsxs)(`section`,{className:`shrink-0 border-b border-border bg-card/45 px-3 py-2`,children:[(0,v.jsxs)(`button`,{type:`button`,onClick:()=>a(!r),"aria-expanded":!r,"aria-label":r?`Expand session tasks`:`Collapse session tasks`,className:n(`flex w-full min-w-0 items-center gap-2 text-left`,!r&&`mb-1.5`),children:[(0,v.jsx)(`span`,{className:`flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted/60`,children:(0,v.jsx)(i,{className:`h-3 w-3 text-muted-foreground`})}),(0,v.jsxs)(`span`,{className:`flex-1 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground`,children:[`Tasks from this session (`,l.length,`)`]}),(0,v.jsx)(`span`,{className:`flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted/60 hover:text-foreground`,children:r?(0,v.jsx)(s,{className:`h-3.5 w-3.5`}):(0,v.jsx)(c,{className:`h-3.5 w-3.5`})})]}),!r&&(0,v.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:l.map(e=>(0,v.jsx)(f,{id:e.id,title:e.title,status:e.status,onClick:()=>t(e.id),compact:!0},e.id))})]})}export{A as n,k as t};
2
- //# sourceMappingURL=PlanGraphPanel-gQ_lb6zP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlanGraphPanel-gQ_lb6zP.js","names":[],"sources":["../../dashboard/src/components/chat/hooks/useIsMobile.ts","../../dashboard/src/components/chat/PlanGraphPanel.tsx"],"sourcesContent":["import { useSyncExternalStore } from 'react'\n\n// Reactive narrow-viewport flag. Subscribes to the same `max-width: 767px`\n// breakpoint the chat single-pane layout uses, via useSyncExternalStore — an\n// external-store subscription, not effect-driven derived state — so it stays\n// correct across resize/rotate without a useEffect.\nconst QUERY = '(max-width: 767px)'\n\nfunction subscribe(cb: () => void): () => void {\n if (typeof window === 'undefined') return () => {}\n const mql = window.matchMedia(QUERY)\n mql.addEventListener('change', cb)\n return () => mql.removeEventListener('change', cb)\n}\n\nexport function useIsMobile(): boolean {\n return useSyncExternalStore(\n subscribe,\n () => (typeof window !== 'undefined' ? window.matchMedia(QUERY).matches : false),\n () => false,\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { ChevronDown, ChevronUp, GitBranch, ListTodo } from 'lucide-react'\nimport { useRelayStore } from '@/store'\nimport type { Plan, PlanNode, PlanOwnerRef, PlanStatus, Task } from '@/types'\nimport { cn } from '@/lib/utils'\nimport { planLookupKey, planTeamLookupKey } from '@/store/slices/plans'\nimport { IssueRefChip } from '@/components/shared/issue-ref-chip'\nimport { TaskChip } from '@/components/shared/task-chip'\nimport { useIsMobile } from './hooks/useIsMobile'\nimport { api } from '@/lib/api'\n\n// Left-to-right DAG: dependency depth flows along x (sequential gates), nodes\n// that share a depth stack along y (parallel lanes). This keeps the panel SHORT\n// — it's an operator overlay above the chat, not a full view — and lets the\n// gate-vs-lane structure read at a glance. Height is capped + scrollable below.\nconst NODE_W = 196\nconst NODE_H = 84\nconst COL_GAP = 52\nconst ROW_GAP = 16\nconst PAD = 14\n\nconst STATUS_ORDER: PlanStatus[] = ['landed', 'in-progress', 'pending', 'blocked']\n\nconst STATUS_STYLE: Record<\n PlanStatus,\n { label: string; dot: string; accent: string; text: string; wire: string }\n> = {\n landed: { label: 'landed', dot: 'bg-emerald-400', accent: 'border-l-emerald-400', text: 'text-emerald-300', wire: '#34d399' },\n 'in-progress': { label: 'in progress', dot: 'bg-sky-400', accent: 'border-l-sky-400', text: 'text-sky-300', wire: '#38bdf8' },\n pending: { label: 'pending', dot: 'bg-amber-400', accent: 'border-l-amber-400', text: 'text-amber-300', wire: '#fbbf24' },\n blocked: { label: 'blocked', dot: 'bg-red-400', accent: 'border-l-red-400', text: 'text-red-300', wire: '#f87171' },\n}\n\ninterface LayoutNode {\n node: PlanNode\n x: number\n y: number\n layer: number\n}\n\nfunction ownerLabel(owner?: PlanOwnerRef): string {\n if (!owner) return ''\n return owner.label || (owner.policyName ? `policy:${owner.policyName}` : owner.agentId || '')\n}\n\nfunction layerPlan(plan: Plan): { nodes: LayoutNode[]; width: number; height: number } {\n const nodeById = new Map(plan.nodes.map((node) => [node.id, node]))\n const indexById = new Map(plan.nodes.map((node, index) => [node.id, index]))\n const outgoing = new Map<string, string[]>()\n const indegree = new Map(plan.nodes.map((node) => [node.id, 0]))\n for (const edge of plan.edges) {\n if (!nodeById.has(edge.from) || !nodeById.has(edge.to)) continue\n outgoing.set(edge.from, [...(outgoing.get(edge.from) ?? []), edge.to])\n indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1)\n }\n\n const layerById = new Map(plan.nodes.map((node) => [node.id, 0]))\n const queue = plan.nodes\n .filter((node) => (indegree.get(node.id) ?? 0) === 0)\n .map((node) => node.id)\n const visited = new Set<string>()\n\n while (queue.length) {\n const id = queue.shift()!\n visited.add(id)\n const fromLayer = layerById.get(id) ?? 0\n for (const to of outgoing.get(id) ?? []) {\n layerById.set(to, Math.max(layerById.get(to) ?? 0, fromLayer + 1))\n indegree.set(to, (indegree.get(to) ?? 0) - 1)\n if ((indegree.get(to) ?? 0) === 0) queue.push(to)\n }\n }\n\n let fallbackLayer = Math.max(0, ...Array.from(layerById.values())) + 1\n for (const node of plan.nodes) {\n if (visited.has(node.id)) continue\n layerById.set(node.id, fallbackLayer++)\n }\n\n const layers = new Map<number, PlanNode[]>()\n for (const node of plan.nodes) {\n const layer = layerById.get(node.id) ?? 0\n layers.set(layer, [...(layers.get(layer) ?? []), node])\n }\n\n const orderedLayers = [...layers.entries()].sort(([a], [b]) => a - b)\n const maxRows = Math.max(1, ...orderedLayers.map(([, nodes]) => nodes.length))\n const rowPitch = NODE_H + ROW_GAP\n\n const layoutNodes: LayoutNode[] = []\n orderedLayers.forEach(([layer, nodes], col) => {\n const ordered = [...nodes].sort((a, b) => {\n const lane = (a.lane || '').localeCompare(b.lane || '')\n return lane || ((indexById.get(a.id) ?? 0) - (indexById.get(b.id) ?? 0))\n })\n // Center each column vertically against the tallest column so the spine\n // runs through the middle and the parallel fan reads as a fan.\n const offset = ((maxRows - ordered.length) * rowPitch) / 2\n ordered.forEach((node, row) => {\n layoutNodes.push({\n node,\n layer,\n x: PAD + col * (NODE_W + COL_GAP),\n y: PAD + offset + row * rowPitch,\n })\n })\n })\n\n const cols = orderedLayers.length\n return {\n nodes: layoutNodes,\n width: Math.max(320, PAD * 2 + cols * NODE_W + Math.max(0, cols - 1) * COL_GAP),\n height: Math.max(NODE_H + PAD * 2, PAD * 2 + maxRows * NODE_H + Math.max(0, maxRows - 1) * ROW_GAP),\n }\n}\n\nfunction edgePath(from: LayoutNode, to: LayoutNode): string {\n const x1 = from.x + NODE_W\n const y1 = from.y + NODE_H / 2\n const x2 = to.x\n const y2 = to.y + NODE_H / 2\n const midX = x1 + Math.max(20, (x2 - x1) / 2)\n return `M ${x1} ${y1} C ${midX} ${y1}, ${midX} ${y2}, ${x2} ${y2}`\n}\n\nexport function PlanGraphPanel({ threadId, teamId, channel }: { threadId?: string | number | null; teamId?: string | null; channel?: string }) {\n const key = teamId ? planTeamLookupKey(teamId, channel) : threadId ? planLookupKey(threadId, channel) : ''\n const plan = useRelayStore((s) => teamId ? s.plansByTeam[key] : key ? s.plansByThread[key] : null)\n const fetchPlan = useRelayStore((s) => s.fetchPlan)\n const planCollapsed = useRelayStore((s) => s.planCollapsed)\n const setPlanCollapsed = useRelayStore((s) => s.setPlanCollapsed)\n const issueRefsById = useRelayStore((s) => s.issueRefsById)\n const deliverableTasks = useRelayStore((s) => s.deliverableTasks)\n const openTaskDetailById = useRelayStore((s) => s.openTaskDetailById)\n const isMobile = useIsMobile()\n // null = no manual toggle yet → follow the viewport default. The graph\n // dominates a phone screen, so it starts collapsed there and expanded on\n // desktop; an explicit user toggle (persisted) overrides the default.\n const collapsed = planCollapsed ?? isMobile\n\n useEffect(() => {\n if (teamId) {\n void fetchPlan({ teamId, channel })\n return\n }\n if (threadId) void fetchPlan({ threadId, channel })\n }, [channel, fetchPlan, teamId, threadId])\n\n const layout = useMemo(() => plan ? layerPlan(plan) : null, [plan])\n const nodeById = useMemo(() => new Map(layout?.nodes.map((node) => [node.node.id, node]) ?? []), [layout])\n\n const legend = useMemo(() => {\n if (!plan) return []\n const counts = new Map<PlanStatus, number>()\n for (const node of plan.nodes) counts.set(node.status, (counts.get(node.status) ?? 0) + 1)\n return STATUS_ORDER.filter((status) => counts.has(status)).map((status) => ({\n status,\n count: counts.get(status) ?? 0,\n }))\n }, [plan])\n\n if (!plan || !layout) return null\n\n const nodeCount = plan.nodes.length\n const landedCount = legend.find((entry) => entry.status === 'landed')?.count ?? 0\n // Thin summary for the collapsed bar (the legend dots are hidden on mobile),\n // e.g. \"5 nodes · 4 landed\".\n const summary = `${nodeCount} node${nodeCount === 1 ? '' : 's'}${landedCount > 0 ? ` · ${landedCount} landed` : ''}`\n\n return (\n <section className=\"shrink-0 border-b border-border bg-card/45 px-3 py-2\">\n <button\n type=\"button\"\n onClick={() => setPlanCollapsed(!collapsed)}\n aria-expanded={!collapsed}\n aria-label={collapsed ? 'Expand plan graph' : 'Collapse plan graph'}\n className={cn(\n 'flex w-full min-w-0 items-center gap-2 text-left',\n !collapsed && 'mb-2',\n )}\n >\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted/60\">\n <GitBranch className=\"h-3 w-3 text-muted-foreground\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-[13px] font-semibold leading-tight text-foreground\">{plan.title || 'Plan'}</div>\n <div className=\"truncate text-[11px] leading-tight text-muted-foreground\">\n {collapsed ? summary : (plan.objective || summary)}\n </div>\n </div>\n {legend.length > 0 && (\n <div className=\"hidden shrink-0 items-center gap-2.5 sm:flex\">\n {legend.map(({ status, count }) => (\n <span key={status} className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\n <span className={cn('h-1.5 w-1.5 rounded-full', STATUS_STYLE[status].dot)} />\n <span className={cn('font-medium tabular-nums', STATUS_STYLE[status].text)}>{count}</span>\n <span>{STATUS_STYLE[status].label}</span>\n </span>\n ))}\n </div>\n )}\n <span className=\"shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium tabular-nums text-muted-foreground\">\n v{plan.version}\n </span>\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted/60 hover:text-foreground\">\n {collapsed ? <ChevronDown className=\"h-3.5 w-3.5\" /> : <ChevronUp className=\"h-3.5 w-3.5\" />}\n </span>\n </button>\n {collapsed ? null : plan.nodes.length === 0 ? (\n <div className=\"rounded-md border border-dashed border-border px-3 py-3 text-center text-xs text-muted-foreground\">\n No nodes yet — the plan graph fills in as the team is composed.\n </div>\n ) : (\n <div className=\"max-h-[min(46vh,360px)] overflow-auto\">\n <div className=\"relative\" style={{ width: layout.width, height: layout.height }}>\n <svg className=\"pointer-events-none absolute inset-0\" width={layout.width} height={layout.height} aria-hidden=\"true\">\n <defs>\n {STATUS_ORDER.map((status) => (\n <marker\n key={status}\n id={`plan-arrow-${status}`}\n viewBox=\"0 0 8 8\"\n refX=\"6.5\"\n refY=\"4\"\n markerWidth=\"6\"\n markerHeight=\"6\"\n orient=\"auto-start-reverse\"\n >\n <path d=\"M0 0 L8 4 L0 8 z\" fill={STATUS_STYLE[status].wire} />\n </marker>\n ))}\n </defs>\n {plan.edges.map((edge) => {\n const from = nodeById.get(edge.from)\n const to = nodeById.get(edge.to)\n if (!from || !to) return null\n const wire = STATUS_STYLE[from.node.status]\n return (\n <path\n key={`${edge.from}->${edge.to}`}\n d={edgePath(from, to)}\n stroke={wire.wire}\n strokeOpacity={0.7}\n strokeWidth={2}\n fill=\"none\"\n strokeLinecap=\"round\"\n markerEnd={`url(#plan-arrow-${from.node.status})`}\n />\n )\n })}\n </svg>\n {layout.nodes.map(({ node, x, y }) => {\n const status = STATUS_STYLE[node.status]\n const owner = ownerLabel(node.ownerRef)\n const issueRef = node.refs?.issueId ? issueRefsById[node.refs.issueId] : null\n const taskNumId = node.refs?.taskId ? parseInt(node.refs.taskId, 10) : null\n const taskTitle = taskNumId != null ? deliverableTasks.find((t) => t.id === taskNumId)?.title : undefined\n return (\n <article\n key={node.id}\n className={cn(\n 'group absolute flex flex-col justify-between rounded-md border border-l-[3px] bg-background/95 p-2',\n 'shadow-sm transition-all hover:-translate-y-px hover:border-border hover:shadow-md hover:bg-background',\n status.accent,\n )}\n style={{ left: x, top: y, width: NODE_W, height: NODE_H }}\n title={node.scopeBlurb || node.label}\n >\n <div className=\"truncate text-xs font-semibold leading-tight text-foreground\">{node.label}</div>\n {(node.scopeBlurb || node.id) && (\n <div className=\"truncate text-[10px] leading-tight text-muted-foreground\">{node.scopeBlurb || node.id}</div>\n )}\n {(issueRef || taskNumId != null) && (\n <div className=\"flex min-w-0 flex-wrap gap-1\">\n {issueRef && <IssueRefChip issueRef={issueRef} compact className=\"max-w-full\" />}\n {taskNumId != null && (\n <TaskChip id={taskNumId} title={taskTitle} onClick={() => openTaskDetailById(taskNumId)} className=\"max-w-full\" />\n )}\n </div>\n )}\n <div className=\"flex min-w-0 items-center justify-between gap-1.5\">\n <div className=\"flex shrink-0 items-center gap-1.5\">\n <span className={cn('h-1.5 w-1.5 shrink-0 rounded-full', status.dot)} />\n <span className={cn('text-[10px] font-medium', status.text)}>{status.label}</span>\n </div>\n <div className=\"flex min-w-0 items-center gap-1.5\">\n {owner && <span className=\"truncate text-[10px] text-muted-foreground\">{owner}</span>}\n {node.lane && (\n <span className=\"shrink-0 rounded-sm bg-muted/70 px-1 py-px text-[9px] font-medium uppercase tracking-wide text-muted-foreground\">\n {node.lane}\n </span>\n )}\n </div>\n </div>\n </article>\n )\n })}\n </div>\n </div>\n )}\n </section>\n )\n}\n\n// Tasks created/triggered from a session (#856, #860). Fetches server-side via createdBy filter.\nexport function SessionTasksPanel({ agentId }: { agentId: string }) {\n const openTaskDetailById = useRelayStore((s) => s.openTaskDetailById)\n const sessionTasksCollapsed = useRelayStore((s) => s.sessionTasksCollapsed)\n const setSessionTasksCollapsed = useRelayStore((s) => s.setSessionTasksCollapsed)\n const [sessionTasks, setSessionTasks] = useState<Task[]>([])\n useEffect(() => {\n void api<import('@/types').Task[]>('GET', '/task-entities?createdBy=' + encodeURIComponent(agentId))\n .then((tasks) => setSessionTasks(tasks))\n .catch(() => {})\n }, [agentId])\n if (sessionTasks.length === 0) return null\n return (\n <section className=\"shrink-0 border-b border-border bg-card/45 px-3 py-2\">\n <button\n type=\"button\"\n onClick={() => setSessionTasksCollapsed(!sessionTasksCollapsed)}\n aria-expanded={!sessionTasksCollapsed}\n aria-label={sessionTasksCollapsed ? 'Expand session tasks' : 'Collapse session tasks'}\n className={cn('flex w-full min-w-0 items-center gap-2 text-left', !sessionTasksCollapsed && 'mb-1.5')}\n >\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted/60\">\n <ListTodo className=\"h-3 w-3 text-muted-foreground\" />\n </span>\n <span className=\"flex-1 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground\">\n Tasks from this session ({sessionTasks.length})\n </span>\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted/60 hover:text-foreground\">\n {sessionTasksCollapsed ? <ChevronDown className=\"h-3.5 w-3.5\" /> : <ChevronUp className=\"h-3.5 w-3.5\" />}\n </span>\n </button>\n {!sessionTasksCollapsed && (\n <div className=\"flex flex-wrap gap-1\">\n {sessionTasks.map((task) => (\n <TaskChip\n key={task.id}\n id={task.id}\n title={task.title}\n status={task.status}\n onClick={() => openTaskDetailById(task.id)}\n compact\n />\n ))}\n </div>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{$ as t,K as n,Qn as r,V as i,Vt as a,Wn as o,Yn as s,Zt as c,_ as l,a as u,er as d,g as f,gt as p,nt as m,pr as h,u as g,z as _}from"./lucide-react-De5edQpl.js";import{f as ee,t as v}from"./store-Bk6Lku_S.js";import{h as te,p as y}from"./types-DSwhOFcJ.js";import{J as b,K as x,W as S,Y as C,a as w,d as T,i as ne,n as re}from"./display-_5kFrHJh.js";import{o as E,r as ie}from"./dist-DBti5--U.js";import{t as D}from"./dist-AbnkNPcD.js";import{i as O,n as k}from"./dist-REUlCFee.js";import{t as A}from"./dist-BJnh7VkB.js";import{t as j}from"./dist-DLOrqIs-.js";import{a as M,i as N,n as P,o as F,r as I,s as ae,t as oe}from"./es2015-GhJvD7eR.js";import{a as L,i as se,n as R,r as z,t as B}from"./dist-1g1lCjVb.js";import{t as V}from"./badge-oaCc6hVH.js";import{t as H}from"./button-Cx0NiToX.js";import{t as ce}from"./copy-button-CsCBPQzj.js";import{C as le,J as U,O as W,S as ue,V as de,X as fe,Y as pe,_ as me,b as he,h as ge,k as G,m as _e,p as ve,q as ye,x as be}from"./index-D4mb_LKw.js";import{r as xe,t as Se}from"./card-DkHdS68K.js";import{i as Ce,n as we,r as Te,t as Ee}from"./branch-state-badge-JDaHO2fG.js";var K=e(h(),1),q=d(),J=`Popover`,[De,Oe]=O(J,[L]),Y=L(),[ke,X]=De(J),Ae=e=>{let{__scopePopover:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!1}=e,s=Y(t),c=K.useRef(null),[l,u]=K.useState(!1),[d,f]=A({prop:r,defaultProp:i??!1,onChange:a,caller:J});return(0,q.jsx)(se,{...s,children:(0,q.jsx)(ke,{scope:t,contentId:ae(),triggerRef:c,open:d,onOpenChange:f,onOpenToggle:K.useCallback(()=>f(e=>!e),[f]),hasCustomAnchor:l,onCustomAnchorAdd:K.useCallback(()=>u(!0),[]),onCustomAnchorRemove:K.useCallback(()=>u(!1),[]),modal:o,children:n})})};Ae.displayName=J;var je=`PopoverAnchor`,Me=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(je,n),a=Y(n),{onCustomAnchorAdd:o,onCustomAnchorRemove:s}=i;return K.useEffect(()=>(o(),()=>s()),[o,s]),(0,q.jsx)(B,{...a,...r,ref:t})});Me.displayName=je;var Z=`PopoverTrigger`,Ne=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(Z,n),a=Y(n),o=E(t,i.triggerRef),s=(0,q.jsx)(D.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.contentId,"data-state":Ke(i.open),...r,ref:o,onClick:k(e.onClick,i.onOpenToggle)});return i.hasCustomAnchor?s:(0,q.jsx)(B,{asChild:!0,...a,children:s})});Ne.displayName=Z;var Q=`PopoverPortal`,[Pe,Fe]=De(Q,{forceMount:void 0}),Ie=e=>{let{__scopePopover:t,forceMount:n,children:r,container:i}=e,a=X(Q,t);return(0,q.jsx)(Pe,{scope:t,forceMount:n,children:(0,q.jsx)(j,{present:n||a.open,children:(0,q.jsx)(N,{asChild:!0,container:i,children:r})})})};Ie.displayName=Q;var $=`PopoverContent`,Le=K.forwardRef((e,t)=>{let n=Fe($,e.__scopePopover),{forceMount:r=n.forceMount,...i}=e,a=X($,e.__scopePopover);return(0,q.jsx)(j,{present:r||a.open,children:a.modal?(0,q.jsx)(ze,{...i,ref:t}):(0,q.jsx)(Be,{...i,ref:t})})});Le.displayName=$;var Re=ie(`PopoverContent.RemoveScroll`),ze=K.forwardRef((e,t)=>{let n=X($,e.__scopePopover),r=K.useRef(null),i=E(t,r),a=K.useRef(!1);return K.useEffect(()=>{let e=r.current;if(e)return oe(e)},[]),(0,q.jsx)(P,{as:Re,allowPinchZoom:!0,children:(0,q.jsx)(Ve,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(e.onCloseAutoFocus,e=>{e.preventDefault(),a.current||n.triggerRef.current?.focus()}),onPointerDownOutside:k(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;a.current=t.button===2||n},{checkForDefaultPrevented:!1}),onFocusOutside:k(e.onFocusOutside,e=>e.preventDefault(),{checkForDefaultPrevented:!1})})})}),Be=K.forwardRef((e,t)=>{let n=X($,e.__scopePopover),r=K.useRef(!1),i=K.useRef(!1);return(0,q.jsx)(Ve,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),Ve=K.forwardRef((e,t)=>{let{__scopePopover:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,disableOutsidePointerEvents:o,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onInteractOutside:u,...d}=e,f=X($,n),p=Y(n);return I(),(0,q.jsx)(M,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,q.jsx)(F,{asChild:!0,disableOutsidePointerEvents:o,onInteractOutside:u,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onDismiss:()=>f.onOpenChange(!1),children:(0,q.jsx)(z,{"data-state":Ke(f.open),role:`dialog`,id:f.contentId,...p,...d,ref:t,style:{...d.style,"--radix-popover-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-popover-content-available-width":`var(--radix-popper-available-width)`,"--radix-popover-content-available-height":`var(--radix-popper-available-height)`,"--radix-popover-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-popover-trigger-height":`var(--radix-popper-anchor-height)`}})})})}),He=`PopoverClose`,Ue=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(He,n);return(0,q.jsx)(D.button,{type:`button`,...r,ref:t,onClick:k(e.onClick,()=>i.onOpenChange(!1))})});Ue.displayName=He;var We=`PopoverArrow`,Ge=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=Y(n);return(0,q.jsx)(R,{...i,...r,ref:t})});Ge.displayName=We;function Ke(e){return e?`open`:`closed`}var qe=Ae,Je=Ne,Ye=Ie,Xe=Le;function Ze({...e}){return(0,q.jsx)(qe,{"data-slot":`popover`,...e})}function Qe({...e}){return(0,q.jsx)(Je,{"data-slot":`popover-trigger`,...e})}function $e({className:e,align:t=`center`,sideOffset:n=4,...i}){return(0,q.jsx)(Ye,{children:(0,q.jsx)(Xe,{"data-slot":`popover-content`,align:t,sideOffset:n,className:r(`z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,e),...i})})}function et({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-header`,className:r(`flex flex-col gap-0.5 text-sm`,e),...t})}function tt({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-title`,className:r(`font-medium`,e),...t})}function nt({agent:e,childAgents:r=[],parentAgent:i}){let o=ee();v(e=>e.set);let s=v(e=>e.switchView),u=v(e=>e.openInboxThread),d=v(e=>e.openAgentDetail),h=v(e=>e.openPairInvite),te=v(e=>e.openRename),y=v(e=>e.openConfirm),E=v(e=>e.doAgentAction),ie=v(e=>e.doDeleteAgent),D=v(e=>e.openFilesForAgent),O=v(e=>e.workspaceAction),k=v(e=>e.openWorkspaceFocus),{terminalOpen:A,terminalTarget:j,terminalOpening:M,openTerminal:N,closeTerminal:P}=Ce(e.id),F=ye(),I=ne(o,e,de(e),F[e.id]||null),ae=w(e,`shutdown`),oe=w(e,`compact`),L=w(e,`clearContext`),se=!!(e.providerCapabilities?.terminal?.live?.read||e.providerCapabilities?.terminal?.attach?.create),R=!!e.providerCapabilities?.terminal?.live?.write,z=re(e),B=i?T(i):e.spawnedBy,U=r.length>0;return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(Se,{className:`group hover:border-zinc-600 transition-colors cursor-pointer`,onClick:()=>d(e),children:(0,q.jsxs)(xe,{className:`p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2.5 mb-2.5`,children:[(0,q.jsx)(G,{agent:e,now:o,className:`mt-0.5`}),(0,q.jsx)(W,{agent:e}),(0,q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0`,children:[(0,q.jsx)(we,{profile:Te(e),className:`text-sm shrink-0`}),(0,q.jsx)(`span`,{className:`text-sm font-medium truncate`,children:T(e)})]}),(0,q.jsx)(`div`,{className:`text-xs mt-0.5 ${b(I.tone)}`,children:I.label}),typeof e.meta?.cwd==`string`&&e.meta.cwd&&(0,q.jsx)(`button`,{type:`button`,className:`mt-0.5 block max-w-full truncate font-mono text-[10px] text-muted-foreground hover:text-foreground`,title:`Open ${e.meta.cwd} in Files`,onClick:t=>{t.stopPropagation(),D(e)},children:S(e.meta.cwd)}),(0,q.jsx)(me,{agent:e,className:`mt-1`})]}),e.branchState&&e.branchWorkspaceId&&(0,q.jsx)(Ee,{state:e.branchState,className:`mt-0.5 shrink-0`,onClick:t=>{t.stopPropagation(),k(e.branchWorkspaceId)}})]}),I.badges.length>0&&(0,q.jsx)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:I.badges.map(e=>(0,q.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded-full font-medium ${e.className}`,children:e.label},e.label))}),(U||e.spawnedBy&&B)&&(0,q.jsxs)(`div`,{className:`mb-2 flex flex-wrap gap-1.5`,onClick:e=>e.stopPropagation(),children:[U&&(0,q.jsxs)(Ze,{children:[(0,q.jsx)(Qe,{asChild:!0,children:(0,q.jsxs)(`button`,{type:`button`,className:`inline-flex h-6 max-w-full items-center gap-1.5 rounded-full border border-sky-500/30 bg-sky-500/10 px-2 text-[10px] font-medium text-sky-300 transition-colors hover:bg-sky-500/15`,title:`${r.length} live child ${r.length===1?`agent`:`agents`}`,children:[(0,q.jsx)(g,{className:`h-3 w-3`}),(0,q.jsx)(`span`,{children:r.length}),(0,q.jsx)(`span`,{className:`flex -space-x-1`,children:r.slice(0,4).map(e=>(0,q.jsx)(G,{agent:e,now:o,className:`h-2 w-2 ring-1 ring-background`},e.id))})]})}),(0,q.jsxs)($e,{align:`start`,className:`w-80`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(et,{children:(0,q.jsx)(tt,{children:`Team`})}),(0,q.jsx)(`div`,{className:`space-y-1.5`,children:r.map(e=>(0,q.jsxs)(`div`,{className:`rounded-md border border-border bg-card/60 p-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,q.jsx)(G,{agent:e,now:o,className:`mt-1`}),(0,q.jsx)(W,{agent:e}),(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`truncate text-xs font-medium`,children:T(e)}),(0,q.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:e.providerCapabilities?.model?.alias||e.providerCapabilities?.model?.id||e.providerCapabilities?.model?.provider||e.status})]}),(0,q.jsx)(V,{variant:`outline`,className:`h-4 px-1.5 text-[9px]`,children:e.status})]}),(0,q.jsxs)(`div`,{className:`mt-2 flex gap-1`,children:[(0,q.jsx)(H,{size:`xs`,variant:`outline`,onClick:()=>d(e),children:`Open`}),(0,q.jsxs)(H,{size:`xs`,variant:`ghost`,onClick:()=>{u(e.id),s(`chat`)},children:[(0,q.jsx)(m,{className:`h-3 w-3`}),`Chat`]})]})]},e.id))})]})]}),e.spawnedBy&&B&&(0,q.jsx)(V,{variant:`outline`,className:`max-w-full text-[10px] text-muted-foreground`,children:(0,q.jsxs)(`span`,{className:`truncate`,children:[`spawned by `,B]})})]}),(e.tags.length>0||C(e.capabilities).length>0)&&(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:[e.tags.slice(0,3).map(e=>(0,q.jsx)(V,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e)),C(e.capabilities).slice(0,2).map(e=>(0,q.jsx)(V,{variant:`secondary`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))]}),(0,q.jsxs)(`div`,{className:`space-y-2 mb-2`,children:[(0,q.jsx)(ue,{agent:e}),(0,q.jsx)(be,{agent:e,compact:!0}),(0,q.jsx)(le,{agent:e})]}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.id!==`user`&&e.id!==`system`&&x(o,e.lastSeen)}),(0,q.jsxs)(`div`,{className:`flex gap-1 mt-2.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(ce,{value:e.id,label:`Copy agent ID`,size:`icon`,className:`h-7 w-7`,iconClassName:`w-3 h-3`}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Chat`,onClick:()=>{u(e.id),s(`chat`)},children:(0,q.jsx)(m,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Pair`,onClick:()=>h(e.id),children:(0,q.jsx)(p,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Rename`,onClick:()=>te(e),children:(0,q.jsx)(n,{className:`w-3 h-3`})}),se&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Terminal`,disabled:M,onClick:()=>void N(),children:(0,q.jsx)(l,{className:`w-3 h-3`})}),(e.branchState===`changes`||e.branchState===`idle`)&&e.branchWorkspaceId&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-amber-400 hover:text-amber-300`,title:`Mark workspace ready — hand off to the auto-merge`,onClick:()=>y(`Mark Workspace Ready`,`Mark ${T(e)}'s branch ready to land? The relay auto-merge will rebase and land it.`,()=>O(e.branchWorkspaceId,`ready`)),children:(0,q.jsx)(a,{className:`w-3 h-3`})}),oe&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Compact`,onClick:()=>y(`Compact Agent`,`Compact context for ${T(e)}?`,()=>E(e,`compact`,`agents-grid`)),children:(0,q.jsx)(t,{className:`w-3 h-3`})}),L&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Clear Context`,onClick:()=>y(`Clear Context`,`Clear context for ${T(e)}?`,()=>E(e,`clearContext`,`agents-grid`)),children:(0,q.jsx)(c,{className:`w-3 h-3`})}),ae&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Shutdown`,onClick:()=>y(`Shutdown Agent`,`Shutdown ${T(e)}?`,()=>E(e,`shutdown`,`agents-grid`)),children:(0,q.jsx)(_,{className:`w-3 h-3`})}),z&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Forget stale agent`,onClick:()=>y(`Forget Agent`,`Forget ${T(e)}?`,()=>ie(e.id)),children:(0,q.jsx)(f,{className:`w-3 h-3`})})]})]})}),j&&(0,q.jsx)(he,{open:A,onOpenChange:P,orchestratorId:j.orchestratorId,session:j.session,interactive:j.interactive||R})]})}function rt(){let e=v(e=>e.agentPresetFilter),t=v(e=>e.agentStatusFilter),n=v(e=>e.agentTagFilter),r=v(e=>e.agentHostFilter),a=v(e=>e.agentSort),c=v(e=>e.agentSortDir),l=v(e=>e.showOffline),d=v(e=>e.set),f=v(e=>e.openAgentSpawn),p=v(e=>e.agentsById),m=ee(),h=U(),g=fe(),_=pe(),b=ve(h,m),x=ge(h,m),S=e||t||n||r;function C(){d({agentPresetFilter:``,agentStatusFilter:``,agentTagFilter:``,agentHostFilter:``})}function w(){d({agentSortDir:c===`asc`?`desc`:`asc`})}return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,q.jsxs)(`select`,{value:e,onChange:e=>d({agentPresetFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`All agents`}),(0,q.jsx)(`option`,{value:`active`,children:`Active`}),y().map(e=>(0,q.jsx)(`option`,{value:e,children:te(e)},e)),(0,q.jsx)(`option`,{value:`paired`,children:`Paired`}),(0,q.jsx)(`option`,{value:`unpaired`,children:`Unpaired`}),(0,q.jsx)(`option`,{value:`offline_stale`,children:`Offline / Stale`})]}),(0,q.jsxs)(`select`,{value:t,onChange:e=>d({agentStatusFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any status`}),(0,q.jsx)(`option`,{value:`online`,children:`Online`}),(0,q.jsx)(`option`,{value:`idle`,children:`Idle`}),(0,q.jsx)(`option`,{value:`busy`,children:`Busy`}),(0,q.jsx)(`option`,{value:`offline`,children:`Offline`}),(0,q.jsx)(`option`,{value:`starting`,children:`Starting`})]}),g.length>0&&(0,q.jsxs)(`select`,{value:n,onChange:e=>d({agentTagFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any tag`}),g.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),_.length>1&&(0,q.jsxs)(`select`,{value:r,onChange:e=>d({agentHostFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any host`}),_.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),(0,q.jsxs)(`select`,{value:a,onChange:e=>d({agentSort:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:`status`,children:`Sort: Status`}),(0,q.jsx)(`option`,{value:`name`,children:`Sort: Name`}),(0,q.jsx)(`option`,{value:`lastSeen`,children:`Sort: Last seen`}),(0,q.jsx)(`option`,{value:`created`,children:`Sort: Created`})]}),(0,q.jsx)(H,{size:`icon`,variant:`outline`,className:`h-8 w-8`,title:`Toggle sort direction`,onClick:w,children:c===`asc`?(0,q.jsx)(o,{className:`w-3.5 h-3.5`}):(0,q.jsx)(s,{className:`w-3.5 h-3.5`})}),(0,q.jsxs)(`label`,{className:`flex items-center gap-1.5 text-sm text-muted-foreground cursor-pointer select-none`,children:[(0,q.jsx)(`input`,{type:`checkbox`,checked:l,onChange:e=>d({showOffline:e.target.checked}),className:`rounded`}),`Show offline`]}),S&&(0,q.jsxs)(H,{size:`sm`,variant:`ghost`,className:`h-8 text-muted-foreground hover:text-foreground gap-1`,onClick:C,children:[(0,q.jsx)(u,{className:`w-3 h-3`}),`Clear filters`]}),(0,q.jsx)(`div`,{className:`ml-auto`,children:(0,q.jsxs)(H,{size:`sm`,onClick:f,className:`gap-1`,children:[(0,q.jsx)(i,{className:`w-3.5 h-3.5`}),`Spawn`]})})]}),x.length===0?(0,q.jsx)(`div`,{className:`text-center py-16 text-muted-foreground text-sm`,children:`No agents match the current filters.`}):(0,q.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-3`,children:x.map(e=>(0,q.jsx)(nt,{agent:e,parentAgent:e.spawnedBy?p[e.spawnedBy]??null:null,childAgents:_e(b.get(e.id)??[])},e.id))})]})}export{rt as AgentsView};
2
- //# sourceMappingURL=agents-DOwnLE42.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{Qn as t,dn as n,er as r,h as i,jt as a,o,pr as s,tr as c,yn as l}from"./lucide-react-De5edQpl.js";import{t as u}from"./store-Bk6Lku_S.js";var d=e(s(),1);function f(e){let t=u(e=>e.showError),[n,r]=(0,d.useState)(!1),[i,a]=(0,d.useState)(null),[o,s]=(0,d.useState)(!1);async function l(){if(!(!e||o)){s(!0);try{a(await c(`POST`,`/agents/`+encodeURIComponent(e)+`/terminal-session`)),r(!0)}catch(e){t(`Terminal Failed`,e.message)}finally{s(!1)}}}function f(t){if(t){r(!0);return}r(!1);let n=i;a(null),e&&n?.mode===`guest`&&c(`DELETE`,`/agents/`+encodeURIComponent(e)+`/terminal-session/`+encodeURIComponent(n.session)).catch(()=>{})}return{terminalOpen:n,terminalTarget:i,terminalOpening:o,openTerminal:l,closeTerminal:f}}var p=r(),m=`•`;function h(e){return u(t=>e&&t.agentProfiles.find(t=>t.name===e)?.icon?.trim()||null)}function g(e){return typeof e?.meta?.profile==`string`?e.meta.profile:void 0}function _({profile:e,className:n,title:r}){let i=h(e),a=r??(e?`Profile: ${e}`:`No profile`);return(0,p.jsx)(`span`,{role:`img`,"aria-label":a,title:a,className:t(`inline-flex items-center justify-center leading-none select-none`,!i&&`text-muted-foreground/70`,n),children:i??m})}var v={idle:{label:`idle`,tip:`Branch worktree — nothing to land yet.`,className:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`,Icon:n},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:a},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:l},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:o},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:i}};function y({state:e,onClick:n,iconOnly:r=!1,className:i}){let a=v[e],{Icon:o}=a,s=!!n,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:n,onKeyDown:s?e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),n?.(e))}:void 0,className:t(`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 i,_ as n,g as r,y as t};
2
- //# sourceMappingURL=branch-state-badge-JDaHO2fG.js.map