agent-relay-server 0.120.1 → 0.120.3
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.
- package/docs/openapi.json +1 -1
- package/package.json +3 -3
- package/public/assets/MessageBubble-Cqi3XsZ7.js +2 -0
- package/public/assets/{MessageBubble-jpshgh3K.js.map → MessageBubble-Cqi3XsZ7.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-CjVG-Jsq.js → PlanGraphPanel-D6Um05oW.js} +2 -2
- package/public/assets/{PlanGraphPanel-CjVG-Jsq.js.map → PlanGraphPanel-D6Um05oW.js.map} +1 -1
- package/public/assets/{activity-DLTFF8Dz.js → activity-B0LsQHEz.js} +2 -2
- package/public/assets/{activity-DLTFF8Dz.js.map → activity-B0LsQHEz.js.map} +1 -1
- package/public/assets/{agent-profiles-BcCLIrON.js → agent-profiles-O--pe5Ic.js} +2 -2
- package/public/assets/{agent-profiles-BcCLIrON.js.map → agent-profiles-O--pe5Ic.js.map} +1 -1
- package/public/assets/{agent-type-icon-BEz393ra.js → agent-type-icon-CeEoMouY.js} +2 -2
- package/public/assets/{agent-type-icon-BEz393ra.js.map → agent-type-icon-CeEoMouY.js.map} +1 -1
- package/public/assets/agents-Ii6XlVwR.js +2 -0
- package/public/assets/{agents-QemvuxKO.js.map → agents-Ii6XlVwR.js.map} +1 -1
- package/public/assets/{analytics-DMLoMwta.js → analytics-BCzdYWRT.js} +2 -2
- package/public/assets/{analytics-DMLoMwta.js.map → analytics-BCzdYWRT.js.map} +1 -1
- package/public/assets/{automation-DACSOffp.js → automation-Crr3Xzui.js} +2 -2
- package/public/assets/{automation-DACSOffp.js.map → automation-Crr3Xzui.js.map} +1 -1
- package/public/assets/{badge-BhUZ1cAb.js → badge-DCIT3Irj.js} +2 -2
- package/public/assets/{badge-BhUZ1cAb.js.map → badge-DCIT3Irj.js.map} +1 -1
- package/public/assets/{branch-state-badge-BYE2U_y4.js → branch-state-badge-Bhw2rloy.js} +2 -2
- package/public/assets/{branch-state-badge-BYE2U_y4.js.map → branch-state-badge-Bhw2rloy.js.map} +1 -1
- package/public/assets/{button-C-V4oij1.js → button-CzdTkRIf.js} +2 -2
- package/public/assets/{button-C-V4oij1.js.map → button-CzdTkRIf.js.map} +1 -1
- package/public/assets/{card-Br1JLjTH.js → card-C3BGuVC6.js} +2 -2
- package/public/assets/{card-Br1JLjTH.js.map → card-C3BGuVC6.js.map} +1 -1
- package/public/assets/{channels-3SlDQL3j.js → channels-CKs9rvsn.js} +2 -2
- package/public/assets/{channels-3SlDQL3j.js.map → channels-CKs9rvsn.js.map} +1 -1
- package/public/assets/chat-BCwEUj5R.js +2 -0
- package/public/assets/chat-BCwEUj5R.js.map +1 -0
- package/public/assets/{connectors-CrEW591Q.js → connectors-D_kQR_vw.js} +2 -2
- package/public/assets/{connectors-CrEW591Q.js.map → connectors-D_kQR_vw.js.map} +1 -1
- package/public/assets/{copy-button-BStzXgtd.js → copy-button-B3o1jpLu.js} +2 -2
- package/public/assets/{copy-button-BStzXgtd.js.map → copy-button-B3o1jpLu.js.map} +1 -1
- package/public/assets/{dist-ChDX_t12.js → dist-B-T7lg0a.js} +2 -2
- package/public/assets/{dist-ChDX_t12.js.map → dist-B-T7lg0a.js.map} +1 -1
- package/public/assets/{dist-DV83j9tm.js → dist-B3e4B9pg.js} +2 -2
- package/public/assets/{dist-DV83j9tm.js.map → dist-B3e4B9pg.js.map} +1 -1
- package/public/assets/{dist-y03IwOrd.js → dist-B6woQ9Tb.js} +2 -2
- package/public/assets/{dist-y03IwOrd.js.map → dist-B6woQ9Tb.js.map} +1 -1
- package/public/assets/{dist-CQ0Z-TDi.js → dist-B9G83DXv.js} +2 -2
- package/public/assets/{dist-CQ0Z-TDi.js.map → dist-B9G83DXv.js.map} +1 -1
- package/public/assets/{dist-Cs8X0P1d.js → dist-BIjlN-xB.js} +2 -2
- package/public/assets/{dist-Cs8X0P1d.js.map → dist-BIjlN-xB.js.map} +1 -1
- package/public/assets/{dist-DyNJNwpi.js → dist-BInckSJC.js} +2 -2
- package/public/assets/{dist-DyNJNwpi.js.map → dist-BInckSJC.js.map} +1 -1
- package/public/assets/{dist-CmFeEXMe.js → dist-BlzVGRhh.js} +2 -2
- package/public/assets/{dist-CmFeEXMe.js.map → dist-BlzVGRhh.js.map} +1 -1
- package/public/assets/{dist-CDZZxxJq.js → dist-C7aTlosb.js} +2 -2
- package/public/assets/{dist-CDZZxxJq.js.map → dist-C7aTlosb.js.map} +1 -1
- package/public/assets/{dist-D2jvo5oA.js → dist-DGfp5dLz.js} +2 -2
- package/public/assets/{dist-D2jvo5oA.js.map → dist-DGfp5dLz.js.map} +1 -1
- package/public/assets/{dist-mm7c7nBt.js → dist-DT-OV6sQ.js} +2 -2
- package/public/assets/{dist-mm7c7nBt.js.map → dist-DT-OV6sQ.js.map} +1 -1
- package/public/assets/{dist-CBMWGhWc.js → dist-OUPTEP6q.js} +2 -2
- package/public/assets/{dist-CBMWGhWc.js.map → dist-OUPTEP6q.js.map} +1 -1
- package/public/assets/{es2015-VnZ2kVIz.js → es2015-CnKXYKpf.js} +2 -2
- package/public/assets/{es2015-VnZ2kVIz.js.map → es2015-CnKXYKpf.js.map} +1 -1
- package/public/assets/formatted-body-impl-CSRGuMcM.js +3 -0
- package/public/assets/formatted-body-impl-CSRGuMcM.js.map +1 -0
- package/public/assets/formatted-body-q_qzt1L-.js +3 -0
- package/public/assets/{formatted-body-Dg9R3RD7.js.map → formatted-body-q_qzt1L-.js.map} +1 -1
- package/public/assets/{index-D_fNJnsI.js → index-Ceiwd02X.js} +10 -10
- package/public/assets/index-Ceiwd02X.js.map +1 -0
- package/public/assets/{input-CtLT7WXi.js → input-B6Q0NWCS.js} +2 -2
- package/public/assets/{input-CtLT7WXi.js.map → input-B6Q0NWCS.js.map} +1 -1
- package/public/assets/{insights-D48n2ojF.js → insights-DUhXqZTZ.js} +2 -2
- package/public/assets/{insights-D48n2ojF.js.map → insights-DUhXqZTZ.js.map} +1 -1
- package/public/assets/{integrations-B-bdliwU.js → integrations-lbg5CjtE.js} +2 -2
- package/public/assets/{integrations-B-bdliwU.js.map → integrations-lbg5CjtE.js.map} +1 -1
- package/public/assets/{lib-ByLQqcD1.js → lib-BHsWPMKB.js} +2 -2
- package/public/assets/{lib-ByLQqcD1.js.map → lib-BHsWPMKB.js.map} +1 -1
- package/public/assets/lucide-react-DuhlF2Sj.js +10 -0
- package/public/assets/lucide-react-DuhlF2Sj.js.map +1 -0
- package/public/assets/{maintenance-LQ_U3Nqy.js → maintenance-CQgneSVf.js} +2 -2
- package/public/assets/{maintenance-LQ_U3Nqy.js.map → maintenance-CQgneSVf.js.map} +1 -1
- package/public/assets/{managed-agents-Cfh8FvY8.js → managed-agents-DsnYf6fm.js} +4 -4
- package/public/assets/{managed-agents-Cfh8FvY8.js.map → managed-agents-DsnYf6fm.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-BSa7zYx1.js → markdown-preview-impl-C1ZtGJp6.js} +2 -2
- package/public/assets/{markdown-preview-impl-BSa7zYx1.js.map → markdown-preview-impl-C1ZtGJp6.js.map} +1 -1
- package/public/assets/{memory-Dr1iYKkC.js → memory-SSLUTOI2.js} +2 -2
- package/public/assets/{memory-Dr1iYKkC.js.map → memory-SSLUTOI2.js.map} +1 -1
- package/public/assets/messages-BY26OP4K.js +2 -0
- package/public/assets/{messages-DRKulS-2.js.map → messages-BY26OP4K.js.map} +1 -1
- package/public/assets/{orchestrators-BguyeViG.js → orchestrators-OY7yPzVI.js} +2 -2
- package/public/assets/{orchestrators-BguyeViG.js.map → orchestrators-OY7yPzVI.js.map} +1 -1
- package/public/assets/overview-Dj0u1tPG.js +2 -0
- package/public/assets/{overview-Dbq2lr7Y.js.map → overview-Dj0u1tPG.js.map} +1 -1
- package/public/assets/{pairs-DD7i2scF.js → pairs-CrUR50ou.js} +2 -2
- package/public/assets/{pairs-DD7i2scF.js.map → pairs-CrUR50ou.js.map} +1 -1
- package/public/assets/{projects-DEn85LQb.js → projects-B_AtxHtH.js} +2 -2
- package/public/assets/{projects-DEn85LQb.js.map → projects-B_AtxHtH.js.map} +1 -1
- package/public/assets/{prompt-settings-DwgrPKY3.js → prompt-settings-CPtYSban.js} +2 -2
- package/public/assets/{prompt-settings-DwgrPKY3.js.map → prompt-settings-CPtYSban.js.map} +1 -1
- package/public/assets/{react-dom-cLkVFBsS.js → react-dom-DWBmcawP.js} +2 -2
- package/public/assets/{react-dom-cLkVFBsS.js.map → react-dom-DWBmcawP.js.map} +1 -1
- package/public/assets/{registry-DCR3xFpe.js → registry-BgUALWn5.js} +2 -2
- package/public/assets/{registry-DCR3xFpe.js.map → registry-BgUALWn5.js.map} +1 -1
- package/public/assets/security-5lHfGk7g.js +3 -0
- package/public/assets/security-5lHfGk7g.js.map +1 -0
- package/public/assets/{select-CpyCRBK3.js → select-Cgx4QSLj.js} +2 -2
- package/public/assets/{select-CpyCRBK3.js.map → select-Cgx4QSLj.js.map} +1 -1
- package/public/assets/settings-DFGgxyun.js +6 -0
- package/public/assets/{settings-DYNFGC2-.js.map → settings-DFGgxyun.js.map} +1 -1
- package/public/assets/store-BM4zM89B.js +9 -0
- package/public/assets/store-BM4zM89B.js.map +1 -0
- package/public/assets/{task-chip-kxk4eNm1.js → task-chip-DXfvXBDx.js} +2 -2
- package/public/assets/{task-chip-kxk4eNm1.js.map → task-chip-DXfvXBDx.js.map} +1 -1
- package/public/assets/{tasks-rdy9Nsbf.js → tasks-BvH5rluu.js} +2 -2
- package/public/assets/{tasks-rdy9Nsbf.js.map → tasks-BvH5rluu.js.map} +1 -1
- package/public/assets/{teams-DHloBagJ.js → teams-VZOIOdoE.js} +2 -2
- package/public/assets/{teams-DHloBagJ.js.map → teams-VZOIOdoE.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-DWTuNejR.js → terminal-viewer-impl-DYY3Wmoe.js} +2 -2
- package/public/assets/{terminal-viewer-impl-DWTuNejR.js.map → terminal-viewer-impl-DYY3Wmoe.js.map} +1 -1
- package/public/assets/types-uVOXgvMT.js.map +1 -1
- package/public/assets/{use-keyboard-viewport-B06XtRUZ.js → use-keyboard-viewport-CP109w9y.js} +2 -2
- package/public/assets/{use-keyboard-viewport-B06XtRUZ.js.map → use-keyboard-viewport-CP109w9y.js.map} +1 -1
- package/public/assets/{user-avatar-DuwCFrER.js → user-avatar-Dw6mzWhv.js} +2 -2
- package/public/assets/{user-avatar-DuwCFrER.js.map → user-avatar-Dw6mzWhv.js.map} +1 -1
- package/public/assets/{work-queue-CShT7nTC.js → work-queue-B6Xk7QNe.js} +2 -2
- package/public/assets/{work-queue-CShT7nTC.js.map → work-queue-B6Xk7QNe.js.map} +1 -1
- package/public/assets/{workspaces-DjQ6EdrZ.js → workspaces-CPIzAHAe.js} +2 -2
- package/public/assets/{workspaces-DjQ6EdrZ.js.map → workspaces-CPIzAHAe.js.map} +1 -1
- package/public/index.html +23 -23
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/src/automations/reconcile.ts +69 -4
- package/src/branch-landed.ts +18 -11
- package/src/bus.ts +25 -18
- package/src/db/connection.ts +53 -1
- package/src/db/maintenance-worker.ts +37 -0
- package/src/db/message-reads.ts +86 -45
- package/src/db/migrations.ts +1 -0
- package/src/db/provider-quotas.ts +6 -7
- package/src/db/schema.ts +2 -1
- package/src/maintenance/jobs.ts +19 -13
- package/src/maintenance/scheduler.ts +8 -3
- package/src/maintenance/types.ts +5 -1
- package/src/mcp/index.ts +5 -5
- package/src/mcp/tools-workspace.ts +8 -3
- package/src/routes/orchestrator-proxy.ts +7 -6
- package/src/routes/sse.ts +2 -1
- package/src/routes/tasks.ts +29 -0
- package/src/routes/workspaces.ts +9 -2
- package/src/runtime-tokens.ts +4 -0
- package/src/security.ts +31 -7
- package/src/server.ts +40 -18
- package/src/services/git-process.ts +61 -0
- package/src/services/git-remote.ts +87 -7
- package/src/services/issue-lifecycle.ts +6 -6
- package/src/services/project.ts +47 -1
- package/src/services/send-message.ts +2 -4
- package/src/services/spawn-agent.ts +2 -2
- package/src/services/task-lifecycle.ts +6 -9
- package/src/settings/registry.ts +6 -4
- package/src/spawn-targets.ts +2 -2
- package/src/sse.ts +131 -46
- package/src/steward.ts +10 -6
- package/src/terminal-authz.ts +50 -0
- package/src/token-db.ts +3 -3
- package/src/validation.ts +1 -1
- package/src/workspace-actions.ts +46 -4
- package/src/workspace-auto-merge.ts +120 -13
- package/src/workspace-orphans.ts +1 -1
- package/src/workspace-probe.ts +19 -10
- package/public/assets/MessageBubble-jpshgh3K.js +0 -2
- package/public/assets/agents-QemvuxKO.js +0 -2
- package/public/assets/chat-xKXCafN9.js +0 -2
- package/public/assets/chat-xKXCafN9.js.map +0 -1
- package/public/assets/formatted-body-Dg9R3RD7.js +0 -3
- package/public/assets/formatted-body-impl-DlasTD8X.js +0 -3
- package/public/assets/formatted-body-impl-DlasTD8X.js.map +0 -1
- package/public/assets/index-D_fNJnsI.js.map +0 -1
- package/public/assets/lucide-react-Dc3ZwCBi.js +0 -9
- package/public/assets/lucide-react-Dc3ZwCBi.js.map +0 -1
- package/public/assets/messages-DRKulS-2.js +0 -2
- package/public/assets/overview-Dbq2lr7Y.js +0 -2
- package/public/assets/security-BH8kTdA-.js +0 -3
- package/public/assets/security-BH8kTdA-.js.map +0 -1
- package/public/assets/settings-DYNFGC2-.js +0 -6
- package/public/assets/store-BuuJUn70.js +0 -9
- package/public/assets/store-BuuJUn70.js.map +0 -1
|
@@ -36,11 +36,14 @@ import { isAwaitingReviewerApproval } from "./reviewer-pipeline";
|
|
|
36
36
|
import { emitWorkspaceTaskSemanticNotifications } from "./services/task-lifecycle";
|
|
37
37
|
import { ensureRepoSteward } from "./steward";
|
|
38
38
|
import { requestWorkspaceMerge, workspaceMergeOrchestrators } from "./workspace-merge";
|
|
39
|
+
import { workspaceOwnerOrchestrator } from "./workspace-host";
|
|
39
40
|
import { workspaceActiveClaim } from "./workspace-claim";
|
|
40
41
|
import { DIRTY_WORKTREE_LAND_SKIP_REASON, READY_TO_LAND_STATUSES } from "./workspace-phase";
|
|
41
42
|
import { fetchHostMergePreview } from "./workspace-probe";
|
|
42
43
|
import type { WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceMergePreview, WorkspaceMergeStrategy, WorkspaceRecord } from "./types";
|
|
43
44
|
import { STEWARD_WAKE_COOLDOWN_MS, stewardFallbackTarget, workspaceAutoMergeEnabled } from "./config";
|
|
45
|
+
import { isPathWithinBase } from "./utils";
|
|
46
|
+
import type { Orchestrator } from "./types";
|
|
44
47
|
|
|
45
48
|
const WORKSPACE_LAND_STRATEGIES = ["direct", "pr"] as const;
|
|
46
49
|
const WORKSPACE_AUTO_MERGE_POLICIES = ["on-green", "on-approval", "manual"] as const;
|
|
@@ -52,6 +55,21 @@ type AutoMergeRequestOptions = {
|
|
|
52
55
|
reviewer?: string;
|
|
53
56
|
};
|
|
54
57
|
|
|
58
|
+
function stewardOwnerForWorkspace(ws: WorkspaceRecord): { owner: Orchestrator } | { error: string } {
|
|
59
|
+
const orchestrators = listOrchestrators();
|
|
60
|
+
if (ws.orchestratorId) {
|
|
61
|
+
const owner = orchestrators.find((orch) => orch.id === ws.orchestratorId);
|
|
62
|
+
if (!owner) return { error: `cannot spawn steward: owning host ${ws.orchestratorId} is not registered` };
|
|
63
|
+
if (owner.status !== "online") return { error: `cannot spawn steward: owning host ${owner.id} is ${owner.status}` };
|
|
64
|
+
if (!isPathWithinBase(ws.worktreePath, owner.baseDir)) {
|
|
65
|
+
return { error: `cannot spawn steward: worktree is not on owning host ${owner.id}` };
|
|
66
|
+
}
|
|
67
|
+
return { owner };
|
|
68
|
+
}
|
|
69
|
+
const owner = workspaceOwnerOrchestrator(ws, orchestrators, { requireApiUrl: true });
|
|
70
|
+
return owner ? { owner } : { error: "cannot spawn steward: no online owner for workspace host path" };
|
|
71
|
+
}
|
|
72
|
+
|
|
55
73
|
function workspaceLandStrategy(metadata: Record<string, unknown>): WorkspaceLandingPolicy | undefined {
|
|
56
74
|
const value = metadata.landStrategy;
|
|
57
75
|
return typeof value === "string" && (WORKSPACE_LAND_STRATEGIES as readonly string[]).includes(value)
|
|
@@ -91,8 +109,8 @@ function autoMergeRequestOptions(ws: WorkspaceRecord): AutoMergeRequestOptions {
|
|
|
91
109
|
|
|
92
110
|
// Don't re-wake the managed steward for the same workspace more than once per this
|
|
93
111
|
// window — a persistent conflict/behind row would otherwise re-ping every sweep.
|
|
94
|
-
// Wake the managed per-repo steward (issue #167) for a workspace it should handle:
|
|
95
|
-
// auto-provision the policy
|
|
112
|
+
// Wake the managed per-host/repo steward (issue #167/#977) for a workspace it should handle:
|
|
113
|
+
// auto-provision the policy on the workspace-owning host, then queue a `policy:` wake
|
|
96
114
|
// message (which also spawns the on-demand agent now via onMessageForPolicy). Honors a
|
|
97
115
|
// per-workspace cooldown so a persistent conflict/behind row isn't re-pinged every sweep.
|
|
98
116
|
// Returns the steward policy name on a fresh wake, or null (disabled / no owner / cooled down).
|
|
@@ -100,8 +118,16 @@ export function wakeRepoSteward(ws: WorkspaceRecord, reason: string): string | n
|
|
|
100
118
|
const meta = ws.metadata as Record<string, unknown>;
|
|
101
119
|
const lastWoke = typeof meta.stewardWokenAt === "number" ? meta.stewardWokenAt : 0;
|
|
102
120
|
if (lastWoke && Date.now() - lastWoke < STEWARD_WAKE_COOLDOWN_MS) return null;
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
121
|
+
const ownerResult = stewardOwnerForWorkspace(ws);
|
|
122
|
+
if ("error" in ownerResult) {
|
|
123
|
+
patchWorkspaceMetadata(ws.id, { stewardWakeError: ownerResult.error, stewardWakeErrorAt: Date.now() });
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const policyName = ensureRepoSteward(ws.repoRoot, ownerResult.owner);
|
|
127
|
+
if (!policyName) {
|
|
128
|
+
patchWorkspaceMetadata(ws.id, { stewardWakeError: "cannot spawn steward: steward policy could not be provisioned", stewardWakeErrorAt: Date.now() });
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
105
131
|
// #640 — resolve the identity triangle so the steward isn't blind to the people-graph:
|
|
106
132
|
// the workspace's branch agent (owner) and that agent's coordinator (owner's `spawnedBy`).
|
|
107
133
|
const { ownerAgentId, coordinatorAgentId } = resolveStewardIdentity(ws);
|
|
@@ -132,11 +158,18 @@ export function wakeRepoSteward(ws: WorkspaceRecord, reason: string): string | n
|
|
|
132
158
|
},
|
|
133
159
|
});
|
|
134
160
|
getLifecycleManager().onMessageForPolicy(policyName);
|
|
135
|
-
patchWorkspaceMetadata(ws.id, {
|
|
161
|
+
patchWorkspaceMetadata(ws.id, {
|
|
162
|
+
stewardWokenAt: Date.now(),
|
|
163
|
+
stewardPolicy: policyName,
|
|
164
|
+
coordinatorAgentId: coordinatorAgentId ?? undefined,
|
|
165
|
+
stewardWakeError: undefined,
|
|
166
|
+
stewardWakeErrorAt: undefined,
|
|
167
|
+
});
|
|
136
168
|
// #641/#642 — tell the owner which steward took over and proactively loop in its coordinator.
|
|
137
169
|
notifyStewardHandoff({ workspace: ws, stewardId: policyName, coordinatorAgentId, reason });
|
|
138
170
|
return policyName;
|
|
139
|
-
} catch {
|
|
171
|
+
} catch (e) {
|
|
172
|
+
patchWorkspaceMetadata(ws.id, { stewardWakeError: e instanceof Error ? e.message : "failed to wake steward", stewardWakeErrorAt: Date.now() });
|
|
140
173
|
return null;
|
|
141
174
|
}
|
|
142
175
|
}
|
|
@@ -247,6 +280,36 @@ function escalateNoProgressMerge(ws: WorkspaceRecord): void {
|
|
|
247
280
|
});
|
|
248
281
|
}
|
|
249
282
|
|
|
283
|
+
function notifyProtectedTipRestore(ws: WorkspaceRecord, preview: WorkspaceMergePreview): void {
|
|
284
|
+
const discardedRef = preview.protectedTipDiscardedRef;
|
|
285
|
+
const discardedHead = preview.protectedTipDiscardedHead;
|
|
286
|
+
if (!discardedRef || !discardedHead) return;
|
|
287
|
+
const { coordinatorAgentId } = resolveStewardIdentity(ws);
|
|
288
|
+
const recipients = [...new Set([coordinatorAgentId, ws.ownerAgentId].filter((r): r is string => Boolean(r)))];
|
|
289
|
+
const body = `Workspace \`${ws.branch ?? ws.id}\` restored protected tip \`${preview.protectedTip?.slice(0, 12) ?? "unknown"}\`; discarded HEAD \`${discardedHead.slice(0, 12)}\` was preserved at \`${discardedRef}\`.`;
|
|
290
|
+
createActivityEvent({
|
|
291
|
+
clientId: `workspace-protected-tip-restore-${ws.id}-${Date.now()}`,
|
|
292
|
+
kind: "state",
|
|
293
|
+
title: "Protected workspace tip restored",
|
|
294
|
+
body,
|
|
295
|
+
meta: ws.branch ?? ws.id,
|
|
296
|
+
icon: "ti-shield",
|
|
297
|
+
view: "orchestrators",
|
|
298
|
+
metadata: { source: "server", maintenanceJobId: "workspace-auto-merge", workspaceId: ws.id, protectedTip: preview.protectedTip, discardedHead, discardedRef },
|
|
299
|
+
});
|
|
300
|
+
if (!recipients.length) return;
|
|
301
|
+
routeNotification({
|
|
302
|
+
type: "workspace.land_gate_warning",
|
|
303
|
+
scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ws.ownerAgentId, parent: coordinatorAgentId ?? undefined },
|
|
304
|
+
recipients,
|
|
305
|
+
message: {
|
|
306
|
+
subject: "Workspace protected tip restored",
|
|
307
|
+
body,
|
|
308
|
+
payload: { kind: "workspace.protected-tip-restore", workspaceId: ws.id, repoRoot: ws.repoRoot, branch: ws.branch, protectedTip: preview.protectedTip, discardedHead, discardedRef },
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
250
313
|
interface LandSweepResult {
|
|
251
314
|
scanned: number;
|
|
252
315
|
merged: string[];
|
|
@@ -255,13 +318,14 @@ interface LandSweepResult {
|
|
|
255
318
|
heldByPause: string[];
|
|
256
319
|
heldAwaitingApproval: string[];
|
|
257
320
|
previewUnavailable: string[];
|
|
321
|
+
dirtyWorktree: string[];
|
|
258
322
|
backedOff: string[];
|
|
259
323
|
leftForSteward: string[];
|
|
260
324
|
wokeStewards: string[];
|
|
261
325
|
}
|
|
262
326
|
|
|
263
327
|
function emptyLandSweep(): LandSweepResult {
|
|
264
|
-
return { scanned: 0, merged: [], heldByLease: [], heldByClaim: [], heldByPause: [], heldAwaitingApproval: [], previewUnavailable: [], backedOff: [], leftForSteward: [], wokeStewards: [] };
|
|
328
|
+
return { scanned: 0, merged: [], heldByLease: [], heldByClaim: [], heldByPause: [], heldAwaitingApproval: [], previewUnavailable: [], dirtyWorktree: [], backedOff: [], leftForSteward: [], wokeStewards: [] };
|
|
265
329
|
}
|
|
266
330
|
|
|
267
331
|
async function fetchFirstUsableMergePreview(
|
|
@@ -270,7 +334,7 @@ async function fetchFirstUsableMergePreview(
|
|
|
270
334
|
): Promise<WorkspaceMergePreview | { available: false } | null> {
|
|
271
335
|
for (const orch of workspaceMergeOrchestrators(ws, orchestrators)) {
|
|
272
336
|
if (!orch.apiUrl) continue;
|
|
273
|
-
const preview = await fetchHostMergePreview(orch.apiUrl, ws);
|
|
337
|
+
const preview = await fetchHostMergePreview(orch.apiUrl, ws, { protectTip: true });
|
|
274
338
|
if (!preview || (preview as { available?: false }).available === false) continue;
|
|
275
339
|
const p = preview as WorkspaceMergePreview;
|
|
276
340
|
if (p.error || p.missing) continue;
|
|
@@ -288,7 +352,7 @@ async function landCandidates(
|
|
|
288
352
|
): Promise<LandSweepResult> {
|
|
289
353
|
const stewardEnabled = getStewardConfig().enabled;
|
|
290
354
|
const merged: string[] = [], previewUnavailable: string[] = [];
|
|
291
|
-
const heldByLease: string[] = [], heldByClaim: string[] = [], heldByPause: string[] = [], heldAwaitingApproval: string[] = [], backedOff: string[] = [], leftForSteward: string[] = [], wokeStewards: string[] = [];
|
|
355
|
+
const heldByLease: string[] = [], heldByClaim: string[] = [], heldByPause: string[] = [], heldAwaitingApproval: string[] = [], dirtyWorktree: string[] = [], backedOff: string[] = [], leftForSteward: string[] = [], wokeStewards: string[] = [];
|
|
292
356
|
|
|
293
357
|
for (const ws of candidates) {
|
|
294
358
|
if (isAwaitingReviewerApproval(ws)) { heldAwaitingApproval.push(ws.id); continue; }
|
|
@@ -310,8 +374,22 @@ async function landCandidates(
|
|
|
310
374
|
continue;
|
|
311
375
|
}
|
|
312
376
|
const p = preview as WorkspaceMergePreview;
|
|
313
|
-
if (p.
|
|
314
|
-
|
|
377
|
+
if (p.protectedTipRestored) notifyProtectedTipRestore(ws, p);
|
|
378
|
+
const dirtyCount = p.dirtyCount ?? 0;
|
|
379
|
+
if (p.reason === DIRTY_WORKTREE_LAND_SKIP_REASON || dirtyCount > 0) {
|
|
380
|
+
const mergeError = p.reason ?? DIRTY_WORKTREE_LAND_SKIP_REASON;
|
|
381
|
+
const heldDirty = patchWorkspaceMetadata(ws.id, {
|
|
382
|
+
...noteMergeNoProgress(ws.metadata),
|
|
383
|
+
mergeError,
|
|
384
|
+
lastLandSkipReason: DIRTY_WORKTREE_LAND_SKIP_REASON,
|
|
385
|
+
lastLandSkipAt: Date.now(),
|
|
386
|
+
}) ?? ws;
|
|
387
|
+
dirtyWorktree.push(ws.id);
|
|
388
|
+
if (mergeNoProgressCount(heldDirty.metadata) >= MAX_NO_PROGRESS_MERGE_ATTEMPTS) {
|
|
389
|
+
backedOff.push(ws.id);
|
|
390
|
+
escalateNoProgressMerge(heldDirty);
|
|
391
|
+
}
|
|
392
|
+
continue;
|
|
315
393
|
} else if (ws.metadata.lastLandSkipReason === DIRTY_WORKTREE_LAND_SKIP_REASON) {
|
|
316
394
|
patchWorkspaceMetadata(ws.id, { lastLandSkipReason: undefined, lastLandSkipAt: undefined });
|
|
317
395
|
}
|
|
@@ -328,11 +406,40 @@ async function landCandidates(
|
|
|
328
406
|
// the steward every sweep for a workspace with no work.
|
|
329
407
|
const canLand = p.noop === true || (p.conflict === false && ahead > 0);
|
|
330
408
|
if (!canLand) {
|
|
409
|
+
let handoffWorkspace = ws;
|
|
410
|
+
if (p.conflict !== true) {
|
|
411
|
+
const mergeError = p.protectedTipReachable === false
|
|
412
|
+
? p.protectedTipError ?? "protected worker tip is no longer reachable"
|
|
413
|
+
: p.reason ?? p.error ?? "merge state unknown";
|
|
414
|
+
handoffWorkspace = patchWorkspaceMetadata(ws.id, {
|
|
415
|
+
...noteMergeNoProgress(ws.metadata),
|
|
416
|
+
mergeError,
|
|
417
|
+
lastMergeStateUnknownAt: Date.now(),
|
|
418
|
+
}) ?? ws;
|
|
419
|
+
if (mergeNoProgressCount(handoffWorkspace.metadata) >= MAX_NO_PROGRESS_MERGE_ATTEMPTS) {
|
|
420
|
+
backedOff.push(ws.id);
|
|
421
|
+
escalateNoProgressMerge(handoffWorkspace);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
331
425
|
leftForSteward.push(ws.id);
|
|
426
|
+
let woke: string | null = null;
|
|
332
427
|
if (stewardEnabled) {
|
|
333
|
-
|
|
428
|
+
woke = wakeRepoSteward(handoffWorkspace, p.conflict === true ? "conflict" : "merge state unknown");
|
|
334
429
|
if (woke) wokeStewards.push(woke);
|
|
335
430
|
}
|
|
431
|
+
if (stewardEnabled && !woke && p.conflict === true) {
|
|
432
|
+
const failedHandoff = patchWorkspaceMetadata(ws.id, {
|
|
433
|
+
...noteMergeNoProgress(ws.metadata),
|
|
434
|
+
mergeError: "cannot spawn steward on the workspace owning host",
|
|
435
|
+
lastStewardWakeFailedAt: Date.now(),
|
|
436
|
+
}) ?? ws;
|
|
437
|
+
if (mergeNoProgressCount(failedHandoff.metadata) >= MAX_NO_PROGRESS_MERGE_ATTEMPTS) {
|
|
438
|
+
backedOff.push(ws.id);
|
|
439
|
+
escalateNoProgressMerge(failedHandoff);
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
336
443
|
if (p.conflict === true) {
|
|
337
444
|
emitWorkspaceTaskSemanticNotifications({
|
|
338
445
|
workspace: ws,
|
|
@@ -372,7 +479,7 @@ async function landCandidates(
|
|
|
372
479
|
});
|
|
373
480
|
}
|
|
374
481
|
|
|
375
|
-
return { scanned: candidates.length, merged, heldByLease, heldByClaim, heldByPause, heldAwaitingApproval, previewUnavailable, backedOff, leftForSteward, wokeStewards };
|
|
482
|
+
return { scanned: candidates.length, merged, heldByLease, heldByClaim, heldByPause, heldAwaitingApproval, previewUnavailable, dirtyWorktree, backedOff, leftForSteward, wokeStewards };
|
|
376
483
|
}
|
|
377
484
|
|
|
378
485
|
// Coalesced, fire-and-forget per-repo land trigger (see module header). A run already
|
package/src/workspace-orphans.ts
CHANGED
|
@@ -556,7 +556,7 @@ export async function reapOrphanedWorktrees(): Promise<Record<string, unknown>>
|
|
|
556
556
|
// Route through the guarded action (#279): no `force`, so a flipped-alive owner
|
|
557
557
|
// is rejected (409) — our safety net. Also does the cleanup_requested transition
|
|
558
558
|
// + audit. Attributed to a distinct requester so incidents are traceable.
|
|
559
|
-
const result = applyWorkspaceAction(workspace, {
|
|
559
|
+
const result = await applyWorkspaceAction(workspace, {
|
|
560
560
|
action: "cleanup",
|
|
561
561
|
agentId: "workspace-dead-owner-reaper",
|
|
562
562
|
auditMetadata: { source: "server", maintenanceJobId: "workspace-orphan-reaper", requestedBy: "workspace-dead-owner-reaper", deadOwner: workspace.ownerAgentId },
|
package/src/workspace-probe.ts
CHANGED
|
@@ -32,12 +32,16 @@ export const workspacePathWithinBase = isPathWithinBase;
|
|
|
32
32
|
export async function fetchHostMergePreview(
|
|
33
33
|
apiUrl: string,
|
|
34
34
|
workspace: WorkspaceRecord,
|
|
35
|
-
opts: { checkPr?: boolean } = {},
|
|
35
|
+
opts: { checkPr?: boolean; protectTip?: boolean } = {},
|
|
36
36
|
): Promise<WorkspaceMergePreview | { available: false } | null> {
|
|
37
37
|
const checkPr = opts.checkPr !== false;
|
|
38
38
|
const query = new URLSearchParams({ path: workspace.worktreePath, ...(checkPr ? { checkPr: "1" } : {}) });
|
|
39
39
|
if (workspace.baseRef) query.set("baseRef", workspace.baseRef);
|
|
40
40
|
if (workspace.baseSha) query.set("baseSha", workspace.baseSha);
|
|
41
|
+
if (opts.protectTip) {
|
|
42
|
+
query.set("workspaceId", workspace.id);
|
|
43
|
+
query.set("protectTip", "1");
|
|
44
|
+
}
|
|
41
45
|
const headers: Record<string, string> = {};
|
|
42
46
|
const token = relayToken();
|
|
43
47
|
if (token) headers[RELAY_TOKEN_HEADER] = token;
|
|
@@ -84,6 +88,18 @@ interface ProbeResult {
|
|
|
84
88
|
skipped?: string;
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
export async function refreshWorkspaceGitState(ws: WorkspaceRecord): Promise<ProbeResult> {
|
|
92
|
+
if (!ws.worktreePath) return { probed: false, workspaceId: ws.id, skipped: "workspace has no worktree" };
|
|
93
|
+
const orch = workspaceOwnerOrchestrator(ws, listOrchestrators(), { requireApiUrl: true });
|
|
94
|
+
if (!orch?.apiUrl) return { probed: false, workspaceId: ws.id, skipped: "no online orchestrator owns this path" };
|
|
95
|
+
const preview = await fetchHostMergePreview(orch.apiUrl, ws, { checkPr: false });
|
|
96
|
+
if (!preview || (preview as { available?: false }).available === false) return { probed: false, workspaceId: ws.id, skipped: "host preview unavailable" };
|
|
97
|
+
const p = preview as WorkspaceMergePreview;
|
|
98
|
+
if (p.error || p.missing) return { probed: false, workspaceId: ws.id, skipped: "host preview error" };
|
|
99
|
+
const flipped = applyBranchFreshness(ws, p);
|
|
100
|
+
return { probed: true, flipped, workspaceId: ws.id };
|
|
101
|
+
}
|
|
102
|
+
|
|
87
103
|
/**
|
|
88
104
|
* Probe THIS agent's branch worktree on turn-end (#237). Single scoped host round-trip
|
|
89
105
|
* (not the full fan-out scan) so the changes badge flips at the exact moment work
|
|
@@ -96,15 +112,8 @@ export async function probeWorkspaceState(agentId: string): Promise<ProbeResult>
|
|
|
96
112
|
const ws = ownedIsolatedWorkspace(agentId);
|
|
97
113
|
if (!ws || !ws.worktreePath) return { probed: false, skipped: "no live isolated workspace" };
|
|
98
114
|
if (ws.status !== "active") return { probed: false, workspaceId: ws.id, skipped: `status ${ws.status} derives badge without git counts` };
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// checkPr:false — a badge probe never needs the gh round-trip (#304).
|
|
102
|
-
const preview = await fetchHostMergePreview(orch.apiUrl, ws, { checkPr: false });
|
|
103
|
-
if (!preview || (preview as { available?: false }).available === false) return { probed: false, workspaceId: ws.id, skipped: "host preview unavailable" };
|
|
104
|
-
const p = preview as WorkspaceMergePreview;
|
|
105
|
-
if (p.error || p.missing) return { probed: false, workspaceId: ws.id, skipped: "host preview error" };
|
|
106
|
-
const flipped = applyBranchFreshness(ws, p);
|
|
107
|
-
return { probed: true, flipped, workspaceId: ws.id };
|
|
115
|
+
// checkPr:false — a badge/readiness probe never needs the gh round-trip (#304).
|
|
116
|
+
return refreshWorkspaceGitState(ws);
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
/**
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{Gn as t,Kn as n,S as r,Sn as i,Ut as a,a as o,bn as s,en as c,er as l,hr as u,ir as d,l as f,nr as p,pn as m,pt as h,r as g}from"./lucide-react-Dc3ZwCBi.js";import{t as _,y as v}from"./store-BuuJUn70.js";import{o as y}from"./types-uVOXgvMT.js";import{V as b,_ as x,f as S,k as C,v as ee}from"./display-exQDWum3.js";import{t as w}from"./agent-type-icon-BEz393ra.js";import{t as T}from"./formatted-body-Dg9R3RD7.js";import{A as E,L as D,M as O,O as te,P as ne,T as k,h as A,k as j,l as M,n as N,o as P,t as F,w as I}from"./index-D_fNJnsI.js";import{t as L}from"./user-avatar-DuwCFrER.js";var R=e(u(),1);function re(){return(0,R.useSyncExternalStore)(e=>v.subscribe(e),()=>v.getPlayingKey(),()=>null)}var z=p();function ie({msg:e,peer:t}){return(0,z.jsx)(A,{msg:e,issueRepo:_(e=>e.agentsById[t]?.issueRepo)})}function B({agent:e,onClick:t}){let n=!!(t&&e);return(0,z.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:l(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,z.jsx)(w,{agent:e})})}function ae({agentId:e,onOpen:t}){let n=_(t=>t.agentsById[e]??null);return(0,z.jsx)(B,{agent:n,onClick:n?()=>t(n):void 0})}function V({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[i,u]=(0,R.useState)(null),[f,p]=(0,R.useState)(null),[m,_]=(0,R.useState)(!1),[v,y]=(0,R.useState)(!1);(0,R.useEffect)(()=>{let t=!1,n=null;async function r(){_(!0),p(null),u(null);try{let r=await d(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),u(n)}catch(e){t||p(e.message)}finally{t||_(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function b(){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,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`button`,{type:`button`,onClick:()=>i&&y(!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,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`img`,{src:i,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,z.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,z.jsx)(g,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,z.jsxs)(`span`,{className:l(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,f?`text-red-400`:`text-muted-foreground`),children:[m?(0,z.jsx)(h,{className:`h-4 w-4 animate-spin`}):(0,z.jsx)(s,{className:`h-4 w-4`}),f||`Loading image`]})}),i&&(0,z.jsx)(F,{open:v,onOpenChange:y,children:(0,z.jsxs)(N,{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,z.jsx)(P,{className:`sr-only`,children:r}),(0,z.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,z.jsx)(`img`,{src:i,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,z.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,z.jsx)(`button`,{type:`button`,onClick:b,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,z.jsx)(c,{className:`w-4 h-4`})}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>y(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,z.jsx)(o,{className:`w-4 h-4`})})]})]})]})})]}):(0,z.jsxs)(`button`,{type:`button`,onClick:b,disabled:!i,className:l(`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:[m?(0,z.jsx)(h,{className:`h-4 w-4 shrink-0 animate-spin`}):f?(0,z.jsx)(s,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,z.jsx)(a,{className:`h-4 w-4 shrink-0`}),(0,z.jsx)(`span`,{className:l(`min-w-0 flex-1 truncate`,f&&`text-red-400`),children:f||r}),(0,z.jsx)(c,{className:`h-3.5 w-3.5 shrink-0`})]})}function H({open:e,onToggle:t,onReact:n}){return(0,z.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,z.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:l(`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,z.jsx)(r,{className:`h-3 w-3`})}),e&&(0,z.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:I.map(e=>(0,z.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 U({msg:e,peer:r}){let[a,o]=(0,R.useState)(!1),s=_(e=>e.agentsById),c=_(e=>e.openAgentDetail),u=e.from===r,d=(u?e.to:e.from)||``,f=s[u?r:d]?.issueRepo??s[r]?.issueRepo,p=!d||d===`broadcast`||d.includes(`:`),m=C(e),h=k(e.occurredAt??e.createdAt),g=u?t:n,v=s[e.from??``]??null;function y(e){e.stopPropagation(),v&&c(v)}return(0,z.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,z.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>o(e=>!e),children:[(0,z.jsx)(i,{className:l(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,a&&`rotate-90`)}),(0,z.jsx)(`button`,{type:`button`,title:v?v.label||v.name||v.id:void 0,disabled:!v,onClick:y,className:l(`shrink-0 transition-opacity`,v?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,z.jsx)(w,{agent:v,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,z.jsx)(g,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,z.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,u?`to`:`from`]}),p?(0,z.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:S(d,s)}):(0,z.jsx)(M,{agentId:d,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!a&&(0,z.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:m}),(0,z.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:h})]}),a&&(0,z.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,z.jsx)(T,{text:m,rawBody:e.body,issueRepo:f,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var W=(0,R.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:i,onPreviewReferencedPathEnd:a}){if(!y(e.from)&&!y(e.to))return(0,z.jsx)(U,{msg:e,peer:t});let o=e.kind===`session`?e.payload?.session:void 0;if(o?.type===`prompt`&&o?.origin===`provider`)return(0,z.jsx)(ie,{msg:e,peer:t});let s=y(e.from),c=_(e=>e.reactToMessage),u=_(e=>e.voiceTtsEnabled),d=re(),p=_(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),h=_(e=>e.agentsById[t]?.issueRepo),g=_(e=>e.usersById),S=_(e=>e.users.length>1),w=s?b(e.from,g):void 0,A=_(e=>e.openAgentDetail);_(e=>e.openTaskDetailById);let[M,N]=(0,R.useState)(!1),P=(0,R.useRef)(null),F=(0,R.useRef)(null),I=(0,R.useRef)(!1),B=C(e),W=k(e.occurredAt??e.createdAt),G=O(e),K=te(e),q=s?ne(e,t):null,J=q?.icon,Y=d===String(e.id),oe=u&&!s&&!E(e)&&B.trim().length>0;function se(t){t.stopPropagation(),Y?v.bargeIn():v.speak(e.body,String(e.id))}(0,R.useEffect)(()=>{if(!M)return;function e(e){j()||P.current&&!P.current.contains(e.target)&&N(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[M]);function X(e){return D(p||`/`,e)}function Z(e,t){let n=X(e);r?.(n,t)}function ce(e,t,n){let r=X(e);i?.(r,t,n)}function Q(t){c(e,t),N(!1)}function le(e){e.button===0&&(F.current={x:e.clientX,y:e.clientY},I.current=!1)}function ue(e){let t=F.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(I.current=!0)}function de(t){if(!(E(e)||s)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(I.current||j()){I.current=!1;return}N(e=>!e)}}let $=n&&!E(e);return(0,z.jsxs)(`div`,{"data-msg-id":e.id,className:l(`group/msg flex mb-3 items-end`,s?`justify-end`:`justify-start`,$&&`gap-1.5`),children:[!s&&$&&(0,z.jsx)(ae,{agentId:t,onOpen:A}),(0,z.jsxs)(`div`,{ref:P,className:l(`relative`,$?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[oe&&(0,z.jsx)(`button`,{type:`button`,title:Y?`Stop playback`:`Play aloud`,onClick:se,className:l(`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`,Y?`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:Y?(0,z.jsx)(m,{className:`h-3.5 w-3.5 animate-pulse`}):(0,z.jsx)(f,{className:`h-3.5 w-3.5`})}),(0,z.jsxs)(`div`,{className:l(`rounded-2xl px-3.5 py-2 text-sm select-text`,!s&&!E(e)&&`cursor-pointer`,s?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:le,onPointerMove:ue,onClick:de,children:[s&&S&&(0,z.jsx)(`p`,{className:l(`text-[11px] font-semibold mb-0.5 text-right`,x(e.from)),children:ee(e.from,g)}),e.subject&&(0,z.jsx)(`p`,{className:l(`text-xs font-semibold mb-1`,s?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,z.jsx)(T,{text:B,rawBody:e.body,issueRepo:h,className:`leading-relaxed`,onPrimary:s,onOpenPath:Z,onPreviewPath:ce,onPreviewPathEnd:a,resolvePathTitle:(e,t)=>`${X(e)}${t?`:${t}`:``}`}),G.map(t=>(0,z.jsx)(V,{attachment:t,outbound:s},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,z.jsxs)(`p`,{className:l(`text-xs mt-1 flex items-center gap-1.5`,s?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,z.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,z.jsx)(`span`,{children:W}),q&&J&&(0,z.jsxs)(`span`,{className:l(`inline-flex items-center gap-1`,q.tone===`ok`&&`text-emerald-300`,q.tone===`warn`&&`text-amber-200`,q.tone===`danger`&&`text-red-200`),title:q.title,children:[(0,z.jsx)(J,{className:`h-3 w-3`}),q.label]})]})]}),!E(e)&&K.length>0&&(0,z.jsxs)(`div`,{className:l(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,s?`justify-end pr-2`:`justify-start pl-2`),children:[!s&&(0,z.jsx)(H,{open:M,onToggle:()=>N(e=>!e),onReact:Q}),K.map(e=>(0,z.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>Q(e.emoji),className:l(`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,z.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,z.jsx)(`span`,{children:e.count})]},e.emoji))]}),!E(e)&&!s&&K.length===0&&(0,z.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,z.jsx)(H,{open:M,onToggle:()=>N(e=>!e),onReact:Q})})]}),s&&$&&(0,z.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,z.jsx)(L,{user:w,address:e.from,distinct:S})})]})});export{W as t};
|
|
2
|
-
//# sourceMappingURL=MessageBubble-jpshgh3K.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{$ as t,K as n,V as r,Vt as i,Wn as a,Yn as o,Zt as s,_ as c,a as l,er as u,g as d,gt as f,hr as p,nr as m,nt as h,u as g,z as _}from"./lucide-react-Dc3ZwCBi.js";import{f as ee,t as v}from"./store-BuuJUn70.js";import{h as y,p as b}from"./types-uVOXgvMT.js";import{J as x,K as S,W as C,Y as w,a as T,d as E,i as te,n as ne}from"./display-exQDWum3.js";import{o as D,r as O}from"./dist-Cs8X0P1d.js";import{t as k}from"./dist-CQ0Z-TDi.js";import{i as re,n as A}from"./dist-ChDX_t12.js";import{t as j}from"./dist-CBMWGhWc.js";import{t as M}from"./dist-CmFeEXMe.js";import{a as N,i as P,n as F,o as I,r as L,s as ie,t as ae}from"./es2015-VnZ2kVIz.js";import{a as R,i as oe,n as se,r as z,t as B}from"./dist-DV83j9tm.js";import{t as V}from"./badge-BhUZ1cAb.js";import{t as H}from"./button-C-V4oij1.js";import{t as ce}from"./copy-button-BStzXgtd.js";import{t as U}from"./agent-type-icon-BEz393ra.js";import{$ as le,Dt as W,Et as ue,G as de,K as fe,Q as pe,Tt as me,Y as he,et as ge,ot as G,q as _e,tt as ve,vt as ye,wt as be}from"./index-D_fNJnsI.js";import{r as xe,t as Se}from"./card-Br1JLjTH.js";import{i as Ce,n as we,r as Te,t as Ee}from"./branch-state-badge-BYE2U_y4.js";var K=e(p(),1),q=m(),J=`Popover`,[De,Oe]=re(J,[R]),Y=R(),[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]=j({prop:r,defaultProp:i??!1,onChange:a,caller:J});return(0,q.jsx)(oe,{...s,children:(0,q.jsx)(ke,{scope:t,contentId:ie(),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 Ne=`PopoverTrigger`,Z=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(Ne,n),a=Y(n),o=D(t,i.triggerRef),s=(0,q.jsx)(k.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.contentId,"data-state":Ke(i.open),...r,ref:o,onClick:A(e.onClick,i.onOpenToggle)});return i.hasCustomAnchor?s:(0,q.jsx)(B,{asChild:!0,...a,children:s})});Z.displayName=Ne;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)(M,{present:n||a.open,children:(0,q.jsx)(P,{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)(M,{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=O(`PopoverContent.RemoveScroll`),ze=K.forwardRef((e,t)=>{let n=X($,e.__scopePopover),r=K.useRef(null),i=D(t,r),a=K.useRef(!1);return K.useEffect(()=>{let e=r.current;if(e)return ae(e)},[]),(0,q.jsx)(F,{as:Re,allowPinchZoom:!0,children:(0,q.jsx)(Ve,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:A(e.onCloseAutoFocus,e=>{e.preventDefault(),a.current||n.triggerRef.current?.focus()}),onPointerDownOutside:A(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;a.current=t.button===2||n},{checkForDefaultPrevented:!1}),onFocusOutside:A(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 L(),(0,q.jsx)(N,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,q.jsx)(I,{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)(k.button,{type:`button`,...r,ref:t,onClick:A(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)(se,{...i,...r,ref:t})});Ge.displayName=We;function Ke(e){return e?`open`:`closed`}var qe=Ae,Je=Z,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,...r}){return(0,q.jsx)(Ye,{children:(0,q.jsx)(Xe,{"data-slot":`popover-content`,align:t,sideOffset:n,className:u(`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),...r})})}function et({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-header`,className:u(`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:u(`font-medium`,e),...t})}function nt({agent:e,childAgents:r=[],parentAgent:a}){let o=ee();v(e=>e.set);let l=v(e=>e.switchView),u=v(e=>e.openInboxThread),p=v(e=>e.openAgentDetail),m=v(e=>e.openPairInvite),y=v(e=>e.openRename),b=v(e=>e.openConfirm),D=v(e=>e.doAgentAction),O=v(e=>e.doDeleteAgent),k=v(e=>e.openFilesForAgent),re=v(e=>e.workspaceAction),A=v(e=>e.openWorkspaceFocus),{terminalOpen:j,terminalTarget:M,terminalOpening:N,openTerminal:P,closeTerminal:F}=Ce(e.id),I=be(),L=te(o,e,ye(e),I[e.id]||null),ie=T(e,`shutdown`),ae=T(e,`compact`),R=T(e,`clearContext`),oe=!!(e.providerCapabilities?.terminal?.live?.read||e.providerCapabilities?.terminal?.attach?.create),se=!!e.providerCapabilities?.terminal?.live?.write,z=ne(e),B=a?E(a):e.spawnedBy,W=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:()=>p(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)(U,{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:E(e)})]}),(0,q.jsx)(`div`,{className:`text-xs mt-0.5 ${x(L.tone)}`,children:L.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(),k(e)},children:C(e.meta.cwd)}),(0,q.jsx)(he,{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(),A(e.branchWorkspaceId)}})]}),L.badges.length>0&&(0,q.jsx)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:L.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))}),(W||e.spawnedBy&&B)&&(0,q.jsxs)(`div`,{className:`mb-2 flex flex-wrap gap-1.5`,onClick:e=>e.stopPropagation(),children:[W&&(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)(U,{agent:e}),(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`truncate text-xs font-medium`,children:E(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:()=>p(e),children:`Open`}),(0,q.jsxs)(H,{size:`xs`,variant:`ghost`,onClick:()=>{u(e.id),l(`chat`)},children:[(0,q.jsx)(h,{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||w(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)),w(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)(ge,{agent:e}),(0,q.jsx)(le,{agent:e,compact:!0}),(0,q.jsx)(ve,{agent:e})]}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.id!==`user`&&e.id!==`system`&&S(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),l(`chat`)},children:(0,q.jsx)(h,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Pair`,onClick:()=>m(e.id),children:(0,q.jsx)(f,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Rename`,onClick:()=>y(e),children:(0,q.jsx)(n,{className:`w-3 h-3`})}),oe&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Terminal`,disabled:N,onClick:()=>void P(),children:(0,q.jsx)(c,{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:()=>b(`Mark Workspace Ready`,`Mark ${E(e)}'s branch ready to land? The relay auto-merge will rebase and land it.`,()=>re(e.branchWorkspaceId,`ready`)),children:(0,q.jsx)(i,{className:`w-3 h-3`})}),ae&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Compact`,onClick:()=>b(`Compact Agent`,`Compact context for ${E(e)}?`,()=>D(e,`compact`,`agents-grid`)),children:(0,q.jsx)(t,{className:`w-3 h-3`})}),R&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Clear Context`,onClick:()=>b(`Clear Context`,`Clear context for ${E(e)}?`,()=>D(e,`clearContext`,`agents-grid`)),children:(0,q.jsx)(s,{className:`w-3 h-3`})}),ie&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Shutdown`,onClick:()=>b(`Shutdown Agent`,`Shutdown ${E(e)}?`,()=>D(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:()=>b(`Forget Agent`,`Forget ${E(e)}?`,()=>O(e.id)),children:(0,q.jsx)(d,{className:`w-3 h-3`})})]})]})}),M&&(0,q.jsx)(pe,{open:j,onOpenChange:F,orchestratorId:M.orchestratorId,session:M.session,interactive:M.interactive||se})]})}function rt(){let e=v(e=>e.agentPresetFilter),t=v(e=>e.agentStatusFilter),n=v(e=>e.agentTagFilter),i=v(e=>e.agentHostFilter),s=v(e=>e.agentSort),c=v(e=>e.agentSortDir),u=v(e=>e.showOffline),d=v(e=>e.set),f=v(e=>e.openAgentSpawn),p=v(e=>e.agentsById),m=ee(),h=me(),g=W(),_=ue(),x=de(h,m),S=_e(h,m),C=e||t||n||i;function w(){d({agentPresetFilter:``,agentStatusFilter:``,agentTagFilter:``,agentHostFilter:``})}function T(){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`}),b().map(e=>(0,q.jsx)(`option`,{value:e,children:y(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:i,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:s,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:T,children:c===`asc`?(0,q.jsx)(a,{className:`w-3.5 h-3.5`}):(0,q.jsx)(o,{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:u,onChange:e=>d({showOffline:e.target.checked}),className:`rounded`}),`Show offline`]}),C&&(0,q.jsxs)(H,{size:`sm`,variant:`ghost`,className:`h-8 text-muted-foreground hover:text-foreground gap-1`,onClick:w,children:[(0,q.jsx)(l,{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)(r,{className:`w-3.5 h-3.5`}),`Spawn`]})})]}),S.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:S.map(e=>(0,q.jsx)(nt,{agent:e,parentAgent:e.spawnedBy?p[e.spawnedBy]??null:null,childAgents:fe(x.get(e.id)??[])},e.id))})]})}export{rt as AgentsView};
|
|
2
|
-
//# sourceMappingURL=agents-QemvuxKO.js.map
|