@nanmicoder/dsh-agent-teams 0.1.12 → 0.1.14
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/README.md +43 -7
- package/README_ZH.md +20 -7
- package/lib/client/ActivityPanel.js +219 -50
- package/lib/client/StagingPlanEditor.js +493 -0
- package/lib/client/activity-model.js +71 -0
- package/lib/client/activity-monitor.js +39 -13
- package/lib/client/index.js +2 -2
- package/lib/client/locales.js +224 -2
- package/lib/client.js +1808 -250
- package/lib/client.js.map +1 -1
- package/lib/command.js +116 -99
- package/lib/index.js +286 -14
- package/lib/members.js +137 -16
- package/lib/profiles.js +572 -0
- package/lib/quality-gates.js +777 -0
- package/lib/scheduler.js +215 -18
- package/lib/snapshot.js +25 -1
- package/lib/state.js +116 -10
- package/lib/tools.js +1230 -38
- package/lib/types/client/ActivityPanel.d.ts +3 -1
- package/lib/types/client/StagingPlanEditor.d.ts +17 -0
- package/lib/types/client/activity-model.d.ts +67 -0
- package/lib/types/client/activity-monitor.d.ts +32 -7
- package/lib/types/client/locales.d.ts +222 -0
- package/lib/types/command.d.ts +11 -56
- package/lib/types/event-types.d.ts +35 -1
- package/lib/types/index.d.ts +9 -0
- package/lib/types/members.d.ts +48 -3
- package/lib/types/profiles.d.ts +124 -0
- package/lib/types/quality-gates.d.ts +148 -0
- package/lib/types/scheduler.d.ts +48 -1
- package/lib/types/snapshot.d.ts +18 -1
- package/lib/types/state.d.ts +8 -3
- package/lib/types/tools.d.ts +73 -9
- package/lib/types/types.d.ts +118 -0
- package/lib/types.js +11 -0
- package/package.json +10 -4
- package/release-notes/v0.1.13.md +60 -0
- package/release-notes/v0.1.14.md +68 -0
package/lib/client.js
CHANGED
|
@@ -7,6 +7,37 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
let react = require("react");
|
|
9
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
|
+
/** Compact `provider/model` route, or just the model when the provider is absent. */
|
|
11
|
+
function memberRouteLabel(member) {
|
|
12
|
+
if (member === void 0) return "";
|
|
13
|
+
const provider = member.provider?.trim() ?? "";
|
|
14
|
+
const model = member.model?.trim() ?? "";
|
|
15
|
+
if (provider !== "" && model !== "") return `${provider}/${model}`;
|
|
16
|
+
return model;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compact route shown on a running task. Prefer the task's own snapshot
|
|
20
|
+
* field; fall back to the assignee member when older hosts omit it.
|
|
21
|
+
*/
|
|
22
|
+
function taskModelLabel(task, members) {
|
|
23
|
+
const direct = task.model?.trim() ?? "";
|
|
24
|
+
if (direct !== "") return direct;
|
|
25
|
+
return memberRouteLabel(members.find((candidate) => candidate.name === task.assignee));
|
|
26
|
+
}
|
|
27
|
+
/** Short model id for tight DAG/chip surfaces (`openai/gpt-5.6-sol` → `gpt-5.6-sol`). */
|
|
28
|
+
function compactModelLabel(route) {
|
|
29
|
+
const trimmed = route.trim();
|
|
30
|
+
if (trimmed === "") return "";
|
|
31
|
+
const slash = trimmed.lastIndexOf("/");
|
|
32
|
+
return slash === -1 ? trimmed : trimmed.slice(slash + 1);
|
|
33
|
+
}
|
|
34
|
+
/** Whether the captain chat should keep showing the in-progress banner. */
|
|
35
|
+
function teamIsActive(team) {
|
|
36
|
+
if (team.halted === true || team.phase === "staged") return false;
|
|
37
|
+
if (team.members.some((member) => member.activity === "working" || member.status === "working")) return true;
|
|
38
|
+
if (team.tasks.some((task) => task.status === "pending" || task.status === "claimed" || task.status === "in_progress")) return true;
|
|
39
|
+
return team.members.length > 0 && team.tasks.length === 0;
|
|
40
|
+
}
|
|
10
41
|
/** Use a fill-width grid when the task graph has no real dependency edges. */
|
|
11
42
|
function usesParallelTaskGrid(tasks) {
|
|
12
43
|
if (tasks.length === 0) return false;
|
|
@@ -25,6 +56,14 @@ window.__ModuleLoader__.load({
|
|
|
25
56
|
return open && owner !== void 0 && owner === current;
|
|
26
57
|
}
|
|
27
58
|
/**
|
|
59
|
+
* Auto-expand only for live teams that appear after the current session's
|
|
60
|
+
* initial restore pass. Replayed cards, archived teams, and live teams restored
|
|
61
|
+
* while reopening a conversation must remain behind the collapsed badge.
|
|
62
|
+
*/
|
|
63
|
+
function activityPanelShouldAutoExpand({ alreadyAutoOpened, pageSettled, restoreComplete, previousLiveTeamIds, currentLiveTeamIds }) {
|
|
64
|
+
return !alreadyAutoOpened && pageSettled && restoreComplete && currentLiveTeamIds.some((teamId) => !previousLiveTeamIds.has(teamId));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
28
67
|
* Resolve the task whose dependency chain should be highlighted.
|
|
29
68
|
*
|
|
30
69
|
* A pinned task is an explicit user choice. Keyboard focus takes precedence
|
|
@@ -241,18 +280,31 @@ window.__ModuleLoader__.load({
|
|
|
241
280
|
}
|
|
242
281
|
/** Poll cadence for the live host snapshot route. */
|
|
243
282
|
const ACTIVITY_POLL_MS = 1e3;
|
|
283
|
+
/**
|
|
284
|
+
* Low-frequency probe cadence while a cardless discovery session still owns
|
|
285
|
+
* no team. The probe keeps the panel able to pick up a team created later in
|
|
286
|
+
* that session (e.g. a run_code-wrapped agent_teams_create) without turning
|
|
287
|
+
* every ordinary session into a one-second filesystem scan.
|
|
288
|
+
*/
|
|
289
|
+
const ACTIVITY_PROBE_MS = 5e3;
|
|
244
290
|
/** Host route serving live and archived team snapshots. */
|
|
245
291
|
const ACTIVITY_STATE_URL = "/plugins/dsh-agent-teams/state";
|
|
292
|
+
const ACTIVITY_HALT_URL = "/plugins/dsh-agent-teams/halt";
|
|
246
293
|
/**
|
|
247
294
|
* Start the single polling loop for the current session's requested targets.
|
|
248
295
|
*
|
|
249
296
|
* With neither targets nor a discovery session this is deliberately inert.
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
297
|
+
* Explicit card targets poll at the live cadence from the start. A discovery
|
|
298
|
+
* session performs an immediate live+archive restore pass, then — while it
|
|
299
|
+
* still owns no team — probes on a low-frequency cadence, so a team created
|
|
300
|
+
* later in that session (e.g. a run_code-wrapped agent_teams_create) is
|
|
301
|
+
* discovered without a manual reload, without turning every ordinary session
|
|
302
|
+
* into a one-second filesystem scan. The moment a team for the discovery
|
|
303
|
+
* session appears, the controller upgrades to the live one-second cadence for
|
|
304
|
+
* the rest of its lifetime. The caller — the session view, which stops the
|
|
305
|
+
* controller when the session is no longer current — bounds the lifetime, and
|
|
306
|
+
* archive state is refreshed when a target or a previously discovered live
|
|
307
|
+
* team disappears.
|
|
256
308
|
*/
|
|
257
309
|
function startActivityPolling(monitorTargets, runtime = {}) {
|
|
258
310
|
const discoverySessionId = runtime.discoverySessionId?.trim();
|
|
@@ -269,12 +321,20 @@ window.__ModuleLoader__.load({
|
|
|
269
321
|
const settleTargets = runtime.settleTargets ?? settleActivityMonitorTargets;
|
|
270
322
|
let cancelled = false;
|
|
271
323
|
let inFlight = false;
|
|
324
|
+
let hot = monitorTargets.length > 0;
|
|
272
325
|
let discoveryComplete = false;
|
|
273
326
|
let discoveredLiveKeys = /* @__PURE__ */ new Set();
|
|
274
327
|
let controller;
|
|
328
|
+
let timer;
|
|
329
|
+
const intervalMs = () => hot ? ACTIVITY_POLL_MS : ACTIVITY_PROBE_MS;
|
|
330
|
+
const reschedule = () => {
|
|
331
|
+
cancel(timer);
|
|
332
|
+
timer = schedule(() => {
|
|
333
|
+
tick();
|
|
334
|
+
}, intervalMs());
|
|
335
|
+
};
|
|
275
336
|
const tick = async () => {
|
|
276
337
|
if (inFlight || cancelled) return;
|
|
277
|
-
if (discoveryComplete && monitorTargets.length === 0 && discoveredLiveKeys.size === 0) return;
|
|
278
338
|
inFlight = true;
|
|
279
339
|
controller = new AbortController();
|
|
280
340
|
try {
|
|
@@ -289,6 +349,10 @@ window.__ModuleLoader__.load({
|
|
|
289
349
|
publishSnapshots({ teams: liveTeams });
|
|
290
350
|
const previousDiscoveredKeys = discoveredLiveKeys;
|
|
291
351
|
discoveredLiveKeys = new Set(discoverySessionId === void 0 || discoverySessionId === "" ? [] : liveTeams.filter((team) => team.captainSessionId === discoverySessionId).map((team) => team.teamId));
|
|
352
|
+
if (!hot && discoveredLiveKeys.size > 0) {
|
|
353
|
+
hot = true;
|
|
354
|
+
reschedule();
|
|
355
|
+
}
|
|
292
356
|
const discoveredTeamArchived = [...previousDiscoveredKeys].some((teamId) => !discoveredLiveKeys.has(teamId));
|
|
293
357
|
const missing = monitorTargets.filter((target) => !liveTeams.some((team) => team.captainSessionId === target.sessionId && team.teamId === target.teamId));
|
|
294
358
|
const needsDiscoveryArchive = discoverySessionId !== void 0 && discoverySessionId !== "" && !discoveryComplete;
|
|
@@ -310,9 +374,9 @@ window.__ModuleLoader__.load({
|
|
|
310
374
|
}
|
|
311
375
|
};
|
|
312
376
|
const firstTick = tick();
|
|
313
|
-
|
|
377
|
+
if (timer === void 0) timer = schedule(() => {
|
|
314
378
|
tick();
|
|
315
|
-
},
|
|
379
|
+
}, intervalMs());
|
|
316
380
|
return {
|
|
317
381
|
firstTick,
|
|
318
382
|
stop: () => {
|
|
@@ -460,38 +524,1206 @@ window.__ModuleLoader__.load({
|
|
|
460
524
|
}),
|
|
461
525
|
(0, react_jsx_runtime.jsx)("button", {
|
|
462
526
|
type: "button",
|
|
463
|
-
className: AgentTeamsCard_module_css_default.panelButton,
|
|
527
|
+
className: AgentTeamsCard_module_css_default.panelButton,
|
|
528
|
+
onClick: () => {
|
|
529
|
+
openActivityPanel(resolved);
|
|
530
|
+
},
|
|
531
|
+
"aria-label": t("action.openActivityPanel"),
|
|
532
|
+
title: t("action.openActivityPanel"),
|
|
533
|
+
children: t("activity.panelButton")
|
|
534
|
+
})
|
|
535
|
+
]
|
|
536
|
+
}), resolved.members.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
537
|
+
className: AgentTeamsCard_module_css_default.members,
|
|
538
|
+
children: resolved.members.map((member) => (0, react_jsx_runtime.jsxs)("button", {
|
|
539
|
+
type: "button",
|
|
540
|
+
className: AgentTeamsCard_module_css_default.member,
|
|
541
|
+
onClick: () => {
|
|
542
|
+
if (member.id !== "") openMember(owner, member.id);
|
|
543
|
+
},
|
|
544
|
+
title: member.role === "" ? member.name : `${member.name} · ${member.role}`,
|
|
545
|
+
children: [memberArtUrl(member.name, member.role) !== null ? (0, react_jsx_runtime.jsx)("img", {
|
|
546
|
+
className: AgentTeamsCard_module_css_default.memberArt,
|
|
547
|
+
src: memberArtUrl(member.name, member.role) ?? "",
|
|
548
|
+
alt: "",
|
|
549
|
+
"aria-hidden": true
|
|
550
|
+
}) : (0, react_jsx_runtime.jsx)("span", {
|
|
551
|
+
className: AgentTeamsCard_module_css_default.memberInitial,
|
|
552
|
+
children: member.name.trim().slice(0, 1).toUpperCase() || "?"
|
|
553
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
554
|
+
className: AgentTeamsCard_module_css_default.memberName,
|
|
555
|
+
children: member.name
|
|
556
|
+
})]
|
|
557
|
+
}, member.id))
|
|
558
|
+
})]
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region \0dsh-css:/home/runner/work/dsh-agent-teams/dsh-agent-teams/src/client/ActivityPanel.module.css.mjs
|
|
563
|
+
const css = "html{--agent-teams-panel-shift:420px}html[data-agent-teams-panel-open] [data-phase=active]{box-sizing:border-box;padding-right:var(--agent-teams-panel-shift)}.aYQbCq_badge,.aYQbCq_panel{--dsw-alias-line-normal:var(--dsw-static-neutral-bluish-150,#e7e9ee);--dsw-alias-line-strong:color-mix(in srgb, var(--dsw-static-neutral-bluish-200,#e1e5ee) 50%, var(--dsw-static-neutral-bluish-300,#cfd3d6));--dsw-alias-bg-module:var(--dsw-alias-bg-layer-1,#fff);--dsw-alias-bg-fill-neutral:var(--dsw-static-neutral-bluish-100,#eef0f4);--dsw-alias-bg-fill-business:var(--dsw-alias-state-business-primary,#4d6bfe);--dsw-alias-bg-fill-success:var(--dsw-alias-state-success-primary,#12a150);--dsw-alias-bg-fill-warning:var(--dsw-alias-state-warn-primary,#e08700);--dsw-alias-bg-fill-danger:var(--dsw-alias-state-error-primary,#e5484d);--dsw-alias-state-success:var(--dsw-alias-state-success-primary,#12a150);--dsw-alias-state-warning:var(--dsw-alias-state-warn-primary,#e08700);--dsw-alias-state-danger:var(--dsw-alias-state-error-primary,#e5484d);--dsw-alias-label-on-fill:var(--dsw-alias-label-primary-inverted,#fff)}.aYQbCq_badge{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 92%, transparent);backdrop-filter:blur(16px);height:34px;box-shadow:0 8px 28px color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;align-items:center;gap:7px;padding:0 12px;font-size:12px;font-weight:600;line-height:20px;transition:border-color .15s,transform .12s;display:inline-flex;position:absolute;top:64px;right:18px}.aYQbCq_badge:hover{border-color:var(--dsw-alias-line-strong);transform:translateY(-1px)}.aYQbCq_badge:active{transform:translateY(0)scale(.98)}.aYQbCq_badge:focus-visible,.aYQbCq_iconButton:focus-visible,.aYQbCq_memberRow:focus-visible,.aYQbCq_membersToggle:focus-visible,.aYQbCq_sectionToggleTitle:focus-visible,.aYQbCq_dagNode:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.aYQbCq_badgeDot,.aYQbCq_panelDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px}.aYQbCq_badgeDot[data-busy=true],.aYQbCq_panelDot[data-busy=true]{background:var(--dsw-alias-state-business-primary);animation:1.25s ease-in-out infinite aYQbCq_agentTeamsPulse}.aYQbCq_badgeCount,.aYQbCq_memberCount,.aYQbCq_teamStats,.aYQbCq_stageLabel,.aYQbCq_taskId{font-variant-numeric:tabular-nums}.aYQbCq_panel{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-line-strong) 58%, transparent);background:color-mix(in srgb, var(--dsw-alias-bg-module) 95%, transparent);backdrop-filter:blur(20px)saturate(1.08);box-shadow:0 12px 32px color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent), 0 32px 72px color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);will-change:transform;border-radius:16px;flex-direction:column;animation:.16s ease-out aYQbCq_agentTeamsPanelIn;display:flex;position:absolute;top:0;left:0;overflow:hidden}.aYQbCq_panel[data-dragging],.aYQbCq_panel[data-resizing]{user-select:none;box-shadow:0 16px 38px color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent), 0 36px 78px color-mix(in srgb, var(--dsw-alias-label-primary) 18%, transparent)}@keyframes aYQbCq_agentTeamsPanelIn{0%{opacity:0}to{opacity:1}}@keyframes aYQbCq_agentTeamsPulse{0%,to{opacity:.42}50%{opacity:1}}.aYQbCq_panelHead{border-bottom:1px solid var(--dsw-alias-line-normal);cursor:grab;touch-action:none;flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:0 14px 0 16px;display:flex}.aYQbCq_panelHead:active,.aYQbCq_panel[data-dragging] .aYQbCq_panelHead{cursor:grabbing}.aYQbCq_panel[data-compact] .aYQbCq_panelHead{cursor:default;touch-action:auto}.aYQbCq_panelTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.aYQbCq_panelControls{flex:none;align-items:center;gap:2px;display:inline-flex}.aYQbCq_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:7px;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,transform .12s;display:inline-flex}.aYQbCq_iconButton:hover{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-primary)}.aYQbCq_iconButton:active{transform:scale(.94)}.aYQbCq_iconButton[data-control=dock][data-mode=docked] svg{transform:scaleX(-1)}.aYQbCq_resizeHandle{z-index:1;touch-action:none;position:absolute}.aYQbCq_resizeHandle[data-resize-edge=left]{cursor:ew-resize;width:8px;top:44px;bottom:8px;left:0}.aYQbCq_resizeHandle[data-resize-edge=bottom]{cursor:ns-resize;height:8px;bottom:0;left:12px;right:12px}.aYQbCq_resizeHandle[data-resize-edge=corner]{cursor:nwse-resize;width:18px;height:18px;bottom:0;right:0}.aYQbCq_resizeHandle[data-resize-edge=corner]:after{border-right:1px solid var(--dsw-alias-label-tertiary);border-bottom:1px solid var(--dsw-alias-label-tertiary);content:\"\";opacity:.52;width:7px;height:7px;position:absolute;bottom:4px;right:4px}.aYQbCq_teams{overscroll-behavior:contain;scrollbar-color:color-mix(in srgb, var(--dsw-alias-label-tertiary) 28%, transparent) transparent;scrollbar-width:thin;flex-direction:column;min-height:0;display:flex;overflow-y:auto}.aYQbCq_teams::-webkit-scrollbar{width:6px}.aYQbCq_teams::-webkit-scrollbar-track{background:0 0}.aYQbCq_teams::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 28%, transparent);background-clip:padding-box;border:2px solid #0000;border-radius:999px}.aYQbCq_teams:hover::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 44%, transparent);background-clip:padding-box}.aYQbCq_team{border-bottom:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:12px;padding:12px 14px 16px;display:flex;container:aYQbCq_agent-team/inline-size}.aYQbCq_team:last-child{border-bottom:0}.aYQbCq_teamHead{align-items:center;gap:10px;min-width:0;display:flex}.aYQbCq_teamName{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;font-weight:600;line-height:18px;overflow:hidden}.aYQbCq_teamStats{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;gap:8px;font-size:10.5px;line-height:16px;display:inline-flex}.aYQbCq_teamStopButton{border:1px solid var(--dsw-alias-line-normal);width:26px;height:26px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border-radius:7px;flex:none;place-items:center;padding:0;transition:border-color .15s,background .15s,color .15s;display:grid}.aYQbCq_teamStopButton:hover{border-color:color-mix(in srgb, var(--dsw-alias-state-danger) 42%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-state-danger) 7%, transparent);color:var(--dsw-alias-state-danger)}.aYQbCq_teamStopButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.aYQbCq_stopModalActions{justify-content:flex-end;gap:8px;display:flex}.aYQbCq_stopModalActions button{border:1px solid var(--dsw-alias-line-normal,#e7e9ee);background:var(--dsw-alias-bg-fill-neutral,#eef0f4);min-height:34px;color:var(--dsw-alias-label-primary,#1c1c1e);cursor:pointer;font:inherit;border-radius:8px;justify-content:center;align-items:center;gap:6px;padding:6px 13px;font-size:12px;font-weight:600;display:inline-flex}.aYQbCq_stopModalActions button[data-danger]{border-color:var(--dsw-alias-state-danger,#e5484d);background:var(--dsw-alias-state-danger,#e5484d);color:var(--dsw-alias-label-on-fill,#fff)}.aYQbCq_stopModalActions button:disabled{cursor:wait;opacity:.58}.aYQbCq_stopModalError{background:color-mix(in srgb, var(--dsw-alias-state-danger,#e5484d) 8%, transparent);color:var(--dsw-alias-state-danger,#e5484d);border-radius:8px;align-items:flex-start;gap:7px;margin:0;padding:9px 10px;font-size:12px;line-height:18px;display:flex}.aYQbCq_stopModalError svg{flex:none;margin-top:1px}.aYQbCq_sectionHead{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}.aYQbCq_sectionTitle{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.aYQbCq_sectionHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.aYQbCq_delegationSection{min-width:0}.aYQbCq_captainNode{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 32%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-module));border-radius:10px;grid-template-columns:48px minmax(0,1fr) auto;align-items:center;gap:9px;min-height:56px;padding:6px 10px;display:grid}.aYQbCq_captainAvatar,.aYQbCq_memberAvatar{flex:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.aYQbCq_captainAvatar{width:46px;height:46px}.aYQbCq_leadAvatar,.aYQbCq_memberArt{object-fit:contain;filter:drop-shadow(0 1px 1px #122d4833);background:0 0;border:0;border-radius:0}.aYQbCq_leadAvatar{width:44px;height:44px}.aYQbCq_memberArt{width:40px;height:40px}.aYQbCq_captainInfo,.aYQbCq_memberInfo{flex-direction:column;min-width:0;display:flex}.aYQbCq_captainInfo{gap:2px}.aYQbCq_captainLine,.aYQbCq_memberLine{align-items:center;gap:6px;min-width:0;display:flex}.aYQbCq_captainName,.aYQbCq_memberName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:600;line-height:18px;overflow:hidden}.aYQbCq_captainRole,.aYQbCq_memberRole{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.aYQbCq_captainSummary,.aYQbCq_memberStatusLine{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;line-height:15px;overflow:hidden}.aYQbCq_memberModel,.aYQbCq_taskDetailModel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9.5px;line-height:14px;overflow:hidden}.aYQbCq_captainState,.aYQbCq_memberState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;align-items:center;gap:5px;font-size:10px;font-weight:500;line-height:15px;display:inline-flex}.aYQbCq_captainState[data-busy=true],.aYQbCq_memberState[data-activity=working]{color:var(--dsw-alias-state-business-primary)}.aYQbCq_workGlyph rect{opacity:.5}.aYQbCq_workGlyph[data-active=true] rect{animation:1.1s ease-in-out infinite aYQbCq_agentTeamsDot}@keyframes aYQbCq_agentTeamsDot{0%,to{opacity:.25}50%{opacity:1}}.aYQbCq_progressOverview{flex-direction:column;gap:7px;display:flex}.aYQbCq_progressTitle{color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:600;line-height:16px}.aYQbCq_progressSegments{gap:3px;display:flex}.aYQbCq_progressSegments>span,.aYQbCq_progressEmpty{background:var(--dsw-alias-line-strong);border-radius:2px;flex:1;height:5px}.aYQbCq_progressEmpty{width:100%;display:block}.aYQbCq_progressSegments>span[data-state=running]{background:var(--dsw-alias-state-business-primary)}.aYQbCq_progressSegments>span[data-state=blocked]{background:var(--dsw-alias-state-warning)}.aYQbCq_progressSegments>span[data-state=completed]{background:var(--dsw-alias-state-success)}.aYQbCq_progressSegments>span[data-state=failed]{background:var(--dsw-alias-state-danger)}.aYQbCq_progressSegments>span[data-state=cancelled]{opacity:.55}.aYQbCq_progressLegend{color:var(--dsw-alias-label-tertiary);gap:10px;font-size:9.5px;line-height:14px;display:flex}.aYQbCq_progressLegend>span[data-state=running]{color:var(--dsw-alias-state-business-primary)}.aYQbCq_progressLegend>span[data-state=blocked]{color:var(--dsw-alias-state-warning)}.aYQbCq_progressLegend>span[data-state=completed]{color:var(--dsw-alias-state-success)}.aYQbCq_progressSummary{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-module));min-width:0;color:var(--dsw-alias-label-secondary);border-radius:8px;align-items:center;gap:6px;padding:5px 8px;font-size:10px;font-weight:600;line-height:15px;display:flex}.aYQbCq_progressSummary[data-state=warning]{background:color-mix(in srgb, var(--dsw-alias-state-warning) 8%, var(--dsw-alias-bg-module))}.aYQbCq_progressSummary[data-state=completed]{background:color-mix(in srgb, var(--dsw-alias-state-success) 8%, var(--dsw-alias-bg-module))}.aYQbCq_progressSummary[data-state=discarded]{background:var(--dsw-alias-bg-fill-neutral)}.aYQbCq_progressSummary>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-business-primary);border-radius:50%;flex:none;width:5px;height:5px}.aYQbCq_progressSummary[data-state=warning] .aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-warning)}.aYQbCq_progressSummary[data-state=completed] .aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-success)}.aYQbCq_progressSummary[data-state=discarded] .aYQbCq_progressSummaryDot{background:var(--dsw-alias-label-tertiary)}.aYQbCq_membersToggle{background:var(--dsw-alias-bg-module-platform);width:100%;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border:0;border-radius:8px;justify-content:space-between;align-items:center;gap:8px;padding:6px 8px;font-size:10.5px;font-weight:600;line-height:15px;display:flex}.aYQbCq_membersToggle:hover{background:var(--dsw-alias-bg-fill-neutral)}.aYQbCq_membersToggle>span{align-items:center;gap:5px;display:inline-flex}.aYQbCq_membersToggle>span:last-child{color:var(--dsw-alias-state-business-primary)}.aYQbCq_chevron{flex:none;transition:transform .14s}.aYQbCq_chevron[data-open=true]{transform:rotate(90deg)}.aYQbCq_delegationTree{flex-direction:column;gap:2px;margin-left:18px;padding:9px 0 0 20px;display:flex;position:relative}.aYQbCq_delegationTree:before{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));content:\"\";width:1px;position:absolute;top:0;bottom:22px;left:0}.aYQbCq_memberBlock{flex-direction:column;min-width:0;padding:3px 0 7px;display:flex;position:relative}.aYQbCq_memberBranch{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));width:20px;height:1px;display:block;position:absolute;top:27px;right:100%}.aYQbCq_memberBranch:before{background:var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;width:5px;height:5px;position:absolute;top:-2px;right:-1px}.aYQbCq_memberRow{box-sizing:border-box;width:100%;min-width:0;min-height:48px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;grid-template-columns:46px minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 6px;transition:background-color .12s,transform .12s;display:grid}.aYQbCq_memberRow:hover,.aYQbCq_memberRow[data-activity=working]{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module))}.aYQbCq_memberRow:active{transform:scale(.995)}.aYQbCq_memberAvatar{width:42px;height:42px}.aYQbCq_memberAvatar[data-unread=true]:after{box-sizing:border-box;border:1px solid var(--dsw-alias-bg-module);background:var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;width:6px;height:6px;animation:1.8s ease-in-out infinite aYQbCq_agentTeamsUnreadPulse;position:absolute;top:0;right:-1px}@keyframes aYQbCq_agentTeamsUnreadPulse{0%,to{opacity:.78;transform:scale(.92)}50%{opacity:1;transform:scale(1.16)}}.aYQbCq_memberInitial{background:var(--dsw-alias-bg-fill-business);width:34px;height:34px;color:var(--dsw-alias-label-on-fill);border-radius:50%;justify-content:center;align-items:center;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.aYQbCq_stateArt{box-sizing:border-box;object-fit:contain;width:22px;height:22px;filter:drop-shadow(0 0 1px var(--dsw-alias-bg-module)) drop-shadow(0 1px 1px #122d483d);background:0 0;border:0;border-radius:0;position:absolute;bottom:-3px;right:-5px}.aYQbCq_stateArt[data-activity=working]{animation:2.4s ease-in-out infinite aYQbCq_agentTeamsFloat}.aYQbCq_stateArt[data-activity=idle]{animation:4.2s ease-in-out infinite aYQbCq_agentTeamsBreathe}.aYQbCq_stateArt[data-activity=unknown]{animation:2.8s ease-in-out infinite aYQbCq_agentTeamsThink}@keyframes aYQbCq_agentTeamsFloat{0%,to{transform:translateY(0)rotate(-4deg)}50%{transform:translateY(-2px)rotate(4deg)}}@keyframes aYQbCq_agentTeamsBreathe{0%,to{opacity:.82;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}@keyframes aYQbCq_agentTeamsThink{0%,to{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}.aYQbCq_memberState{margin-left:auto}.aYQbCq_memberCount{color:var(--dsw-alias-label-tertiary);font-size:10.5px;line-height:16px}.aYQbCq_assignmentLine{align-items:center;gap:7px;min-width:0;padding:0 6px 0 60px;display:flex}.aYQbCq_assignmentLabel{color:var(--dsw-alias-label-tertiary);flex:none;font-size:9.5px;line-height:14px}.aYQbCq_assignmentTasks{flex-wrap:wrap;flex:1;gap:4px;min-width:0;display:flex}.aYQbCq_assignmentChip{background:var(--dsw-alias-bg-fill-neutral);max-width:100%;min-height:16px;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;align-items:center;padding:0 5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;font-weight:600;line-height:14px;display:inline-flex;overflow:hidden}.aYQbCq_assignmentChip[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=cancelled]{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.aYQbCq_unreadPill{color:var(--dsw-alias-state-business-primary);white-space:nowrap;flex:none;font-size:9.5px;font-weight:600;line-height:14px}.aYQbCq_taskEmpty{color:var(--dsw-alias-label-tertiary);font-size:9.5px;line-height:14px}.aYQbCq_dependencySection{border-top:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:7px;min-width:0;padding-top:10px;display:flex}.aYQbCq_sectionToggleTitle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:0;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.aYQbCq_dagViewport{scrollbar-width:thin;min-width:0;padding:2px 0 4px;overflow-x:auto}.aYQbCq_dagCanvas{min-width:100%;position:relative}.aYQbCq_dagCanvas[data-layout=parallel]{flex-wrap:wrap;gap:8px;display:flex}.aYQbCq_dagCanvas[data-layout=parallel] .aYQbCq_dagNode{flex:92px;min-width:92px;position:relative}.aYQbCq_dagEdges{pointer-events:none;position:absolute;inset:0;overflow:visible}.aYQbCq_dagEdges path{fill:none;stroke:var(--dsw-alias-line-strong);stroke-width:1px;transition:opacity .14s,stroke .14s,stroke-width .14s}.aYQbCq_dagEdges path[data-active=true]{stroke:var(--dsw-alias-state-business-primary);stroke-width:1.6px}.aYQbCq_dagEdges path[data-dimmed=true]{opacity:.24}.aYQbCq_dagNode{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module);color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;border-radius:6px;flex-direction:column;justify-content:center;gap:1px;padding:0 6px;transition:border-color .14s,background-color .14s,opacity .14s;display:flex;position:absolute}.aYQbCq_dagNode:hover,.aYQbCq_dagNode[data-focused=true]{border-color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module))}.aYQbCq_dagNode[data-dimmed=true]{opacity:.3}.aYQbCq_dagNode[data-state=running][data-dimmed=true]{opacity:.58}.aYQbCq_dagNode[data-state=completed]{border-color:color-mix(in srgb, var(--dsw-alias-state-success) 48%, var(--dsw-alias-line-normal))}.aYQbCq_dagNode[data-state=blocked]{border-color:color-mix(in srgb, var(--dsw-alias-state-warning) 52%, var(--dsw-alias-line-normal))}.aYQbCq_dagNode[data-state=failed]{border-color:color-mix(in srgb, var(--dsw-alias-state-danger) 56%, var(--dsw-alias-line-normal))}.aYQbCq_dagNodeHead{color:var(--dsw-alias-label-primary);align-items:center;gap:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9.5px;font-weight:700;display:flex}.aYQbCq_dagNodeDot{background:var(--dsw-alias-line-strong);border-radius:1.5px;flex:none;width:5px;height:5px}.aYQbCq_dagNode[data-state=running] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-business-primary)}.aYQbCq_dagNode[data-state=running] .aYQbCq_dagNodeHead{padding-right:12px}.aYQbCq_dagRunningState{width:9px;height:9px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex;position:absolute;top:4px;right:5px}.aYQbCq_dagRunningState .aYQbCq_workGlyph{width:9px;height:9px}.aYQbCq_dagNode[data-state=blocked] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-warning)}.aYQbCq_dagNode[data-state=completed] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-success)}.aYQbCq_dagNode[data-state=failed] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-danger)}.aYQbCq_dagNodeLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:8.5px;line-height:11px;overflow:hidden}.aYQbCq_taskDetail{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module-platform);border-radius:9px;flex-direction:column;gap:3px;min-width:0;padding:7px 9px;display:flex}.aYQbCq_taskDetailHead{align-items:center;gap:6px;min-width:0;display:flex}.aYQbCq_taskDetailId{color:var(--dsw-alias-state-business-primary);flex:none;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;font-weight:700}.aYQbCq_taskDetailSubject{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:600;line-height:16px;overflow:hidden}.aYQbCq_taskDetailBadge{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 5px;font-size:8.5px;font-weight:600;line-height:14px}.aYQbCq_taskDetailBadge[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailLine,.aYQbCq_taskDetailMeta{color:var(--dsw-alias-label-secondary);font-size:9.5px;line-height:14px}.aYQbCq_taskDetailMeta{color:var(--dsw-alias-label-tertiary)}.aYQbCq_emptyHint{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:11px;line-height:16px}.aYQbCq_planEditor{border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 30%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 94%, var(--dsw-alias-state-business-primary));box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 5%, transparent);border-radius:10px;flex-direction:column;gap:12px;margin:0 10px 12px;padding:12px;display:flex}.aYQbCq_planHeader>span{justify-content:space-between;align-items:center;gap:8px;display:flex}.aYQbCq_planHeader>span>span{flex-direction:column;gap:2px;min-width:0;display:flex}.aYQbCq_planHeader strong{color:var(--dsw-alias-label-primary);font-size:12px}.aYQbCq_planHeader small{color:var(--dsw-alias-label-secondary);font-size:9px;font-weight:500;line-height:13px}.aYQbCq_planHeader em{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill);border-radius:999px;flex:none;padding:1px 7px;font-size:9px;font-style:normal;line-height:16px}.aYQbCq_planHeader p{color:var(--dsw-alias-label-secondary);margin:5px 0 0;font-size:10px;line-height:15px}.aYQbCq_planFlow{grid-template-columns:repeat(3,minmax(0,1fr));margin:0;padding:0;list-style:none;display:grid}.aYQbCq_planFlow li{min-width:0;color:var(--dsw-alias-label-tertiary);align-items:center;gap:5px;font-size:9px;font-weight:600;line-height:14px;display:flex;position:relative}.aYQbCq_planFlow li:not(:last-child):after{background:var(--dsw-alias-line-normal);content:\"\";flex:1;min-width:8px;height:1px;margin-right:5px}.aYQbCq_planFlow li>span{border:1px solid var(--dsw-alias-line-normal);border-radius:50%;flex:none;place-items:center;width:18px;height:18px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;display:grid}.aYQbCq_planFlow li[data-active]{color:var(--dsw-alias-state-business-primary)}.aYQbCq_planFlow li[data-active]>span{border-color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent)}.aYQbCq_planSection{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module-platform);border-radius:8px;overflow:hidden}.aYQbCq_planSectionToggle,.aYQbCq_planCardHeader{box-sizing:border-box;width:100%;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0}.aYQbCq_planSectionToggle{justify-content:space-between;align-items:center;gap:8px;min-height:42px;padding:7px 9px;display:flex}.aYQbCq_planSectionToggle:hover,.aYQbCq_planCardHeader:hover{background:color-mix(in srgb, var(--dsw-alias-bg-fill-neutral) 46%, transparent)}.aYQbCq_planSectionToggle>span{align-items:baseline;gap:7px;min-width:0;display:flex}.aYQbCq_planSectionToggle strong{font-size:10.5px}.aYQbCq_planSectionToggle small{color:var(--dsw-alias-label-tertiary);font-size:9px}.aYQbCq_planList{border-top:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:0;display:flex}.aYQbCq_planEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;padding:12px;font-size:10px}.aYQbCq_planCard{background:0 0;border:0;border-radius:0;min-width:0;margin:0;padding:0;display:block;position:relative}.aYQbCq_planCard+.aYQbCq_planCard{border-top:1px solid var(--dsw-alias-line-normal)}.aYQbCq_planCard[data-open=true]{background:color-mix(in srgb, var(--dsw-alias-bg-base) 62%, transparent)}.aYQbCq_planCardHeader{grid-template-columns:minmax(80px,.9fr) minmax(72px,1.15fr) auto 12px;align-items:center;gap:7px;min-height:40px;padding:6px 9px;display:grid}.aYQbCq_planCardIdentity{flex-direction:column;gap:1px;min-width:0;display:flex}.aYQbCq_planCardIdentity strong,.aYQbCq_planTaskSummary{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-weight:650;line-height:14px;overflow:hidden}.aYQbCq_planCardIdentity>span,.aYQbCq_planCardMeta{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:8.5px;line-height:12px;overflow:hidden}.aYQbCq_planTaskId{background:var(--dsw-alias-bg-fill-neutral);width:max-content;color:var(--dsw-alias-label-secondary);border-radius:4px;padding:1px 5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:8.5px;font-weight:700;line-height:14px}.aYQbCq_planDirty{background:color-mix(in srgb, var(--dsw-alias-state-warning) 13%, transparent);color:var(--dsw-alias-state-warning);border-radius:999px;justify-self:end;padding:1px 5px;font-size:8px;font-style:normal;font-weight:650;line-height:14px}.aYQbCq_planChevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .18s cubic-bezier(.2,.7,.2,1)}.aYQbCq_planChevron[data-open=true]{transform:rotate(90deg)}.aYQbCq_planCardBody{flex-direction:column;gap:8px;padding:0 9px 9px;display:flex}.aYQbCq_planCardBody fieldset{border:0;flex-direction:column;gap:7px;min-width:0;margin:0;padding:0;display:flex}.aYQbCq_planCardBody label,.aYQbCq_planNewTask label{min-width:0;color:var(--dsw-alias-label-tertiary);flex-direction:column;flex:1;gap:4px;font-size:9px;display:flex}.aYQbCq_planCardBody label small{color:var(--dsw-alias-label-tertiary);font-size:8px;line-height:11px}.aYQbCq_planCard input,.aYQbCq_planCard textarea,.aYQbCq_planCard select,.aYQbCq_planNewTask input{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-base);width:100%;min-width:0;color:var(--dsw-alias-label-primary);font:inherit;border-radius:6px;outline:none;font-size:10.5px;line-height:16px;transition:border-color .16s,box-shadow .16s}.aYQbCq_planCard input,.aYQbCq_planCard select,.aYQbCq_planNewTask input{min-height:32px;padding:6px 8px}.aYQbCq_planCard textarea{resize:vertical;min-height:58px;padding:7px 8px}.aYQbCq_planCard input:focus-visible,.aYQbCq_planCard textarea:focus-visible,.aYQbCq_planCard select:focus-visible,.aYQbCq_planNewTask input:focus-visible{border-color:var(--dsw-alias-state-business-primary);box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 16%, transparent)}.aYQbCq_planGrid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:6px;display:grid}.aYQbCq_planModelPicker{grid-template-columns:minmax(0,1fr);gap:5px;display:grid}.aYQbCq_planModelMenu{width:100%;display:flex}.aYQbCq_planModelTrigger{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:100%;min-height:38px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:7px;justify-content:space-between;align-items:center;gap:8px;padding:7px 9px;transition:border-color .16s,background-color .16s,transform .12s;display:flex}.aYQbCq_planModelTrigger:hover:not(:disabled){border-color:var(--dsw-alias-border-l3);background:var(--dsw-alias-interactive-bg-hover)}.aYQbCq_planModelTrigger:active:not(:disabled){transform:translateY(1px)}.aYQbCq_planModelTrigger:focus-visible{border-color:var(--dsw-alias-state-business-primary);outline:2px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 16%, transparent);outline-offset:1px}.aYQbCq_planModelTrigger:disabled{cursor:wait;opacity:.64}.aYQbCq_planModelTriggerCopy{align-items:baseline;gap:6px;min-width:0;display:flex}.aYQbCq_planModelTriggerCopy strong,.aYQbCq_planModelTriggerCopy span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aYQbCq_planModelTriggerCopy strong{color:var(--dsw-alias-label-primary);font-size:10px;font-weight:650;line-height:15px}.aYQbCq_planModelTriggerCopy span{color:var(--dsw-alias-label-tertiary);font-size:9px;line-height:14px}.aYQbCq_planModelMenuRow{grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;width:100%;min-width:0;display:grid}.aYQbCq_planModelMenuRow>span:first-child{color:var(--dsw-alias-label-primary)}.aYQbCq_planModelMenuRow strong{color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap;font-weight:450;overflow:hidden}.aYQbCq_planModelMenuBack{align-items:center;gap:7px;display:inline-flex}.aYQbCq_planModelMenuBack svg{transform:rotate(180deg)}.aYQbCq_planModelEffortRow{flex-direction:column;align-items:flex-start;min-width:0;display:flex}.aYQbCq_planModelEffortRow small{width:100%;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.aYQbCq_planModelHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:8.5px;line-height:12px;overflow:hidden}.aYQbCq_planModelNotice{background:color-mix(in srgb, var(--dsw-alias-state-warning) 9%, transparent);color:var(--dsw-alias-label-secondary);border-radius:6px;grid-column:1/-1;justify-content:space-between;align-items:center;gap:8px;padding:6px 7px;font-size:8.5px;line-height:12px;display:flex}.aYQbCq_planModelNotice button{color:var(--dsw-alias-state-business-primary);cursor:pointer;font:inherit;background:0 0;border:0;flex:none;padding:2px 6px;font-weight:650}.aYQbCq_planActions,.aYQbCq_planApproveRow,.aYQbCq_planNewTask,.aYQbCq_planConfirm,.aYQbCq_planApproveActions,.aYQbCq_planSecondaryActions{align-items:center;gap:7px;display:flex}.aYQbCq_planReviewActions{grid-template-columns:minmax(0,1fr);gap:6px;width:100%;display:grid}.aYQbCq_planSecondaryActions{grid-template-columns:minmax(0,1fr) auto;display:grid}.aYQbCq_planActions{justify-content:flex-end}.aYQbCq_planActions button,.aYQbCq_planNewTask button,.aYQbCq_planApproveRow button,.aYQbCq_planConfirm button{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-fill-neutral);min-height:30px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:5px 10px;font-size:9.5px;font-weight:600;transition:background .16s,border-color .16s,transform .16s}.aYQbCq_planActions button:hover:not(:disabled),.aYQbCq_planNewTask button:hover:not(:disabled),.aYQbCq_planApproveRow button:hover:not(:disabled),.aYQbCq_planConfirm button:hover:not(:disabled){border-color:var(--dsw-alias-label-tertiary)}.aYQbCq_planActions button:active:not(:disabled),.aYQbCq_planNewTask button:active:not(:disabled),.aYQbCq_planApproveRow button:active:not(:disabled),.aYQbCq_planConfirm button:active:not(:disabled){transform:scale(.98)}.aYQbCq_planActions button[data-danger],.aYQbCq_planConfirm button[data-danger]{color:var(--dsw-alias-state-danger)}.aYQbCq_planFeedback{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;align-items:center;gap:5px;font-size:9px;line-height:13px;animation:.18s ease-out aYQbCq_plan-feedback-in;display:inline-flex}.aYQbCq_planFeedback[data-tone=success]{color:var(--dsw-alias-state-success)}.aYQbCq_planFeedback[data-tone=error]{color:var(--dsw-alias-state-danger)}.aYQbCq_planFeedback>span{border:1px solid;border-radius:50%;flex:none;place-items:center;width:15px;height:15px;display:grid}.aYQbCq_planFeedback svg{width:11px;height:11px}@keyframes aYQbCq_plan-feedback-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}.aYQbCq_planConfirm{border:1px solid color-mix(in srgb, var(--dsw-alias-state-danger) 30%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-state-danger) 7%, transparent);border-radius:7px;flex-wrap:wrap;justify-content:flex-end;padding:7px}.aYQbCq_planConfirm>span{min-width:140px;color:var(--dsw-alias-label-secondary);flex:1;font-size:9px;line-height:13px}.aYQbCq_planNewTask{align-items:flex-end}.aYQbCq_planNewTask label{gap:4px}.aYQbCq_planNewTask label>span{line-height:13px}.aYQbCq_planApproveRow{z-index:1;border:1px solid var(--dsw-alias-line-normal);background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 94%, transparent);min-height:50px;box-shadow:0 -5px 16px color-mix(in srgb, var(--dsw-alias-bg-base) 35%, transparent);backdrop-filter:blur(8px);border-radius:8px;flex-direction:column;justify-content:flex-end;align-items:stretch;margin:0 -4px -4px;padding:8px;position:sticky;bottom:0}.aYQbCq_planApproveRow[data-armed=true]{border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 45%, var(--dsw-alias-line-normal))}.aYQbCq_planApproveRow[data-discard=true]{border-color:color-mix(in srgb, var(--dsw-alias-state-danger) 45%, var(--dsw-alias-line-normal))}.aYQbCq_planApproveCopy{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.aYQbCq_planApproveCopy strong{color:var(--dsw-alias-label-primary);font-size:9.5px;line-height:13px}.aYQbCq_planApproveCopy small{color:var(--dsw-alias-label-tertiary);font-size:8.5px;line-height:12px}.aYQbCq_planApproveRow button{background:var(--dsw-alias-state-business-primary);min-height:32px;color:var(--dsw-alias-label-on-fill);padding-inline:13px}.aYQbCq_planReviewActions>button[data-plan-approve]{width:100%}.aYQbCq_planApproveActions>button:first-child{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-primary)}.aYQbCq_planSecondaryActions>button,.aYQbCq_planApproveActions>button[data-danger]{border-color:var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-primary)}.aYQbCq_planSecondaryActions>button[data-danger],.aYQbCq_planApproveActions>button[data-danger]{color:var(--dsw-alias-state-danger)}.aYQbCq_planSectionToggle:focus-visible,.aYQbCq_planCardHeader:focus-visible,.aYQbCq_planActions button:focus-visible,.aYQbCq_planNewTask button:focus-visible,.aYQbCq_planApproveRow button:focus-visible,.aYQbCq_planConfirm button:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}.aYQbCq_planActions button:disabled,.aYQbCq_planNewTask button:disabled,.aYQbCq_planApproveRow button:disabled{cursor:default;opacity:.55}.aYQbCq_historicPill{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-tertiary);border-radius:4px;flex:none;margin-left:auto;padding:1px 7px;font-size:9.5px;font-weight:600;line-height:15px}.aYQbCq_members{flex-direction:column;gap:3px;display:flex}.aYQbCq_archiveLabel{color:var(--dsw-alias-label-tertiary);padding:5px 14px 0;font-size:9.5px;font-weight:600;line-height:14px;display:block}@media (prefers-reduced-motion:reduce){.aYQbCq_panel,.aYQbCq_badge,.aYQbCq_badgeDot,.aYQbCq_panelDot,.aYQbCq_workGlyph rect,.aYQbCq_stateArt,.aYQbCq_memberAvatar[data-unread=true]:after,.aYQbCq_planChevron,.aYQbCq_planFeedback,.aYQbCq_planActions button,.aYQbCq_planNewTask button,.aYQbCq_planApproveRow button,.aYQbCq_planConfirm button,.aYQbCq_planCard input,.aYQbCq_planCard textarea,.aYQbCq_planCard select,.aYQbCq_planNewTask input{transition:none;animation:none}}@media (width<=960px){html[data-agent-teams-panel-open] [data-phase=active]{padding-right:0}}@media (width<=640px){.aYQbCq_badge{top:56px;right:10px}.aYQbCq_teamStats span[data-stat=messages]{display:none}.aYQbCq_captainNode{grid-template-columns:48px minmax(0,1fr)}.aYQbCq_captainState{display:none}.aYQbCq_delegationTree{margin-left:12px;padding-left:15px}.aYQbCq_memberBranch{width:15px}.aYQbCq_assignmentLine{padding-left:53px}.aYQbCq_planFlow li{gap:4px;font-size:8px}.aYQbCq_planFlow li:not(:last-child):after{margin-right:3px}.aYQbCq_planCardHeader{grid-template-columns:auto minmax(0,1fr) auto}.aYQbCq_planCardHeader .aYQbCq_planCardMeta{display:none}.aYQbCq_planGrid,.aYQbCq_planModelPicker{grid-template-columns:minmax(0,1fr)}.aYQbCq_planNewTask,.aYQbCq_planApproveRow{flex-direction:column;align-items:stretch}.aYQbCq_planNewTask button,.aYQbCq_planApproveRow>button,.aYQbCq_planApproveActions,.aYQbCq_planReviewActions{width:100%}.aYQbCq_planApproveActions button,.aYQbCq_planReviewActions button,.aYQbCq_planSecondaryActions button{flex:1}}@container aYQbCq_agent-team (width<=360px){.aYQbCq_planEditor{margin-inline:0;padding-inline:10px}.aYQbCq_planHeader>span{align-items:flex-start}.aYQbCq_planFlow li{gap:3px;font-size:7.5px}.aYQbCq_planFlow li:not(:last-child):after{min-width:4px;margin-right:2px}.aYQbCq_planSecondaryActions,.aYQbCq_planApproveActions{grid-template-columns:minmax(0,1fr);width:100%;display:grid}.aYQbCq_planSecondaryActions button,.aYQbCq_planApproveActions button{width:100%}}";
|
|
564
|
+
const tagId = "@nanmicoder/dsh-agent-teams/ActivityPanel.module.css";
|
|
565
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
566
|
+
const tag = document.createElement("style");
|
|
567
|
+
tag.dataset.plugin = "@nanmicoder/dsh-agent-teams";
|
|
568
|
+
tag.dataset.pluginCss = tagId;
|
|
569
|
+
tag.textContent = css;
|
|
570
|
+
document.head.appendChild(tag);
|
|
571
|
+
}
|
|
572
|
+
var ActivityPanel_module_css_default = {
|
|
573
|
+
"agent-team": "aYQbCq_agent-team",
|
|
574
|
+
"agentTeamsBreathe": "aYQbCq_agentTeamsBreathe",
|
|
575
|
+
"agentTeamsDot": "aYQbCq_agentTeamsDot",
|
|
576
|
+
"agentTeamsFloat": "aYQbCq_agentTeamsFloat",
|
|
577
|
+
"agentTeamsPanelIn": "aYQbCq_agentTeamsPanelIn",
|
|
578
|
+
"agentTeamsPulse": "aYQbCq_agentTeamsPulse",
|
|
579
|
+
"agentTeamsThink": "aYQbCq_agentTeamsThink",
|
|
580
|
+
"agentTeamsUnreadPulse": "aYQbCq_agentTeamsUnreadPulse",
|
|
581
|
+
"archiveLabel": "aYQbCq_archiveLabel",
|
|
582
|
+
"assignmentChip": "aYQbCq_assignmentChip",
|
|
583
|
+
"assignmentLabel": "aYQbCq_assignmentLabel",
|
|
584
|
+
"assignmentLine": "aYQbCq_assignmentLine",
|
|
585
|
+
"assignmentTasks": "aYQbCq_assignmentTasks",
|
|
586
|
+
"badge": "aYQbCq_badge",
|
|
587
|
+
"badgeCount": "aYQbCq_badgeCount",
|
|
588
|
+
"badgeDot": "aYQbCq_badgeDot",
|
|
589
|
+
"captainAvatar": "aYQbCq_captainAvatar",
|
|
590
|
+
"captainInfo": "aYQbCq_captainInfo",
|
|
591
|
+
"captainLine": "aYQbCq_captainLine",
|
|
592
|
+
"captainName": "aYQbCq_captainName",
|
|
593
|
+
"captainNode": "aYQbCq_captainNode",
|
|
594
|
+
"captainRole": "aYQbCq_captainRole",
|
|
595
|
+
"captainState": "aYQbCq_captainState",
|
|
596
|
+
"captainSummary": "aYQbCq_captainSummary",
|
|
597
|
+
"chevron": "aYQbCq_chevron",
|
|
598
|
+
"dagCanvas": "aYQbCq_dagCanvas",
|
|
599
|
+
"dagEdges": "aYQbCq_dagEdges",
|
|
600
|
+
"dagNode": "aYQbCq_dagNode",
|
|
601
|
+
"dagNodeDot": "aYQbCq_dagNodeDot",
|
|
602
|
+
"dagNodeHead": "aYQbCq_dagNodeHead",
|
|
603
|
+
"dagNodeLabel": "aYQbCq_dagNodeLabel",
|
|
604
|
+
"dagRunningState": "aYQbCq_dagRunningState",
|
|
605
|
+
"dagViewport": "aYQbCq_dagViewport",
|
|
606
|
+
"delegationSection": "aYQbCq_delegationSection",
|
|
607
|
+
"delegationTree": "aYQbCq_delegationTree",
|
|
608
|
+
"dependencySection": "aYQbCq_dependencySection",
|
|
609
|
+
"emptyHint": "aYQbCq_emptyHint",
|
|
610
|
+
"historicPill": "aYQbCq_historicPill",
|
|
611
|
+
"iconButton": "aYQbCq_iconButton",
|
|
612
|
+
"leadAvatar": "aYQbCq_leadAvatar",
|
|
613
|
+
"memberArt": "aYQbCq_memberArt",
|
|
614
|
+
"memberAvatar": "aYQbCq_memberAvatar",
|
|
615
|
+
"memberBlock": "aYQbCq_memberBlock",
|
|
616
|
+
"memberBranch": "aYQbCq_memberBranch",
|
|
617
|
+
"memberCount": "aYQbCq_memberCount",
|
|
618
|
+
"memberInfo": "aYQbCq_memberInfo",
|
|
619
|
+
"memberInitial": "aYQbCq_memberInitial",
|
|
620
|
+
"memberLine": "aYQbCq_memberLine",
|
|
621
|
+
"memberModel": "aYQbCq_memberModel",
|
|
622
|
+
"memberName": "aYQbCq_memberName",
|
|
623
|
+
"memberRole": "aYQbCq_memberRole",
|
|
624
|
+
"memberRow": "aYQbCq_memberRow",
|
|
625
|
+
"memberState": "aYQbCq_memberState",
|
|
626
|
+
"memberStatusLine": "aYQbCq_memberStatusLine",
|
|
627
|
+
"members": "aYQbCq_members",
|
|
628
|
+
"membersToggle": "aYQbCq_membersToggle",
|
|
629
|
+
"panel": "aYQbCq_panel",
|
|
630
|
+
"panelControls": "aYQbCq_panelControls",
|
|
631
|
+
"panelDot": "aYQbCq_panelDot",
|
|
632
|
+
"panelHead": "aYQbCq_panelHead",
|
|
633
|
+
"panelTitle": "aYQbCq_panelTitle",
|
|
634
|
+
"plan-feedback-in": "aYQbCq_plan-feedback-in",
|
|
635
|
+
"planActions": "aYQbCq_planActions",
|
|
636
|
+
"planApproveActions": "aYQbCq_planApproveActions",
|
|
637
|
+
"planApproveCopy": "aYQbCq_planApproveCopy",
|
|
638
|
+
"planApproveRow": "aYQbCq_planApproveRow",
|
|
639
|
+
"planCard": "aYQbCq_planCard",
|
|
640
|
+
"planCardBody": "aYQbCq_planCardBody",
|
|
641
|
+
"planCardHeader": "aYQbCq_planCardHeader",
|
|
642
|
+
"planCardIdentity": "aYQbCq_planCardIdentity",
|
|
643
|
+
"planCardMeta": "aYQbCq_planCardMeta",
|
|
644
|
+
"planChevron": "aYQbCq_planChevron",
|
|
645
|
+
"planConfirm": "aYQbCq_planConfirm",
|
|
646
|
+
"planDirty": "aYQbCq_planDirty",
|
|
647
|
+
"planEditor": "aYQbCq_planEditor",
|
|
648
|
+
"planEmpty": "aYQbCq_planEmpty",
|
|
649
|
+
"planFeedback": "aYQbCq_planFeedback",
|
|
650
|
+
"planFlow": "aYQbCq_planFlow",
|
|
651
|
+
"planGrid": "aYQbCq_planGrid",
|
|
652
|
+
"planHeader": "aYQbCq_planHeader",
|
|
653
|
+
"planList": "aYQbCq_planList",
|
|
654
|
+
"planModelEffortRow": "aYQbCq_planModelEffortRow",
|
|
655
|
+
"planModelHint": "aYQbCq_planModelHint",
|
|
656
|
+
"planModelMenu": "aYQbCq_planModelMenu",
|
|
657
|
+
"planModelMenuBack": "aYQbCq_planModelMenuBack",
|
|
658
|
+
"planModelMenuRow": "aYQbCq_planModelMenuRow",
|
|
659
|
+
"planModelNotice": "aYQbCq_planModelNotice",
|
|
660
|
+
"planModelPicker": "aYQbCq_planModelPicker",
|
|
661
|
+
"planModelTrigger": "aYQbCq_planModelTrigger",
|
|
662
|
+
"planModelTriggerCopy": "aYQbCq_planModelTriggerCopy",
|
|
663
|
+
"planNewTask": "aYQbCq_planNewTask",
|
|
664
|
+
"planReviewActions": "aYQbCq_planReviewActions",
|
|
665
|
+
"planSecondaryActions": "aYQbCq_planSecondaryActions",
|
|
666
|
+
"planSection": "aYQbCq_planSection",
|
|
667
|
+
"planSectionToggle": "aYQbCq_planSectionToggle",
|
|
668
|
+
"planTaskId": "aYQbCq_planTaskId",
|
|
669
|
+
"planTaskSummary": "aYQbCq_planTaskSummary",
|
|
670
|
+
"progressEmpty": "aYQbCq_progressEmpty",
|
|
671
|
+
"progressLegend": "aYQbCq_progressLegend",
|
|
672
|
+
"progressOverview": "aYQbCq_progressOverview",
|
|
673
|
+
"progressSegments": "aYQbCq_progressSegments",
|
|
674
|
+
"progressSummary": "aYQbCq_progressSummary",
|
|
675
|
+
"progressSummaryDot": "aYQbCq_progressSummaryDot",
|
|
676
|
+
"progressTitle": "aYQbCq_progressTitle",
|
|
677
|
+
"resizeHandle": "aYQbCq_resizeHandle",
|
|
678
|
+
"sectionHead": "aYQbCq_sectionHead",
|
|
679
|
+
"sectionHint": "aYQbCq_sectionHint",
|
|
680
|
+
"sectionTitle": "aYQbCq_sectionTitle",
|
|
681
|
+
"sectionToggleTitle": "aYQbCq_sectionToggleTitle",
|
|
682
|
+
"stageLabel": "aYQbCq_stageLabel",
|
|
683
|
+
"stateArt": "aYQbCq_stateArt",
|
|
684
|
+
"stopModalActions": "aYQbCq_stopModalActions",
|
|
685
|
+
"stopModalError": "aYQbCq_stopModalError",
|
|
686
|
+
"taskDetail": "aYQbCq_taskDetail",
|
|
687
|
+
"taskDetailBadge": "aYQbCq_taskDetailBadge",
|
|
688
|
+
"taskDetailHead": "aYQbCq_taskDetailHead",
|
|
689
|
+
"taskDetailId": "aYQbCq_taskDetailId",
|
|
690
|
+
"taskDetailLine": "aYQbCq_taskDetailLine",
|
|
691
|
+
"taskDetailMeta": "aYQbCq_taskDetailMeta",
|
|
692
|
+
"taskDetailModel": "aYQbCq_taskDetailModel",
|
|
693
|
+
"taskDetailSubject": "aYQbCq_taskDetailSubject",
|
|
694
|
+
"taskEmpty": "aYQbCq_taskEmpty",
|
|
695
|
+
"taskId": "aYQbCq_taskId",
|
|
696
|
+
"team": "aYQbCq_team",
|
|
697
|
+
"teamHead": "aYQbCq_teamHead",
|
|
698
|
+
"teamName": "aYQbCq_teamName",
|
|
699
|
+
"teamStats": "aYQbCq_teamStats",
|
|
700
|
+
"teamStopButton": "aYQbCq_teamStopButton",
|
|
701
|
+
"teams": "aYQbCq_teams",
|
|
702
|
+
"unreadPill": "aYQbCq_unreadPill",
|
|
703
|
+
"workGlyph": "aYQbCq_workGlyph"
|
|
704
|
+
};
|
|
705
|
+
//#endregion
|
|
706
|
+
//#region lib/client/StagingPlanEditor.js
|
|
707
|
+
/**
|
|
708
|
+
* Editable pre-run roster and DAG review for staged AgentTeams plans.
|
|
709
|
+
*
|
|
710
|
+
* This leaf owns only transient form/disclosure state. Durable truth remains
|
|
711
|
+
* on the host and returns through the ordinary activity polling snapshot.
|
|
712
|
+
* @module dsh-agent-teams/client/staging-plan
|
|
713
|
+
*/
|
|
714
|
+
const PLAN_URL = "/plugins/dsh-agent-teams/plan";
|
|
715
|
+
function useDismissSuccess(feedback, setFeedback) {
|
|
716
|
+
(0, react.useEffect)(() => {
|
|
717
|
+
if (feedback?.tone !== "success") return;
|
|
718
|
+
const timeout = window.setTimeout(() => {
|
|
719
|
+
setFeedback(void 0);
|
|
720
|
+
}, 3500);
|
|
721
|
+
return () => {
|
|
722
|
+
window.clearTimeout(timeout);
|
|
723
|
+
};
|
|
724
|
+
}, [feedback, setFeedback]);
|
|
725
|
+
}
|
|
726
|
+
async function mutatePlan(payload) {
|
|
727
|
+
const response = await fetch(PLAN_URL, {
|
|
728
|
+
method: "POST",
|
|
729
|
+
cache: "no-store",
|
|
730
|
+
headers: { "content-type": "application/json" },
|
|
731
|
+
body: JSON.stringify(payload)
|
|
732
|
+
});
|
|
733
|
+
if (response.ok) return;
|
|
734
|
+
let message = `HTTP ${response.status}`;
|
|
735
|
+
try {
|
|
736
|
+
const body = await response.json();
|
|
737
|
+
if (typeof body.error === "string" && body.error.trim() !== "") message = body.error;
|
|
738
|
+
} catch {}
|
|
739
|
+
throw new Error(message);
|
|
740
|
+
}
|
|
741
|
+
function errorMessage(error) {
|
|
742
|
+
return error instanceof Error ? error.message : String(error);
|
|
743
|
+
}
|
|
744
|
+
function DisclosureChevron({ open }) {
|
|
745
|
+
return (0, react_jsx_runtime.jsx)("svg", {
|
|
746
|
+
className: ActivityPanel_module_css_default.planChevron,
|
|
747
|
+
"data-open": open,
|
|
748
|
+
width: "12",
|
|
749
|
+
height: "12",
|
|
750
|
+
viewBox: "0 0 12 12",
|
|
751
|
+
fill: "none",
|
|
752
|
+
stroke: "currentColor",
|
|
753
|
+
strokeWidth: "1.5",
|
|
754
|
+
strokeLinecap: "round",
|
|
755
|
+
"aria-hidden": true,
|
|
756
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: "M4 2.5 7.5 6 4 9.5" })
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
function Feedback({ value }) {
|
|
760
|
+
if (value === void 0) return null;
|
|
761
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
762
|
+
className: ActivityPanel_module_css_default.planFeedback,
|
|
763
|
+
"data-tone": value.tone,
|
|
764
|
+
role: value.tone === "error" ? "alert" : "status",
|
|
765
|
+
"aria-live": value.tone === "error" ? "assertive" : "polite",
|
|
766
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
767
|
+
"aria-hidden": true,
|
|
768
|
+
children: value.tone === "success" ? (0, react_jsx_runtime.jsx)("svg", {
|
|
769
|
+
viewBox: "0 0 12 12",
|
|
770
|
+
fill: "none",
|
|
771
|
+
stroke: "currentColor",
|
|
772
|
+
strokeWidth: "1.8",
|
|
773
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: "m2.5 6.2 2.2 2.2 4.8-5" })
|
|
774
|
+
}) : (0, react_jsx_runtime.jsx)("svg", {
|
|
775
|
+
viewBox: "0 0 12 12",
|
|
776
|
+
fill: "none",
|
|
777
|
+
stroke: "currentColor",
|
|
778
|
+
strokeWidth: "1.8",
|
|
779
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: "M6 2.3v4.1M6 8.8v.1" })
|
|
780
|
+
})
|
|
781
|
+
}), value.message]
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
function routeKey(provider, model) {
|
|
785
|
+
return JSON.stringify([provider, model]);
|
|
786
|
+
}
|
|
787
|
+
const MODEL_MENU_OPEN_MODELS = "open:models";
|
|
788
|
+
const MODEL_MENU_OPEN_EFFORT = "open:effort";
|
|
789
|
+
const MODEL_MENU_BACK = "navigate:back";
|
|
790
|
+
const MODEL_MENU_RETRY = "action:retry";
|
|
791
|
+
const MODEL_MENU_DEFAULT_EFFORT = "effort:default";
|
|
792
|
+
function modelMenuId(provider, model) {
|
|
793
|
+
return `model:${routeKey(provider, model)}`;
|
|
794
|
+
}
|
|
795
|
+
function effortMenuId(effort) {
|
|
796
|
+
return `effort:${effort}`;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Thin staged-plan adapter over the official model directory. It deliberately
|
|
800
|
+
* reads only catalog metadata: choosing a member route must not change the
|
|
801
|
+
* captain session's composer model.
|
|
802
|
+
*/
|
|
803
|
+
function StagedModelPicker({ directory, provider, model, reasoningEffort, busy, onChange, t }) {
|
|
804
|
+
const state = (0, react.useSyncExternalStore)(directory.store.subscribe, directory.store.getSnapshot);
|
|
805
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
806
|
+
const [pane, setPane] = (0, react.useState)("root");
|
|
807
|
+
const catalogRoutes = state.groups.flatMap((group) => group.models.map((candidate) => ({
|
|
808
|
+
key: routeKey(group.id, candidate.id),
|
|
809
|
+
provider: group.id,
|
|
810
|
+
providerName: group.name,
|
|
811
|
+
model: candidate
|
|
812
|
+
})));
|
|
813
|
+
const selectedKey = routeKey(provider, model);
|
|
814
|
+
const selected = catalogRoutes.find((candidate) => candidate.key === selectedKey);
|
|
815
|
+
const efforts = selected?.model.reasoning?.efforts ?? [];
|
|
816
|
+
const currentMissing = provider !== "" && model !== "" && selected === void 0;
|
|
817
|
+
const defaultEffort = selected?.model.reasoning?.defaultEffort;
|
|
818
|
+
const effectiveEffort = reasoningEffort === "" || reasoningEffort === "default" ? defaultEffort : reasoningEffort;
|
|
819
|
+
const selectedEffort = efforts.find((effort) => effort.id === effectiveEffort);
|
|
820
|
+
const modelLabel = selected?.model.name ?? (model === "" ? t("plan.model.choose") : model);
|
|
821
|
+
const effortLabel = selectedEffort?.name ?? (effectiveEffort === void 0 ? t("plan.model.providerDefault") : effectiveEffort);
|
|
822
|
+
const unavailable = state.status === "error" || state.failures.length > 0;
|
|
823
|
+
const close = () => {
|
|
824
|
+
setOpen(false);
|
|
825
|
+
setPane("root");
|
|
826
|
+
};
|
|
827
|
+
const rootItems = [{
|
|
828
|
+
id: MODEL_MENU_OPEN_MODELS,
|
|
829
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
830
|
+
className: ActivityPanel_module_css_default.planModelMenuRow,
|
|
831
|
+
children: [
|
|
832
|
+
(0, react_jsx_runtime.jsx)("span", { children: t("plan.member.model") }),
|
|
833
|
+
(0, react_jsx_runtime.jsx)("strong", { children: modelLabel }),
|
|
834
|
+
(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false })
|
|
835
|
+
]
|
|
836
|
+
}),
|
|
837
|
+
disabled: state.status === "loading" && catalogRoutes.length === 0
|
|
838
|
+
}, {
|
|
839
|
+
id: MODEL_MENU_OPEN_EFFORT,
|
|
840
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
841
|
+
className: ActivityPanel_module_css_default.planModelMenuRow,
|
|
842
|
+
children: [
|
|
843
|
+
(0, react_jsx_runtime.jsx)("span", { children: t("plan.member.reasoning") }),
|
|
844
|
+
(0, react_jsx_runtime.jsx)("strong", { children: effortLabel }),
|
|
845
|
+
(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false })
|
|
846
|
+
]
|
|
847
|
+
}),
|
|
848
|
+
disabled: selected?.model.reasoning === void 0
|
|
849
|
+
}];
|
|
850
|
+
const modelItems = [{
|
|
851
|
+
id: MODEL_MENU_BACK,
|
|
852
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
853
|
+
className: ActivityPanel_module_css_default.planModelMenuBack,
|
|
854
|
+
children: [(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false }), t("plan.model.back")]
|
|
855
|
+
})
|
|
856
|
+
}, {
|
|
857
|
+
type: "separator",
|
|
858
|
+
id: "models:separator"
|
|
859
|
+
}];
|
|
860
|
+
if (catalogRoutes.length === 0) modelItems.push({
|
|
861
|
+
id: "models:empty",
|
|
862
|
+
label: state.status === "loading" ? t("plan.model.loading") : t("plan.model.empty"),
|
|
863
|
+
disabled: true
|
|
864
|
+
});
|
|
865
|
+
else for (const group of state.groups) {
|
|
866
|
+
modelItems.push({
|
|
867
|
+
type: "label",
|
|
868
|
+
id: `provider:${group.id}`,
|
|
869
|
+
text: group.name
|
|
870
|
+
});
|
|
871
|
+
for (const candidate of group.models) modelItems.push({
|
|
872
|
+
id: modelMenuId(group.id, candidate.id),
|
|
873
|
+
label: candidate.name
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
const effortItems = [
|
|
877
|
+
{
|
|
878
|
+
id: MODEL_MENU_BACK,
|
|
879
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
880
|
+
className: ActivityPanel_module_css_default.planModelMenuBack,
|
|
881
|
+
children: [(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false }), t("plan.model.back")]
|
|
882
|
+
})
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
type: "separator",
|
|
886
|
+
id: "effort:separator"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
id: MODEL_MENU_DEFAULT_EFFORT,
|
|
890
|
+
label: defaultEffort === void 0 ? t("plan.model.providerDefault") : t("plan.model.modelDefault", { effort: efforts.find((effort) => effort.id === defaultEffort)?.name ?? defaultEffort })
|
|
891
|
+
},
|
|
892
|
+
...efforts.map((effort) => ({
|
|
893
|
+
id: effortMenuId(effort.id),
|
|
894
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
895
|
+
className: ActivityPanel_module_css_default.planModelEffortRow,
|
|
896
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: effort.name }), effort.description !== void 0 && (0, react_jsx_runtime.jsx)("small", { children: effort.description })]
|
|
897
|
+
})
|
|
898
|
+
}))
|
|
899
|
+
];
|
|
900
|
+
const items = pane === "models" ? modelItems : pane === "effort" ? effortItems : rootItems;
|
|
901
|
+
const selectedId = pane === "models" ? modelMenuId(provider, model) : pane === "effort" ? reasoningEffort === "" || reasoningEffort === "default" ? MODEL_MENU_DEFAULT_EFFORT : effortMenuId(reasoningEffort) : void 0;
|
|
902
|
+
const choose = (id) => {
|
|
903
|
+
if (id === MODEL_MENU_OPEN_MODELS) {
|
|
904
|
+
setPane("models");
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
if (id === MODEL_MENU_OPEN_EFFORT) {
|
|
908
|
+
setPane("effort");
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
if (id === MODEL_MENU_BACK) {
|
|
912
|
+
setPane("root");
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
if (id === MODEL_MENU_RETRY) {
|
|
916
|
+
directory.load().catch(() => void 0);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
const nextModel = catalogRoutes.find((candidate) => modelMenuId(candidate.provider, candidate.model.id) === id);
|
|
920
|
+
if (nextModel !== void 0) {
|
|
921
|
+
close();
|
|
922
|
+
if (nextModel.provider === provider && nextModel.model.id === model) return;
|
|
923
|
+
onChange({
|
|
924
|
+
provider: nextModel.provider,
|
|
925
|
+
model: nextModel.model.id,
|
|
926
|
+
reasoningEffort: "default"
|
|
927
|
+
});
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
if (id === MODEL_MENU_DEFAULT_EFFORT) {
|
|
931
|
+
close();
|
|
932
|
+
if (effectiveEffort === defaultEffort) return;
|
|
933
|
+
onChange({
|
|
934
|
+
provider,
|
|
935
|
+
model,
|
|
936
|
+
reasoningEffort: "default"
|
|
937
|
+
});
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const nextEffort = efforts.find((effort) => effortMenuId(effort.id) === id);
|
|
941
|
+
if (nextEffort === void 0) return;
|
|
942
|
+
close();
|
|
943
|
+
if (nextEffort.id === reasoningEffort) return;
|
|
944
|
+
onChange({
|
|
945
|
+
provider,
|
|
946
|
+
model,
|
|
947
|
+
reasoningEffort: nextEffort.id
|
|
948
|
+
});
|
|
949
|
+
};
|
|
950
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
951
|
+
className: ActivityPanel_module_css_default.planModelPicker,
|
|
952
|
+
"data-model-directory-status": state.status,
|
|
953
|
+
children: [
|
|
954
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
955
|
+
open,
|
|
956
|
+
portal: true,
|
|
957
|
+
align: "end",
|
|
958
|
+
compact: true,
|
|
959
|
+
className: ActivityPanel_module_css_default.planModelMenu,
|
|
960
|
+
items,
|
|
961
|
+
footer: unavailable ? [{
|
|
962
|
+
id: MODEL_MENU_RETRY,
|
|
963
|
+
label: t("plan.model.retry")
|
|
964
|
+
}] : void 0,
|
|
965
|
+
selectedId,
|
|
966
|
+
onSelect: choose,
|
|
967
|
+
onClose: close,
|
|
968
|
+
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
969
|
+
type: "button",
|
|
970
|
+
className: ActivityPanel_module_css_default.planModelTrigger,
|
|
971
|
+
"data-plan-model-trigger": true,
|
|
972
|
+
"aria-label": t("plan.model.triggerAria", {
|
|
973
|
+
model: modelLabel,
|
|
974
|
+
effort: effortLabel
|
|
975
|
+
}),
|
|
976
|
+
"aria-haspopup": "menu",
|
|
977
|
+
"aria-expanded": open,
|
|
978
|
+
disabled: busy,
|
|
979
|
+
onClick: () => {
|
|
980
|
+
if (open) close();
|
|
981
|
+
else {
|
|
982
|
+
setPane("root");
|
|
983
|
+
setOpen(true);
|
|
984
|
+
directory.load().catch(() => void 0);
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
988
|
+
className: ActivityPanel_module_css_default.planModelTriggerCopy,
|
|
989
|
+
children: [(0, react_jsx_runtime.jsx)("strong", { children: state.status === "loading" && catalogRoutes.length === 0 ? t("plan.model.loading") : modelLabel }), (0, react_jsx_runtime.jsx)("span", { children: effortLabel })]
|
|
990
|
+
}), (0, react_jsx_runtime.jsx)(DisclosureChevron, { open })]
|
|
991
|
+
})
|
|
992
|
+
}),
|
|
993
|
+
(0, react_jsx_runtime.jsx)("small", {
|
|
994
|
+
className: ActivityPanel_module_css_default.planModelHint,
|
|
995
|
+
children: currentMissing ? t("plan.model.currentUnavailable", {
|
|
996
|
+
provider,
|
|
997
|
+
model
|
|
998
|
+
}) : selected?.model.description ?? t("plan.model.route", {
|
|
999
|
+
provider,
|
|
1000
|
+
model
|
|
1001
|
+
})
|
|
1002
|
+
}),
|
|
1003
|
+
unavailable && (0, react_jsx_runtime.jsxs)("span", {
|
|
1004
|
+
className: ActivityPanel_module_css_default.planModelNotice,
|
|
1005
|
+
role: state.status === "error" ? "alert" : "status",
|
|
1006
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: state.error ?? t("plan.model.partialFailure", { count: state.failures.length }) }), (0, react_jsx_runtime.jsx)("button", {
|
|
1007
|
+
type: "button",
|
|
1008
|
+
disabled: busy || state.status === "loading",
|
|
1009
|
+
onClick: () => {
|
|
1010
|
+
directory.load().catch(() => void 0);
|
|
1011
|
+
},
|
|
1012
|
+
children: t("plan.model.retry")
|
|
1013
|
+
})]
|
|
1014
|
+
})
|
|
1015
|
+
]
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
function StagedMemberEditor({ team, member, modelDirectory, onPendingChange, t }) {
|
|
1019
|
+
const bodyId = (0, react.useId)();
|
|
1020
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
1021
|
+
const [role, setRole] = (0, react.useState)(member.role);
|
|
1022
|
+
const [provider, setProvider] = (0, react.useState)(member.provider ?? "");
|
|
1023
|
+
const [model, setModel] = (0, react.useState)(member.model ?? "");
|
|
1024
|
+
const [reasoningEffort, setReasoningEffort] = (0, react.useState)(member.reasoningEffort ?? "");
|
|
1025
|
+
const [executionPrompt, setExecutionPrompt] = (0, react.useState)(member.executionPrompt ?? "");
|
|
1026
|
+
const remoteSignature = JSON.stringify([
|
|
1027
|
+
member.role,
|
|
1028
|
+
member.provider ?? "",
|
|
1029
|
+
member.model ?? "",
|
|
1030
|
+
member.reasoningEffort ?? "",
|
|
1031
|
+
member.executionPrompt ?? ""
|
|
1032
|
+
]);
|
|
1033
|
+
const [savedSignature, setSavedSignature] = (0, react.useState)(remoteSignature);
|
|
1034
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
1035
|
+
const [feedback, setFeedback] = (0, react.useState)();
|
|
1036
|
+
useDismissSuccess(feedback, setFeedback);
|
|
1037
|
+
const dirty = JSON.stringify([
|
|
1038
|
+
role,
|
|
1039
|
+
provider,
|
|
1040
|
+
model,
|
|
1041
|
+
reasoningEffort,
|
|
1042
|
+
executionPrompt
|
|
1043
|
+
]) !== savedSignature;
|
|
1044
|
+
(0, react.useEffect)(() => {
|
|
1045
|
+
onPendingChange(`member:${member.name}`, dirty || busy);
|
|
1046
|
+
return () => {
|
|
1047
|
+
onPendingChange(`member:${member.name}`, false);
|
|
1048
|
+
};
|
|
1049
|
+
}, [
|
|
1050
|
+
busy,
|
|
1051
|
+
dirty,
|
|
1052
|
+
member.name,
|
|
1053
|
+
onPendingChange
|
|
1054
|
+
]);
|
|
1055
|
+
(0, react.useEffect)(() => {
|
|
1056
|
+
setRole(member.role);
|
|
1057
|
+
setProvider(member.provider ?? "");
|
|
1058
|
+
setModel(member.model ?? "");
|
|
1059
|
+
setReasoningEffort(member.reasoningEffort ?? "");
|
|
1060
|
+
setExecutionPrompt(member.executionPrompt ?? "");
|
|
1061
|
+
setSavedSignature(remoteSignature);
|
|
1062
|
+
}, [
|
|
1063
|
+
member.role,
|
|
1064
|
+
member.provider,
|
|
1065
|
+
member.model,
|
|
1066
|
+
member.reasoningEffort,
|
|
1067
|
+
member.executionPrompt,
|
|
1068
|
+
remoteSignature
|
|
1069
|
+
]);
|
|
1070
|
+
const markEdited = () => {
|
|
1071
|
+
setFeedback(void 0);
|
|
1072
|
+
};
|
|
1073
|
+
const persist = async (selection = {
|
|
1074
|
+
provider,
|
|
1075
|
+
model,
|
|
1076
|
+
reasoningEffort
|
|
1077
|
+
}) => {
|
|
1078
|
+
const nextSignature = JSON.stringify([
|
|
1079
|
+
role,
|
|
1080
|
+
selection.provider,
|
|
1081
|
+
selection.model,
|
|
1082
|
+
selection.reasoningEffort,
|
|
1083
|
+
executionPrompt
|
|
1084
|
+
]);
|
|
1085
|
+
setProvider(selection.provider);
|
|
1086
|
+
setModel(selection.model);
|
|
1087
|
+
setReasoningEffort(selection.reasoningEffort);
|
|
1088
|
+
setBusy(true);
|
|
1089
|
+
setFeedback(void 0);
|
|
1090
|
+
try {
|
|
1091
|
+
await mutatePlan({
|
|
1092
|
+
sessionId: team.captainSessionId,
|
|
1093
|
+
teamId: team.teamId,
|
|
1094
|
+
action: "update_member",
|
|
1095
|
+
memberName: member.name,
|
|
1096
|
+
role,
|
|
1097
|
+
provider: selection.provider,
|
|
1098
|
+
model: selection.model,
|
|
1099
|
+
reasoningEffort: selection.reasoningEffort,
|
|
1100
|
+
executionPrompt
|
|
1101
|
+
});
|
|
1102
|
+
setSavedSignature(nextSignature);
|
|
1103
|
+
setFeedback({
|
|
1104
|
+
tone: "success",
|
|
1105
|
+
message: t("plan.saved")
|
|
1106
|
+
});
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
setFeedback({
|
|
1109
|
+
tone: "error",
|
|
1110
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1111
|
+
});
|
|
1112
|
+
} finally {
|
|
1113
|
+
setBusy(false);
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
const save = async (event) => {
|
|
1117
|
+
event.preventDefault();
|
|
1118
|
+
await persist();
|
|
1119
|
+
};
|
|
1120
|
+
const route = `${provider}/${model}`.replace(/^\//u, "");
|
|
1121
|
+
return (0, react_jsx_runtime.jsxs)("article", {
|
|
1122
|
+
className: ActivityPanel_module_css_default.planCard,
|
|
1123
|
+
"data-plan-member": member.name,
|
|
1124
|
+
"data-open": open,
|
|
1125
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
1126
|
+
type: "button",
|
|
1127
|
+
className: ActivityPanel_module_css_default.planCardHeader,
|
|
1128
|
+
"aria-expanded": open,
|
|
1129
|
+
"aria-controls": bodyId,
|
|
1130
|
+
onClick: () => {
|
|
1131
|
+
setOpen((current) => !current);
|
|
1132
|
+
},
|
|
1133
|
+
children: [
|
|
1134
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1135
|
+
className: ActivityPanel_module_css_default.planCardIdentity,
|
|
1136
|
+
children: [(0, react_jsx_runtime.jsx)("strong", { children: member.name }), (0, react_jsx_runtime.jsx)("span", { children: role || t("plan.member.roleFallback") })]
|
|
1137
|
+
}),
|
|
1138
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1139
|
+
className: ActivityPanel_module_css_default.planCardMeta,
|
|
1140
|
+
title: route,
|
|
1141
|
+
children: route
|
|
1142
|
+
}),
|
|
1143
|
+
dirty && (0, react_jsx_runtime.jsx)("em", {
|
|
1144
|
+
className: ActivityPanel_module_css_default.planDirty,
|
|
1145
|
+
children: t("plan.unsaved")
|
|
1146
|
+
}),
|
|
1147
|
+
(0, react_jsx_runtime.jsx)(DisclosureChevron, { open })
|
|
1148
|
+
]
|
|
1149
|
+
}), open && (0, react_jsx_runtime.jsxs)("form", {
|
|
1150
|
+
id: bodyId,
|
|
1151
|
+
className: ActivityPanel_module_css_default.planCardBody,
|
|
1152
|
+
onSubmit: (event) => {
|
|
1153
|
+
save(event);
|
|
1154
|
+
},
|
|
1155
|
+
children: [(0, react_jsx_runtime.jsxs)("fieldset", {
|
|
1156
|
+
disabled: busy,
|
|
1157
|
+
children: [
|
|
1158
|
+
(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.member.role"), (0, react_jsx_runtime.jsx)("input", {
|
|
1159
|
+
name: "role",
|
|
1160
|
+
value: role,
|
|
1161
|
+
onChange: (event) => {
|
|
1162
|
+
setRole(event.currentTarget.value);
|
|
1163
|
+
markEdited();
|
|
1164
|
+
}
|
|
1165
|
+
})] }),
|
|
1166
|
+
(0, react_jsx_runtime.jsx)(StagedModelPicker, {
|
|
1167
|
+
directory: modelDirectory,
|
|
1168
|
+
provider,
|
|
1169
|
+
model,
|
|
1170
|
+
reasoningEffort,
|
|
1171
|
+
busy,
|
|
1172
|
+
onChange: (selection) => {
|
|
1173
|
+
persist(selection);
|
|
1174
|
+
},
|
|
1175
|
+
t
|
|
1176
|
+
}),
|
|
1177
|
+
(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.member.prompt"), (0, react_jsx_runtime.jsx)("textarea", {
|
|
1178
|
+
name: "executionPrompt",
|
|
1179
|
+
value: executionPrompt,
|
|
1180
|
+
onChange: (event) => {
|
|
1181
|
+
setExecutionPrompt(event.currentTarget.value);
|
|
1182
|
+
markEdited();
|
|
1183
|
+
},
|
|
1184
|
+
rows: 3
|
|
1185
|
+
})] })
|
|
1186
|
+
]
|
|
1187
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
1188
|
+
className: ActivityPanel_module_css_default.planActions,
|
|
1189
|
+
children: [(0, react_jsx_runtime.jsx)(Feedback, { value: feedback }), (0, react_jsx_runtime.jsx)("button", {
|
|
1190
|
+
type: "submit",
|
|
1191
|
+
disabled: busy || !dirty || provider.trim() === "" || model.trim() === "",
|
|
1192
|
+
children: busy ? t("plan.saving") : t("plan.save")
|
|
1193
|
+
})]
|
|
1194
|
+
})]
|
|
1195
|
+
})]
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
function StagedTaskEditor({ team, task, onPendingChange, t }) {
|
|
1199
|
+
const bodyId = (0, react.useId)();
|
|
1200
|
+
const taskDependencies = task.dependencies.join(", ");
|
|
1201
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
1202
|
+
const [subject, setSubject] = (0, react.useState)(task.subject);
|
|
1203
|
+
const [description, setDescription] = (0, react.useState)(task.description ?? "");
|
|
1204
|
+
const [assignee, setAssignee] = (0, react.useState)(task.assignee);
|
|
1205
|
+
const [dependencies, setDependencies] = (0, react.useState)(taskDependencies);
|
|
1206
|
+
const remoteSignature = JSON.stringify([
|
|
1207
|
+
task.subject,
|
|
1208
|
+
task.description ?? "",
|
|
1209
|
+
task.assignee,
|
|
1210
|
+
taskDependencies
|
|
1211
|
+
]);
|
|
1212
|
+
const [savedSignature, setSavedSignature] = (0, react.useState)(remoteSignature);
|
|
1213
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
1214
|
+
const [confirmingRemove, setConfirmingRemove] = (0, react.useState)(false);
|
|
1215
|
+
const [feedback, setFeedback] = (0, react.useState)();
|
|
1216
|
+
useDismissSuccess(feedback, setFeedback);
|
|
1217
|
+
const signature = JSON.stringify([
|
|
1218
|
+
subject,
|
|
1219
|
+
description,
|
|
1220
|
+
assignee,
|
|
1221
|
+
dependencies
|
|
1222
|
+
]);
|
|
1223
|
+
const dirty = signature !== savedSignature;
|
|
1224
|
+
(0, react.useEffect)(() => {
|
|
1225
|
+
onPendingChange(`task:${task.id}`, dirty || busy);
|
|
1226
|
+
return () => {
|
|
1227
|
+
onPendingChange(`task:${task.id}`, false);
|
|
1228
|
+
};
|
|
1229
|
+
}, [
|
|
1230
|
+
busy,
|
|
1231
|
+
dirty,
|
|
1232
|
+
onPendingChange,
|
|
1233
|
+
task.id
|
|
1234
|
+
]);
|
|
1235
|
+
(0, react.useEffect)(() => {
|
|
1236
|
+
setSubject(task.subject);
|
|
1237
|
+
setDescription(task.description ?? "");
|
|
1238
|
+
setAssignee(task.assignee);
|
|
1239
|
+
setDependencies(taskDependencies);
|
|
1240
|
+
setSavedSignature(remoteSignature);
|
|
1241
|
+
}, [
|
|
1242
|
+
task.subject,
|
|
1243
|
+
task.description,
|
|
1244
|
+
task.assignee,
|
|
1245
|
+
taskDependencies,
|
|
1246
|
+
remoteSignature
|
|
1247
|
+
]);
|
|
1248
|
+
const markEdited = () => {
|
|
1249
|
+
setFeedback(void 0);
|
|
1250
|
+
setConfirmingRemove(false);
|
|
1251
|
+
};
|
|
1252
|
+
const save = async (event) => {
|
|
1253
|
+
event.preventDefault();
|
|
1254
|
+
setBusy(true);
|
|
1255
|
+
setFeedback(void 0);
|
|
1256
|
+
try {
|
|
1257
|
+
await mutatePlan({
|
|
1258
|
+
sessionId: team.captainSessionId,
|
|
1259
|
+
teamId: team.teamId,
|
|
1260
|
+
action: "update_task",
|
|
1261
|
+
taskId: task.id,
|
|
1262
|
+
subject,
|
|
1263
|
+
description,
|
|
1264
|
+
assignee,
|
|
1265
|
+
dependencies: dependencies.split(",").map((item) => item.trim()).filter(Boolean)
|
|
1266
|
+
});
|
|
1267
|
+
setSavedSignature(signature);
|
|
1268
|
+
setFeedback({
|
|
1269
|
+
tone: "success",
|
|
1270
|
+
message: t("plan.saved")
|
|
1271
|
+
});
|
|
1272
|
+
} catch (error) {
|
|
1273
|
+
setFeedback({
|
|
1274
|
+
tone: "error",
|
|
1275
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1276
|
+
});
|
|
1277
|
+
} finally {
|
|
1278
|
+
setBusy(false);
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
const remove = async () => {
|
|
1282
|
+
setBusy(true);
|
|
1283
|
+
setFeedback(void 0);
|
|
1284
|
+
try {
|
|
1285
|
+
await mutatePlan({
|
|
1286
|
+
sessionId: team.captainSessionId,
|
|
1287
|
+
teamId: team.teamId,
|
|
1288
|
+
action: "remove_task",
|
|
1289
|
+
taskId: task.id
|
|
1290
|
+
});
|
|
1291
|
+
setFeedback({
|
|
1292
|
+
tone: "success",
|
|
1293
|
+
message: t("plan.removed")
|
|
1294
|
+
});
|
|
1295
|
+
} catch (error) {
|
|
1296
|
+
setFeedback({
|
|
1297
|
+
tone: "error",
|
|
1298
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1299
|
+
});
|
|
1300
|
+
setBusy(false);
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
const dependencySummary = task.dependencies.length === 0 ? t("plan.dependencies.none") : t("plan.dependencies.count", { count: task.dependencies.length });
|
|
1304
|
+
return (0, react_jsx_runtime.jsxs)("article", {
|
|
1305
|
+
className: ActivityPanel_module_css_default.planCard,
|
|
1306
|
+
"data-plan-task": task.id,
|
|
1307
|
+
"data-open": open,
|
|
1308
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
1309
|
+
type: "button",
|
|
1310
|
+
className: ActivityPanel_module_css_default.planCardHeader,
|
|
1311
|
+
"aria-expanded": open,
|
|
1312
|
+
"aria-controls": bodyId,
|
|
1313
|
+
onClick: () => {
|
|
1314
|
+
setOpen((current) => !current);
|
|
1315
|
+
},
|
|
1316
|
+
children: [
|
|
1317
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1318
|
+
className: ActivityPanel_module_css_default.planTaskId,
|
|
1319
|
+
children: task.id
|
|
1320
|
+
}),
|
|
1321
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1322
|
+
className: ActivityPanel_module_css_default.planTaskSummary,
|
|
1323
|
+
title: subject,
|
|
1324
|
+
children: subject
|
|
1325
|
+
}),
|
|
1326
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1327
|
+
className: ActivityPanel_module_css_default.planCardMeta,
|
|
1328
|
+
children: [
|
|
1329
|
+
assignee || t("plan.task.unassigned"),
|
|
1330
|
+
" · ",
|
|
1331
|
+
dependencySummary
|
|
1332
|
+
]
|
|
1333
|
+
}),
|
|
1334
|
+
dirty && (0, react_jsx_runtime.jsx)("em", {
|
|
1335
|
+
className: ActivityPanel_module_css_default.planDirty,
|
|
1336
|
+
children: t("plan.unsaved")
|
|
1337
|
+
}),
|
|
1338
|
+
(0, react_jsx_runtime.jsx)(DisclosureChevron, { open })
|
|
1339
|
+
]
|
|
1340
|
+
}), open && (0, react_jsx_runtime.jsxs)("form", {
|
|
1341
|
+
id: bodyId,
|
|
1342
|
+
className: ActivityPanel_module_css_default.planCardBody,
|
|
1343
|
+
onSubmit: (event) => {
|
|
1344
|
+
save(event);
|
|
1345
|
+
},
|
|
1346
|
+
children: [
|
|
1347
|
+
(0, react_jsx_runtime.jsxs)("fieldset", {
|
|
1348
|
+
disabled: busy,
|
|
1349
|
+
children: [
|
|
1350
|
+
(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.subject"), (0, react_jsx_runtime.jsx)("input", {
|
|
1351
|
+
name: "subject",
|
|
1352
|
+
required: true,
|
|
1353
|
+
value: subject,
|
|
1354
|
+
onChange: (event) => {
|
|
1355
|
+
setSubject(event.currentTarget.value);
|
|
1356
|
+
markEdited();
|
|
1357
|
+
}
|
|
1358
|
+
})] }),
|
|
1359
|
+
(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.description"), (0, react_jsx_runtime.jsx)("textarea", {
|
|
1360
|
+
name: "description",
|
|
1361
|
+
value: description,
|
|
1362
|
+
onChange: (event) => {
|
|
1363
|
+
setDescription(event.currentTarget.value);
|
|
1364
|
+
markEdited();
|
|
1365
|
+
},
|
|
1366
|
+
rows: 3
|
|
1367
|
+
})] }),
|
|
1368
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1369
|
+
className: ActivityPanel_module_css_default.planGrid,
|
|
1370
|
+
children: [(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.assignee"), (0, react_jsx_runtime.jsxs)("select", {
|
|
1371
|
+
name: "assignee",
|
|
1372
|
+
value: assignee,
|
|
1373
|
+
onChange: (event) => {
|
|
1374
|
+
setAssignee(event.currentTarget.value);
|
|
1375
|
+
markEdited();
|
|
1376
|
+
},
|
|
1377
|
+
children: [(0, react_jsx_runtime.jsx)("option", {
|
|
1378
|
+
value: "",
|
|
1379
|
+
children: t("plan.task.unassigned")
|
|
1380
|
+
}), team.members.map((member) => (0, react_jsx_runtime.jsx)("option", {
|
|
1381
|
+
value: member.name,
|
|
1382
|
+
children: member.name
|
|
1383
|
+
}, member.name))]
|
|
1384
|
+
})] }), (0, react_jsx_runtime.jsxs)("label", { children: [
|
|
1385
|
+
t("plan.task.dependencies"),
|
|
1386
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
1387
|
+
name: "dependencies",
|
|
1388
|
+
value: dependencies,
|
|
1389
|
+
onChange: (event) => {
|
|
1390
|
+
setDependencies(event.currentTarget.value);
|
|
1391
|
+
markEdited();
|
|
1392
|
+
}
|
|
1393
|
+
}),
|
|
1394
|
+
(0, react_jsx_runtime.jsx)("small", { children: t("plan.task.dependenciesHint") })
|
|
1395
|
+
] })]
|
|
1396
|
+
})
|
|
1397
|
+
]
|
|
1398
|
+
}),
|
|
1399
|
+
confirmingRemove && (0, react_jsx_runtime.jsxs)("span", {
|
|
1400
|
+
className: ActivityPanel_module_css_default.planConfirm,
|
|
1401
|
+
role: "alert",
|
|
1402
|
+
children: [
|
|
1403
|
+
(0, react_jsx_runtime.jsx)("span", { children: t("plan.removeWarning", { task: task.id }) }),
|
|
1404
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
1405
|
+
type: "button",
|
|
1406
|
+
onClick: () => {
|
|
1407
|
+
setConfirmingRemove(false);
|
|
1408
|
+
},
|
|
1409
|
+
children: t("plan.cancel")
|
|
1410
|
+
}),
|
|
1411
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
1412
|
+
type: "button",
|
|
1413
|
+
"data-danger": true,
|
|
1414
|
+
"data-confirming": true,
|
|
1415
|
+
onClick: () => {
|
|
1416
|
+
remove();
|
|
1417
|
+
},
|
|
1418
|
+
children: t("plan.removeConfirm")
|
|
1419
|
+
})
|
|
1420
|
+
]
|
|
1421
|
+
}),
|
|
1422
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1423
|
+
className: ActivityPanel_module_css_default.planActions,
|
|
1424
|
+
children: [
|
|
1425
|
+
(0, react_jsx_runtime.jsx)(Feedback, { value: feedback }),
|
|
1426
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
1427
|
+
type: "button",
|
|
1428
|
+
"data-danger": true,
|
|
1429
|
+
onClick: () => {
|
|
1430
|
+
setConfirmingRemove(true);
|
|
1431
|
+
setFeedback(void 0);
|
|
1432
|
+
},
|
|
1433
|
+
disabled: busy || confirmingRemove,
|
|
1434
|
+
children: t("plan.remove")
|
|
1435
|
+
}),
|
|
1436
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
1437
|
+
type: "submit",
|
|
1438
|
+
disabled: busy || !dirty || subject.trim() === "",
|
|
1439
|
+
children: busy ? t("plan.saving") : t("plan.save")
|
|
1440
|
+
})
|
|
1441
|
+
]
|
|
1442
|
+
})
|
|
1443
|
+
]
|
|
1444
|
+
})]
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
function StagingPlanEditor({ team, modelDirectory, onContinuePlanning, onDiscarded, t }) {
|
|
1448
|
+
const membersId = (0, react.useId)();
|
|
1449
|
+
const tasksId = (0, react.useId)();
|
|
1450
|
+
const [membersOpen, setMembersOpen] = (0, react.useState)(true);
|
|
1451
|
+
const [tasksOpen, setTasksOpen] = (0, react.useState)(true);
|
|
1452
|
+
const [newTask, setNewTask] = (0, react.useState)("");
|
|
1453
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
1454
|
+
const [discardArmed, setDiscardArmed] = (0, react.useState)(false);
|
|
1455
|
+
const [pendingEditors, setPendingEditors] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
1456
|
+
const [feedback, setFeedback] = (0, react.useState)();
|
|
1457
|
+
useDismissSuccess(feedback, setFeedback);
|
|
1458
|
+
const dependencyLinks = team.tasks.reduce((total, task) => total + task.dependencies.length, 0);
|
|
1459
|
+
const runnable = team.members.length > 0 && team.tasks.length > 0;
|
|
1460
|
+
const hasPendingEdits = pendingEditors.size > 0 || newTask.trim() !== "";
|
|
1461
|
+
const waitingForFeedback = team.planReviewState === "awaiting_feedback";
|
|
1462
|
+
(0, react.useEffect)(() => {
|
|
1463
|
+
modelDirectory.load().catch(() => void 0);
|
|
1464
|
+
}, [modelDirectory]);
|
|
1465
|
+
const onPendingChange = (0, react.useCallback)((key, pending) => {
|
|
1466
|
+
setPendingEditors((current) => {
|
|
1467
|
+
if (pending === current.has(key)) return current;
|
|
1468
|
+
const next = new Set(current);
|
|
1469
|
+
if (pending) next.add(key);
|
|
1470
|
+
else next.delete(key);
|
|
1471
|
+
return next;
|
|
1472
|
+
});
|
|
1473
|
+
}, []);
|
|
1474
|
+
const addTask = async (event) => {
|
|
1475
|
+
event.preventDefault();
|
|
1476
|
+
setBusy(true);
|
|
1477
|
+
setFeedback(void 0);
|
|
1478
|
+
try {
|
|
1479
|
+
await mutatePlan({
|
|
1480
|
+
sessionId: team.captainSessionId,
|
|
1481
|
+
teamId: team.teamId,
|
|
1482
|
+
action: "add_task",
|
|
1483
|
+
subject: newTask,
|
|
1484
|
+
dependencies: []
|
|
1485
|
+
});
|
|
1486
|
+
setNewTask("");
|
|
1487
|
+
setFeedback({
|
|
1488
|
+
tone: "success",
|
|
1489
|
+
message: t("plan.taskAdded")
|
|
1490
|
+
});
|
|
1491
|
+
setTasksOpen(true);
|
|
1492
|
+
} catch (error) {
|
|
1493
|
+
setFeedback({
|
|
1494
|
+
tone: "error",
|
|
1495
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1496
|
+
});
|
|
1497
|
+
} finally {
|
|
1498
|
+
setBusy(false);
|
|
1499
|
+
}
|
|
1500
|
+
};
|
|
1501
|
+
const approve = async () => {
|
|
1502
|
+
setBusy(true);
|
|
1503
|
+
setFeedback(void 0);
|
|
1504
|
+
try {
|
|
1505
|
+
await mutatePlan({
|
|
1506
|
+
sessionId: team.captainSessionId,
|
|
1507
|
+
teamId: team.teamId,
|
|
1508
|
+
action: "approve"
|
|
1509
|
+
});
|
|
1510
|
+
} catch (error) {
|
|
1511
|
+
setFeedback({
|
|
1512
|
+
tone: "error",
|
|
1513
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1514
|
+
});
|
|
1515
|
+
setBusy(false);
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
const continueInChat = async () => {
|
|
1519
|
+
if (waitingForFeedback) {
|
|
1520
|
+
onContinuePlanning();
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
setBusy(true);
|
|
1524
|
+
setFeedback(void 0);
|
|
1525
|
+
try {
|
|
1526
|
+
await mutatePlan({
|
|
1527
|
+
sessionId: team.captainSessionId,
|
|
1528
|
+
teamId: team.teamId,
|
|
1529
|
+
action: "continue"
|
|
1530
|
+
});
|
|
1531
|
+
onContinuePlanning();
|
|
1532
|
+
} catch (error) {
|
|
1533
|
+
setFeedback({
|
|
1534
|
+
tone: "error",
|
|
1535
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1536
|
+
});
|
|
1537
|
+
setBusy(false);
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1540
|
+
const discard = async () => {
|
|
1541
|
+
setBusy(true);
|
|
1542
|
+
setFeedback(void 0);
|
|
1543
|
+
try {
|
|
1544
|
+
await mutatePlan({
|
|
1545
|
+
sessionId: team.captainSessionId,
|
|
1546
|
+
teamId: team.teamId,
|
|
1547
|
+
action: "discard"
|
|
1548
|
+
});
|
|
1549
|
+
onDiscarded();
|
|
1550
|
+
} catch (error) {
|
|
1551
|
+
setFeedback({
|
|
1552
|
+
tone: "error",
|
|
1553
|
+
message: t("plan.failed", { message: errorMessage(error) })
|
|
1554
|
+
});
|
|
1555
|
+
setBusy(false);
|
|
1556
|
+
setDiscardArmed(false);
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1559
|
+
return (0, react_jsx_runtime.jsxs)("section", {
|
|
1560
|
+
className: ActivityPanel_module_css_default.planEditor,
|
|
1561
|
+
"data-staging-editor": true,
|
|
1562
|
+
children: [
|
|
1563
|
+
(0, react_jsx_runtime.jsxs)("header", {
|
|
1564
|
+
className: ActivityPanel_module_css_default.planHeader,
|
|
1565
|
+
children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: t("plan.title") }), (0, react_jsx_runtime.jsx)("small", { children: t("plan.readySummary", {
|
|
1566
|
+
members: team.members.length,
|
|
1567
|
+
tasks: team.tasks.length,
|
|
1568
|
+
links: dependencyLinks
|
|
1569
|
+
}) })] }), (0, react_jsx_runtime.jsx)("em", { children: t("plan.badge") })] }), (0, react_jsx_runtime.jsx)("p", { children: t("plan.description") })]
|
|
1570
|
+
}),
|
|
1571
|
+
(0, react_jsx_runtime.jsxs)("ol", {
|
|
1572
|
+
className: ActivityPanel_module_css_default.planFlow,
|
|
1573
|
+
"aria-label": t("plan.flow.aria"),
|
|
1574
|
+
children: [
|
|
1575
|
+
(0, react_jsx_runtime.jsxs)("li", {
|
|
1576
|
+
"data-active": true,
|
|
1577
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: "1" }), t("plan.flow.review")]
|
|
1578
|
+
}),
|
|
1579
|
+
(0, react_jsx_runtime.jsxs)("li", { children: [(0, react_jsx_runtime.jsx)("span", { children: "2" }), t("plan.flow.spawn")] }),
|
|
1580
|
+
(0, react_jsx_runtime.jsxs)("li", { children: [(0, react_jsx_runtime.jsx)("span", { children: "3" }), t("plan.flow.run")] })
|
|
1581
|
+
]
|
|
1582
|
+
}),
|
|
1583
|
+
(0, react_jsx_runtime.jsxs)("section", {
|
|
1584
|
+
className: ActivityPanel_module_css_default.planSection,
|
|
1585
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
1586
|
+
type: "button",
|
|
1587
|
+
className: ActivityPanel_module_css_default.planSectionToggle,
|
|
1588
|
+
"aria-expanded": membersOpen,
|
|
1589
|
+
"aria-controls": membersId,
|
|
464
1590
|
onClick: () => {
|
|
465
|
-
|
|
1591
|
+
setMembersOpen((current) => !current);
|
|
466
1592
|
},
|
|
467
|
-
"
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
1593
|
+
children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: t("plan.members.title") }), (0, react_jsx_runtime.jsx)("small", { children: t("plan.members.count", { count: team.members.length }) })] }), (0, react_jsx_runtime.jsx)(DisclosureChevron, { open: membersOpen })]
|
|
1594
|
+
}), membersOpen && (0, react_jsx_runtime.jsx)("div", {
|
|
1595
|
+
id: membersId,
|
|
1596
|
+
className: ActivityPanel_module_css_default.planList,
|
|
1597
|
+
children: team.members.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
1598
|
+
className: ActivityPanel_module_css_default.planEmpty,
|
|
1599
|
+
children: t("plan.members.empty")
|
|
1600
|
+
}) : team.members.map((member) => (0, react_jsx_runtime.jsx)(StagedMemberEditor, {
|
|
1601
|
+
team,
|
|
1602
|
+
member,
|
|
1603
|
+
modelDirectory,
|
|
1604
|
+
onPendingChange,
|
|
1605
|
+
t
|
|
1606
|
+
}, member.name))
|
|
1607
|
+
})]
|
|
1608
|
+
}),
|
|
1609
|
+
(0, react_jsx_runtime.jsxs)("section", {
|
|
1610
|
+
className: ActivityPanel_module_css_default.planSection,
|
|
1611
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
1612
|
+
type: "button",
|
|
1613
|
+
className: ActivityPanel_module_css_default.planSectionToggle,
|
|
1614
|
+
"aria-expanded": tasksOpen,
|
|
1615
|
+
"aria-controls": tasksId,
|
|
1616
|
+
onClick: () => {
|
|
1617
|
+
setTasksOpen((current) => !current);
|
|
1618
|
+
},
|
|
1619
|
+
children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: t("plan.tasks.title") }), (0, react_jsx_runtime.jsx)("small", { children: t("plan.tasks.count", {
|
|
1620
|
+
count: team.tasks.length,
|
|
1621
|
+
links: dependencyLinks
|
|
1622
|
+
}) })] }), (0, react_jsx_runtime.jsx)(DisclosureChevron, { open: tasksOpen })]
|
|
1623
|
+
}), tasksOpen && (0, react_jsx_runtime.jsx)("div", {
|
|
1624
|
+
id: tasksId,
|
|
1625
|
+
className: ActivityPanel_module_css_default.planList,
|
|
1626
|
+
children: team.tasks.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
1627
|
+
className: ActivityPanel_module_css_default.planEmpty,
|
|
1628
|
+
children: t("plan.tasks.empty")
|
|
1629
|
+
}) : team.tasks.map((task) => (0, react_jsx_runtime.jsx)(StagedTaskEditor, {
|
|
1630
|
+
team,
|
|
1631
|
+
task,
|
|
1632
|
+
onPendingChange,
|
|
1633
|
+
t
|
|
1634
|
+
}, task.id))
|
|
1635
|
+
})]
|
|
1636
|
+
}),
|
|
1637
|
+
(0, react_jsx_runtime.jsxs)("form", {
|
|
1638
|
+
className: ActivityPanel_module_css_default.planNewTask,
|
|
1639
|
+
onSubmit: (event) => {
|
|
1640
|
+
addTask(event);
|
|
479
1641
|
},
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}), (0, react_jsx_runtime.jsx)("
|
|
490
|
-
|
|
491
|
-
|
|
1642
|
+
children: [(0, react_jsx_runtime.jsxs)("label", { children: [(0, react_jsx_runtime.jsx)("span", { children: t("plan.newTaskLabel") }), (0, react_jsx_runtime.jsx)("input", {
|
|
1643
|
+
name: "newTask",
|
|
1644
|
+
value: newTask,
|
|
1645
|
+
onChange: (event) => {
|
|
1646
|
+
setNewTask(event.currentTarget.value);
|
|
1647
|
+
setFeedback(void 0);
|
|
1648
|
+
},
|
|
1649
|
+
placeholder: t("plan.newTask"),
|
|
1650
|
+
disabled: busy
|
|
1651
|
+
})] }), (0, react_jsx_runtime.jsx)("button", {
|
|
1652
|
+
type: "submit",
|
|
1653
|
+
disabled: busy || newTask.trim() === "",
|
|
1654
|
+
children: busy ? t("plan.adding") : t("plan.addTask")
|
|
492
1655
|
})]
|
|
493
|
-
},
|
|
494
|
-
|
|
1656
|
+
}),
|
|
1657
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1658
|
+
className: ActivityPanel_module_css_default.planApproveRow,
|
|
1659
|
+
"data-armed": discardArmed || void 0,
|
|
1660
|
+
"data-discard": discardArmed || void 0,
|
|
1661
|
+
"data-review-state": waitingForFeedback ? "awaiting-feedback" : "awaiting-review",
|
|
1662
|
+
children: [
|
|
1663
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1664
|
+
className: ActivityPanel_module_css_default.planApproveCopy,
|
|
1665
|
+
children: [(0, react_jsx_runtime.jsx)("strong", { children: discardArmed ? t("plan.discardConfirmTitle") : waitingForFeedback ? t("plan.feedbackTitle") : t("plan.approveTitle") }), (0, react_jsx_runtime.jsx)("small", { children: discardArmed ? t("plan.discardWarning") : waitingForFeedback ? t("plan.feedbackHint") : hasPendingEdits ? t("plan.pendingEdits") : t("plan.approveHint", {
|
|
1666
|
+
members: team.members.length,
|
|
1667
|
+
tasks: team.tasks.length
|
|
1668
|
+
}) })]
|
|
1669
|
+
}),
|
|
1670
|
+
(0, react_jsx_runtime.jsx)(Feedback, { value: feedback }),
|
|
1671
|
+
discardArmed ? (0, react_jsx_runtime.jsxs)("span", {
|
|
1672
|
+
className: ActivityPanel_module_css_default.planApproveActions,
|
|
1673
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1674
|
+
type: "button",
|
|
1675
|
+
disabled: busy,
|
|
1676
|
+
onClick: () => {
|
|
1677
|
+
setDiscardArmed(false);
|
|
1678
|
+
},
|
|
1679
|
+
children: t("plan.cancel")
|
|
1680
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
1681
|
+
type: "button",
|
|
1682
|
+
"data-plan-discard": true,
|
|
1683
|
+
"data-danger": true,
|
|
1684
|
+
"data-confirming": true,
|
|
1685
|
+
disabled: busy,
|
|
1686
|
+
onClick: () => {
|
|
1687
|
+
discard();
|
|
1688
|
+
},
|
|
1689
|
+
children: busy ? t("plan.discarding") : t("plan.discardConfirm")
|
|
1690
|
+
})]
|
|
1691
|
+
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
1692
|
+
className: ActivityPanel_module_css_default.planReviewActions,
|
|
1693
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1694
|
+
type: "button",
|
|
1695
|
+
"data-plan-approve": true,
|
|
1696
|
+
disabled: busy || !runnable || hasPendingEdits,
|
|
1697
|
+
onClick: () => {
|
|
1698
|
+
approve();
|
|
1699
|
+
},
|
|
1700
|
+
children: t("plan.approve")
|
|
1701
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
1702
|
+
className: ActivityPanel_module_css_default.planSecondaryActions,
|
|
1703
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1704
|
+
type: "button",
|
|
1705
|
+
"data-plan-continue": true,
|
|
1706
|
+
disabled: busy,
|
|
1707
|
+
onClick: () => {
|
|
1708
|
+
continueInChat();
|
|
1709
|
+
},
|
|
1710
|
+
children: t(waitingForFeedback ? "plan.returnToChat" : "plan.continue")
|
|
1711
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
1712
|
+
type: "button",
|
|
1713
|
+
"data-plan-discard": true,
|
|
1714
|
+
"data-danger": true,
|
|
1715
|
+
disabled: busy,
|
|
1716
|
+
onClick: () => {
|
|
1717
|
+
setDiscardArmed(true);
|
|
1718
|
+
setFeedback(void 0);
|
|
1719
|
+
},
|
|
1720
|
+
children: t("plan.discard")
|
|
1721
|
+
})]
|
|
1722
|
+
})]
|
|
1723
|
+
})
|
|
1724
|
+
]
|
|
1725
|
+
})
|
|
1726
|
+
]
|
|
495
1727
|
});
|
|
496
1728
|
}
|
|
497
1729
|
//#endregion
|
|
@@ -649,108 +1881,6 @@ window.__ModuleLoader__.load({
|
|
|
649
1881
|
};
|
|
650
1882
|
}
|
|
651
1883
|
//#endregion
|
|
652
|
-
//#region \0dsh-css:/home/runner/work/dsh-agent-teams/dsh-agent-teams/src/client/ActivityPanel.module.css.mjs
|
|
653
|
-
const css = "html{--agent-teams-panel-shift:420px}html[data-agent-teams-panel-open] [data-phase=active]{box-sizing:border-box;padding-right:var(--agent-teams-panel-shift)}.aYQbCq_badge,.aYQbCq_panel{--dsw-alias-line-normal:var(--dsw-static-neutral-bluish-150,#e7e9ee);--dsw-alias-line-strong:color-mix(in srgb, var(--dsw-static-neutral-bluish-200,#e1e5ee) 50%, var(--dsw-static-neutral-bluish-300,#cfd3d6));--dsw-alias-bg-module:var(--dsw-alias-bg-layer-1,#fff);--dsw-alias-bg-fill-neutral:var(--dsw-static-neutral-bluish-100,#eef0f4);--dsw-alias-bg-fill-business:var(--dsw-alias-state-business-primary,#4d6bfe);--dsw-alias-bg-fill-success:var(--dsw-alias-state-success-primary,#12a150);--dsw-alias-bg-fill-warning:var(--dsw-alias-state-warn-primary,#e08700);--dsw-alias-bg-fill-danger:var(--dsw-alias-state-error-primary,#e5484d);--dsw-alias-state-success:var(--dsw-alias-state-success-primary,#12a150);--dsw-alias-state-warning:var(--dsw-alias-state-warn-primary,#e08700);--dsw-alias-state-danger:var(--dsw-alias-state-error-primary,#e5484d);--dsw-alias-label-on-fill:var(--dsw-alias-label-primary-inverted,#fff)}.aYQbCq_badge{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 92%, transparent);backdrop-filter:blur(16px);height:34px;box-shadow:0 8px 28px color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;align-items:center;gap:7px;padding:0 12px;font-size:12px;font-weight:600;line-height:20px;transition:border-color .15s,transform .12s;display:inline-flex;position:absolute;top:64px;right:18px}.aYQbCq_badge:hover{border-color:var(--dsw-alias-line-strong);transform:translateY(-1px)}.aYQbCq_badge:active{transform:translateY(0)scale(.98)}.aYQbCq_badge:focus-visible,.aYQbCq_iconButton:focus-visible,.aYQbCq_memberRow:focus-visible,.aYQbCq_membersToggle:focus-visible,.aYQbCq_sectionToggleTitle:focus-visible,.aYQbCq_dagNode:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.aYQbCq_badgeDot,.aYQbCq_panelDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px}.aYQbCq_badgeDot[data-busy=true],.aYQbCq_panelDot[data-busy=true]{background:var(--dsw-alias-state-business-primary);animation:1.25s ease-in-out infinite aYQbCq_agentTeamsPulse}.aYQbCq_badgeCount,.aYQbCq_memberCount,.aYQbCq_teamStats,.aYQbCq_stageLabel,.aYQbCq_taskId{font-variant-numeric:tabular-nums}.aYQbCq_panel{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-line-strong) 58%, transparent);background:color-mix(in srgb, var(--dsw-alias-bg-module) 95%, transparent);backdrop-filter:blur(20px)saturate(1.08);box-shadow:0 12px 32px color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent), 0 32px 72px color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);will-change:transform;border-radius:16px;flex-direction:column;animation:.16s ease-out aYQbCq_agentTeamsPanelIn;display:flex;position:absolute;top:0;left:0;overflow:hidden}.aYQbCq_panel[data-dragging],.aYQbCq_panel[data-resizing]{user-select:none;box-shadow:0 16px 38px color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent), 0 36px 78px color-mix(in srgb, var(--dsw-alias-label-primary) 18%, transparent)}@keyframes aYQbCq_agentTeamsPanelIn{0%{opacity:0}to{opacity:1}}@keyframes aYQbCq_agentTeamsPulse{0%,to{opacity:.42}50%{opacity:1}}.aYQbCq_panelHead{border-bottom:1px solid var(--dsw-alias-line-normal);cursor:grab;touch-action:none;flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:0 14px 0 16px;display:flex}.aYQbCq_panelHead:active,.aYQbCq_panel[data-dragging] .aYQbCq_panelHead{cursor:grabbing}.aYQbCq_panel[data-compact] .aYQbCq_panelHead{cursor:default;touch-action:auto}.aYQbCq_panelTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.aYQbCq_panelControls{flex:none;align-items:center;gap:2px;display:inline-flex}.aYQbCq_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:7px;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,transform .12s;display:inline-flex}.aYQbCq_iconButton:hover{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-primary)}.aYQbCq_iconButton:active{transform:scale(.94)}.aYQbCq_iconButton[data-control=dock][data-mode=docked] svg{transform:scaleX(-1)}.aYQbCq_resizeHandle{z-index:1;touch-action:none;position:absolute}.aYQbCq_resizeHandle[data-resize-edge=left]{cursor:ew-resize;width:8px;top:44px;bottom:8px;left:0}.aYQbCq_resizeHandle[data-resize-edge=bottom]{cursor:ns-resize;height:8px;bottom:0;left:12px;right:12px}.aYQbCq_resizeHandle[data-resize-edge=corner]{cursor:nwse-resize;width:18px;height:18px;bottom:0;right:0}.aYQbCq_resizeHandle[data-resize-edge=corner]:after{border-right:1px solid var(--dsw-alias-label-tertiary);border-bottom:1px solid var(--dsw-alias-label-tertiary);content:\"\";opacity:.52;width:7px;height:7px;position:absolute;bottom:4px;right:4px}.aYQbCq_teams{overscroll-behavior:contain;scrollbar-color:color-mix(in srgb, var(--dsw-alias-label-tertiary) 28%, transparent) transparent;scrollbar-width:thin;flex-direction:column;min-height:0;display:flex;overflow-y:auto}.aYQbCq_teams::-webkit-scrollbar{width:6px}.aYQbCq_teams::-webkit-scrollbar-track{background:0 0}.aYQbCq_teams::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 28%, transparent);background-clip:padding-box;border:2px solid #0000;border-radius:999px}.aYQbCq_teams:hover::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 44%, transparent);background-clip:padding-box}.aYQbCq_team{border-bottom:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:12px;padding:12px 14px 16px;display:flex}.aYQbCq_team:last-child{border-bottom:0}.aYQbCq_teamHead{align-items:center;gap:10px;min-width:0;display:flex}.aYQbCq_teamName{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;font-weight:600;line-height:18px;overflow:hidden}.aYQbCq_teamStats{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;gap:8px;font-size:10.5px;line-height:16px;display:inline-flex}.aYQbCq_sectionHead{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}.aYQbCq_sectionTitle{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.aYQbCq_sectionHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.aYQbCq_delegationSection{min-width:0}.aYQbCq_captainNode{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 32%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-module));border-radius:10px;grid-template-columns:48px minmax(0,1fr) auto;align-items:center;gap:9px;min-height:56px;padding:6px 10px;display:grid}.aYQbCq_captainAvatar,.aYQbCq_memberAvatar{flex:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.aYQbCq_captainAvatar{width:46px;height:46px}.aYQbCq_leadAvatar,.aYQbCq_memberArt{object-fit:contain;filter:drop-shadow(0 1px 1px #122d4833);background:0 0;border:0;border-radius:0}.aYQbCq_leadAvatar{width:44px;height:44px}.aYQbCq_memberArt{width:40px;height:40px}.aYQbCq_captainInfo,.aYQbCq_memberInfo{flex-direction:column;min-width:0;display:flex}.aYQbCq_captainInfo{gap:2px}.aYQbCq_captainLine,.aYQbCq_memberLine{align-items:center;gap:6px;min-width:0;display:flex}.aYQbCq_captainName,.aYQbCq_memberName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:600;line-height:18px;overflow:hidden}.aYQbCq_captainRole,.aYQbCq_memberRole{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.aYQbCq_captainSummary,.aYQbCq_memberStatusLine{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;line-height:15px;overflow:hidden}.aYQbCq_captainState,.aYQbCq_memberState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;align-items:center;gap:5px;font-size:10px;font-weight:500;line-height:15px;display:inline-flex}.aYQbCq_captainState[data-busy=true],.aYQbCq_memberState[data-activity=working]{color:var(--dsw-alias-state-business-primary)}.aYQbCq_workGlyph rect{opacity:.5}.aYQbCq_workGlyph[data-active=true] rect{animation:1.1s ease-in-out infinite aYQbCq_agentTeamsDot}@keyframes aYQbCq_agentTeamsDot{0%,to{opacity:.25}50%{opacity:1}}.aYQbCq_progressOverview{flex-direction:column;gap:7px;display:flex}.aYQbCq_progressTitle{color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:600;line-height:16px}.aYQbCq_progressSegments{gap:3px;display:flex}.aYQbCq_progressSegments>span,.aYQbCq_progressEmpty{background:var(--dsw-alias-line-strong);border-radius:2px;flex:1;height:5px}.aYQbCq_progressEmpty{width:100%;display:block}.aYQbCq_progressSegments>span[data-state=running]{background:var(--dsw-alias-state-business-primary)}.aYQbCq_progressSegments>span[data-state=blocked]{background:var(--dsw-alias-state-warning)}.aYQbCq_progressSegments>span[data-state=completed]{background:var(--dsw-alias-state-success)}.aYQbCq_progressSegments>span[data-state=failed]{background:var(--dsw-alias-state-danger)}.aYQbCq_progressSegments>span[data-state=cancelled]{opacity:.55}.aYQbCq_progressLegend{color:var(--dsw-alias-label-tertiary);gap:10px;font-size:9.5px;line-height:14px;display:flex}.aYQbCq_progressLegend>span[data-state=running]{color:var(--dsw-alias-state-business-primary)}.aYQbCq_progressLegend>span[data-state=blocked]{color:var(--dsw-alias-state-warning)}.aYQbCq_progressLegend>span[data-state=completed]{color:var(--dsw-alias-state-success)}.aYQbCq_progressSummary{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-module));min-width:0;color:var(--dsw-alias-label-secondary);border-radius:8px;align-items:center;gap:6px;padding:5px 8px;font-size:10px;font-weight:600;line-height:15px;display:flex}.aYQbCq_progressSummary[data-state=warning]{background:color-mix(in srgb, var(--dsw-alias-state-warning) 8%, var(--dsw-alias-bg-module))}.aYQbCq_progressSummary[data-state=completed]{background:color-mix(in srgb, var(--dsw-alias-state-success) 8%, var(--dsw-alias-bg-module))}.aYQbCq_progressSummary>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-business-primary);border-radius:50%;flex:none;width:5px;height:5px}.aYQbCq_progressSummary[data-state=warning] .aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-warning)}.aYQbCq_progressSummary[data-state=completed] .aYQbCq_progressSummaryDot{background:var(--dsw-alias-state-success)}.aYQbCq_membersToggle{background:var(--dsw-alias-bg-module-platform);width:100%;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border:0;border-radius:8px;justify-content:space-between;align-items:center;gap:8px;padding:6px 8px;font-size:10.5px;font-weight:600;line-height:15px;display:flex}.aYQbCq_membersToggle:hover{background:var(--dsw-alias-bg-fill-neutral)}.aYQbCq_membersToggle>span{align-items:center;gap:5px;display:inline-flex}.aYQbCq_membersToggle>span:last-child{color:var(--dsw-alias-state-business-primary)}.aYQbCq_chevron{flex:none;transition:transform .14s}.aYQbCq_chevron[data-open=true]{transform:rotate(90deg)}.aYQbCq_delegationTree{flex-direction:column;gap:2px;margin-left:18px;padding:9px 0 0 20px;display:flex;position:relative}.aYQbCq_delegationTree:before{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));content:\"\";width:1px;position:absolute;top:0;bottom:22px;left:0}.aYQbCq_memberBlock{flex-direction:column;min-width:0;padding:3px 0 7px;display:flex;position:relative}.aYQbCq_memberBranch{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));width:20px;height:1px;display:block;position:absolute;top:27px;right:100%}.aYQbCq_memberBranch:before{background:var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;width:5px;height:5px;position:absolute;top:-2px;right:-1px}.aYQbCq_memberRow{box-sizing:border-box;width:100%;min-width:0;min-height:48px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;grid-template-columns:46px minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 6px;transition:background-color .12s,transform .12s;display:grid}.aYQbCq_memberRow:hover,.aYQbCq_memberRow[data-activity=working]{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module))}.aYQbCq_memberRow:active{transform:scale(.995)}.aYQbCq_memberAvatar{width:42px;height:42px}.aYQbCq_memberAvatar[data-unread=true]:after{box-sizing:border-box;border:1px solid var(--dsw-alias-bg-module);background:var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;width:6px;height:6px;animation:1.8s ease-in-out infinite aYQbCq_agentTeamsUnreadPulse;position:absolute;top:0;right:-1px}@keyframes aYQbCq_agentTeamsUnreadPulse{0%,to{opacity:.78;transform:scale(.92)}50%{opacity:1;transform:scale(1.16)}}.aYQbCq_memberInitial{background:var(--dsw-alias-bg-fill-business);width:34px;height:34px;color:var(--dsw-alias-label-on-fill);border-radius:50%;justify-content:center;align-items:center;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.aYQbCq_stateArt{box-sizing:border-box;object-fit:contain;width:22px;height:22px;filter:drop-shadow(0 0 1px var(--dsw-alias-bg-module)) drop-shadow(0 1px 1px #122d483d);background:0 0;border:0;border-radius:0;position:absolute;bottom:-3px;right:-5px}.aYQbCq_stateArt[data-activity=working]{animation:2.4s ease-in-out infinite aYQbCq_agentTeamsFloat}.aYQbCq_stateArt[data-activity=idle]{animation:4.2s ease-in-out infinite aYQbCq_agentTeamsBreathe}.aYQbCq_stateArt[data-activity=unknown]{animation:2.8s ease-in-out infinite aYQbCq_agentTeamsThink}@keyframes aYQbCq_agentTeamsFloat{0%,to{transform:translateY(0)rotate(-4deg)}50%{transform:translateY(-2px)rotate(4deg)}}@keyframes aYQbCq_agentTeamsBreathe{0%,to{opacity:.82;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}@keyframes aYQbCq_agentTeamsThink{0%,to{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}.aYQbCq_memberState{margin-left:auto}.aYQbCq_memberCount{color:var(--dsw-alias-label-tertiary);font-size:10.5px;line-height:16px}.aYQbCq_assignmentLine{align-items:center;gap:7px;min-width:0;padding:0 6px 0 60px;display:flex}.aYQbCq_assignmentLabel{color:var(--dsw-alias-label-tertiary);flex:none;font-size:9.5px;line-height:14px}.aYQbCq_assignmentTasks{flex-wrap:wrap;flex:1;gap:4px;min-width:0;display:flex}.aYQbCq_assignmentChip{background:var(--dsw-alias-bg-fill-neutral);min-height:16px;color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:0 5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;font-weight:600;line-height:14px;display:inline-flex}.aYQbCq_assignmentChip[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.aYQbCq_assignmentChip[data-state=cancelled]{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.aYQbCq_unreadPill{color:var(--dsw-alias-state-business-primary);white-space:nowrap;flex:none;font-size:9.5px;font-weight:600;line-height:14px}.aYQbCq_taskEmpty{color:var(--dsw-alias-label-tertiary);font-size:9.5px;line-height:14px}.aYQbCq_dependencySection{border-top:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:7px;min-width:0;padding-top:10px;display:flex}.aYQbCq_sectionToggleTitle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:0;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.aYQbCq_dagViewport{scrollbar-width:thin;min-width:0;padding:2px 0 4px;overflow-x:auto}.aYQbCq_dagCanvas{min-width:100%;position:relative}.aYQbCq_dagCanvas[data-layout=parallel]{flex-wrap:wrap;gap:8px;display:flex}.aYQbCq_dagCanvas[data-layout=parallel] .aYQbCq_dagNode{flex:92px;min-width:92px;position:relative}.aYQbCq_dagEdges{pointer-events:none;position:absolute;inset:0;overflow:visible}.aYQbCq_dagEdges path{fill:none;stroke:var(--dsw-alias-line-strong);stroke-width:1px;transition:opacity .14s,stroke .14s,stroke-width .14s}.aYQbCq_dagEdges path[data-active=true]{stroke:var(--dsw-alias-state-business-primary);stroke-width:1.6px}.aYQbCq_dagEdges path[data-dimmed=true]{opacity:.24}.aYQbCq_dagNode{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module);color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;border-radius:6px;flex-direction:column;justify-content:center;gap:1px;padding:0 6px;transition:border-color .14s,background-color .14s,opacity .14s;display:flex;position:absolute}.aYQbCq_dagNode:hover,.aYQbCq_dagNode[data-focused=true]{border-color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module))}.aYQbCq_dagNode[data-dimmed=true]{opacity:.3}.aYQbCq_dagNode[data-state=running][data-dimmed=true]{opacity:.58}.aYQbCq_dagNode[data-state=completed]{border-color:color-mix(in srgb, var(--dsw-alias-state-success) 48%, var(--dsw-alias-line-normal))}.aYQbCq_dagNode[data-state=blocked]{border-color:color-mix(in srgb, var(--dsw-alias-state-warning) 52%, var(--dsw-alias-line-normal))}.aYQbCq_dagNode[data-state=failed]{border-color:color-mix(in srgb, var(--dsw-alias-state-danger) 56%, var(--dsw-alias-line-normal))}.aYQbCq_dagNodeHead{color:var(--dsw-alias-label-primary);align-items:center;gap:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9.5px;font-weight:700;display:flex}.aYQbCq_dagNodeDot{background:var(--dsw-alias-line-strong);border-radius:1.5px;flex:none;width:5px;height:5px}.aYQbCq_dagNode[data-state=running] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-business-primary)}.aYQbCq_dagNode[data-state=running] .aYQbCq_dagNodeHead{padding-right:12px}.aYQbCq_dagRunningState{width:9px;height:9px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex;position:absolute;top:4px;right:5px}.aYQbCq_dagRunningState .aYQbCq_workGlyph{width:9px;height:9px}.aYQbCq_dagNode[data-state=blocked] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-warning)}.aYQbCq_dagNode[data-state=completed] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-success)}.aYQbCq_dagNode[data-state=failed] .aYQbCq_dagNodeDot{background:var(--dsw-alias-state-danger)}.aYQbCq_dagNodeLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:8.5px;line-height:11px;overflow:hidden}.aYQbCq_taskDetail{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module-platform);border-radius:9px;flex-direction:column;gap:3px;min-width:0;padding:7px 9px;display:flex}.aYQbCq_taskDetailHead{align-items:center;gap:6px;min-width:0;display:flex}.aYQbCq_taskDetailId{color:var(--dsw-alias-state-business-primary);flex:none;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;font-weight:700}.aYQbCq_taskDetailSubject{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:600;line-height:16px;overflow:hidden}.aYQbCq_taskDetailBadge{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:0 5px;font-size:8.5px;font-weight:600;line-height:14px}.aYQbCq_taskDetailBadge[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailBadge[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.aYQbCq_taskDetailLine,.aYQbCq_taskDetailMeta{color:var(--dsw-alias-label-secondary);font-size:9.5px;line-height:14px}.aYQbCq_taskDetailMeta{color:var(--dsw-alias-label-tertiary)}.aYQbCq_emptyHint{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:11px;line-height:16px}.aYQbCq_historicPill{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-tertiary);border-radius:4px;flex:none;margin-left:auto;padding:1px 7px;font-size:9.5px;font-weight:600;line-height:15px}.aYQbCq_members{flex-direction:column;gap:3px;display:flex}.aYQbCq_archiveLabel{color:var(--dsw-alias-label-tertiary);padding:5px 14px 0;font-size:9.5px;font-weight:600;line-height:14px;display:block}@media (prefers-reduced-motion:reduce){.aYQbCq_panel,.aYQbCq_badge,.aYQbCq_badgeDot,.aYQbCq_panelDot,.aYQbCq_workGlyph rect,.aYQbCq_stateArt,.aYQbCq_memberAvatar[data-unread=true]:after{transition:none;animation:none}}@media (width<=960px){html[data-agent-teams-panel-open] [data-phase=active]{padding-right:0}}@media (width<=640px){.aYQbCq_badge{top:56px;right:10px}.aYQbCq_teamStats span[data-stat=messages]{display:none}.aYQbCq_captainNode{grid-template-columns:48px minmax(0,1fr)}.aYQbCq_captainState{display:none}.aYQbCq_delegationTree{margin-left:12px;padding-left:15px}.aYQbCq_memberBranch{width:15px}.aYQbCq_assignmentLine{padding-left:53px}}";
|
|
654
|
-
const tagId = "@nanmicoder/dsh-agent-teams/ActivityPanel.module.css";
|
|
655
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
656
|
-
const tag = document.createElement("style");
|
|
657
|
-
tag.dataset.plugin = "@nanmicoder/dsh-agent-teams";
|
|
658
|
-
tag.dataset.pluginCss = tagId;
|
|
659
|
-
tag.textContent = css;
|
|
660
|
-
document.head.appendChild(tag);
|
|
661
|
-
}
|
|
662
|
-
var ActivityPanel_module_css_default = {
|
|
663
|
-
"agentTeamsBreathe": "aYQbCq_agentTeamsBreathe",
|
|
664
|
-
"agentTeamsDot": "aYQbCq_agentTeamsDot",
|
|
665
|
-
"agentTeamsFloat": "aYQbCq_agentTeamsFloat",
|
|
666
|
-
"agentTeamsPanelIn": "aYQbCq_agentTeamsPanelIn",
|
|
667
|
-
"agentTeamsPulse": "aYQbCq_agentTeamsPulse",
|
|
668
|
-
"agentTeamsThink": "aYQbCq_agentTeamsThink",
|
|
669
|
-
"agentTeamsUnreadPulse": "aYQbCq_agentTeamsUnreadPulse",
|
|
670
|
-
"archiveLabel": "aYQbCq_archiveLabel",
|
|
671
|
-
"assignmentChip": "aYQbCq_assignmentChip",
|
|
672
|
-
"assignmentLabel": "aYQbCq_assignmentLabel",
|
|
673
|
-
"assignmentLine": "aYQbCq_assignmentLine",
|
|
674
|
-
"assignmentTasks": "aYQbCq_assignmentTasks",
|
|
675
|
-
"badge": "aYQbCq_badge",
|
|
676
|
-
"badgeCount": "aYQbCq_badgeCount",
|
|
677
|
-
"badgeDot": "aYQbCq_badgeDot",
|
|
678
|
-
"captainAvatar": "aYQbCq_captainAvatar",
|
|
679
|
-
"captainInfo": "aYQbCq_captainInfo",
|
|
680
|
-
"captainLine": "aYQbCq_captainLine",
|
|
681
|
-
"captainName": "aYQbCq_captainName",
|
|
682
|
-
"captainNode": "aYQbCq_captainNode",
|
|
683
|
-
"captainRole": "aYQbCq_captainRole",
|
|
684
|
-
"captainState": "aYQbCq_captainState",
|
|
685
|
-
"captainSummary": "aYQbCq_captainSummary",
|
|
686
|
-
"chevron": "aYQbCq_chevron",
|
|
687
|
-
"dagCanvas": "aYQbCq_dagCanvas",
|
|
688
|
-
"dagEdges": "aYQbCq_dagEdges",
|
|
689
|
-
"dagNode": "aYQbCq_dagNode",
|
|
690
|
-
"dagNodeDot": "aYQbCq_dagNodeDot",
|
|
691
|
-
"dagNodeHead": "aYQbCq_dagNodeHead",
|
|
692
|
-
"dagNodeLabel": "aYQbCq_dagNodeLabel",
|
|
693
|
-
"dagRunningState": "aYQbCq_dagRunningState",
|
|
694
|
-
"dagViewport": "aYQbCq_dagViewport",
|
|
695
|
-
"delegationSection": "aYQbCq_delegationSection",
|
|
696
|
-
"delegationTree": "aYQbCq_delegationTree",
|
|
697
|
-
"dependencySection": "aYQbCq_dependencySection",
|
|
698
|
-
"emptyHint": "aYQbCq_emptyHint",
|
|
699
|
-
"historicPill": "aYQbCq_historicPill",
|
|
700
|
-
"iconButton": "aYQbCq_iconButton",
|
|
701
|
-
"leadAvatar": "aYQbCq_leadAvatar",
|
|
702
|
-
"memberArt": "aYQbCq_memberArt",
|
|
703
|
-
"memberAvatar": "aYQbCq_memberAvatar",
|
|
704
|
-
"memberBlock": "aYQbCq_memberBlock",
|
|
705
|
-
"memberBranch": "aYQbCq_memberBranch",
|
|
706
|
-
"memberCount": "aYQbCq_memberCount",
|
|
707
|
-
"memberInfo": "aYQbCq_memberInfo",
|
|
708
|
-
"memberInitial": "aYQbCq_memberInitial",
|
|
709
|
-
"memberLine": "aYQbCq_memberLine",
|
|
710
|
-
"memberName": "aYQbCq_memberName",
|
|
711
|
-
"memberRole": "aYQbCq_memberRole",
|
|
712
|
-
"memberRow": "aYQbCq_memberRow",
|
|
713
|
-
"memberState": "aYQbCq_memberState",
|
|
714
|
-
"memberStatusLine": "aYQbCq_memberStatusLine",
|
|
715
|
-
"members": "aYQbCq_members",
|
|
716
|
-
"membersToggle": "aYQbCq_membersToggle",
|
|
717
|
-
"panel": "aYQbCq_panel",
|
|
718
|
-
"panelControls": "aYQbCq_panelControls",
|
|
719
|
-
"panelDot": "aYQbCq_panelDot",
|
|
720
|
-
"panelHead": "aYQbCq_panelHead",
|
|
721
|
-
"panelTitle": "aYQbCq_panelTitle",
|
|
722
|
-
"progressEmpty": "aYQbCq_progressEmpty",
|
|
723
|
-
"progressLegend": "aYQbCq_progressLegend",
|
|
724
|
-
"progressOverview": "aYQbCq_progressOverview",
|
|
725
|
-
"progressSegments": "aYQbCq_progressSegments",
|
|
726
|
-
"progressSummary": "aYQbCq_progressSummary",
|
|
727
|
-
"progressSummaryDot": "aYQbCq_progressSummaryDot",
|
|
728
|
-
"progressTitle": "aYQbCq_progressTitle",
|
|
729
|
-
"resizeHandle": "aYQbCq_resizeHandle",
|
|
730
|
-
"sectionHead": "aYQbCq_sectionHead",
|
|
731
|
-
"sectionHint": "aYQbCq_sectionHint",
|
|
732
|
-
"sectionTitle": "aYQbCq_sectionTitle",
|
|
733
|
-
"sectionToggleTitle": "aYQbCq_sectionToggleTitle",
|
|
734
|
-
"stageLabel": "aYQbCq_stageLabel",
|
|
735
|
-
"stateArt": "aYQbCq_stateArt",
|
|
736
|
-
"taskDetail": "aYQbCq_taskDetail",
|
|
737
|
-
"taskDetailBadge": "aYQbCq_taskDetailBadge",
|
|
738
|
-
"taskDetailHead": "aYQbCq_taskDetailHead",
|
|
739
|
-
"taskDetailId": "aYQbCq_taskDetailId",
|
|
740
|
-
"taskDetailLine": "aYQbCq_taskDetailLine",
|
|
741
|
-
"taskDetailMeta": "aYQbCq_taskDetailMeta",
|
|
742
|
-
"taskDetailSubject": "aYQbCq_taskDetailSubject",
|
|
743
|
-
"taskEmpty": "aYQbCq_taskEmpty",
|
|
744
|
-
"taskId": "aYQbCq_taskId",
|
|
745
|
-
"team": "aYQbCq_team",
|
|
746
|
-
"teamHead": "aYQbCq_teamHead",
|
|
747
|
-
"teamName": "aYQbCq_teamName",
|
|
748
|
-
"teamStats": "aYQbCq_teamStats",
|
|
749
|
-
"teams": "aYQbCq_teams",
|
|
750
|
-
"unreadPill": "aYQbCq_unreadPill",
|
|
751
|
-
"workGlyph": "aYQbCq_workGlyph"
|
|
752
|
-
};
|
|
753
|
-
//#endregion
|
|
754
1884
|
//#region lib/client/ActivityPanel.js
|
|
755
1885
|
/**
|
|
756
1886
|
* AgentTeams activity panel: the top-right floater monitoring every team.
|
|
@@ -784,6 +1914,7 @@ window.__ModuleLoader__.load({
|
|
|
784
1914
|
const PANEL_SHIFT_PROPERTY = "--agent-teams-panel-shift";
|
|
785
1915
|
const PANEL_CONVERSATION_GAP = 14;
|
|
786
1916
|
const MOVE_THRESHOLD = 4;
|
|
1917
|
+
const CAPTAIN_ASSIGNEE = "captain";
|
|
787
1918
|
function initialPanelLayout() {
|
|
788
1919
|
if (typeof window === "undefined") return DEFAULT_PANEL_LAYOUT;
|
|
789
1920
|
return parsePanelLayout(window.localStorage.getItem(PANEL_LAYOUT_STORAGE_KEY));
|
|
@@ -836,6 +1967,15 @@ window.__ModuleLoader__.load({
|
|
|
836
1967
|
function formatTaskIds(ids, t) {
|
|
837
1968
|
return ids.join(t("format.listSeparator"));
|
|
838
1969
|
}
|
|
1970
|
+
function taskTitle(task, model) {
|
|
1971
|
+
const extras = [
|
|
1972
|
+
task.kind,
|
|
1973
|
+
task.round === void 0 ? void 0 : `r${task.round}`,
|
|
1974
|
+
task.verdict,
|
|
1975
|
+
model === "" ? void 0 : model
|
|
1976
|
+
].filter((item) => item !== void 0);
|
|
1977
|
+
return extras.length === 0 ? `${task.id} · ${task.subject}` : `${task.id} · ${task.subject} · ${extras.join(" · ")}`;
|
|
1978
|
+
}
|
|
839
1979
|
/** Badge/bar coloring key: visual state, widened for terminal statuses. */
|
|
840
1980
|
function taskTone(state, status) {
|
|
841
1981
|
if (status === "failed") return "failed";
|
|
@@ -916,7 +2056,13 @@ window.__ModuleLoader__.load({
|
|
|
916
2056
|
const owned = tasks.filter((task) => task.assignee === member.name);
|
|
917
2057
|
const current = owned.find((task) => task.id === member.currentTask);
|
|
918
2058
|
const blocked = owned.find((task) => task.state === "blocked");
|
|
919
|
-
if (member.activity === "working" && current !== void 0)
|
|
2059
|
+
if (member.activity === "working" && current !== void 0) {
|
|
2060
|
+
const model = taskModelLabel(current, [member]);
|
|
2061
|
+
return model === "" ? t("member.status.executing", { taskId: current.id }) : t("member.status.executingModel", {
|
|
2062
|
+
taskId: current.id,
|
|
2063
|
+
model
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
920
2066
|
if (member.activity === "working") return t("member.status.working");
|
|
921
2067
|
if (blocked !== void 0) {
|
|
922
2068
|
const dependency = tasks.find((task) => blocked.dependencies.includes(task.id) && task.state !== "completed");
|
|
@@ -935,13 +2081,23 @@ window.__ModuleLoader__.load({
|
|
|
935
2081
|
const head = withoutVerb.split(/[((·::]/u)[0]?.trim() ?? withoutVerb;
|
|
936
2082
|
return head.length > 18 ? `${head.slice(0, 17)}…` : head;
|
|
937
2083
|
}
|
|
938
|
-
function taskSummary(team, t) {
|
|
2084
|
+
function taskSummary(team, t, discarded = false) {
|
|
939
2085
|
const completed = team.tasks.filter((task) => task.status === "completed");
|
|
2086
|
+
const cancelled = team.tasks.filter((task) => task.status === "cancelled");
|
|
940
2087
|
const running = team.tasks.filter((task) => task.state === "running");
|
|
941
2088
|
const blocked = team.tasks.filter((task) => task.state === "blocked");
|
|
942
|
-
const ready = team.tasks.filter((task) => task.state === "open" && task.status !== "completed");
|
|
2089
|
+
const ready = team.tasks.filter((task) => task.state === "open" && task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled");
|
|
2090
|
+
const failed = team.tasks.filter((task) => task.status === "failed");
|
|
2091
|
+
if (discarded) return t("task.summary.discarded", { count: team.tasks.length });
|
|
943
2092
|
if (team.tasks.length === 0) return t("task.summary.waitingBreakdown");
|
|
2093
|
+
if (team.phase === "staged") return t("task.summary.staged", { count: team.tasks.length });
|
|
944
2094
|
if (completed.length === team.tasks.length) return t("task.summary.allDelivered", { count: completed.length });
|
|
2095
|
+
if (completed.length + cancelled.length + failed.length === team.tasks.length) return t("task.summary.ended", {
|
|
2096
|
+
completed: completed.length,
|
|
2097
|
+
cancelled: cancelled.length,
|
|
2098
|
+
failed: failed.length
|
|
2099
|
+
});
|
|
2100
|
+
if (failed.length > 0 && running.length === 0 && ready.length === 0 && blocked.length === 0) return t("task.summary.failedSettled", { count: failed.length });
|
|
945
2101
|
if (blocked.length > 0 && running.length > 0) return t("task.summary.blockedAndRunning", {
|
|
946
2102
|
tasks: formatTaskIds(blocked.slice(0, 3).map((task) => task.id), t),
|
|
947
2103
|
more: blocked.length > 3 ? t("task.summary.more", { count: blocked.length - 3 }) : ""
|
|
@@ -951,11 +2107,12 @@ window.__ModuleLoader__.load({
|
|
|
951
2107
|
if (blocked.length > 0) return t("task.summary.blocked", { tasks: formatTaskIds(blocked.map((task) => task.id), t) });
|
|
952
2108
|
return t("task.summary.waitingSchedule");
|
|
953
2109
|
}
|
|
954
|
-
function ProgressOverview({ team, t }) {
|
|
955
|
-
const running = team.tasks.filter((task) => task.state === "running").length;
|
|
956
|
-
const blocked = team.tasks.filter((task) => task.state === "blocked").length;
|
|
957
|
-
const completed = team.tasks.filter((task) => task.status === "completed").length;
|
|
958
|
-
const
|
|
2110
|
+
function ProgressOverview({ team, t, discarded = false }) {
|
|
2111
|
+
const running = discarded ? 0 : team.tasks.filter((task) => task.state === "running").length;
|
|
2112
|
+
const blocked = discarded ? 0 : team.tasks.filter((task) => task.state === "blocked").length;
|
|
2113
|
+
const completed = discarded ? 0 : team.tasks.filter((task) => task.status === "completed").length;
|
|
2114
|
+
const settled = !discarded && team.tasks.length > 0 && team.tasks.every((task) => task.status === "completed" || task.status === "failed" || task.status === "cancelled");
|
|
2115
|
+
const summaryTone = discarded ? "discarded" : blocked > 0 ? "warning" : settled ? "completed" : "running";
|
|
959
2116
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
960
2117
|
className: ActivityPanel_module_css_default.progressOverview,
|
|
961
2118
|
"aria-label": t("progress.aria"),
|
|
@@ -968,7 +2125,7 @@ window.__ModuleLoader__.load({
|
|
|
968
2125
|
team.tasks.length > 0 ? (0, react_jsx_runtime.jsx)("span", {
|
|
969
2126
|
className: ActivityPanel_module_css_default.progressSegments,
|
|
970
2127
|
"aria-hidden": true,
|
|
971
|
-
children: team.tasks.map((task) => (0, react_jsx_runtime.jsx)("span", { "data-state": taskTone(task.state, task.status) }, task.id))
|
|
2128
|
+
children: team.tasks.map((task) => (0, react_jsx_runtime.jsx)("span", { "data-state": discarded ? "cancelled" : taskTone(task.state, task.status) }, task.id))
|
|
972
2129
|
}) : (0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.progressEmpty }),
|
|
973
2130
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
974
2131
|
className: ActivityPanel_module_css_default.progressLegend,
|
|
@@ -990,12 +2147,12 @@ window.__ModuleLoader__.load({
|
|
|
990
2147
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
991
2148
|
className: ActivityPanel_module_css_default.progressSummary,
|
|
992
2149
|
"data-state": summaryTone,
|
|
993
|
-
children: [(0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.progressSummaryDot }), (0, react_jsx_runtime.jsx)("span", { children: taskSummary(team, t) })]
|
|
2150
|
+
children: [(0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.progressSummaryDot }), (0, react_jsx_runtime.jsx)("span", { children: taskSummary(team, t, discarded) })]
|
|
994
2151
|
})
|
|
995
2152
|
]
|
|
996
2153
|
});
|
|
997
2154
|
}
|
|
998
|
-
function DependencyMap({ tasks, t }) {
|
|
2155
|
+
function DependencyMap({ tasks, members, t, discarded = false }) {
|
|
999
2156
|
const [open, setOpen] = (0, react.useState)(true);
|
|
1000
2157
|
const [hoverTaskId, setHoverTaskId] = (0, react.useState)(null);
|
|
1001
2158
|
const [keyboardTaskId, setKeyboardTaskId] = (0, react.useState)(null);
|
|
@@ -1034,6 +2191,7 @@ window.__ModuleLoader__.load({
|
|
|
1034
2191
|
if (tasks.length === 0) return null;
|
|
1035
2192
|
const fallbackTask = tasks.find((task) => task.state === "blocked") ?? tasks.find((task) => task.state === "running") ?? tasks[0];
|
|
1036
2193
|
const detailTask = tasks.find((task) => task.id === focusedTaskId) ?? fallbackTask;
|
|
2194
|
+
const detailModel = taskModelLabel(detailTask, members);
|
|
1037
2195
|
const waitingOn = detailTask.dependencies.filter((dependency) => tasks.find((task) => task.id === dependency)?.status !== "completed");
|
|
1038
2196
|
const dependents = tasks.filter((task) => task.dependencies.includes(detailTask.id));
|
|
1039
2197
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
@@ -1081,52 +2239,57 @@ window.__ModuleLoader__.load({
|
|
|
1081
2239
|
"data-dimmed": related !== null && !active
|
|
1082
2240
|
}, `${edge.from}:${edge.to}`);
|
|
1083
2241
|
})
|
|
1084
|
-
}), layout.nodes.map(({ task, x, y }) =>
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
(
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
2242
|
+
}), layout.nodes.map(({ task, x, y }) => {
|
|
2243
|
+
const model = taskModelLabel(task, members);
|
|
2244
|
+
const shortModel = compactModelLabel(model);
|
|
2245
|
+
return (0, react_jsx_runtime.jsxs)("button", {
|
|
2246
|
+
type: "button",
|
|
2247
|
+
className: ActivityPanel_module_css_default.dagNode,
|
|
2248
|
+
style: parallel ? { height: 30 } : {
|
|
2249
|
+
left: x,
|
|
2250
|
+
top: y,
|
|
2251
|
+
width: 92,
|
|
2252
|
+
height: 30
|
|
2253
|
+
},
|
|
2254
|
+
"data-task-id": task.id,
|
|
2255
|
+
"data-state": discarded ? "cancelled" : taskTone(task.state, task.status),
|
|
2256
|
+
"data-task-model": model || void 0,
|
|
2257
|
+
"data-focused": related?.has(task.id) ?? false,
|
|
2258
|
+
"data-dimmed": related !== null && !related.has(task.id),
|
|
2259
|
+
"aria-pressed": pinnedTaskId === task.id,
|
|
2260
|
+
title: taskTitle(task, model),
|
|
2261
|
+
onClick: () => {
|
|
2262
|
+
setPinnedTaskId((current) => current === task.id ? null : task.id);
|
|
2263
|
+
},
|
|
2264
|
+
onMouseEnter: () => {
|
|
2265
|
+
scheduleHover(task.id);
|
|
2266
|
+
},
|
|
2267
|
+
onMouseLeave: () => {
|
|
2268
|
+
scheduleHover(null);
|
|
2269
|
+
},
|
|
2270
|
+
onFocus: () => {
|
|
2271
|
+
setKeyboardTaskId(task.id);
|
|
2272
|
+
},
|
|
2273
|
+
onBlur: () => {
|
|
2274
|
+
setKeyboardTaskId(null);
|
|
2275
|
+
},
|
|
2276
|
+
children: [
|
|
2277
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
2278
|
+
className: ActivityPanel_module_css_default.dagNodeHead,
|
|
2279
|
+
children: [(0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.dagNodeDot }), task.id]
|
|
2280
|
+
}),
|
|
2281
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
2282
|
+
className: ActivityPanel_module_css_default.dagNodeLabel,
|
|
2283
|
+
children: task.state === "running" && shortModel !== "" ? shortModel : compactTaskLabel(task.subject)
|
|
2284
|
+
}),
|
|
2285
|
+
task.state === "running" && (0, react_jsx_runtime.jsx)("span", {
|
|
2286
|
+
className: ActivityPanel_module_css_default.dagRunningState,
|
|
2287
|
+
"aria-label": t("task.runningAria"),
|
|
2288
|
+
children: (0, react_jsx_runtime.jsx)(WorkGlyph, { active: true })
|
|
2289
|
+
})
|
|
2290
|
+
]
|
|
2291
|
+
}, task.id);
|
|
2292
|
+
})]
|
|
1130
2293
|
})
|
|
1131
2294
|
}), (0, react_jsx_runtime.jsxs)("section", {
|
|
1132
2295
|
className: ActivityPanel_module_css_default.taskDetail,
|
|
@@ -1146,8 +2309,8 @@ window.__ModuleLoader__.load({
|
|
|
1146
2309
|
}),
|
|
1147
2310
|
(0, react_jsx_runtime.jsx)("span", {
|
|
1148
2311
|
className: ActivityPanel_module_css_default.taskDetailBadge,
|
|
1149
|
-
"data-state": taskTone(detailTask.state, detailTask.status),
|
|
1150
|
-
children: taskStatusLabel(detailTask.status, t)
|
|
2312
|
+
"data-state": discarded ? "cancelled" : taskTone(detailTask.state, detailTask.status),
|
|
2313
|
+
children: discarded ? t("task.status.notRun") : taskStatusLabel(detailTask.status, t)
|
|
1151
2314
|
})
|
|
1152
2315
|
]
|
|
1153
2316
|
}),
|
|
@@ -1156,9 +2319,14 @@ window.__ModuleLoader__.load({
|
|
|
1156
2319
|
children: [
|
|
1157
2320
|
detailTask.assignee || t("task.assignee.unclaimed"),
|
|
1158
2321
|
" · ",
|
|
1159
|
-
detailTask.status === "completed" ? t("task.detail.completed") : detailTask.dependencies.length === 0 ? t("task.detail.noPrerequisite") : waitingOn.length === 0 ? t("task.detail.ready") : t("task.detail.waitingOn", { tasks: formatTaskIds(waitingOn, t) })
|
|
2322
|
+
discarded ? t("task.detail.notRun") : detailTask.status === "completed" ? t("task.detail.completed") : detailTask.dependencies.length === 0 ? t("task.detail.noPrerequisite") : waitingOn.length === 0 ? t("task.detail.ready") : t("task.detail.waitingOn", { tasks: formatTaskIds(waitingOn, t) })
|
|
1160
2323
|
]
|
|
1161
2324
|
}),
|
|
2325
|
+
detailModel !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
2326
|
+
className: ActivityPanel_module_css_default.taskDetailModel,
|
|
2327
|
+
"data-task-model": detailModel,
|
|
2328
|
+
children: t("task.model", { model: detailModel })
|
|
2329
|
+
}),
|
|
1162
2330
|
(0, react_jsx_runtime.jsx)("span", {
|
|
1163
2331
|
className: ActivityPanel_module_css_default.taskDetailMeta,
|
|
1164
2332
|
children: dependents.length === 0 ? t("task.detail.noDownstream") : t("task.detail.unlocks", { tasks: formatTaskIds(dependents.map((task) => task.id), t) })
|
|
@@ -1167,13 +2335,53 @@ window.__ModuleLoader__.load({
|
|
|
1167
2335
|
})] })]
|
|
1168
2336
|
});
|
|
1169
2337
|
}
|
|
1170
|
-
function TeamSection({ team, onNavigate, t, historic = false }) {
|
|
2338
|
+
function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, onNavigate, t, historic = false }) {
|
|
1171
2339
|
const [membersOpen, setMembersOpen] = (0, react.useState)(true);
|
|
2340
|
+
const [stopOpen, setStopOpen] = (0, react.useState)(false);
|
|
2341
|
+
const [stopping, setStopping] = (0, react.useState)(false);
|
|
2342
|
+
const [stopError, setStopError] = (0, react.useState)("");
|
|
2343
|
+
const discarded = historic && team.phase === "staged";
|
|
2344
|
+
const stopped = !historic && team.halted === true;
|
|
1172
2345
|
const busyCount = team.members.filter((member) => member.activity === "working").length;
|
|
1173
|
-
const assignedCount = team.tasks.filter((task) => task.assignee !== "").length;
|
|
2346
|
+
const assignedCount = team.tasks.filter((task) => task.assignee !== "" && task.assignee !== CAPTAIN_ASSIGNEE).length;
|
|
2347
|
+
const captainOwned = team.tasks.filter((task) => task.assignee === CAPTAIN_ASSIGNEE && task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled");
|
|
2348
|
+
const captainBusy = captainOwned.length > 0;
|
|
2349
|
+
const captainTaskIds = formatTaskIds(captainOwned.map((task) => task.id), t);
|
|
1174
2350
|
const completedCount = team.tasks.filter((task) => task.status === "completed").length;
|
|
1175
2351
|
const allCompleted = team.tasks.length > 0 && completedCount === team.tasks.length;
|
|
1176
|
-
|
|
2352
|
+
const allSettled = team.tasks.length > 0 && team.tasks.every((task) => task.status === "completed" || task.status === "failed" || task.status === "cancelled");
|
|
2353
|
+
const unfinishedCount = team.tasks.filter((task) => task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled").length;
|
|
2354
|
+
const canStop = !historic && team.phase === "running" && team.halted !== true && teamIsActive(team);
|
|
2355
|
+
const stopTeam = async () => {
|
|
2356
|
+
if (stopping) return;
|
|
2357
|
+
setStopping(true);
|
|
2358
|
+
setStopError("");
|
|
2359
|
+
try {
|
|
2360
|
+
const response = await fetch(ACTIVITY_HALT_URL, {
|
|
2361
|
+
method: "POST",
|
|
2362
|
+
cache: "no-store",
|
|
2363
|
+
headers: { "content-type": "application/json" },
|
|
2364
|
+
body: JSON.stringify({
|
|
2365
|
+
sessionId: team.captainSessionId,
|
|
2366
|
+
teamId: team.teamId
|
|
2367
|
+
})
|
|
2368
|
+
});
|
|
2369
|
+
if (!response.ok) {
|
|
2370
|
+
let message = t("team.stopRequestFailed");
|
|
2371
|
+
try {
|
|
2372
|
+
const body = await response.json();
|
|
2373
|
+
if (typeof body.error === "string" && body.error.trim() !== "") message = body.error;
|
|
2374
|
+
} catch {}
|
|
2375
|
+
throw new Error(message);
|
|
2376
|
+
}
|
|
2377
|
+
setStopOpen(false);
|
|
2378
|
+
} catch (error) {
|
|
2379
|
+
setStopError(t("team.stopFailed", { message: error instanceof Error ? error.message : String(error) }));
|
|
2380
|
+
} finally {
|
|
2381
|
+
setStopping(false);
|
|
2382
|
+
}
|
|
2383
|
+
};
|
|
2384
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("section", {
|
|
1177
2385
|
className: ActivityPanel_module_css_default.team,
|
|
1178
2386
|
"data-team-id": team.teamId,
|
|
1179
2387
|
children: [
|
|
@@ -1187,7 +2395,11 @@ window.__ModuleLoader__.load({
|
|
|
1187
2395
|
}),
|
|
1188
2396
|
historic && (0, react_jsx_runtime.jsx)("span", {
|
|
1189
2397
|
className: ActivityPanel_module_css_default.historicPill,
|
|
1190
|
-
children: t("team.ended")
|
|
2398
|
+
children: t(discarded ? "team.discarded" : "team.ended")
|
|
2399
|
+
}),
|
|
2400
|
+
stopped && (0, react_jsx_runtime.jsx)("span", {
|
|
2401
|
+
className: ActivityPanel_module_css_default.historicPill,
|
|
2402
|
+
children: t("team.stopped")
|
|
1191
2403
|
}),
|
|
1192
2404
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
1193
2405
|
className: ActivityPanel_module_css_default.teamStats,
|
|
@@ -1208,9 +2420,27 @@ window.__ModuleLoader__.load({
|
|
|
1208
2420
|
children: t("team.stats.messages", { count: team.messageCount })
|
|
1209
2421
|
})
|
|
1210
2422
|
]
|
|
2423
|
+
}),
|
|
2424
|
+
canStop && (0, react_jsx_runtime.jsx)("button", {
|
|
2425
|
+
type: "button",
|
|
2426
|
+
className: ActivityPanel_module_css_default.teamStopButton,
|
|
2427
|
+
"aria-label": t("team.stop"),
|
|
2428
|
+
title: t("team.stop"),
|
|
2429
|
+
onClick: () => {
|
|
2430
|
+
setStopError("");
|
|
2431
|
+
setStopOpen(true);
|
|
2432
|
+
},
|
|
2433
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconStopFill16, {})
|
|
1211
2434
|
})
|
|
1212
2435
|
]
|
|
1213
2436
|
}),
|
|
2437
|
+
team.phase === "staged" && !historic && modelDirectory !== void 0 && onContinuePlanning !== void 0 && onDiscarded !== void 0 && (0, react_jsx_runtime.jsx)(StagingPlanEditor, {
|
|
2438
|
+
team,
|
|
2439
|
+
modelDirectory,
|
|
2440
|
+
onContinuePlanning,
|
|
2441
|
+
onDiscarded,
|
|
2442
|
+
t
|
|
2443
|
+
}),
|
|
1214
2444
|
(0, react_jsx_runtime.jsxs)("section", {
|
|
1215
2445
|
className: ActivityPanel_module_css_default.delegationSection,
|
|
1216
2446
|
"aria-label": t("delegation.aria"),
|
|
@@ -1241,7 +2471,16 @@ window.__ModuleLoader__.load({
|
|
|
1241
2471
|
})]
|
|
1242
2472
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1243
2473
|
className: ActivityPanel_module_css_default.captainSummary,
|
|
1244
|
-
children: t("captain.summary", {
|
|
2474
|
+
children: discarded ? t("captain.summary.discarded", {
|
|
2475
|
+
tasks: team.tasks.length,
|
|
2476
|
+
members: team.members.length
|
|
2477
|
+
}) : captainBusy ? t("captain.summary.withTakeover", {
|
|
2478
|
+
tasks: assignedCount,
|
|
2479
|
+
captainTasks: captainTaskIds
|
|
2480
|
+
}) : team.phase === "staged" ? t(team.planReviewState === "awaiting_feedback" ? "captain.summary.awaitingFeedback" : "captain.summary.staged", {
|
|
2481
|
+
tasks: team.tasks.length,
|
|
2482
|
+
members: team.members.length
|
|
2483
|
+
}) : t("captain.summary", {
|
|
1245
2484
|
tasks: assignedCount,
|
|
1246
2485
|
members: team.members.length
|
|
1247
2486
|
})
|
|
@@ -1249,14 +2488,15 @@ window.__ModuleLoader__.load({
|
|
|
1249
2488
|
}),
|
|
1250
2489
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
1251
2490
|
className: ActivityPanel_module_css_default.captainState,
|
|
1252
|
-
"data-busy": busyCount > 0,
|
|
1253
|
-
children: [(0, react_jsx_runtime.jsx)(WorkGlyph, { active: busyCount > 0 }), busyCount > 0 ? t("captain.state.working", { count: busyCount }) : t(allCompleted ? "captain.state.collected" : "captain.state.waiting")]
|
|
2491
|
+
"data-busy": captainBusy || busyCount > 0,
|
|
2492
|
+
children: [(0, react_jsx_runtime.jsx)(WorkGlyph, { active: captainBusy || busyCount > 0 }), discarded ? t("captain.state.discarded") : captainBusy ? t("captain.state.takeover", { tasks: captainTaskIds }) : team.phase === "staged" ? t(team.planReviewState === "awaiting_feedback" ? "captain.state.awaitingFeedback" : "captain.state.staged") : busyCount > 0 ? t("captain.state.working", { count: busyCount }) : t(allCompleted ? "captain.state.collected" : allSettled ? "captain.state.settled" : "captain.state.waiting")]
|
|
1254
2493
|
})
|
|
1255
2494
|
]
|
|
1256
2495
|
}),
|
|
1257
2496
|
(0, react_jsx_runtime.jsx)(ProgressOverview, {
|
|
1258
2497
|
team,
|
|
1259
|
-
t
|
|
2498
|
+
t,
|
|
2499
|
+
discarded
|
|
1260
2500
|
}),
|
|
1261
2501
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
1262
2502
|
type: "button",
|
|
@@ -1275,6 +2515,7 @@ window.__ModuleLoader__.load({
|
|
|
1275
2515
|
children: t("members.empty")
|
|
1276
2516
|
}), team.members.map((member) => {
|
|
1277
2517
|
const owned = team.tasks.filter((task) => task.assignee === member.name);
|
|
2518
|
+
const memberModel = memberRouteLabel(member);
|
|
1278
2519
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1279
2520
|
className: ActivityPanel_module_css_default.memberBlock,
|
|
1280
2521
|
"data-activity": member.activity,
|
|
@@ -1314,27 +2555,35 @@ window.__ModuleLoader__.load({
|
|
|
1314
2555
|
}),
|
|
1315
2556
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
1316
2557
|
className: ActivityPanel_module_css_default.memberInfo,
|
|
1317
|
-
children: [
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
2558
|
+
children: [
|
|
2559
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
2560
|
+
className: ActivityPanel_module_css_default.memberLine,
|
|
2561
|
+
children: [
|
|
2562
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
2563
|
+
className: ActivityPanel_module_css_default.memberName,
|
|
2564
|
+
children: member.name
|
|
2565
|
+
}),
|
|
2566
|
+
member.role !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
2567
|
+
className: ActivityPanel_module_css_default.memberRole,
|
|
2568
|
+
children: member.role
|
|
2569
|
+
}),
|
|
2570
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
2571
|
+
className: ActivityPanel_module_css_default.memberState,
|
|
2572
|
+
"data-activity": member.activity,
|
|
2573
|
+
children: [(0, react_jsx_runtime.jsx)(WorkGlyph, { active: member.activity === "working" }), discarded ? t("member.state.notCreated") : stopped ? t("member.state.stopped") : team.phase === "staged" ? t("member.state.staged") : memberStateLabel(member, team.tasks, historic, t)]
|
|
2574
|
+
})
|
|
2575
|
+
]
|
|
2576
|
+
}),
|
|
2577
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
2578
|
+
className: ActivityPanel_module_css_default.memberStatusLine,
|
|
2579
|
+
children: discarded ? t("member.status.discarded") : stopped ? t("member.status.stopped") : team.phase === "staged" ? t("member.status.staged") : historic && owned.length > 0 && owned.every((task) => task.status === "completed" || task.status === "failed" || task.status === "cancelled") ? t("member.status.settled") : memberStatusText(member, team.tasks, t)
|
|
2580
|
+
}),
|
|
2581
|
+
memberModel !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
2582
|
+
className: ActivityPanel_module_css_default.memberModel,
|
|
2583
|
+
"data-member-model": memberModel,
|
|
2584
|
+
children: t("member.model", { model: memberModel })
|
|
2585
|
+
})
|
|
2586
|
+
]
|
|
1338
2587
|
}),
|
|
1339
2588
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
1340
2589
|
className: ActivityPanel_module_css_default.memberCount,
|
|
@@ -1350,32 +2599,74 @@ window.__ModuleLoader__.load({
|
|
|
1350
2599
|
className: ActivityPanel_module_css_default.assignmentLine,
|
|
1351
2600
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1352
2601
|
className: ActivityPanel_module_css_default.assignmentLabel,
|
|
1353
|
-
children: t("assignment.label")
|
|
2602
|
+
children: t(discarded ? "assignment.discarded" : team.phase === "staged" ? "assignment.staged" : "assignment.label")
|
|
1354
2603
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1355
2604
|
className: ActivityPanel_module_css_default.assignmentTasks,
|
|
1356
2605
|
children: owned.length === 0 ? (0, react_jsx_runtime.jsx)("span", {
|
|
1357
2606
|
className: ActivityPanel_module_css_default.taskEmpty,
|
|
1358
2607
|
children: t("assignment.empty")
|
|
1359
|
-
}) : owned.map((task) =>
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
2608
|
+
}) : owned.map((task) => {
|
|
2609
|
+
const model = taskModelLabel(task, team.members);
|
|
2610
|
+
const shortModel = compactModelLabel(model);
|
|
2611
|
+
return (0, react_jsx_runtime.jsx)("span", {
|
|
2612
|
+
className: ActivityPanel_module_css_default.assignmentChip,
|
|
2613
|
+
"data-state": discarded ? "cancelled" : taskTone(task.state, task.status),
|
|
2614
|
+
"data-task-model": model || void 0,
|
|
2615
|
+
title: taskTitle(task, model),
|
|
2616
|
+
children: task.state === "running" && shortModel !== "" ? `${task.id} · ${shortModel}` : task.id
|
|
2617
|
+
}, task.id);
|
|
2618
|
+
})
|
|
1365
2619
|
})]
|
|
1366
2620
|
})
|
|
1367
2621
|
]
|
|
1368
|
-
}, member.id);
|
|
2622
|
+
}, member.id || member.name);
|
|
1369
2623
|
})]
|
|
1370
2624
|
})
|
|
1371
2625
|
]
|
|
1372
2626
|
}),
|
|
1373
2627
|
(0, react_jsx_runtime.jsx)(DependencyMap, {
|
|
1374
2628
|
tasks: team.tasks,
|
|
1375
|
-
|
|
2629
|
+
members: team.members,
|
|
2630
|
+
t,
|
|
2631
|
+
discarded
|
|
1376
2632
|
})
|
|
1377
2633
|
]
|
|
1378
|
-
})
|
|
2634
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2635
|
+
open: stopOpen,
|
|
2636
|
+
onClose: () => {
|
|
2637
|
+
if (!stopping) setStopOpen(false);
|
|
2638
|
+
},
|
|
2639
|
+
title: t("team.stopTitle", { team: team.name }),
|
|
2640
|
+
closeLabel: t("plan.cancel"),
|
|
2641
|
+
description: t("team.stopDescription", {
|
|
2642
|
+
tasks: unfinishedCount,
|
|
2643
|
+
members: busyCount
|
|
2644
|
+
}),
|
|
2645
|
+
footer: (0, react_jsx_runtime.jsxs)("span", {
|
|
2646
|
+
className: ActivityPanel_module_css_default.stopModalActions,
|
|
2647
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
2648
|
+
type: "button",
|
|
2649
|
+
disabled: stopping,
|
|
2650
|
+
onClick: () => {
|
|
2651
|
+
setStopOpen(false);
|
|
2652
|
+
},
|
|
2653
|
+
children: t("team.stopCancel")
|
|
2654
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
2655
|
+
type: "button",
|
|
2656
|
+
"data-danger": true,
|
|
2657
|
+
disabled: stopping,
|
|
2658
|
+
onClick: () => {
|
|
2659
|
+
stopTeam();
|
|
2660
|
+
},
|
|
2661
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconStopFill16, {}), stopping ? t("team.stopping") : t("team.stopConfirm")]
|
|
2662
|
+
})]
|
|
2663
|
+
}),
|
|
2664
|
+
children: stopError !== "" && (0, react_jsx_runtime.jsxs)("p", {
|
|
2665
|
+
className: ActivityPanel_module_css_default.stopModalError,
|
|
2666
|
+
role: "alert",
|
|
2667
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16, {}), stopError]
|
|
2668
|
+
})
|
|
2669
|
+
})] });
|
|
1379
2670
|
}
|
|
1380
2671
|
/** Legacy conversation cards may outlive their host archive. Project their
|
|
1381
2672
|
* durable roster through the same rebuilt panel instead of a second UI. */
|
|
@@ -1385,6 +2676,7 @@ window.__ModuleLoader__.load({
|
|
|
1385
2676
|
teamId: data.teamId,
|
|
1386
2677
|
name: data.teamName,
|
|
1387
2678
|
captainSessionId: data.captainSessionId || owner,
|
|
2679
|
+
phase: "running",
|
|
1388
2680
|
members: data.members.map((member) => ({
|
|
1389
2681
|
...member,
|
|
1390
2682
|
status: "removed",
|
|
@@ -1400,7 +2692,7 @@ window.__ModuleLoader__.load({
|
|
|
1400
2692
|
captainInbox: []
|
|
1401
2693
|
};
|
|
1402
2694
|
}
|
|
1403
|
-
function ActivityPanel({ sessionsList, openMember, t }) {
|
|
2695
|
+
function ActivityPanel({ sessionsList, modelDirectories, openMember, t }) {
|
|
1404
2696
|
const navigateToSession = (parentId, childId) => {
|
|
1405
2697
|
setOpen(false);
|
|
1406
2698
|
setWasActive(false);
|
|
@@ -1420,7 +2712,19 @@ window.__ModuleLoader__.load({
|
|
|
1420
2712
|
const frameRef = (0, react.useRef)(null);
|
|
1421
2713
|
const pendingLayoutRef = (0, react.useRef)(null);
|
|
1422
2714
|
const current = (0, react.useSyncExternalStore)(sessionsList.subscribe, sessionsList.getSnapshot).current;
|
|
2715
|
+
const autoOpenTrackerRef = (0, react.useRef)({
|
|
2716
|
+
sessionId: current,
|
|
2717
|
+
restoreComplete: false,
|
|
2718
|
+
liveTeamIds: /* @__PURE__ */ new Set()
|
|
2719
|
+
});
|
|
1423
2720
|
const monitorTargets = (0, react.useSyncExternalStore)(subscribeActivityMonitorTargets, getActivityMonitorTargetsSnapshot);
|
|
2721
|
+
const returnToComposer = () => {
|
|
2722
|
+
setOpen(false);
|
|
2723
|
+
setOpenOwner(void 0);
|
|
2724
|
+
window.requestAnimationFrame(() => {
|
|
2725
|
+
document.querySelector("[data-composer-card] textarea")?.focus();
|
|
2726
|
+
});
|
|
2727
|
+
};
|
|
1424
2728
|
const { teams, archivedTeams } = (0, react.useSyncExternalStore)(subscribeActivitySnapshots, getActivitySnapshotsSnapshot);
|
|
1425
2729
|
const currentTargets = (0, react.useMemo)(() => current === void 0 ? [] : monitorTargets.filter((target) => target.sessionId === current), [current, monitorTargets]);
|
|
1426
2730
|
const currentRef = (0, react.useRef)(current);
|
|
@@ -1471,11 +2775,17 @@ window.__ModuleLoader__.load({
|
|
|
1471
2775
|
};
|
|
1472
2776
|
}, [current]);
|
|
1473
2777
|
(0, react.useLayoutEffect)(() => {
|
|
2778
|
+
const tracker = autoOpenTrackerRef.current;
|
|
2779
|
+
if (tracker.sessionId !== current) {
|
|
2780
|
+
tracker.sessionId = current;
|
|
2781
|
+
tracker.restoreComplete = false;
|
|
2782
|
+
tracker.liveTeamIds = /* @__PURE__ */ new Set();
|
|
2783
|
+
setWasActive(false);
|
|
2784
|
+
setAutoOpened(false);
|
|
2785
|
+
}
|
|
1474
2786
|
if (openOwner === void 0 || openOwner === current) return;
|
|
1475
2787
|
setOpen(false);
|
|
1476
2788
|
setOpenOwner(void 0);
|
|
1477
|
-
setWasActive(false);
|
|
1478
|
-
setAutoOpened(false);
|
|
1479
2789
|
}, [current, openOwner]);
|
|
1480
2790
|
(0, react.useLayoutEffect)(() => {
|
|
1481
2791
|
const root = document.documentElement;
|
|
@@ -1499,7 +2809,16 @@ window.__ModuleLoader__.load({
|
|
|
1499
2809
|
(0, react.useEffect)(() => {
|
|
1500
2810
|
if (current === void 0) return;
|
|
1501
2811
|
const controller = startActivityPolling(currentTargets, { discoverySessionId: current });
|
|
2812
|
+
let active = true;
|
|
2813
|
+
const tracker = autoOpenTrackerRef.current;
|
|
2814
|
+
if (tracker.sessionId === current && !tracker.restoreComplete) controller.firstTick.then(() => {
|
|
2815
|
+
const latest = autoOpenTrackerRef.current;
|
|
2816
|
+
if (!active || latest.sessionId !== current || latest.restoreComplete) return;
|
|
2817
|
+
latest.liveTeamIds = new Set(getActivitySnapshotsSnapshot().teams.filter((team) => team.captainSessionId === current).map((team) => team.teamId));
|
|
2818
|
+
latest.restoreComplete = true;
|
|
2819
|
+
});
|
|
1502
2820
|
return () => {
|
|
2821
|
+
active = false;
|
|
1503
2822
|
controller.stop();
|
|
1504
2823
|
};
|
|
1505
2824
|
}, [current, currentTargets]);
|
|
@@ -1541,11 +2860,21 @@ window.__ModuleLoader__.load({
|
|
|
1541
2860
|
teams
|
|
1542
2861
|
]);
|
|
1543
2862
|
const visibleCount = visibleTeams.length + visibleArchived.length + visibleHistoric.length;
|
|
2863
|
+
const visibleLiveTeamIds = (0, react.useMemo)(() => visibleTeams.map((team) => team.teamId).sort(), [visibleTeams]);
|
|
1544
2864
|
(0, react.useEffect)(() => {
|
|
2865
|
+
const tracker = autoOpenTrackerRef.current;
|
|
2866
|
+
const settled = performance.now() - mountedAtRef.current >= AUTO_OPEN_SETTLE_MS;
|
|
2867
|
+
const shouldAutoExpand = tracker.sessionId === current && activityPanelShouldAutoExpand({
|
|
2868
|
+
alreadyAutoOpened: autoOpened,
|
|
2869
|
+
pageSettled: settled,
|
|
2870
|
+
restoreComplete: tracker.restoreComplete,
|
|
2871
|
+
previousLiveTeamIds: tracker.liveTeamIds,
|
|
2872
|
+
currentLiveTeamIds: visibleLiveTeamIds
|
|
2873
|
+
});
|
|
2874
|
+
if (tracker.sessionId === current && tracker.restoreComplete) tracker.liveTeamIds = new Set(visibleLiveTeamIds);
|
|
1545
2875
|
if (visibleCount > 0) {
|
|
1546
2876
|
setWasActive(true);
|
|
1547
|
-
|
|
1548
|
-
if (!autoOpened && settled) {
|
|
2877
|
+
if (shouldAutoExpand) {
|
|
1549
2878
|
setOpenOwner(current);
|
|
1550
2879
|
setOpen(true);
|
|
1551
2880
|
setAutoOpened(true);
|
|
@@ -1564,8 +2893,10 @@ window.__ModuleLoader__.load({
|
|
|
1564
2893
|
};
|
|
1565
2894
|
}, [
|
|
1566
2895
|
visibleCount,
|
|
2896
|
+
visibleLiveTeamIds.join("\0"),
|
|
1567
2897
|
autoOpened,
|
|
1568
|
-
wasActive
|
|
2898
|
+
wasActive,
|
|
2899
|
+
current
|
|
1569
2900
|
]);
|
|
1570
2901
|
const busy = (0, react.useMemo)(() => visibleTeams.some((team) => team.members.some((member) => member.activity === "working")), [visibleTeams]);
|
|
1571
2902
|
const hasTeams = visibleCount > 0;
|
|
@@ -1744,6 +3075,9 @@ window.__ModuleLoader__.load({
|
|
|
1744
3075
|
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1745
3076
|
visibleTeams.map((team) => (0, react_jsx_runtime.jsx)(TeamSection, {
|
|
1746
3077
|
team,
|
|
3078
|
+
modelDirectory: team.phase === "staged" ? modelDirectories.directoryFor(team.captainSessionId) : void 0,
|
|
3079
|
+
onContinuePlanning: returnToComposer,
|
|
3080
|
+
onDiscarded: returnToComposer,
|
|
1747
3081
|
onNavigate: navigateToSession,
|
|
1748
3082
|
t
|
|
1749
3083
|
}, team.teamId)),
|
|
@@ -1753,7 +3087,7 @@ window.__ModuleLoader__.load({
|
|
|
1753
3087
|
className: ActivityPanel_module_css_default.archivedWrap,
|
|
1754
3088
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1755
3089
|
className: ActivityPanel_module_css_default.archiveLabel,
|
|
1756
|
-
children: t("archive.label")
|
|
3090
|
+
children: t(team.phase === "staged" ? "archive.discardedLabel" : "archive.label")
|
|
1757
3091
|
}), (0, react_jsx_runtime.jsx)(TeamSection, {
|
|
1758
3092
|
team,
|
|
1759
3093
|
onNavigate: navigateToSession,
|
|
@@ -1900,13 +3234,23 @@ window.__ModuleLoader__.load({
|
|
|
1900
3234
|
"card.memberCount": "{count} 名成员",
|
|
1901
3235
|
"action.openActivityPanel": "打开活动面板",
|
|
1902
3236
|
"activity.panelButton": "活动面板",
|
|
1903
|
-
"activity.badgeAria": "AgentTeams
|
|
3237
|
+
"activity.badgeAria": "AgentTeams 活动与历史,{count} 条团队记录",
|
|
1904
3238
|
"activity.panelAria": "AgentTeams 活动面板",
|
|
1905
3239
|
"activity.title": "AgentTeams 活动",
|
|
1906
3240
|
"activity.float": "切换为浮动面板",
|
|
1907
3241
|
"activity.dockRight": "停靠到右侧",
|
|
1908
3242
|
"activity.collapse": "收起活动面板",
|
|
1909
3243
|
"activity.empty": "暂无团队活动",
|
|
3244
|
+
"team.stop": "停止团队",
|
|
3245
|
+
"team.stopped": "已停止",
|
|
3246
|
+
"team.stopTitle": "确认停止“{team}”?",
|
|
3247
|
+
"team.stopDescription": "将取消 {tasks} 项未完成任务,并停止 {members} 名正在工作的成员。已完成的结果会保留。",
|
|
3248
|
+
"team.stopCancel": "继续运行",
|
|
3249
|
+
"team.stopConfirm": "确认停止",
|
|
3250
|
+
"team.stopping": "正在停止…",
|
|
3251
|
+
"team.stopFailed": "停止失败:{message}",
|
|
3252
|
+
"team.stopRequestFailed": "服务器未能停止团队,请重试",
|
|
3253
|
+
"team.discarded": "已放弃",
|
|
1910
3254
|
"format.listSeparator": "、",
|
|
1911
3255
|
"task.status.pending": "待领取",
|
|
1912
3256
|
"task.status.claimed": "已认领",
|
|
@@ -1914,6 +3258,7 @@ window.__ModuleLoader__.load({
|
|
|
1914
3258
|
"task.status.completed": "已完成",
|
|
1915
3259
|
"task.status.failed": "失败",
|
|
1916
3260
|
"task.status.cancelled": "已取消",
|
|
3261
|
+
"task.status.notRun": "未执行",
|
|
1917
3262
|
"member.state.working": "工作中",
|
|
1918
3263
|
"member.state.failed": "有失败",
|
|
1919
3264
|
"member.state.waiting": "等待",
|
|
@@ -1922,7 +3267,11 @@ window.__ModuleLoader__.load({
|
|
|
1922
3267
|
"member.state.removed": "已移除",
|
|
1923
3268
|
"member.state.pending": "待执行",
|
|
1924
3269
|
"member.state.unassigned": "待派工",
|
|
3270
|
+
"member.state.staged": "待创建",
|
|
3271
|
+
"member.state.notCreated": "未创建",
|
|
3272
|
+
"member.state.stopped": "已停止",
|
|
1925
3273
|
"member.status.executing": "正在执行 {taskId}",
|
|
3274
|
+
"member.status.executingModel": "正在执行 {taskId} · {model}",
|
|
1926
3275
|
"member.status.working": "正在处理已派任务",
|
|
1927
3276
|
"member.status.waitingOn": "等待 {taskId} · {assignee}",
|
|
1928
3277
|
"member.status.waitingPrerequisite": "等待前置任务",
|
|
@@ -1930,14 +3279,22 @@ window.__ModuleLoader__.load({
|
|
|
1930
3279
|
"member.status.delivered": "任务已交付",
|
|
1931
3280
|
"member.status.idle": "待继续执行",
|
|
1932
3281
|
"member.status.unknown": "状态未知",
|
|
3282
|
+
"member.status.staged": "确认后创建并启动",
|
|
3283
|
+
"member.status.settled": "任务均已终结",
|
|
3284
|
+
"member.status.discarded": "计划已放弃,未创建",
|
|
3285
|
+
"member.status.stopped": "团队已停止,需显式恢复",
|
|
1933
3286
|
"task.assignee.unclaimed": "待认领",
|
|
1934
3287
|
"task.summary.waitingBreakdown": "等待队长拆解任务",
|
|
3288
|
+
"task.summary.staged": "{count} 项计划等待确认",
|
|
3289
|
+
"task.summary.discarded": "{count} 项计划已放弃,均未执行",
|
|
1935
3290
|
"task.summary.allDelivered": "全部 {count} 项任务已交付",
|
|
3291
|
+
"task.summary.ended": "终态:{completed} 已交付 · {cancelled} 已取消 · {failed} 失败",
|
|
1936
3292
|
"task.summary.blockedAndRunning": "{tasks}{more} 等待前置,其余已开工",
|
|
1937
3293
|
"task.summary.more": " 等 {count} 项",
|
|
1938
3294
|
"task.summary.running": "{tasks} 正在执行",
|
|
1939
3295
|
"task.summary.ready": "{tasks} 已就绪待开工",
|
|
1940
3296
|
"task.summary.blocked": "{tasks} 等待前置",
|
|
3297
|
+
"task.summary.failedSettled": "{count} 项已失败,自动循环已停止",
|
|
1941
3298
|
"task.summary.waitingSchedule": "等待下一轮调度",
|
|
1942
3299
|
"progress.aria": "团队总进度",
|
|
1943
3300
|
"progress.title": "总进度",
|
|
@@ -1951,13 +3308,89 @@ window.__ModuleLoader__.load({
|
|
|
1951
3308
|
"dependency.hint.chain": "悬停高亮依赖链 · 点击固定",
|
|
1952
3309
|
"dependency.hint.pinned": "{taskId} 已固定 · Esc 取消",
|
|
1953
3310
|
"task.runningAria": "运行中",
|
|
3311
|
+
"task.model": "{model}",
|
|
3312
|
+
"member.model": "{model}",
|
|
1954
3313
|
"task.detail.completed": "已完成并交付",
|
|
1955
3314
|
"task.detail.noPrerequisite": "无前置,可立即开工",
|
|
1956
3315
|
"task.detail.ready": "前置已就绪,可开工",
|
|
1957
3316
|
"task.detail.waitingOn": "等待 {tasks}",
|
|
3317
|
+
"task.detail.notRun": "计划已放弃,任务未执行",
|
|
1958
3318
|
"task.detail.noDownstream": "无下游任务",
|
|
1959
3319
|
"task.detail.unlocks": "完成后解锁 {tasks}",
|
|
1960
3320
|
"team.ended": "已结束",
|
|
3321
|
+
"plan.badge": "待确认",
|
|
3322
|
+
"plan.title": "执行前计划审查",
|
|
3323
|
+
"plan.description": "成员尚未创建、任务尚未调度。可直接调整计划,也可返回对话告诉队长哪里需要修改。",
|
|
3324
|
+
"plan.member.role": "角色",
|
|
3325
|
+
"plan.member.provider": "Provider",
|
|
3326
|
+
"plan.member.model": "模型",
|
|
3327
|
+
"plan.member.reasoning": "推理等级",
|
|
3328
|
+
"plan.member.reasoningHint": "留空使用默认值;可用 low、medium、high、xhigh 等",
|
|
3329
|
+
"plan.model.choose": "选择模型",
|
|
3330
|
+
"plan.model.currentUnavailable": "{provider}/{model}(当前目录不可用)",
|
|
3331
|
+
"plan.model.route": "路由:{provider}/{model}",
|
|
3332
|
+
"plan.model.defaultReasoning": "默认推理等级",
|
|
3333
|
+
"plan.model.providerDefault": "Provider 默认值",
|
|
3334
|
+
"plan.model.modelDefault": "模型默认值({effort})",
|
|
3335
|
+
"plan.model.triggerAria": "选择成员模型,当前 {model},推理等级 {effort}",
|
|
3336
|
+
"plan.model.back": "返回",
|
|
3337
|
+
"plan.model.loading": "正在加载模型…",
|
|
3338
|
+
"plan.model.empty": "暂无可用模型",
|
|
3339
|
+
"plan.model.partialFailure": "{count} 个 Provider 的模型目录加载失败",
|
|
3340
|
+
"plan.model.retry": "重试",
|
|
3341
|
+
"plan.member.prompt": "角色提示词",
|
|
3342
|
+
"plan.member.roleFallback": "未设置角色",
|
|
3343
|
+
"plan.task.subject": "任务名称",
|
|
3344
|
+
"plan.task.description": "任务说明",
|
|
3345
|
+
"plan.task.assignee": "负责人",
|
|
3346
|
+
"plan.task.dependencies": "依赖任务 ID(逗号分隔)",
|
|
3347
|
+
"plan.task.dependenciesHint": "例如 task-1, task-2;不得形成循环依赖",
|
|
3348
|
+
"plan.task.unassigned": "共享任务池",
|
|
3349
|
+
"plan.unsaved": "未保存",
|
|
3350
|
+
"plan.save": "保存",
|
|
3351
|
+
"plan.saving": "保存中…",
|
|
3352
|
+
"plan.remove": "删除",
|
|
3353
|
+
"plan.removed": "任务已删除",
|
|
3354
|
+
"plan.removeConfirm": "确认删除",
|
|
3355
|
+
"plan.removeWarning": "删除 {task} 后将重新计算依赖关系。",
|
|
3356
|
+
"plan.cancel": "取消",
|
|
3357
|
+
"plan.addTask": "添加任务",
|
|
3358
|
+
"plan.adding": "添加中…",
|
|
3359
|
+
"plan.taskAdded": "任务已添加",
|
|
3360
|
+
"plan.newTask": "新任务名称",
|
|
3361
|
+
"plan.newTaskLabel": "新增计划任务",
|
|
3362
|
+
"plan.readySummary": "{members} 名成员 · {tasks} 项任务 · {links} 条依赖",
|
|
3363
|
+
"plan.flow.aria": "团队启动流程",
|
|
3364
|
+
"plan.flow.review": "审查计划",
|
|
3365
|
+
"plan.flow.spawn": "创建成员",
|
|
3366
|
+
"plan.flow.run": "开始执行",
|
|
3367
|
+
"plan.members.title": "成员与模型路由",
|
|
3368
|
+
"plan.members.count": "{count} 名成员",
|
|
3369
|
+
"plan.members.empty": "尚未规划成员",
|
|
3370
|
+
"plan.tasks.title": "任务与依赖",
|
|
3371
|
+
"plan.tasks.count": "{count} 项任务 · {links} 条依赖",
|
|
3372
|
+
"plan.tasks.empty": "尚未规划任务",
|
|
3373
|
+
"plan.dependencies.none": "无依赖",
|
|
3374
|
+
"plan.dependencies.count": "{count} 条依赖",
|
|
3375
|
+
"plan.approve": "确认并启动团队",
|
|
3376
|
+
"plan.approving": "正在创建成员…",
|
|
3377
|
+
"plan.approveTitle": "计划检查完毕?",
|
|
3378
|
+
"plan.approveHint": "确认后将创建 {members} 名成员并调度 {tasks} 项任务。",
|
|
3379
|
+
"plan.approveConfirmTitle": "确认启动此团队",
|
|
3380
|
+
"plan.approveWarning": "启动后不能再在此处编辑成员和依赖。",
|
|
3381
|
+
"plan.approveConfirm": "确认启动",
|
|
3382
|
+
"plan.continue": "返回对话修改",
|
|
3383
|
+
"plan.returnToChat": "回到对话",
|
|
3384
|
+
"plan.feedbackTitle": "正在等你说明修改方向",
|
|
3385
|
+
"plan.feedbackHint": "队长会在对话中追问;收到你的回复后,只修改这份草案并再次等待确认。",
|
|
3386
|
+
"plan.discard": "放弃本次计划",
|
|
3387
|
+
"plan.discardConfirmTitle": "放弃本次计划?",
|
|
3388
|
+
"plan.discardWarning": "该计划会结束并归档;尚未创建任何成员,也不会执行任务。",
|
|
3389
|
+
"plan.discardConfirm": "确认放弃",
|
|
3390
|
+
"plan.discarding": "正在放弃…",
|
|
3391
|
+
"plan.pendingEdits": "请先保存当前修改,再启动团队。",
|
|
3392
|
+
"plan.saved": "计划已保存",
|
|
3393
|
+
"plan.failed": "操作失败:{message}",
|
|
1961
3394
|
"team.stats.members": "{count} 名成员",
|
|
1962
3395
|
"team.stats.completed": "{completed}/{total} 完成",
|
|
1963
3396
|
"team.stats.messages": "{count} 条消息",
|
|
@@ -1965,29 +3398,51 @@ window.__ModuleLoader__.load({
|
|
|
1965
3398
|
"captain.name": "队长",
|
|
1966
3399
|
"captain.role": "拆解 · 派发 · 汇总",
|
|
1967
3400
|
"captain.summary": "已派发 {tasks} 项任务给 {members} 名成员",
|
|
3401
|
+
"captain.summary.staged": "已规划 {tasks} 项任务与 {members} 名成员,等待确认",
|
|
3402
|
+
"captain.summary.awaitingFeedback": "草案已保留,等待你在对话中说明修改方向",
|
|
3403
|
+
"captain.summary.discarded": "计划已放弃:{members} 名成员未创建,{tasks} 项任务未执行",
|
|
3404
|
+
"captain.summary.withTakeover": "已派发 {tasks} 项给成员 · 队长接管 {captainTasks}",
|
|
1968
3405
|
"captain.state.working": "{count} 人执行中",
|
|
3406
|
+
"captain.state.takeover": "正在执行 {tasks}",
|
|
1969
3407
|
"captain.state.collected": "已收齐",
|
|
1970
3408
|
"captain.state.waiting": "等待回报",
|
|
3409
|
+
"captain.state.staged": "待确认",
|
|
3410
|
+
"captain.state.awaitingFeedback": "待反馈",
|
|
3411
|
+
"captain.state.discarded": "已放弃",
|
|
3412
|
+
"captain.state.settled": "已终结",
|
|
1971
3413
|
"members.toggle": "{count} 名成员",
|
|
1972
3414
|
"members.collapse": "收起",
|
|
1973
3415
|
"members.expand": "展开",
|
|
1974
3416
|
"members.empty": "暂无成员,等待队长组建团队",
|
|
1975
3417
|
"assignment.label": "队长派发",
|
|
3418
|
+
"assignment.staged": "计划任务",
|
|
3419
|
+
"assignment.discarded": "未执行的计划",
|
|
1976
3420
|
"assignment.empty": "暂无任务",
|
|
1977
|
-
"archive.label": "已结束 · 历史归档"
|
|
3421
|
+
"archive.label": "已结束 · 历史归档",
|
|
3422
|
+
"archive.discardedLabel": "计划已放弃 · 历史归档"
|
|
1978
3423
|
};
|
|
1979
3424
|
/** English dictionary, checked complete against the Chinese source key set. */
|
|
1980
3425
|
const en = {
|
|
1981
3426
|
"card.memberCount": "{count} members",
|
|
1982
3427
|
"action.openActivityPanel": "Open activity panel",
|
|
1983
3428
|
"activity.panelButton": "Activity panel",
|
|
1984
|
-
"activity.badgeAria": "AgentTeams activity, {count}
|
|
3429
|
+
"activity.badgeAria": "AgentTeams activity and history, {count} team records",
|
|
1985
3430
|
"activity.panelAria": "AgentTeams activity panel",
|
|
1986
3431
|
"activity.title": "AgentTeams activity",
|
|
1987
3432
|
"activity.float": "Switch to floating panel",
|
|
1988
3433
|
"activity.dockRight": "Dock to the right",
|
|
1989
3434
|
"activity.collapse": "Collapse activity panel",
|
|
1990
3435
|
"activity.empty": "No team activity",
|
|
3436
|
+
"team.stop": "Stop team",
|
|
3437
|
+
"team.stopped": "Stopped",
|
|
3438
|
+
"team.stopTitle": "Stop “{team}”?",
|
|
3439
|
+
"team.stopDescription": "This cancels {tasks} unfinished tasks and stops {members} working members. Completed results are kept.",
|
|
3440
|
+
"team.stopCancel": "Keep running",
|
|
3441
|
+
"team.stopConfirm": "Stop team",
|
|
3442
|
+
"team.stopping": "Stopping…",
|
|
3443
|
+
"team.stopFailed": "Could not stop team: {message}",
|
|
3444
|
+
"team.stopRequestFailed": "The server could not stop this team. Try again.",
|
|
3445
|
+
"team.discarded": "Discarded",
|
|
1991
3446
|
"format.listSeparator": ", ",
|
|
1992
3447
|
"task.status.pending": "Unclaimed",
|
|
1993
3448
|
"task.status.claimed": "Claimed",
|
|
@@ -1995,6 +3450,7 @@ window.__ModuleLoader__.load({
|
|
|
1995
3450
|
"task.status.completed": "Completed",
|
|
1996
3451
|
"task.status.failed": "Failed",
|
|
1997
3452
|
"task.status.cancelled": "Cancelled",
|
|
3453
|
+
"task.status.notRun": "Not run",
|
|
1998
3454
|
"member.state.working": "Working",
|
|
1999
3455
|
"member.state.failed": "Has failures",
|
|
2000
3456
|
"member.state.waiting": "Waiting",
|
|
@@ -2003,7 +3459,11 @@ window.__ModuleLoader__.load({
|
|
|
2003
3459
|
"member.state.removed": "Removed",
|
|
2004
3460
|
"member.state.pending": "Pending",
|
|
2005
3461
|
"member.state.unassigned": "Awaiting assignment",
|
|
3462
|
+
"member.state.staged": "Not spawned",
|
|
3463
|
+
"member.state.notCreated": "Not created",
|
|
3464
|
+
"member.state.stopped": "Stopped",
|
|
2006
3465
|
"member.status.executing": "Working on {taskId}",
|
|
3466
|
+
"member.status.executingModel": "Working on {taskId} · {model}",
|
|
2007
3467
|
"member.status.working": "Working on assigned tasks",
|
|
2008
3468
|
"member.status.waitingOn": "Waiting for {taskId} · {assignee}",
|
|
2009
3469
|
"member.status.waitingPrerequisite": "Waiting for prerequisites",
|
|
@@ -2011,14 +3471,22 @@ window.__ModuleLoader__.load({
|
|
|
2011
3471
|
"member.status.delivered": "Tasks delivered",
|
|
2012
3472
|
"member.status.idle": "Ready to continue",
|
|
2013
3473
|
"member.status.unknown": "Status unknown",
|
|
3474
|
+
"member.status.staged": "Will be spawned after approval",
|
|
3475
|
+
"member.status.settled": "All assigned work is settled",
|
|
3476
|
+
"member.status.discarded": "Plan discarded; member was not created",
|
|
3477
|
+
"member.status.stopped": "Team stopped; explicit resume required",
|
|
2014
3478
|
"task.assignee.unclaimed": "Unclaimed",
|
|
2015
3479
|
"task.summary.waitingBreakdown": "Waiting for the captain to break down the work",
|
|
3480
|
+
"task.summary.staged": "{count} planned tasks awaiting approval",
|
|
3481
|
+
"task.summary.discarded": "{count} planned tasks discarded; none ran",
|
|
2016
3482
|
"task.summary.allDelivered": "All {count} tasks delivered",
|
|
3483
|
+
"task.summary.ended": "Final: {completed} delivered · {cancelled} cancelled · {failed} failed",
|
|
2017
3484
|
"task.summary.blockedAndRunning": "{tasks}{more} waiting on prerequisites; other work has started",
|
|
2018
3485
|
"task.summary.more": " and {count} more",
|
|
2019
3486
|
"task.summary.running": "{tasks} in progress",
|
|
2020
3487
|
"task.summary.ready": "{tasks} ready to start",
|
|
2021
3488
|
"task.summary.blocked": "{tasks} waiting on prerequisites",
|
|
3489
|
+
"task.summary.failedSettled": "{count} failed; the automatic loop has stopped",
|
|
2022
3490
|
"task.summary.waitingSchedule": "Waiting for the next scheduling round",
|
|
2023
3491
|
"progress.aria": "Overall team progress",
|
|
2024
3492
|
"progress.title": "Overall progress",
|
|
@@ -2032,13 +3500,89 @@ window.__ModuleLoader__.load({
|
|
|
2032
3500
|
"dependency.hint.chain": "Hover to highlight dependencies · Click to pin",
|
|
2033
3501
|
"dependency.hint.pinned": "{taskId} pinned · Esc to clear",
|
|
2034
3502
|
"task.runningAria": "Running",
|
|
3503
|
+
"task.model": "{model}",
|
|
3504
|
+
"member.model": "{model}",
|
|
2035
3505
|
"task.detail.completed": "Completed and delivered",
|
|
2036
3506
|
"task.detail.noPrerequisite": "No prerequisites; ready to start",
|
|
2037
3507
|
"task.detail.ready": "Prerequisites ready; can start",
|
|
2038
3508
|
"task.detail.waitingOn": "Waiting for {tasks}",
|
|
3509
|
+
"task.detail.notRun": "Plan discarded; task was not run",
|
|
2039
3510
|
"task.detail.noDownstream": "No downstream tasks",
|
|
2040
3511
|
"task.detail.unlocks": "Unlocks {tasks} when complete",
|
|
2041
3512
|
"team.ended": "Ended",
|
|
3513
|
+
"plan.badge": "Awaiting approval",
|
|
3514
|
+
"plan.title": "Pre-run plan review",
|
|
3515
|
+
"plan.description": "Members have not been spawned and tasks have not been scheduled. Edit the draft here, or return to chat and tell the Captain what should change.",
|
|
3516
|
+
"plan.member.role": "Role",
|
|
3517
|
+
"plan.member.provider": "Provider",
|
|
3518
|
+
"plan.member.model": "Model",
|
|
3519
|
+
"plan.member.reasoning": "Reasoning effort",
|
|
3520
|
+
"plan.member.reasoningHint": "Leave blank for default; accepts low, medium, high, xhigh, and more",
|
|
3521
|
+
"plan.model.choose": "Choose a model",
|
|
3522
|
+
"plan.model.currentUnavailable": "{provider}/{model} (not in the current catalog)",
|
|
3523
|
+
"plan.model.route": "Route: {provider}/{model}",
|
|
3524
|
+
"plan.model.defaultReasoning": "Default reasoning effort",
|
|
3525
|
+
"plan.model.providerDefault": "Provider default",
|
|
3526
|
+
"plan.model.modelDefault": "Model default ({effort})",
|
|
3527
|
+
"plan.model.triggerAria": "Choose member model, currently {model}, reasoning effort {effort}",
|
|
3528
|
+
"plan.model.back": "Back",
|
|
3529
|
+
"plan.model.loading": "Loading models…",
|
|
3530
|
+
"plan.model.empty": "No models available",
|
|
3531
|
+
"plan.model.partialFailure": "{count} provider catalogs could not be loaded",
|
|
3532
|
+
"plan.model.retry": "Retry",
|
|
3533
|
+
"plan.member.prompt": "Role prompt",
|
|
3534
|
+
"plan.member.roleFallback": "Role not set",
|
|
3535
|
+
"plan.task.subject": "Task subject",
|
|
3536
|
+
"plan.task.description": "Task description",
|
|
3537
|
+
"plan.task.assignee": "Assignee",
|
|
3538
|
+
"plan.task.dependencies": "Dependency task IDs (comma-separated)",
|
|
3539
|
+
"plan.task.dependenciesHint": "For example task-1, task-2; cycles are rejected",
|
|
3540
|
+
"plan.task.unassigned": "Shared task pool",
|
|
3541
|
+
"plan.unsaved": "Unsaved",
|
|
3542
|
+
"plan.save": "Save",
|
|
3543
|
+
"plan.saving": "Saving…",
|
|
3544
|
+
"plan.remove": "Remove",
|
|
3545
|
+
"plan.removed": "Task removed",
|
|
3546
|
+
"plan.removeConfirm": "Confirm remove",
|
|
3547
|
+
"plan.removeWarning": "Removing {task} will recalculate downstream dependencies.",
|
|
3548
|
+
"plan.cancel": "Cancel",
|
|
3549
|
+
"plan.addTask": "Add task",
|
|
3550
|
+
"plan.adding": "Adding…",
|
|
3551
|
+
"plan.taskAdded": "Task added",
|
|
3552
|
+
"plan.newTask": "New task subject",
|
|
3553
|
+
"plan.newTaskLabel": "Add a planned task",
|
|
3554
|
+
"plan.readySummary": "{members} members · {tasks} tasks · {links} dependencies",
|
|
3555
|
+
"plan.flow.aria": "Team launch flow",
|
|
3556
|
+
"plan.flow.review": "Review plan",
|
|
3557
|
+
"plan.flow.spawn": "Create members",
|
|
3558
|
+
"plan.flow.run": "Start work",
|
|
3559
|
+
"plan.members.title": "Members & model routes",
|
|
3560
|
+
"plan.members.count": "{count} members",
|
|
3561
|
+
"plan.members.empty": "No members planned yet",
|
|
3562
|
+
"plan.tasks.title": "Tasks & dependencies",
|
|
3563
|
+
"plan.tasks.count": "{count} tasks · {links} dependencies",
|
|
3564
|
+
"plan.tasks.empty": "No tasks planned yet",
|
|
3565
|
+
"plan.dependencies.none": "No dependencies",
|
|
3566
|
+
"plan.dependencies.count": "{count} dependencies",
|
|
3567
|
+
"plan.approve": "Approve & Run",
|
|
3568
|
+
"plan.approving": "Creating members…",
|
|
3569
|
+
"plan.approveTitle": "Plan ready?",
|
|
3570
|
+
"plan.approveHint": "Approval creates {members} members and schedules {tasks} tasks.",
|
|
3571
|
+
"plan.approveConfirmTitle": "Confirm team launch",
|
|
3572
|
+
"plan.approveWarning": "Member routes and dependencies cannot be edited here after launch.",
|
|
3573
|
+
"plan.approveConfirm": "Confirm launch",
|
|
3574
|
+
"plan.continue": "Return to chat & revise",
|
|
3575
|
+
"plan.returnToChat": "Return to chat",
|
|
3576
|
+
"plan.feedbackTitle": "Waiting for your revision direction",
|
|
3577
|
+
"plan.feedbackHint": "The Captain will ask in chat. After your reply, it will revise this draft and wait for approval again.",
|
|
3578
|
+
"plan.discard": "Discard this plan",
|
|
3579
|
+
"plan.discardConfirmTitle": "Discard this plan?",
|
|
3580
|
+
"plan.discardWarning": "The plan will end and be archived. No members have been spawned and no tasks will run.",
|
|
3581
|
+
"plan.discardConfirm": "Discard plan",
|
|
3582
|
+
"plan.discarding": "Discarding…",
|
|
3583
|
+
"plan.pendingEdits": "Save the current edits before launching the team.",
|
|
3584
|
+
"plan.saved": "Plan saved",
|
|
3585
|
+
"plan.failed": "Operation failed: {message}",
|
|
2042
3586
|
"team.stats.members": "{count} members",
|
|
2043
3587
|
"team.stats.completed": "{completed}/{total} completed",
|
|
2044
3588
|
"team.stats.messages": "{count} messages",
|
|
@@ -2046,16 +3590,28 @@ window.__ModuleLoader__.load({
|
|
|
2046
3590
|
"captain.name": "Captain",
|
|
2047
3591
|
"captain.role": "Break down · Delegate · Synthesize",
|
|
2048
3592
|
"captain.summary": "Assigned {tasks} tasks to {members} members",
|
|
3593
|
+
"captain.summary.staged": "Planned {tasks} tasks and {members} members; awaiting approval",
|
|
3594
|
+
"captain.summary.awaitingFeedback": "Draft preserved; waiting for your revision direction in chat",
|
|
3595
|
+
"captain.summary.discarded": "Plan discarded: {members} members were not created and {tasks} tasks did not run",
|
|
3596
|
+
"captain.summary.withTakeover": "Assigned {tasks} to members · Captain owns {captainTasks}",
|
|
2049
3597
|
"captain.state.working": "{count} active",
|
|
3598
|
+
"captain.state.takeover": "Working on {tasks}",
|
|
2050
3599
|
"captain.state.collected": "All reports received",
|
|
2051
3600
|
"captain.state.waiting": "Waiting for reports",
|
|
3601
|
+
"captain.state.staged": "Awaiting approval",
|
|
3602
|
+
"captain.state.awaitingFeedback": "Awaiting feedback",
|
|
3603
|
+
"captain.state.discarded": "Discarded",
|
|
3604
|
+
"captain.state.settled": "Settled",
|
|
2052
3605
|
"members.toggle": "Members {count}",
|
|
2053
3606
|
"members.collapse": "Collapse",
|
|
2054
3607
|
"members.expand": "Expand",
|
|
2055
3608
|
"members.empty": "No members yet; waiting for the captain to assemble the team",
|
|
2056
3609
|
"assignment.label": "Captain assigned",
|
|
3610
|
+
"assignment.staged": "Planned task",
|
|
3611
|
+
"assignment.discarded": "Plan not run",
|
|
2057
3612
|
"assignment.empty": "No tasks",
|
|
2058
|
-
"archive.label": "Ended · Archived history"
|
|
3613
|
+
"archive.label": "Ended · Archived history",
|
|
3614
|
+
"archive.discardedLabel": "Plan discarded · Archived history"
|
|
2059
3615
|
};
|
|
2060
3616
|
//#endregion
|
|
2061
3617
|
//#region lib/client/session-navigation.js
|
|
@@ -2089,7 +3645,8 @@ window.__ModuleLoader__.load({
|
|
|
2089
3645
|
"conversationEvents",
|
|
2090
3646
|
"slots",
|
|
2091
3647
|
"sessions",
|
|
2092
|
-
"locale"
|
|
3648
|
+
"locale",
|
|
3649
|
+
"modelDirectories"
|
|
2093
3650
|
];
|
|
2094
3651
|
/** The replayed user message is the canonical transcript entry. */
|
|
2095
3652
|
function HiddenAgentTeamsCommand() {
|
|
@@ -2112,6 +3669,7 @@ window.__ModuleLoader__.load({
|
|
|
2112
3669
|
};
|
|
2113
3670
|
const Panel = ({ t }) => (0, react_jsx_runtime.jsx)(ActivityPanel, {
|
|
2114
3671
|
sessionsList: ctx.sessions.list,
|
|
3672
|
+
modelDirectories: ctx.modelDirectories,
|
|
2115
3673
|
openMember,
|
|
2116
3674
|
t
|
|
2117
3675
|
});
|