dsh-plugin-t-expert 0.2.9 → 0.2.12

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/lib/client.js CHANGED
@@ -19719,6 +19719,128 @@ function date4(params) {
19719
19719
  // inlined team-engine client bundle
19720
19720
  var client_bundle_default = 'window.__ModuleLoader__.load({\n id: "dsh-plugin-t-expert",\n factory: (require) => {\n var module = { exports: {} };\n var exports = module.exports;\n Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });\n let react_jsx_runtime = require("react/jsx-runtime");\n let react = require("react");\n let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");\n /** Compact `provider/model` route, or just the model when the provider is absent. */\n function memberRouteLabel(member) {\n if (member === void 0) return "";\n const provider = member.provider?.trim() ?? "";\n const model = member.model?.trim() ?? "";\n if (provider !== "" && model !== "") return `${provider}/${model}`;\n return model;\n }\n /**\n * Compact route shown on a running task. Prefer the task\'s own snapshot\n * field; fall back to the assignee member when older hosts omit it.\n */\n function taskModelLabel(task, members) {\n const direct = task.model?.trim() ?? "";\n if (direct !== "") return direct;\n return memberRouteLabel(members.find((candidate) => candidate.name === task.assignee));\n }\n /** Short model id for tight DAG/chip surfaces (`openai/gpt-5.6-sol` \u2192 `gpt-5.6-sol`). */\n function compactModelLabel(route) {\n const trimmed = route.trim();\n if (trimmed === "") return "";\n const slash = trimmed.lastIndexOf("/");\n return slash === -1 ? trimmed : trimmed.slice(slash + 1);\n }\n /** Whether the captain chat should keep showing the in-progress banner. */\n function teamIsActive(team) {\n if (team.halted === true || team.phase === "staged") return false;\n if (team.members.some((member) => member.activity === "working" || member.status === "working")) return true;\n if (team.tasks.some((task) => task.status === "pending" || task.status === "claimed" || task.status === "in_progress")) return true;\n return team.members.length > 0 && team.tasks.length === 0;\n }\n /** Use a fill-width grid when the task graph has no real dependency edges. */\n function usesParallelTaskGrid(tasks) {\n if (tasks.length === 0) return false;\n const taskIds = new Set(tasks.map((task) => task.id));\n return tasks.every((task) => task.dependencies.every((dependency) => !taskIds.has(dependency)));\n }\n /**\n * Whether an expanded activity panel still belongs to the current session.\n *\n * The panel is mounted in the root-scoped shell overlay, so React does not\n * remount it when the conversation route changes. Ownership keeps an expanded\n * panel from leaking onto the new-session screen (or another conversation)\n * while its local open state is being reset.\n */\n function activityPanelExpandedForSession(open, owner, current) {\n return open && owner !== void 0 && owner === current;\n }\n /**\n * Auto-expand only for live teams that appear after the current session\'s\n * initial restore pass. Replayed cards, archived teams, and live teams restored\n * while reopening a conversation must remain behind the collapsed badge.\n */\n function activityPanelShouldAutoExpand({ alreadyAutoOpened, pageSettled, restoreComplete, previousLiveTeamIds, currentLiveTeamIds }) {\n return !alreadyAutoOpened && pageSettled && restoreComplete && currentLiveTeamIds.some((teamId) => !previousLiveTeamIds.has(teamId));\n }\n /**\n * Resolve the task whose dependency chain should be highlighted.\n *\n * A pinned task is an explicit user choice. Keyboard focus takes precedence\n * over delayed pointer intent so an older hover timer cannot steal the active\n * chain from someone navigating the task map with the keyboard.\n */\n function dependencyFocusTaskId(pinnedTaskId, keyboardTaskId, hoverTaskId) {\n return pinnedTaskId ?? keyboardTaskId ?? hoverTaskId;\n }\n /** Group tasks by their precomputed dependency depth. */\n function taskStages(tasks) {\n const byDepth = /* @__PURE__ */ new Map();\n for (const task of tasks) {\n const depth = Number.isFinite(task.depth) ? Math.max(0, Math.floor(task.depth)) : 0;\n const stage = byDepth.get(depth) ?? [];\n stage.push(task);\n byDepth.set(depth, stage);\n }\n return [...byDepth.entries()].sort(([left], [right]) => left - right).map(([depth, stageTasks]) => ({\n depth,\n tasks: stageTasks.slice().sort((left, right) => left.id.localeCompare(right.id, "en", { numeric: true }))\n }));\n }\n /**\n * Lay tasks out as the reference panel\'s compact left-to-right DAG.\n *\n * Columns are dependency-depth stages. Rows are stable task-id order within\n * each stage. Edges use cubic curves so fan-in remains readable without\n * turning every task into a large card.\n */\n function compactDagLayout(tasks) {\n const stages = taskStages(tasks);\n const positions = /* @__PURE__ */ new Map();\n const nodes = [];\n for (const [column, stage] of stages.entries()) for (const [row, task] of stage.tasks.entries()) {\n const x = column * 118;\n const y = row * 38;\n positions.set(task.id, {\n x,\n y\n });\n nodes.push({\n task,\n x,\n y\n });\n }\n const edges = [];\n for (const task of tasks) {\n const target = positions.get(task.id);\n if (target === void 0) continue;\n for (const dependency of task.dependencies) {\n const source = positions.get(dependency);\n if (source === void 0) continue;\n const x1 = source.x + 92;\n const y1 = source.y + 30 / 2;\n const x2 = target.x;\n const y2 = target.y + 30 / 2;\n edges.push({\n from: dependency,\n to: task.id,\n path: `M${x1} ${y1}C${x1 + 14} ${y1},${x2 - 14} ${y2},${x2} ${y2}`\n });\n }\n }\n const rows = Math.max(1, ...stages.map((stage) => stage.tasks.length));\n return {\n width: stages.length === 0 ? 0 : stages.length * 92 + (stages.length - 1) * 26,\n height: stages.length === 0 ? 0 : rows * 30 + (rows - 1) * 8,\n nodes,\n edges\n };\n }\n /**\n * Return the complete upstream/downstream chain around one task.\n *\n * Traversal uses both dependency directions and remains cycle-safe, so the UI\n * can highlight every handoff related to the focused task even if malformed\n * durable data contains a cycle.\n */\n function relatedTaskIds(taskId, tasks) {\n const byId = new Map(tasks.map((task) => [task.id, task]));\n if (!byId.has(taskId)) return /* @__PURE__ */ new Set();\n const dependents = /* @__PURE__ */ new Map();\n for (const task of tasks) for (const dependency of task.dependencies) {\n const targets = dependents.get(dependency) ?? [];\n targets.push(task.id);\n dependents.set(dependency, targets);\n }\n const related = /* @__PURE__ */ new Set();\n const upstreamSeen = /* @__PURE__ */ new Set();\n const downstreamSeen = /* @__PURE__ */ new Set();\n const visitUpstream = (id) => {\n if (upstreamSeen.has(id)) return;\n upstreamSeen.add(id);\n related.add(id);\n for (const dependency of byId.get(id)?.dependencies ?? []) visitUpstream(dependency);\n };\n const visitDownstream = (id) => {\n if (downstreamSeen.has(id)) return;\n downstreamSeen.add(id);\n related.add(id);\n for (const dependent of dependents.get(id) ?? []) visitDownstream(dependent);\n };\n visitUpstream(taskId);\n visitDownstream(taskId);\n return related;\n }\n\n\n /** Shared, demand-driven state for the T Team browser monitor. */\n const targets = /* @__PURE__ */ new Map();\n const targetListeners = /* @__PURE__ */ new Set();\n const snapshotListeners = /* @__PURE__ */ new Set();\n let targetSnapshot = [];\n let activitySnapshots = {\n teams: [],\n archivedTeams: []\n };\n function targetKey(sessionId, teamId) {\n return `${sessionId}\\u0000${teamId}`;\n }\n function publishTargets() {\n targetSnapshot = [...targets.values()].filter((target) => target.active).map(({ key, sessionId, teamId }) => ({\n key,\n sessionId,\n teamId\n }));\n for (const listener of targetListeners) listener();\n }\n /** Subscribe to the active monitor-target list (React external-store shape). */\n function subscribeActivityMonitorTargets(listener) {\n targetListeners.add(listener);\n return () => {\n targetListeners.delete(listener);\n };\n }\n /** Read the stable active-target snapshot. */\n function getActivityMonitorTargetsSnapshot() {\n return targetSnapshot;\n }\n /**\n * Register one successful T Team card as a monitoring demand.\n *\n * The returned cleanup is reference-counted so multiple cards and React\n * StrictMode remounts cannot stop another card\'s monitor.\n */\n function monitorAgentTeam(sessionId, teamId) {\n const owner = sessionId.trim();\n const id = teamId.trim();\n if (owner === "" || id === "") return () => {};\n const key = targetKey(owner, id);\n const existing = targets.get(key);\n if (existing === void 0) {\n targets.set(key, {\n key,\n sessionId: owner,\n teamId: id,\n refs: 1,\n active: true\n });\n publishTargets();\n } else {\n existing.refs += 1;\n if (!existing.active) {\n existing.active = true;\n publishTargets();\n }\n }\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const current = targets.get(key);\n if (current === void 0) return;\n current.refs -= 1;\n if (current.refs <= 0) {\n targets.delete(key);\n if (current.active) publishTargets();\n }\n };\n }\n /** Stop polling targets whose final archived snapshot has been captured. */\n function settleActivityMonitorTargets(keys) {\n let changed = false;\n for (const key of keys) {\n const target = targets.get(key);\n if (target?.active !== true) continue;\n target.active = false;\n changed = true;\n }\n if (changed) publishTargets();\n }\n /** Subscribe to the shared live/archive snapshot. */\n function subscribeActivitySnapshots(listener) {\n snapshotListeners.add(listener);\n return () => {\n snapshotListeners.delete(listener);\n };\n }\n /** Read the stable shared live/archive snapshot. */\n function getActivitySnapshotsSnapshot() {\n return activitySnapshots;\n }\n /** Publish one or both successful state-route responses. */\n function updateActivitySnapshots(update) {\n const next = {\n teams: update.teams ?? activitySnapshots.teams,\n archivedTeams: update.archivedTeams ?? activitySnapshots.archivedTeams\n };\n if (next.teams === activitySnapshots.teams && next.archivedTeams === activitySnapshots.archivedTeams) return;\n activitySnapshots = next;\n for (const listener of snapshotListeners) listener();\n }\n /** Poll cadence for the live host snapshot route. */\n const ACTIVITY_POLL_MS = 1e3;\n /**\n * Low-frequency probe cadence while a cardless discovery session still owns\n * no team. The probe keeps the panel able to pick up a team created later in\n * that session (e.g. a run_code-wrapped t_team_create) without turning\n * every ordinary session into a one-second filesystem scan.\n */\n const ACTIVITY_PROBE_MS = 5e3;\n /** Host route serving live and archived team snapshots. */\n const ACTIVITY_STATE_URL = "/plugins/t-team/state";\n const ACTIVITY_HALT_URL = "/plugins/t-team/halt";\n /**\n * Start the single polling loop for the current session\'s requested targets.\n *\n * With neither targets nor a discovery session this is deliberately inert.\n * Explicit card targets poll at the live cadence from the start. A discovery\n * session performs an immediate live+archive restore pass, then \u2014 while it\n * still owns no team \u2014 probes on a low-frequency cadence, so a team created\n * later in that session (e.g. a run_code-wrapped t_team_create) is\n * discovered without a manual reload, without turning every ordinary session\n * into a one-second filesystem scan. The moment a team for the discovery\n * session appears, the controller upgrades to the live one-second cadence for\n * the rest of its lifetime. The caller \u2014 the session view, which stops the\n * controller when the session is no longer current \u2014 bounds the lifetime, and\n * archive state is refreshed when a target or a previously discovered live\n * team disappears.\n */\n function startActivityPolling(monitorTargets, runtime = {}) {\n const discoverySessionId = runtime.discoverySessionId?.trim();\n if (monitorTargets.length === 0 && (discoverySessionId === void 0 || discoverySessionId === "")) return {\n firstTick: Promise.resolve(),\n stop: () => {}\n };\n const fetchState = runtime.fetchState ?? ((url, init) => fetch(url, init));\n const schedule = runtime.schedule ?? ((callback, intervalMs) => setInterval(callback, intervalMs));\n const cancel = runtime.cancel ?? ((timer) => {\n clearInterval(timer);\n });\n const publishSnapshots = runtime.publishSnapshots ?? updateActivitySnapshots;\n const settleTargets = runtime.settleTargets ?? settleActivityMonitorTargets;\n let cancelled = false;\n let inFlight = false;\n let hot = monitorTargets.length > 0;\n let discoveryComplete = false;\n let discoveredLiveKeys = /* @__PURE__ */ new Set();\n let controller;\n let timer;\n const intervalMs = () => hot ? ACTIVITY_POLL_MS : ACTIVITY_PROBE_MS;\n const reschedule = () => {\n cancel(timer);\n timer = schedule(() => {\n tick();\n }, intervalMs());\n };\n const tick = async () => {\n if (inFlight || cancelled) return;\n inFlight = true;\n controller = new AbortController();\n try {\n const liveResponse = await fetchState(ACTIVITY_STATE_URL, {\n cache: "no-store",\n signal: controller.signal\n });\n if (!liveResponse.ok) return;\n const body = await liveResponse.json();\n if (cancelled || !Array.isArray(body.teams)) return;\n const liveTeams = body.teams;\n publishSnapshots({ teams: liveTeams });\n const previousDiscoveredKeys = discoveredLiveKeys;\n discoveredLiveKeys = new Set(discoverySessionId === void 0 || discoverySessionId === "" ? [] : liveTeams.filter((team) => team.captainSessionId === discoverySessionId).map((team) => team.teamId));\n if (!hot && discoveredLiveKeys.size > 0) {\n hot = true;\n reschedule();\n }\n const discoveredTeamArchived = [...previousDiscoveredKeys].some((teamId) => !discoveredLiveKeys.has(teamId));\n const missing = monitorTargets.filter((target) => !liveTeams.some((team) => team.captainSessionId === target.sessionId && team.teamId === target.teamId));\n const needsDiscoveryArchive = discoverySessionId !== void 0 && discoverySessionId !== "" && !discoveryComplete;\n if (missing.length === 0 && !needsDiscoveryArchive && !discoveredTeamArchived) return;\n const archivedResponse = await fetchState(`${ACTIVITY_STATE_URL}?archived=1`, {\n cache: "no-store",\n signal: controller.signal\n });\n if (!archivedResponse.ok) return;\n const archivedBody = await archivedResponse.json();\n if (cancelled || !Array.isArray(archivedBody.teams)) return;\n publishSnapshots({ archivedTeams: archivedBody.teams });\n discoveryComplete = true;\n settleTargets(new Set(missing.map((target) => target.key)));\n } catch (error) {\n if (error?.name === "AbortError") return;\n } finally {\n inFlight = false;\n }\n };\n const firstTick = tick();\n if (timer === void 0) timer = schedule(() => {\n tick();\n }, intervalMs());\n return {\n firstTick,\n stop: () => {\n if (cancelled) return;\n cancelled = true;\n controller?.abort();\n cancel(timer);\n }\n };\n }\n\n\n /**\n * Shared whale artwork lookup for the activity panel and the conversation\n * card: role keywords map to the packaged role images; the captain always\n * uses the lead whale.\n * @module t-team/client/artwork\n */\n /** Artwork route prefix served by the plugin host half. */\n const ART_BASE = "/plugins/t-team/assets/";\n /** V2 whale role artwork per role keyword. */\n const ROLE_ART = [\n [/data|analys|metric|performance|\u6570\u636E|\u5206\u6790|\u6307\u6807|\u6027\u80FD/, "member-data-v2.png"],\n [/resear|investig|explor|study|\u7814\u7A76|\u8C03\u67E5|\u63A2\u7D22|\u8C03\u7814/, "member-researcher-v2.png"],\n [/\\bqa\\b|test|verif|quality|\u6D4B\u8BD5|\u8D28\u91CF|\u9A8C\u8BC1/, "member-qa-v2.png"],\n [/engineer|dev\\b|server|backend|\\bapi\\b|runtime|watcher|contract|\u5DE5\u7A0B|\u540E\u7AEF|\u670D\u52A1|\u63A5\u53E3|\u5F00\u53D1|\u4EE3\u7801|\u7F16\u7A0B/, "member-engineer-v2.png"],\n [/design|\\bui\\b|\\bux\\b|front|theme|accessib|\u8BBE\u8BA1|\u524D\u7AEF|\u4E3B\u9898|\u65E0\u969C\u788D/, "member-designer-v2.png"],\n [/secur|audit|risk|threat|review|\u5B89\u5168|\u5BA1\u8BA1|\u5BA1\u67E5|\u98CE\u9669/, "member-security-v2.png"],\n [/docs|writer|product|spec|\u64B0\u5199|\u6587\u6848|\u5199\u4F5C|\u6587\u6863|\u89C4\u8303/, "member-docs-v2.png"],\n [/release|\\bbuild\\b|deploy|\\bops\\b|\\bci\\b|ship|coordin|\u53D1\u5E03|\u6784\u5EFA|\u90E8\u7F72|\u8FD0\u7EF4|\u534F\u8C03/, "member-operator-v2.png"]\n ];\n /** Captain artwork (always the lead whale). */\n const LEAD_ART = `${ART_BASE}team-lead-v2.png`;\n /** Status action artwork per member activity. */\n const ACTION_ART = {\n working: `${ART_BASE}action-working-v2.png`,\n idle: `${ART_BASE}action-sleeping-v2.png`,\n unknown: `${ART_BASE}action-thinking-v2.png`\n };\n /**\n * Member artwork URL, or null when no role matches (initial-letter fallback).\n * @param name - the member\'s display name.\n * @param role - the member\'s role text.\n * @returns the artwork URL, or null when unmatched.\n */\n function memberArtUrl(name, role) {\n const identity = `${name} ${role}`.toLowerCase();\n for (const [pattern, art] of ROLE_ART) if (pattern.test(identity)) return `${ART_BASE}${art}`;\n return null;\n }\n\n\n const css$1 = ".kPAopq_root{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module-platform);border-radius:10px;flex-direction:column;gap:8px;width:100%;min-width:0;padding:10px 12px;display:flex}.kPAopq_head{align-items:center;gap:8px;min-width:0;display:flex}.kPAopq_leadAvatar{object-fit:contain;filter:drop-shadow(0 1px 1px #122d4833);background:0 0;border:0;border-radius:0;flex:none;width:30px;height:30px}.kPAopq_teamName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:0 auto;font-size:13px;font-weight:600;line-height:20px;overflow:hidden}.kPAopq_memberCount{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;margin-left:auto;font-size:11px;line-height:16px}.kPAopq_panelButton{border:1px solid var(--dsw-alias-line-strong);background:var(--dsw-alias-bg-module);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;flex:none;padding:2px 8px;font-size:10.5px;font-weight:600;line-height:16px;transition:border-color .12s,color .12s}.kPAopq_panelButton:hover{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.kPAopq_panelButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.kPAopq_members{flex-wrap:wrap;gap:6px;min-width:0;display:flex}.kPAopq_member{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module);max-width:160px;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;align-items:center;gap:5px;padding:3px 8px 3px 3px;font-size:11px;font-weight:500;line-height:16px;transition:border-color .12s,background-color .12s;display:inline-flex}.kPAopq_member:hover{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-fill-neutral)}.kPAopq_member:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.kPAopq_memberArt{object-fit:contain;filter:drop-shadow(0 1px 1px #122d482e);background:0 0;border:0;border-radius:0;width:24px;height:24px}.kPAopq_memberInitial{background:var(--dsw-alias-bg-fill-business);width:20px;height:20px;color:var(--dsw-alias-label-on-fill);border-radius:50%;justify-content:center;align-items:center;font-size:10px;font-weight:600;line-height:20px;display:inline-flex}.kPAopq_memberName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}";\n const tagId$1 = "dsh-plugin-t-expert/TTeamCard.module.css";\n if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {\n const tag = document.createElement("style");\n tag.dataset.plugin = "dsh-plugin-t-expert";\n tag.dataset.pluginCss = tagId$1;\n tag.textContent = css$1;\n document.head.appendChild(tag);\n }\n var TTeamCard_module_css_default = {\n "head": "kPAopq_head",\n "leadAvatar": "kPAopq_leadAvatar",\n "member": "kPAopq_member",\n "memberArt": "kPAopq_memberArt",\n "memberCount": "kPAopq_memberCount",\n "memberInitial": "kPAopq_memberInitial",\n "memberName": "kPAopq_memberName",\n "members": "kPAopq_members",\n "panelButton": "kPAopq_panelButton",\n "root": "kPAopq_root",\n "teamName": "kPAopq_teamName"\n };\n\n\n /**\n * T Team conversation card: the lightweight in-conversation summary for\n * one team \u2014 the captain\'s whale avatar and name, the member roster as\n * clickable whale avatars (opening the member\'s subagent transcript), and\n * an "activity panel" button that re-activates the top-right floater.\n *\n * The floater and this card share the `t-team:open-panel` window event\n * so the card can summon the panel even after it was closed (or when an old\n * session is re-opened for review).\n * @module t-team/client/card\n */\n /** Window event name the floater listens for to open itself. */\n const OPEN_PANEL_EVENT = "t-team:open-panel";\n /** Re-activate the top-right activity panel, carrying this team\'s summary\n * so the panel can show it even when the team no longer exists on disk\n * (historical session review). */\n function openActivityPanel(data) {\n window.dispatchEvent(new CustomEvent(OPEN_PANEL_EVENT, { detail: {\n teamId: data.teamId,\n captainSessionId: data.captainSessionId,\n teamName: data.teamName,\n members: data.members\n } }));\n }\n /** Render one durable team as a compact conversation card. */\n function TTeamCard({ node, openMember, sessionId, t }) {\n const data = node.data;\n const owner = data.captainSessionId || sessionId;\n const { teams, archivedTeams } = (0, react.useSyncExternalStore)(subscribeActivitySnapshots, getActivitySnapshotsSnapshot);\n (0, react.useEffect)(() => {\n return monitorAgentTeam(owner, data.teamId);\n }, [data.teamId, owner]);\n const snapshot = teams.find((team) => team.teamId === data.teamId && (owner === "" || team.captainSessionId === owner)) ?? archivedTeams.find((team) => team.teamId === data.teamId && (owner === "" || team.captainSessionId === owner));\n const resolved = (0, react.useMemo)(() => ({\n ...data,\n captainSessionId: snapshot?.captainSessionId ?? owner,\n teamName: snapshot?.name ?? data.teamName,\n members: snapshot?.members.map((member) => ({\n id: member.id,\n name: member.name,\n role: member.role\n })) ?? data.members\n }), [\n data,\n owner,\n snapshot\n ]);\n return (0, react_jsx_runtime.jsxs)("section", {\n className: TTeamCard_module_css_default.root,\n "data-t-team-card": true,\n "data-team-id": resolved.teamId,\n children: [(0, react_jsx_runtime.jsxs)("header", {\n className: TTeamCard_module_css_default.head,\n children: [\n (0, react_jsx_runtime.jsx)("img", {\n className: TTeamCard_module_css_default.leadAvatar,\n src: LEAD_ART,\n alt: "",\n "aria-hidden": true\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: TTeamCard_module_css_default.teamName,\n title: resolved.teamName,\n children: resolved.teamName\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: TTeamCard_module_css_default.memberCount,\n children: t("card.memberCount", { count: resolved.members.length })\n }),\n (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n className: TTeamCard_module_css_default.panelButton,\n onClick: () => {\n openActivityPanel(resolved);\n },\n "aria-label": t("action.openActivityPanel"),\n title: t("action.openActivityPanel"),\n children: t("activity.panelButton")\n })\n ]\n }), resolved.members.length > 0 && (0, react_jsx_runtime.jsx)("div", {\n className: TTeamCard_module_css_default.members,\n children: resolved.members.map((member) => (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: TTeamCard_module_css_default.member,\n onClick: () => {\n if (member.id !== "") openMember(owner, member.id);\n },\n title: member.role === "" ? member.name : `${member.name} \xB7 ${member.role}`,\n children: [memberArtUrl(member.name, member.role) !== null ? (0, react_jsx_runtime.jsx)("img", {\n className: TTeamCard_module_css_default.memberArt,\n src: memberArtUrl(member.name, member.role) ?? "",\n alt: "",\n "aria-hidden": true\n }) : (0, react_jsx_runtime.jsx)("span", {\n className: TTeamCard_module_css_default.memberInitial,\n children: member.name.trim().slice(0, 1).toUpperCase() || "?"\n }), (0, react_jsx_runtime.jsx)("span", {\n className: TTeamCard_module_css_default.memberName,\n children: member.name\n })]\n }, member.id))\n })]\n });\n }\n\n\n const css = "html{--t-team-panel-shift:420px}html[data-t-team-panel-open] [data-phase=active]{box-sizing:border-box;padding-right:var(--t-team-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_tTeamPulse}.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_tTeamPanelIn;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_tTeamPanelIn{0%{opacity:0}to{opacity:1}}@keyframes aYQbCq_tTeamPulse{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:5;touch-action:none;pointer-events:auto;position:absolute}.aYQbCq_resizeHandle[data-resize-edge=left]{cursor:ew-resize;width:14px;top:44px;bottom:14px;left:0}.aYQbCq_resizeHandle[data-resize-edge=left]:after{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 42%, transparent);content:\\"\\";opacity:.45;border-radius:999px;width:3px;height:48px;transition:background-color .12s,opacity .12s;position:absolute;top:50%;left:4px;transform:translateY(-50%)}.aYQbCq_resizeHandle[data-resize-edge=bottom]{cursor:ns-resize;height:14px;bottom:0;left:20px;right:20px}.aYQbCq_resizeHandle[data-resize-edge=bottom]:after{background:color-mix(in srgb, var(--dsw-alias-label-tertiary) 42%, transparent);content:\\"\\";opacity:.45;border-radius:999px;width:48px;height:3px;transition:background-color .12s,opacity .12s;position:absolute;bottom:4px;left:50%;transform:translate(-50%)}.aYQbCq_resizeHandle[data-resize-edge=corner]{cursor:nwse-resize;width:28px;height:28px;bottom:0;right:0}.aYQbCq_resizeHandle[data-resize-edge=corner]:after{border-right:2px solid var(--dsw-alias-label-tertiary);border-bottom:2px solid var(--dsw-alias-label-tertiary);content:\\"\\";opacity:.58;width:10px;height:10px;transition:border-color .12s,opacity .12s;position:absolute;bottom:6px;right:6px}.aYQbCq_resizeHandle:hover:after,.aYQbCq_panel[data-resizing] .aYQbCq_resizeHandle:after{background-color:var(--dsw-alias-bg-fill-business);border-color:var(--dsw-alias-bg-fill-business);opacity:.95}.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_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_memberModel{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-fill-neutral);min-width:0;max-width:132px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;flex:0 auto;align-items:center;padding:0 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;font-weight:600;line-height:15px;display:inline-flex;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-bg-fill-business)}.aYQbCq_workGlyph rect{opacity:.5}.aYQbCq_workGlyph[data-active=true] rect{animation:1.1s ease-in-out infinite aYQbCq_tTeamDot}@keyframes aYQbCq_tTeamDot{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_tTeamUnreadPulse;position:absolute;top:0;right:-1px}@keyframes aYQbCq_tTeamUnreadPulse{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_tTeamFloat}.aYQbCq_stateArt[data-activity=idle]{animation:4.2s ease-in-out infinite aYQbCq_tTeamBreathe}.aYQbCq_stateArt[data-activity=unknown]{animation:2.8s ease-in-out infinite aYQbCq_tTeamThink}@keyframes aYQbCq_tTeamFloat{0%,to{transform:translateY(0)rotate(-4deg)}50%{transform:translateY(-2px)rotate(4deg)}}@keyframes aYQbCq_tTeamBreathe{0%,to{opacity:.82;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}@keyframes aYQbCq_tTeamThink{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-t-team-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%}}";\n const tagId = "dsh-plugin-t-expert/ActivityPanel.module.css";\n if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {\n const tag = document.createElement("style");\n tag.dataset.plugin = "dsh-plugin-t-expert";\n tag.dataset.pluginCss = tagId;\n tag.textContent = css;\n document.head.appendChild(tag);\n }\n var ActivityPanel_module_css_default = {\n "agent-team": "aYQbCq_agent-team",\n "tTeamBreathe": "aYQbCq_tTeamBreathe",\n "tTeamDot": "aYQbCq_tTeamDot",\n "tTeamFloat": "aYQbCq_tTeamFloat",\n "tTeamPanelIn": "aYQbCq_tTeamPanelIn",\n "tTeamPulse": "aYQbCq_tTeamPulse",\n "tTeamThink": "aYQbCq_tTeamThink",\n "tTeamUnreadPulse": "aYQbCq_tTeamUnreadPulse",\n "archiveLabel": "aYQbCq_archiveLabel",\n "assignmentChip": "aYQbCq_assignmentChip",\n "assignmentLabel": "aYQbCq_assignmentLabel",\n "assignmentLine": "aYQbCq_assignmentLine",\n "assignmentTasks": "aYQbCq_assignmentTasks",\n "badge": "aYQbCq_badge",\n "badgeCount": "aYQbCq_badgeCount",\n "badgeDot": "aYQbCq_badgeDot",\n "captainAvatar": "aYQbCq_captainAvatar",\n "captainInfo": "aYQbCq_captainInfo",\n "captainLine": "aYQbCq_captainLine",\n "captainName": "aYQbCq_captainName",\n "captainNode": "aYQbCq_captainNode",\n "captainRole": "aYQbCq_captainRole",\n "captainState": "aYQbCq_captainState",\n "captainSummary": "aYQbCq_captainSummary",\n "chevron": "aYQbCq_chevron",\n "dagCanvas": "aYQbCq_dagCanvas",\n "dagEdges": "aYQbCq_dagEdges",\n "dagNode": "aYQbCq_dagNode",\n "dagNodeDot": "aYQbCq_dagNodeDot",\n "dagNodeHead": "aYQbCq_dagNodeHead",\n "dagNodeLabel": "aYQbCq_dagNodeLabel",\n "dagRunningState": "aYQbCq_dagRunningState",\n "dagViewport": "aYQbCq_dagViewport",\n "delegationSection": "aYQbCq_delegationSection",\n "delegationTree": "aYQbCq_delegationTree",\n "dependencySection": "aYQbCq_dependencySection",\n "emptyHint": "aYQbCq_emptyHint",\n "historicPill": "aYQbCq_historicPill",\n "iconButton": "aYQbCq_iconButton",\n "leadAvatar": "aYQbCq_leadAvatar",\n "memberArt": "aYQbCq_memberArt",\n "memberAvatar": "aYQbCq_memberAvatar",\n "memberBlock": "aYQbCq_memberBlock",\n "memberBranch": "aYQbCq_memberBranch",\n "memberCount": "aYQbCq_memberCount",\n "memberInfo": "aYQbCq_memberInfo",\n "memberInitial": "aYQbCq_memberInitial",\n "memberLine": "aYQbCq_memberLine",\n "memberModel": "aYQbCq_memberModel",\n "memberName": "aYQbCq_memberName",\n "memberRole": "aYQbCq_memberRole",\n "memberRow": "aYQbCq_memberRow",\n "memberState": "aYQbCq_memberState",\n "memberStatusLine": "aYQbCq_memberStatusLine",\n "members": "aYQbCq_members",\n "membersToggle": "aYQbCq_membersToggle",\n "panel": "aYQbCq_panel",\n "panelControls": "aYQbCq_panelControls",\n "panelDot": "aYQbCq_panelDot",\n "panelHead": "aYQbCq_panelHead",\n "panelTitle": "aYQbCq_panelTitle",\n "plan-feedback-in": "aYQbCq_plan-feedback-in",\n "planActions": "aYQbCq_planActions",\n "planApproveActions": "aYQbCq_planApproveActions",\n "planApproveCopy": "aYQbCq_planApproveCopy",\n "planApproveRow": "aYQbCq_planApproveRow",\n "planCard": "aYQbCq_planCard",\n "planCardBody": "aYQbCq_planCardBody",\n "planCardHeader": "aYQbCq_planCardHeader",\n "planCardIdentity": "aYQbCq_planCardIdentity",\n "planCardMeta": "aYQbCq_planCardMeta",\n "planChevron": "aYQbCq_planChevron",\n "planConfirm": "aYQbCq_planConfirm",\n "planDirty": "aYQbCq_planDirty",\n "planEditor": "aYQbCq_planEditor",\n "planEmpty": "aYQbCq_planEmpty",\n "planFeedback": "aYQbCq_planFeedback",\n "planFlow": "aYQbCq_planFlow",\n "planGrid": "aYQbCq_planGrid",\n "planHeader": "aYQbCq_planHeader",\n "planList": "aYQbCq_planList",\n "planModelEffortRow": "aYQbCq_planModelEffortRow",\n "planModelHint": "aYQbCq_planModelHint",\n "planModelMenu": "aYQbCq_planModelMenu",\n "planModelMenuBack": "aYQbCq_planModelMenuBack",\n "planModelMenuRow": "aYQbCq_planModelMenuRow",\n "planModelNotice": "aYQbCq_planModelNotice",\n "planModelPicker": "aYQbCq_planModelPicker",\n "planModelTrigger": "aYQbCq_planModelTrigger",\n "planModelTriggerCopy": "aYQbCq_planModelTriggerCopy",\n "planNewTask": "aYQbCq_planNewTask",\n "planReviewActions": "aYQbCq_planReviewActions",\n "planSecondaryActions": "aYQbCq_planSecondaryActions",\n "planSection": "aYQbCq_planSection",\n "planSectionToggle": "aYQbCq_planSectionToggle",\n "planTaskId": "aYQbCq_planTaskId",\n "planTaskSummary": "aYQbCq_planTaskSummary",\n "progressEmpty": "aYQbCq_progressEmpty",\n "progressLegend": "aYQbCq_progressLegend",\n "progressOverview": "aYQbCq_progressOverview",\n "progressSegments": "aYQbCq_progressSegments",\n "progressSummary": "aYQbCq_progressSummary",\n "progressSummaryDot": "aYQbCq_progressSummaryDot",\n "progressTitle": "aYQbCq_progressTitle",\n "resizeHandle": "aYQbCq_resizeHandle",\n "sectionHead": "aYQbCq_sectionHead",\n "sectionHint": "aYQbCq_sectionHint",\n "sectionTitle": "aYQbCq_sectionTitle",\n "sectionToggleTitle": "aYQbCq_sectionToggleTitle",\n "stageLabel": "aYQbCq_stageLabel",\n "stateArt": "aYQbCq_stateArt",\n "stopModalActions": "aYQbCq_stopModalActions",\n "stopModalError": "aYQbCq_stopModalError",\n "taskDetail": "aYQbCq_taskDetail",\n "taskDetailBadge": "aYQbCq_taskDetailBadge",\n "taskDetailHead": "aYQbCq_taskDetailHead",\n "taskDetailId": "aYQbCq_taskDetailId",\n "taskDetailLine": "aYQbCq_taskDetailLine",\n "taskDetailMeta": "aYQbCq_taskDetailMeta",\n "taskDetailModel": "aYQbCq_taskDetailModel",\n "taskDetailSubject": "aYQbCq_taskDetailSubject",\n "taskEmpty": "aYQbCq_taskEmpty",\n "taskId": "aYQbCq_taskId",\n "team": "aYQbCq_team",\n "teamHead": "aYQbCq_teamHead",\n "teamName": "aYQbCq_teamName",\n "teamStats": "aYQbCq_teamStats",\n "teamStopButton": "aYQbCq_teamStopButton",\n "teams": "aYQbCq_teams",\n "unreadPill": "aYQbCq_unreadPill",\n "workGlyph": "aYQbCq_workGlyph"\n };\n\n\n /**\n * Editable pre-run roster and DAG review for staged T Team plans.\n *\n * This leaf owns only transient form/disclosure state. Durable truth remains\n * on the host and returns through the ordinary activity polling snapshot.\n * @module t-team/client/staging-plan\n */\n const PLAN_URL = "/plugins/t-team/plan";\n function useDismissSuccess(feedback, setFeedback) {\n (0, react.useEffect)(() => {\n if (feedback?.tone !== "success") return;\n const timeout = window.setTimeout(() => {\n setFeedback(void 0);\n }, 3500);\n return () => {\n window.clearTimeout(timeout);\n };\n }, [feedback, setFeedback]);\n }\n async function mutatePlan(payload) {\n const response = await fetch(PLAN_URL, {\n method: "POST",\n cache: "no-store",\n headers: { "content-type": "application/json" },\n body: JSON.stringify(payload)\n });\n if (response.ok) return;\n let message = `HTTP ${response.status}`;\n try {\n const body = await response.json();\n if (typeof body.error === "string" && body.error.trim() !== "") message = body.error;\n } catch {}\n throw new Error(message);\n }\n function errorMessage(error) {\n return error instanceof Error ? error.message : String(error);\n }\n function DisclosureChevron({ open }) {\n return (0, react_jsx_runtime.jsx)("svg", {\n className: ActivityPanel_module_css_default.planChevron,\n "data-open": open,\n width: "12",\n height: "12",\n viewBox: "0 0 12 12",\n fill: "none",\n stroke: "currentColor",\n strokeWidth: "1.5",\n strokeLinecap: "round",\n "aria-hidden": true,\n children: (0, react_jsx_runtime.jsx)("path", { d: "M4 2.5 7.5 6 4 9.5" })\n });\n }\n function Feedback({ value }) {\n if (value === void 0) return null;\n return (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planFeedback,\n "data-tone": value.tone,\n role: value.tone === "error" ? "alert" : "status",\n "aria-live": value.tone === "error" ? "assertive" : "polite",\n children: [(0, react_jsx_runtime.jsx)("span", {\n "aria-hidden": true,\n children: value.tone === "success" ? (0, react_jsx_runtime.jsx)("svg", {\n viewBox: "0 0 12 12",\n fill: "none",\n stroke: "currentColor",\n strokeWidth: "1.8",\n children: (0, react_jsx_runtime.jsx)("path", { d: "m2.5 6.2 2.2 2.2 4.8-5" })\n }) : (0, react_jsx_runtime.jsx)("svg", {\n viewBox: "0 0 12 12",\n fill: "none",\n stroke: "currentColor",\n strokeWidth: "1.8",\n children: (0, react_jsx_runtime.jsx)("path", { d: "M6 2.3v4.1M6 8.8v.1" })\n })\n }), value.message]\n });\n }\n function routeKey(provider, model) {\n return JSON.stringify([provider, model]);\n }\n const MODEL_MENU_OPEN_MODELS = "open:models";\n const MODEL_MENU_OPEN_EFFORT = "open:effort";\n const MODEL_MENU_BACK = "navigate:back";\n const MODEL_MENU_RETRY = "action:retry";\n const MODEL_MENU_DEFAULT_EFFORT = "effort:default";\n function modelMenuId(provider, model) {\n return `model:${routeKey(provider, model)}`;\n }\n function effortMenuId(effort) {\n return `effort:${effort}`;\n }\n /**\n * Thin staged-plan adapter over the official model directory. It deliberately\n * reads only catalog metadata: choosing a member route must not change the\n * captain session\'s composer model.\n */\n function StagedModelPicker({ directory, provider, model, reasoningEffort, busy, onChange, t }) {\n const state = (0, react.useSyncExternalStore)(directory.store.subscribe, directory.store.getSnapshot);\n const [open, setOpen] = (0, react.useState)(false);\n const [pane, setPane] = (0, react.useState)("root");\n const catalogRoutes = state.groups.flatMap((group) => group.models.map((candidate) => ({\n key: routeKey(group.id, candidate.id),\n provider: group.id,\n providerName: group.name,\n model: candidate\n })));\n const selectedKey = routeKey(provider, model);\n const selected = catalogRoutes.find((candidate) => candidate.key === selectedKey);\n const efforts = selected?.model.reasoning?.efforts ?? [];\n const currentMissing = provider !== "" && model !== "" && selected === void 0;\n const defaultEffort = selected?.model.reasoning?.defaultEffort;\n const effectiveEffort = reasoningEffort === "" || reasoningEffort === "default" ? defaultEffort : reasoningEffort;\n const selectedEffort = efforts.find((effort) => effort.id === effectiveEffort);\n const modelLabel = selected?.model.name ?? (model === "" ? t("plan.model.choose") : model);\n const effortLabel = selectedEffort?.name ?? (effectiveEffort === void 0 ? t("plan.model.providerDefault") : effectiveEffort);\n const unavailable = state.status === "error" || state.failures.length > 0;\n const close = () => {\n setOpen(false);\n setPane("root");\n };\n const rootItems = [{\n id: MODEL_MENU_OPEN_MODELS,\n label: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelMenuRow,\n children: [\n (0, react_jsx_runtime.jsx)("span", { children: t("plan.member.model") }),\n (0, react_jsx_runtime.jsx)("strong", { children: modelLabel }),\n (0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false })\n ]\n }),\n disabled: state.status === "loading" && catalogRoutes.length === 0\n }, {\n id: MODEL_MENU_OPEN_EFFORT,\n label: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelMenuRow,\n children: [\n (0, react_jsx_runtime.jsx)("span", { children: t("plan.member.reasoning") }),\n (0, react_jsx_runtime.jsx)("strong", { children: effortLabel }),\n (0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false })\n ]\n }),\n disabled: selected?.model.reasoning === void 0\n }];\n const modelItems = [{\n id: MODEL_MENU_BACK,\n label: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelMenuBack,\n children: [(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false }), t("plan.model.back")]\n })\n }, {\n type: "separator",\n id: "models:separator"\n }];\n if (catalogRoutes.length === 0) modelItems.push({\n id: "models:empty",\n label: state.status === "loading" ? t("plan.model.loading") : t("plan.model.empty"),\n disabled: true\n });\n else for (const group of state.groups) {\n modelItems.push({\n type: "label",\n id: `provider:${group.id}`,\n text: group.name\n });\n for (const candidate of group.models) modelItems.push({\n id: modelMenuId(group.id, candidate.id),\n label: candidate.name\n });\n }\n const effortItems = [\n {\n id: MODEL_MENU_BACK,\n label: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelMenuBack,\n children: [(0, react_jsx_runtime.jsx)(DisclosureChevron, { open: false }), t("plan.model.back")]\n })\n },\n {\n type: "separator",\n id: "effort:separator"\n },\n {\n id: MODEL_MENU_DEFAULT_EFFORT,\n label: defaultEffort === void 0 ? t("plan.model.providerDefault") : t("plan.model.modelDefault", { effort: efforts.find((effort) => effort.id === defaultEffort)?.name ?? defaultEffort })\n },\n ...efforts.map((effort) => ({\n id: effortMenuId(effort.id),\n label: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelEffortRow,\n children: [(0, react_jsx_runtime.jsx)("span", { children: effort.name }), effort.description !== void 0 && (0, react_jsx_runtime.jsx)("small", { children: effort.description })]\n })\n }))\n ];\n const items = pane === "models" ? modelItems : pane === "effort" ? effortItems : rootItems;\n const selectedId = pane === "models" ? modelMenuId(provider, model) : pane === "effort" ? reasoningEffort === "" || reasoningEffort === "default" ? MODEL_MENU_DEFAULT_EFFORT : effortMenuId(reasoningEffort) : void 0;\n const choose = (id) => {\n if (id === MODEL_MENU_OPEN_MODELS) {\n setPane("models");\n return;\n }\n if (id === MODEL_MENU_OPEN_EFFORT) {\n setPane("effort");\n return;\n }\n if (id === MODEL_MENU_BACK) {\n setPane("root");\n return;\n }\n if (id === MODEL_MENU_RETRY) {\n directory.load().catch(() => void 0);\n return;\n }\n const nextModel = catalogRoutes.find((candidate) => modelMenuId(candidate.provider, candidate.model.id) === id);\n if (nextModel !== void 0) {\n close();\n if (nextModel.provider === provider && nextModel.model.id === model) return;\n onChange({\n provider: nextModel.provider,\n model: nextModel.model.id,\n reasoningEffort: "default"\n });\n return;\n }\n if (id === MODEL_MENU_DEFAULT_EFFORT) {\n close();\n if (effectiveEffort === defaultEffort) return;\n onChange({\n provider,\n model,\n reasoningEffort: "default"\n });\n return;\n }\n const nextEffort = efforts.find((effort) => effortMenuId(effort.id) === id);\n if (nextEffort === void 0) return;\n close();\n if (nextEffort.id === reasoningEffort) return;\n onChange({\n provider,\n model,\n reasoningEffort: nextEffort.id\n });\n };\n return (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.planModelPicker,\n "data-model-directory-status": state.status,\n children: [\n (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {\n open,\n portal: true,\n align: "end",\n compact: true,\n className: ActivityPanel_module_css_default.planModelMenu,\n items,\n footer: unavailable ? [{\n id: MODEL_MENU_RETRY,\n label: t("plan.model.retry")\n }] : void 0,\n selectedId,\n onSelect: choose,\n onClose: close,\n anchor: (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.planModelTrigger,\n "data-plan-model-trigger": true,\n "aria-label": t("plan.model.triggerAria", {\n model: modelLabel,\n effort: effortLabel\n }),\n "aria-haspopup": "menu",\n "aria-expanded": open,\n disabled: busy,\n onClick: () => {\n if (open) close();\n else {\n setPane("root");\n setOpen(true);\n directory.load().catch(() => void 0);\n }\n },\n children: [(0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelTriggerCopy,\n 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 })]\n }), (0, react_jsx_runtime.jsx)(DisclosureChevron, { open })]\n })\n }),\n (0, react_jsx_runtime.jsx)("small", {\n className: ActivityPanel_module_css_default.planModelHint,\n children: currentMissing ? t("plan.model.currentUnavailable", {\n provider,\n model\n }) : selected?.model.description ?? t("plan.model.route", {\n provider,\n model\n })\n }),\n unavailable && (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planModelNotice,\n role: state.status === "error" ? "alert" : "status",\n children: [(0, react_jsx_runtime.jsx)("span", { children: state.error ?? t("plan.model.partialFailure", { count: state.failures.length }) }), (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n disabled: busy || state.status === "loading",\n onClick: () => {\n directory.load().catch(() => void 0);\n },\n children: t("plan.model.retry")\n })]\n })\n ]\n });\n }\n function StagedMemberEditor({ team, member, modelDirectory, onPendingChange, t }) {\n const bodyId = (0, react.useId)();\n const [open, setOpen] = (0, react.useState)(false);\n const [role, setRole] = (0, react.useState)(member.role);\n const [provider, setProvider] = (0, react.useState)(member.provider ?? "");\n const [model, setModel] = (0, react.useState)(member.model ?? "");\n const [reasoningEffort, setReasoningEffort] = (0, react.useState)(member.reasoningEffort ?? "");\n const [executionPrompt, setExecutionPrompt] = (0, react.useState)(member.executionPrompt ?? "");\n const remoteSignature = JSON.stringify([\n member.role,\n member.provider ?? "",\n member.model ?? "",\n member.reasoningEffort ?? "",\n member.executionPrompt ?? ""\n ]);\n const [savedSignature, setSavedSignature] = (0, react.useState)(remoteSignature);\n const [busy, setBusy] = (0, react.useState)(false);\n const [feedback, setFeedback] = (0, react.useState)();\n useDismissSuccess(feedback, setFeedback);\n const dirty = JSON.stringify([\n role,\n provider,\n model,\n reasoningEffort,\n executionPrompt\n ]) !== savedSignature;\n (0, react.useEffect)(() => {\n onPendingChange(`member:${member.name}`, dirty || busy);\n return () => {\n onPendingChange(`member:${member.name}`, false);\n };\n }, [\n busy,\n dirty,\n member.name,\n onPendingChange\n ]);\n (0, react.useEffect)(() => {\n setRole(member.role);\n setProvider(member.provider ?? "");\n setModel(member.model ?? "");\n setReasoningEffort(member.reasoningEffort ?? "");\n setExecutionPrompt(member.executionPrompt ?? "");\n setSavedSignature(remoteSignature);\n }, [\n member.role,\n member.provider,\n member.model,\n member.reasoningEffort,\n member.executionPrompt,\n remoteSignature\n ]);\n const markEdited = () => {\n setFeedback(void 0);\n };\n const persist = async (selection = {\n provider,\n model,\n reasoningEffort\n }) => {\n const nextSignature = JSON.stringify([\n role,\n selection.provider,\n selection.model,\n selection.reasoningEffort,\n executionPrompt\n ]);\n setProvider(selection.provider);\n setModel(selection.model);\n setReasoningEffort(selection.reasoningEffort);\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "update_member",\n memberName: member.name,\n role,\n provider: selection.provider,\n model: selection.model,\n reasoningEffort: selection.reasoningEffort,\n executionPrompt\n });\n setSavedSignature(nextSignature);\n setFeedback({\n tone: "success",\n message: t("plan.saved")\n });\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n } finally {\n setBusy(false);\n }\n };\n const save = async (event) => {\n event.preventDefault();\n await persist();\n };\n const route = `${provider}/${model}`.replace(/^\\//u, "");\n return (0, react_jsx_runtime.jsxs)("article", {\n className: ActivityPanel_module_css_default.planCard,\n "data-plan-member": member.name,\n "data-open": open,\n children: [(0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.planCardHeader,\n "aria-expanded": open,\n "aria-controls": bodyId,\n onClick: () => {\n setOpen((current) => !current);\n },\n children: [\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planCardIdentity,\n children: [(0, react_jsx_runtime.jsx)("strong", { children: member.name }), (0, react_jsx_runtime.jsx)("span", { children: role || t("plan.member.roleFallback") })]\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.planCardMeta,\n title: route,\n children: route\n }),\n dirty && (0, react_jsx_runtime.jsx)("em", {\n className: ActivityPanel_module_css_default.planDirty,\n children: t("plan.unsaved")\n }),\n (0, react_jsx_runtime.jsx)(DisclosureChevron, { open })\n ]\n }), open && (0, react_jsx_runtime.jsxs)("form", {\n id: bodyId,\n className: ActivityPanel_module_css_default.planCardBody,\n onSubmit: (event) => {\n save(event);\n },\n children: [(0, react_jsx_runtime.jsxs)("fieldset", {\n disabled: busy,\n children: [\n (0, react_jsx_runtime.jsxs)("label", { children: [t("plan.member.role"), (0, react_jsx_runtime.jsx)("input", {\n name: "role",\n value: role,\n onChange: (event) => {\n setRole(event.currentTarget.value);\n markEdited();\n }\n })] }),\n (0, react_jsx_runtime.jsx)(StagedModelPicker, {\n directory: modelDirectory,\n provider,\n model,\n reasoningEffort,\n busy,\n onChange: (selection) => {\n persist(selection);\n },\n t\n }),\n (0, react_jsx_runtime.jsxs)("label", { children: [t("plan.member.prompt"), (0, react_jsx_runtime.jsx)("textarea", {\n name: "executionPrompt",\n value: executionPrompt,\n onChange: (event) => {\n setExecutionPrompt(event.currentTarget.value);\n markEdited();\n },\n rows: 3\n })] })\n ]\n }), (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planActions,\n children: [(0, react_jsx_runtime.jsx)(Feedback, { value: feedback }), (0, react_jsx_runtime.jsx)("button", {\n type: "submit",\n disabled: busy || !dirty || provider.trim() === "" || model.trim() === "",\n children: busy ? t("plan.saving") : t("plan.save")\n })]\n })]\n })]\n });\n }\n function StagedTaskEditor({ team, task, onPendingChange, t }) {\n const bodyId = (0, react.useId)();\n const taskDependencies = task.dependencies.join(", ");\n const [open, setOpen] = (0, react.useState)(false);\n const [subject, setSubject] = (0, react.useState)(task.subject);\n const [description, setDescription] = (0, react.useState)(task.description ?? "");\n const [assignee, setAssignee] = (0, react.useState)(task.assignee);\n const [dependencies, setDependencies] = (0, react.useState)(taskDependencies);\n const remoteSignature = JSON.stringify([\n task.subject,\n task.description ?? "",\n task.assignee,\n taskDependencies\n ]);\n const [savedSignature, setSavedSignature] = (0, react.useState)(remoteSignature);\n const [busy, setBusy] = (0, react.useState)(false);\n const [confirmingRemove, setConfirmingRemove] = (0, react.useState)(false);\n const [feedback, setFeedback] = (0, react.useState)();\n useDismissSuccess(feedback, setFeedback);\n const signature = JSON.stringify([\n subject,\n description,\n assignee,\n dependencies\n ]);\n const dirty = signature !== savedSignature;\n (0, react.useEffect)(() => {\n onPendingChange(`task:${task.id}`, dirty || busy);\n return () => {\n onPendingChange(`task:${task.id}`, false);\n };\n }, [\n busy,\n dirty,\n onPendingChange,\n task.id\n ]);\n (0, react.useEffect)(() => {\n setSubject(task.subject);\n setDescription(task.description ?? "");\n setAssignee(task.assignee);\n setDependencies(taskDependencies);\n setSavedSignature(remoteSignature);\n }, [\n task.subject,\n task.description,\n task.assignee,\n taskDependencies,\n remoteSignature\n ]);\n const markEdited = () => {\n setFeedback(void 0);\n setConfirmingRemove(false);\n };\n const save = async (event) => {\n event.preventDefault();\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "update_task",\n taskId: task.id,\n subject,\n description,\n assignee,\n dependencies: dependencies.split(",").map((item) => item.trim()).filter(Boolean)\n });\n setSavedSignature(signature);\n setFeedback({\n tone: "success",\n message: t("plan.saved")\n });\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n } finally {\n setBusy(false);\n }\n };\n const remove = async () => {\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "remove_task",\n taskId: task.id\n });\n setFeedback({\n tone: "success",\n message: t("plan.removed")\n });\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n setBusy(false);\n }\n };\n const dependencySummary = task.dependencies.length === 0 ? t("plan.dependencies.none") : t("plan.dependencies.count", { count: task.dependencies.length });\n return (0, react_jsx_runtime.jsxs)("article", {\n className: ActivityPanel_module_css_default.planCard,\n "data-plan-task": task.id,\n "data-open": open,\n children: [(0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.planCardHeader,\n "aria-expanded": open,\n "aria-controls": bodyId,\n onClick: () => {\n setOpen((current) => !current);\n },\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.planTaskId,\n children: task.id\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.planTaskSummary,\n title: subject,\n children: subject\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planCardMeta,\n children: [\n assignee || t("plan.task.unassigned"),\n " \xB7 ",\n dependencySummary\n ]\n }),\n dirty && (0, react_jsx_runtime.jsx)("em", {\n className: ActivityPanel_module_css_default.planDirty,\n children: t("plan.unsaved")\n }),\n (0, react_jsx_runtime.jsx)(DisclosureChevron, { open })\n ]\n }), open && (0, react_jsx_runtime.jsxs)("form", {\n id: bodyId,\n className: ActivityPanel_module_css_default.planCardBody,\n onSubmit: (event) => {\n save(event);\n },\n children: [\n (0, react_jsx_runtime.jsxs)("fieldset", {\n disabled: busy,\n children: [\n (0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.subject"), (0, react_jsx_runtime.jsx)("input", {\n name: "subject",\n required: true,\n value: subject,\n onChange: (event) => {\n setSubject(event.currentTarget.value);\n markEdited();\n }\n })] }),\n (0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.description"), (0, react_jsx_runtime.jsx)("textarea", {\n name: "description",\n value: description,\n onChange: (event) => {\n setDescription(event.currentTarget.value);\n markEdited();\n },\n rows: 3\n })] }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planGrid,\n children: [(0, react_jsx_runtime.jsxs)("label", { children: [t("plan.task.assignee"), (0, react_jsx_runtime.jsxs)("select", {\n name: "assignee",\n value: assignee,\n onChange: (event) => {\n setAssignee(event.currentTarget.value);\n markEdited();\n },\n children: [(0, react_jsx_runtime.jsx)("option", {\n value: "",\n children: t("plan.task.unassigned")\n }), team.members.map((member) => (0, react_jsx_runtime.jsx)("option", {\n value: member.name,\n children: member.name\n }, member.name))]\n })] }), (0, react_jsx_runtime.jsxs)("label", { children: [\n t("plan.task.dependencies"),\n (0, react_jsx_runtime.jsx)("input", {\n name: "dependencies",\n value: dependencies,\n onChange: (event) => {\n setDependencies(event.currentTarget.value);\n markEdited();\n }\n }),\n (0, react_jsx_runtime.jsx)("small", { children: t("plan.task.dependenciesHint") })\n ] })]\n })\n ]\n }),\n confirmingRemove && (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planConfirm,\n role: "alert",\n children: [\n (0, react_jsx_runtime.jsx)("span", { children: t("plan.removeWarning", { task: task.id }) }),\n (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n onClick: () => {\n setConfirmingRemove(false);\n },\n children: t("plan.cancel")\n }),\n (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-danger": true,\n "data-confirming": true,\n onClick: () => {\n remove();\n },\n children: t("plan.removeConfirm")\n })\n ]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planActions,\n children: [\n (0, react_jsx_runtime.jsx)(Feedback, { value: feedback }),\n (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-danger": true,\n onClick: () => {\n setConfirmingRemove(true);\n setFeedback(void 0);\n },\n disabled: busy || confirmingRemove,\n children: t("plan.remove")\n }),\n (0, react_jsx_runtime.jsx)("button", {\n type: "submit",\n disabled: busy || !dirty || subject.trim() === "",\n children: busy ? t("plan.saving") : t("plan.save")\n })\n ]\n })\n ]\n })]\n });\n }\n function StagingPlanEditor({ team, modelDirectory, onContinuePlanning, onDiscarded, t }) {\n const membersId = (0, react.useId)();\n const tasksId = (0, react.useId)();\n const [membersOpen, setMembersOpen] = (0, react.useState)(true);\n const [tasksOpen, setTasksOpen] = (0, react.useState)(true);\n const [newTask, setNewTask] = (0, react.useState)("");\n const [busy, setBusy] = (0, react.useState)(false);\n const [discardArmed, setDiscardArmed] = (0, react.useState)(false);\n const [pendingEditors, setPendingEditors] = (0, react.useState)(/* @__PURE__ */ new Set());\n const [feedback, setFeedback] = (0, react.useState)();\n useDismissSuccess(feedback, setFeedback);\n const dependencyLinks = team.tasks.reduce((total, task) => total + task.dependencies.length, 0);\n const runnable = team.members.length > 0 && team.tasks.length > 0;\n const hasPendingEdits = pendingEditors.size > 0 || newTask.trim() !== "";\n const waitingForFeedback = team.planReviewState === "awaiting_feedback";\n (0, react.useEffect)(() => {\n modelDirectory.load().catch(() => void 0);\n }, [modelDirectory]);\n const onPendingChange = (0, react.useCallback)((key, pending) => {\n setPendingEditors((current) => {\n if (pending === current.has(key)) return current;\n const next = new Set(current);\n if (pending) next.add(key);\n else next.delete(key);\n return next;\n });\n }, []);\n const addTask = async (event) => {\n event.preventDefault();\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "add_task",\n subject: newTask,\n dependencies: []\n });\n setNewTask("");\n setFeedback({\n tone: "success",\n message: t("plan.taskAdded")\n });\n setTasksOpen(true);\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n } finally {\n setBusy(false);\n }\n };\n const approve = async () => {\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "approve"\n });\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n setBusy(false);\n }\n };\n const continueInChat = async () => {\n if (waitingForFeedback) {\n onContinuePlanning();\n return;\n }\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "continue"\n });\n onContinuePlanning();\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n setBusy(false);\n }\n };\n const discard = async () => {\n setBusy(true);\n setFeedback(void 0);\n try {\n await mutatePlan({\n sessionId: team.captainSessionId,\n teamId: team.teamId,\n action: "discard"\n });\n onDiscarded();\n } catch (error) {\n setFeedback({\n tone: "error",\n message: t("plan.failed", { message: errorMessage(error) })\n });\n setBusy(false);\n setDiscardArmed(false);\n }\n };\n return (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.planEditor,\n "data-staging-editor": true,\n children: [\n (0, react_jsx_runtime.jsxs)("header", {\n className: ActivityPanel_module_css_default.planHeader,\n 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", {\n members: team.members.length,\n tasks: team.tasks.length,\n links: dependencyLinks\n }) })] }), (0, react_jsx_runtime.jsx)("em", { children: t("plan.badge") })] }), (0, react_jsx_runtime.jsx)("p", { children: t("plan.description") })]\n }),\n (0, react_jsx_runtime.jsxs)("ol", {\n className: ActivityPanel_module_css_default.planFlow,\n "aria-label": t("plan.flow.aria"),\n children: [\n (0, react_jsx_runtime.jsxs)("li", {\n "data-active": true,\n children: [(0, react_jsx_runtime.jsx)("span", { children: "1" }), t("plan.flow.review")]\n }),\n (0, react_jsx_runtime.jsxs)("li", { children: [(0, react_jsx_runtime.jsx)("span", { children: "2" }), t("plan.flow.spawn")] }),\n (0, react_jsx_runtime.jsxs)("li", { children: [(0, react_jsx_runtime.jsx)("span", { children: "3" }), t("plan.flow.run")] })\n ]\n }),\n (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.planSection,\n children: [(0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.planSectionToggle,\n "aria-expanded": membersOpen,\n "aria-controls": membersId,\n onClick: () => {\n setMembersOpen((current) => !current);\n },\n 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 })]\n }), membersOpen && (0, react_jsx_runtime.jsx)("div", {\n id: membersId,\n className: ActivityPanel_module_css_default.planList,\n children: team.members.length === 0 ? (0, react_jsx_runtime.jsx)("p", {\n className: ActivityPanel_module_css_default.planEmpty,\n children: t("plan.members.empty")\n }) : team.members.map((member) => (0, react_jsx_runtime.jsx)(StagedMemberEditor, {\n team,\n member,\n modelDirectory,\n onPendingChange,\n t\n }, member.name))\n })]\n }),\n (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.planSection,\n children: [(0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.planSectionToggle,\n "aria-expanded": tasksOpen,\n "aria-controls": tasksId,\n onClick: () => {\n setTasksOpen((current) => !current);\n },\n 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", {\n count: team.tasks.length,\n links: dependencyLinks\n }) })] }), (0, react_jsx_runtime.jsx)(DisclosureChevron, { open: tasksOpen })]\n }), tasksOpen && (0, react_jsx_runtime.jsx)("div", {\n id: tasksId,\n className: ActivityPanel_module_css_default.planList,\n children: team.tasks.length === 0 ? (0, react_jsx_runtime.jsx)("p", {\n className: ActivityPanel_module_css_default.planEmpty,\n children: t("plan.tasks.empty")\n }) : team.tasks.map((task) => (0, react_jsx_runtime.jsx)(StagedTaskEditor, {\n team,\n task,\n onPendingChange,\n t\n }, task.id))\n })]\n }),\n (0, react_jsx_runtime.jsxs)("form", {\n className: ActivityPanel_module_css_default.planNewTask,\n onSubmit: (event) => {\n addTask(event);\n },\n children: [(0, react_jsx_runtime.jsxs)("label", { children: [(0, react_jsx_runtime.jsx)("span", { children: t("plan.newTaskLabel") }), (0, react_jsx_runtime.jsx)("input", {\n name: "newTask",\n value: newTask,\n onChange: (event) => {\n setNewTask(event.currentTarget.value);\n setFeedback(void 0);\n },\n placeholder: t("plan.newTask"),\n disabled: busy\n })] }), (0, react_jsx_runtime.jsx)("button", {\n type: "submit",\n disabled: busy || newTask.trim() === "",\n children: busy ? t("plan.adding") : t("plan.addTask")\n })]\n }),\n (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.planApproveRow,\n "data-armed": discardArmed || void 0,\n "data-discard": discardArmed || void 0,\n "data-review-state": waitingForFeedback ? "awaiting-feedback" : "awaiting-review",\n children: [\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planApproveCopy,\n 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", {\n members: team.members.length,\n tasks: team.tasks.length\n }) })]\n }),\n (0, react_jsx_runtime.jsx)(Feedback, { value: feedback }),\n discardArmed ? (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planApproveActions,\n children: [(0, react_jsx_runtime.jsx)("button", {\n type: "button",\n disabled: busy,\n onClick: () => {\n setDiscardArmed(false);\n },\n children: t("plan.cancel")\n }), (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-plan-discard": true,\n "data-danger": true,\n "data-confirming": true,\n disabled: busy,\n onClick: () => {\n discard();\n },\n children: busy ? t("plan.discarding") : t("plan.discardConfirm")\n })]\n }) : (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planReviewActions,\n children: [(0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-plan-approve": true,\n disabled: busy || !runnable || hasPendingEdits,\n onClick: () => {\n approve();\n },\n children: t("plan.approve")\n }), (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.planSecondaryActions,\n children: [(0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-plan-continue": true,\n disabled: busy,\n onClick: () => {\n continueInChat();\n },\n children: t(waitingForFeedback ? "plan.returnToChat" : "plan.continue")\n }), (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n "data-plan-discard": true,\n "data-danger": true,\n disabled: busy,\n onClick: () => {\n setDiscardArmed(true);\n setFeedback(void 0);\n },\n children: t("plan.discard")\n })]\n })]\n })\n ]\n })\n ]\n });\n }\n\n\n /** Pure persisted geometry rules for the T Team shell-overlay panel. */\n const PANEL_LAYOUT_STORAGE_KEY = "t-team:activity-panel:v1";\n const DEFAULT_PANEL_LAYOUT = Object.freeze({\n mode: "docked",\n x: 0,\n y: 64,\n width: 388,\n height: 640,\n heightMode: "auto"\n });\n function clamp(value, minimum, maximum) {\n return Math.min(Math.max(value, minimum), maximum);\n }\n function finite(value) {\n return typeof value === "number" && Number.isFinite(value);\n }\n /** Decode one versioned localStorage value, rejecting partial/corrupt state. */\n function parsePanelLayout(value) {\n if (value === null) return DEFAULT_PANEL_LAYOUT;\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed !== "object" || parsed === null) return DEFAULT_PANEL_LAYOUT;\n const record = parsed;\n if (record.mode !== "docked" && record.mode !== "floating" || !finite(record.x) || !finite(record.y) || !finite(record.width) || !finite(record.height)) return DEFAULT_PANEL_LAYOUT;\n return {\n mode: record.mode,\n x: record.x,\n y: record.y,\n width: record.width,\n height: record.height,\n heightMode: record.mode === "floating" && record.heightMode === "manual" ? "manual" : "auto"\n };\n } catch {\n return DEFAULT_PANEL_LAYOUT;\n }\n }\n /** Whether the panel should become a simple inset overlay with no gestures. */\n function compactPanelForBounds(bounds) {\n return bounds.width <= 960;\n }\n /** Docked and compact panels always fit content; floating panels may be user-sized. */\n function panelUsesAutoHeight(layout, bounds) {\n return compactPanelForBounds(bounds) || layout.mode === "docked" || layout.heightMode === "auto";\n }\n /** CSS max-height ceiling that keeps an auto-height panel inside its shell. */\n function panelMaximumHeight(layout, bounds) {\n const bottomInset = compactPanelForBounds(bounds) || layout.mode === "floating" ? 12 : 48;\n return Math.max(1, bounds.height - layout.y - bottomInset);\n }\n /** Resolve persisted state into a visible rectangle inside the current shell. */\n function resolvePanelGeometry(layout, bounds) {\n const boundsWidth = Math.max(1, bounds.width);\n const boundsHeight = Math.max(1, bounds.height);\n if (compactPanelForBounds(bounds)) return {\n ...layout,\n x: 12,\n y: 12,\n width: Math.max(1, boundsWidth - 24),\n height: Math.max(1, boundsHeight - 24)\n };\n const maximumWidth = Math.max(1, Math.min(640, boundsWidth - 24));\n const minimumWidth = Math.min(320, maximumWidth);\n const width = clamp(layout.width, minimumWidth, maximumWidth);\n const maximumHeight = Math.max(1, boundsHeight - 24);\n const minimumHeight = Math.min(360, maximumHeight);\n if (layout.mode === "docked") {\n const y = clamp(64, 12, Math.max(12, boundsHeight - minimumHeight - 12));\n const availableHeight = Math.max(1, boundsHeight - y - 48);\n const height = clamp(availableHeight, Math.min(minimumHeight, availableHeight), maximumHeight);\n const anchorRight = clamp(bounds.anchorRight, 0, boundsWidth);\n const maximumX = Math.max(12, boundsWidth - width - 12);\n return {\n mode: "docked",\n x: clamp(anchorRight - 18 - width, 12, maximumX),\n y,\n width,\n height,\n heightMode: layout.heightMode\n };\n }\n const height = clamp(layout.height, minimumHeight, maximumHeight);\n return {\n mode: "floating",\n x: clamp(layout.x, 12, Math.max(12, boundsWidth - width - 12)),\n y: clamp(layout.y, 12, Math.max(12, boundsHeight - height - 12)),\n width,\n height,\n heightMode: layout.heightMode\n };\n }\n /** Undock without a visual jump by adopting the panel\'s resolved rectangle. */\n function floatPanelLayout(geometry, bounds) {\n return resolvePanelGeometry({\n ...geometry,\n mode: "floating"\n }, bounds);\n }\n /** Return to the right dock, preserving width and restoring content-fit height. */\n function dockPanelLayout(layout, bounds) {\n return resolvePanelGeometry({\n ...layout,\n mode: "docked",\n heightMode: "auto"\n }, bounds);\n }\n /** Translate a floating panel and clamp it back into the visible shell. */\n function movePanelLayout(start, dx, dy, bounds) {\n return resolvePanelGeometry({\n ...start,\n mode: "floating",\n x: start.x + dx,\n y: start.y + dy\n }, bounds);\n }\n /** Resize while keeping the edge opposite the active handle stationary. */\n function resizePanelLayout(start, edge, dx, dy, bounds) {\n if (start.mode === "docked") {\n if (edge !== "left") return resolvePanelGeometry(start, bounds);\n return resolvePanelGeometry({\n ...start,\n width: start.width - dx\n }, bounds);\n }\n const resolved = resolvePanelGeometry(start, bounds);\n const minimumWidth = Math.min(320, resolved.x + resolved.width - 12);\n const minimumHeight = Math.min(360, bounds.height - resolved.y - 12);\n if (edge === "left") {\n const right = resolved.x + resolved.width;\n const maximumWidth = Math.max(1, Math.min(640, right - 12));\n const width = clamp(resolved.width - dx, Math.min(minimumWidth, maximumWidth), maximumWidth);\n return {\n ...resolved,\n x: right - width,\n width\n };\n }\n const maximumHeight = Math.max(1, bounds.height - resolved.y - 12);\n const height = clamp(resolved.height + dy, Math.min(minimumHeight, maximumHeight), maximumHeight);\n if (edge === "bottom") return {\n ...resolved,\n height,\n heightMode: "manual"\n };\n const maximumWidth = Math.max(1, Math.min(640, bounds.width - resolved.x - 12));\n const width = clamp(resolved.width + dx, Math.min(minimumWidth, maximumWidth), maximumWidth);\n return {\n ...resolved,\n width,\n height,\n heightMode: "manual"\n };\n }\n\n\n /**\n * T Team activity panel: the top-right floater monitoring every team.\n *\n * Modeled on the Claude Code desktop SessionActivityPanel: a shell-overlay\n * panel that docks at the conversation\'s top-right edge by default, can be\n * dragged into a floating window, resized, and folded into an activity badge.\n * On wide viewports the docked panel makes the conversation column yield\n * space; narrow viewports keep a simple inset overlay. It\n * polls the host `/plugins/t-team/state` route for\n * server-side snapshots (durable files + live subagent activity), with a\n * collapsed badge that auto-expands once when activity appears. Archived\n * teams stay available for the owning conversation after live work ends.\n *\n * The floater mounts in ui-layout\'s additive `shell.overlay`; it is not a\n * conversation node \u2014 the in-conversation panel was removed in favor of this\n * always-available monitor.\n * @module t-team/client/activity\n */\n /** Grace before the panel collapses once no team remains. */\n const AUTOCLOSE_GRACE_MS = 2e3;\n /**\n * Page-settle window after mount: activity restored on page load only shows\n * the collapsed badge, so the panel never yanks the conversation column\n * right after load. New activity after this window auto-expands as usual.\n */\n const AUTO_OPEN_SETTLE_MS = 4e3;\n /** Root marker shared with the panel CSS while the shell overlay is expanded. */\n const PANEL_OPEN_ATTRIBUTE = "data-t-team-panel-open";\n /** Shared width concession consumed by the conversation root CSS. */\n const PANEL_SHIFT_PROPERTY = "--t-team-panel-shift";\n const PANEL_CONVERSATION_GAP = 14;\n const MOVE_THRESHOLD = 4;\n const CAPTAIN_ASSIGNEE = "captain";\n function initialPanelLayout() {\n if (typeof window === "undefined") return DEFAULT_PANEL_LAYOUT;\n return parsePanelLayout(window.localStorage.getItem(PANEL_LAYOUT_STORAGE_KEY));\n }\n function initialPanelBounds() {\n if (typeof window === "undefined") return {\n width: 1440,\n height: 900,\n anchorRight: 1440\n };\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n anchorRight: window.innerWidth\n };\n }\n /** Initial-letter fallback for unmatched roles. */\n function memberInitial(name) {\n return name.trim().slice(0, 1).toUpperCase() || "?";\n }\n function stableHash(value) {\n let hash = 0;\n for (let index = 0; index < value.length; index += 1) hash = (hash << 5) - hash + value.charCodeAt(index) | 0;\n return Math.abs(hash);\n }\n const ACCENTS = [\n "var(--dsw-alias-state-business-primary)",\n "var(--dsw-alias-state-success)",\n "var(--dsw-alias-state-danger)",\n "var(--dsw-alias-state-warning)",\n "var(--dsw-alias-label-tertiary)"\n ];\n function accentOf(id) {\n return ACCENTS[stableHash(id) % ACCENTS.length] ?? ACCENTS[0];\n }\n /** Badge text follows the raw task status (finer than the 4 visual states):\n * claimed/pending/failed/cancelled keep their own labels and colors. */\n const TASK_STATUS_LABEL = {\n pending: "task.status.pending",\n claimed: "task.status.claimed",\n in_progress: "task.status.inProgress",\n completed: "task.status.completed",\n failed: "task.status.failed",\n cancelled: "task.status.cancelled"\n };\n function taskStatusLabel(status, t) {\n const key = TASK_STATUS_LABEL[status];\n return key === void 0 ? status : t(key);\n }\n function formatTaskIds(ids, t) {\n return ids.join(t("format.listSeparator"));\n }\n function taskTitle(task, model) {\n const extras = [\n task.kind,\n task.round === void 0 ? void 0 : `r${task.round}`,\n task.verdict,\n model === "" ? void 0 : model\n ].filter((item) => item !== void 0);\n return extras.length === 0 ? `${task.id} \xB7 ${task.subject}` : `${task.id} \xB7 ${task.subject} \xB7 ${extras.join(" \xB7 ")}`;\n }\n /** Badge/bar coloring key: visual state, widened for terminal statuses. */\n function taskTone(state, status) {\n if (status === "failed") return "failed";\n if (status === "cancelled") return "cancelled";\n return state;\n }\n function Chevron({ open }) {\n return (0, react_jsx_runtime.jsx)("svg", {\n className: ActivityPanel_module_css_default.chevron,\n "data-open": open,\n width: "9",\n height: "9",\n viewBox: "0 0 10 10",\n fill: "none",\n stroke: "currentColor",\n strokeWidth: "1.5",\n strokeLinecap: "round",\n "aria-hidden": true,\n children: (0, react_jsx_runtime.jsx)("path", { d: "M3.5 2l3 3-3 3" })\n });\n }\n function WorkGlyph({ active }) {\n return (0, react_jsx_runtime.jsx)("svg", {\n className: ActivityPanel_module_css_default.workGlyph,\n "data-active": active,\n width: "11",\n height: "11",\n viewBox: "0 0 11 11",\n fill: "currentColor",\n "aria-hidden": true,\n children: [\n [0, 0],\n [4.2, 0],\n [8.4, 0],\n [0, 4.2],\n [4.2, 4.2],\n [8.4, 4.2]\n ].map(([x, y], index) => (0, react_jsx_runtime.jsx)("rect", {\n x,\n y,\n width: "2.6",\n height: "2.6",\n rx: ".6",\n style: { animationDelay: `${index * .15}s` }\n }, `${x}:${y}`))\n });\n }\n /** Collapsed badge: an always-visible corner pill while any team exists. */\n function CollapsedBadge({ count, busy, onClick, t }) {\n return (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.badge,\n "data-t-team-collapsed": true,\n "data-busy": busy,\n onClick,\n "aria-label": t("activity.badgeAria", { count }),\n children: [(0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.badgeDot,\n "data-busy": busy,\n "aria-hidden": true\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.badgeCount,\n children: count\n })]\n });\n }\n function memberStateLabel(member, tasks, historic, t) {\n const owned = tasks.filter((task) => task.assignee === member.name);\n if (member.activity === "working") return t("member.state.working");\n if (owned.some((task) => task.status === "failed")) return t("member.state.failed");\n if (owned.some((task) => task.state === "blocked")) return t("member.state.waiting");\n if (owned.length > 0 && owned.every((task) => task.status === "completed")) return t("member.state.delivered");\n if (member.status === "removed") return t(historic ? "member.state.left" : "member.state.removed");\n if (owned.length > 0) return t("member.state.pending");\n return t("member.state.unassigned");\n }\n function memberStatusText(member, tasks, t) {\n const owned = tasks.filter((task) => task.assignee === member.name);\n const current = owned.find((task) => task.id === member.currentTask);\n const blocked = owned.find((task) => task.state === "blocked");\n if (member.activity === "working" && current !== void 0) {\n const model = taskModelLabel(current, [member]);\n return model === "" ? t("member.status.executing", { taskId: current.id }) : t("member.status.executingModel", {\n taskId: current.id,\n model\n });\n }\n if (member.activity === "working") return t("member.status.working");\n if (blocked !== void 0) {\n const dependency = tasks.find((task) => blocked.dependencies.includes(task.id) && task.state !== "completed");\n if (dependency !== void 0) return t("member.status.waitingOn", {\n taskId: dependency.id,\n assignee: dependency.assignee || t("task.assignee.unclaimed")\n });\n return t("member.status.waitingPrerequisite");\n }\n if (member.total === 0) return t("member.status.waitingAssignment");\n if (member.done === member.total) return t("member.status.delivered");\n return t(member.activity === "idle" ? "member.status.idle" : "member.status.unknown");\n }\n function compactTaskLabel(subject) {\n const withoutVerb = subject.replace(/^\u5F00\u53D1\\s*/u, "").replace(/^\\d+[-_.\u3001\\s]*/u, "");\n const head = withoutVerb.split(/[\uFF08(\xB7\uFF1A:]/u)[0]?.trim() ?? withoutVerb;\n return head.length > 18 ? `${head.slice(0, 17)}\u2026` : head;\n }\n function taskSummary(team, t, discarded = false) {\n const completed = team.tasks.filter((task) => task.status === "completed");\n const cancelled = team.tasks.filter((task) => task.status === "cancelled");\n const running = team.tasks.filter((task) => task.state === "running");\n const blocked = team.tasks.filter((task) => task.state === "blocked");\n const ready = team.tasks.filter((task) => task.state === "open" && task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled");\n const failed = team.tasks.filter((task) => task.status === "failed");\n if (discarded) return t("task.summary.discarded", { count: team.tasks.length });\n if (team.tasks.length === 0) return t("task.summary.waitingBreakdown");\n if (team.phase === "staged") return t("task.summary.staged", { count: team.tasks.length });\n if (completed.length === team.tasks.length) return t("task.summary.allDelivered", { count: completed.length });\n if (completed.length + cancelled.length + failed.length === team.tasks.length) return t("task.summary.ended", {\n completed: completed.length,\n cancelled: cancelled.length,\n failed: failed.length\n });\n if (failed.length > 0 && running.length === 0 && ready.length === 0 && blocked.length === 0) return t("task.summary.failedSettled", { count: failed.length });\n if (blocked.length > 0 && running.length > 0) return t("task.summary.blockedAndRunning", {\n tasks: formatTaskIds(blocked.slice(0, 3).map((task) => task.id), t),\n more: blocked.length > 3 ? t("task.summary.more", { count: blocked.length - 3 }) : ""\n });\n if (running.length > 0) return t("task.summary.running", { tasks: formatTaskIds(running.map((task) => task.id), t) });\n if (ready.length > 0) return t("task.summary.ready", { tasks: formatTaskIds(ready.map((task) => task.id), t) });\n if (blocked.length > 0) return t("task.summary.blocked", { tasks: formatTaskIds(blocked.map((task) => task.id), t) });\n return t("task.summary.waitingSchedule");\n }\n function ProgressOverview({ team, t, discarded = false }) {\n const running = discarded ? 0 : team.tasks.filter((task) => task.state === "running").length;\n const blocked = discarded ? 0 : team.tasks.filter((task) => task.state === "blocked").length;\n const completed = discarded ? 0 : team.tasks.filter((task) => task.status === "completed").length;\n const settled = !discarded && team.tasks.length > 0 && team.tasks.every((task) => task.status === "completed" || task.status === "failed" || task.status === "cancelled");\n const summaryTone = discarded ? "discarded" : blocked > 0 ? "warning" : settled ? "completed" : "running";\n return (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.progressOverview,\n "aria-label": t("progress.aria"),\n "data-progress-summary": true,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.progressTitle,\n children: t("progress.title")\n }),\n team.tasks.length > 0 ? (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.progressSegments,\n "aria-hidden": true,\n children: team.tasks.map((task) => (0, react_jsx_runtime.jsx)("span", { "data-state": discarded ? "cancelled" : taskTone(task.state, task.status) }, task.id))\n }) : (0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.progressEmpty }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.progressLegend,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n "data-state": "running",\n children: t("progress.running", { count: running })\n }),\n (0, react_jsx_runtime.jsx)("span", {\n "data-state": "blocked",\n children: t("progress.blocked", { count: blocked })\n }),\n (0, react_jsx_runtime.jsx)("span", {\n "data-state": "completed",\n children: t("progress.delivered", { count: completed })\n })\n ]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.progressSummary,\n "data-state": summaryTone,\n children: [(0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.progressSummaryDot }), (0, react_jsx_runtime.jsx)("span", { children: taskSummary(team, t, discarded) })]\n })\n ]\n });\n }\n function DependencyMap({ tasks, members, t, discarded = false }) {\n const [open, setOpen] = (0, react.useState)(true);\n const [hoverTaskId, setHoverTaskId] = (0, react.useState)(null);\n const [keyboardTaskId, setKeyboardTaskId] = (0, react.useState)(null);\n const [pinnedTaskId, setPinnedTaskId] = (0, react.useState)(null);\n const hoverTimer = (0, react.useRef)(null);\n const focusedTaskId = dependencyFocusTaskId(pinnedTaskId, keyboardTaskId, hoverTaskId);\n const layout = (0, react.useMemo)(() => compactDagLayout(tasks), [tasks]);\n const parallel = (0, react.useMemo)(() => usesParallelTaskGrid(tasks), [tasks]);\n const related = (0, react.useMemo)(() => focusedTaskId === null ? null : relatedTaskIds(focusedTaskId, tasks), [focusedTaskId, tasks]);\n const scheduleHover = (id) => {\n if (hoverTimer.current !== null) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = null;\n }\n if (id === null) {\n setHoverTaskId(null);\n return;\n }\n hoverTimer.current = setTimeout(() => {\n hoverTimer.current = null;\n setHoverTaskId(id);\n }, 180);\n };\n (0, react.useEffect)(() => () => {\n if (hoverTimer.current !== null) clearTimeout(hoverTimer.current);\n }, []);\n (0, react.useEffect)(() => {\n const onKeyDown = (event) => {\n if (event.key === "Escape") setPinnedTaskId(null);\n };\n window.addEventListener("keydown", onKeyDown);\n return () => {\n window.removeEventListener("keydown", onKeyDown);\n };\n }, []);\n if (tasks.length === 0) return null;\n const fallbackTask = tasks.find((task) => task.state === "blocked") ?? tasks.find((task) => task.state === "running") ?? tasks[0];\n const detailTask = tasks.find((task) => task.id === focusedTaskId) ?? fallbackTask;\n const detailModel = taskModelLabel(detailTask, members);\n const waitingOn = detailTask.dependencies.filter((dependency) => tasks.find((task) => task.id === dependency)?.status !== "completed");\n const dependents = tasks.filter((task) => task.dependencies.includes(detailTask.id));\n return (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.dependencySection,\n "aria-label": t("dependency.aria"),\n "data-dependency-map": true,\n children: [(0, react_jsx_runtime.jsxs)("header", {\n className: ActivityPanel_module_css_default.sectionHead,\n children: [(0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.sectionToggleTitle,\n onClick: () => {\n setOpen((current) => !current);\n },\n "aria-expanded": open,\n children: [\n (0, react_jsx_runtime.jsx)(Chevron, { open }),\n (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),\n " ",\n t(parallel ? "dependency.parallel" : "dependency.title")\n ]\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.sectionHint,\n children: pinnedTaskId === null ? t(parallel ? "dependency.hint.parallel" : "dependency.hint.chain") : t("dependency.hint.pinned", { taskId: pinnedTaskId })\n })]\n }), open && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {\n className: ActivityPanel_module_css_default.dagViewport,\n children: (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.dagCanvas,\n "data-layout": parallel ? "parallel" : "dependency",\n style: parallel ? void 0 : {\n width: layout.width,\n height: layout.height\n },\n children: [!parallel && (0, react_jsx_runtime.jsx)("svg", {\n className: ActivityPanel_module_css_default.dagEdges,\n width: layout.width,\n height: layout.height,\n "aria-hidden": true,\n children: layout.edges.map((edge) => {\n const active = related !== null && related.has(edge.from) && related.has(edge.to);\n return (0, react_jsx_runtime.jsx)("path", {\n d: edge.path,\n "data-active": active,\n "data-dimmed": related !== null && !active\n }, `${edge.from}:${edge.to}`);\n })\n }), layout.nodes.map(({ task, x, y }) => {\n const model = taskModelLabel(task, members);\n const shortModel = compactModelLabel(model);\n return (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.dagNode,\n style: parallel ? { height: 30 } : {\n left: x,\n top: y,\n width: 92,\n height: 30\n },\n "data-task-id": task.id,\n "data-state": discarded ? "cancelled" : taskTone(task.state, task.status),\n "data-task-model": model || void 0,\n "data-focused": related?.has(task.id) ?? false,\n "data-dimmed": related !== null && !related.has(task.id),\n "aria-pressed": pinnedTaskId === task.id,\n title: taskTitle(task, model),\n onClick: () => {\n setPinnedTaskId((current) => current === task.id ? null : task.id);\n },\n onMouseEnter: () => {\n scheduleHover(task.id);\n },\n onMouseLeave: () => {\n scheduleHover(null);\n },\n onFocus: () => {\n setKeyboardTaskId(task.id);\n },\n onBlur: () => {\n setKeyboardTaskId(null);\n },\n children: [\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.dagNodeHead,\n children: [(0, react_jsx_runtime.jsx)("span", { className: ActivityPanel_module_css_default.dagNodeDot }), task.id]\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.dagNodeLabel,\n children: task.state === "running" && shortModel !== "" ? shortModel : compactTaskLabel(task.subject)\n }),\n task.state === "running" && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.dagRunningState,\n "aria-label": t("task.runningAria"),\n children: (0, react_jsx_runtime.jsx)(WorkGlyph, { active: true })\n })\n ]\n }, task.id);\n })]\n })\n }), (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.taskDetail,\n "data-task-detail": detailTask.id,\n children: [\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.taskDetailHead,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskDetailId,\n children: detailTask.id\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskDetailSubject,\n title: detailTask.subject,\n children: detailTask.subject.replace(/^\u5F00\u53D1\\s*/u, "")\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskDetailBadge,\n "data-state": discarded ? "cancelled" : taskTone(detailTask.state, detailTask.status),\n children: discarded ? t("task.status.notRun") : taskStatusLabel(detailTask.status, t)\n })\n ]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.taskDetailLine,\n children: [\n detailTask.assignee || t("task.assignee.unclaimed"),\n " \xB7 ",\n 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) })\n ]\n }),\n detailModel !== "" && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskDetailModel,\n "data-task-model": detailModel,\n children: t("task.model", { model: detailModel })\n }),\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskDetailMeta,\n children: dependents.length === 0 ? t("task.detail.noDownstream") : t("task.detail.unlocks", { tasks: formatTaskIds(dependents.map((task) => task.id), t) })\n })\n ]\n })] })]\n });\n }\n function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, onNavigate, t, historic = false }) {\n const [membersOpen, setMembersOpen] = (0, react.useState)(true);\n const [stopOpen, setStopOpen] = (0, react.useState)(false);\n const [stopping, setStopping] = (0, react.useState)(false);\n const [stopError, setStopError] = (0, react.useState)("");\n const discarded = historic && team.phase === "staged";\n const stopped = !historic && team.halted === true;\n const busyCount = team.members.filter((member) => member.activity === "working").length;\n const assignedCount = team.tasks.filter((task) => task.assignee !== "" && task.assignee !== CAPTAIN_ASSIGNEE).length;\n const captainOwned = team.tasks.filter((task) => task.assignee === CAPTAIN_ASSIGNEE && task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled");\n const captainBusy = captainOwned.length > 0;\n const captainTaskIds = formatTaskIds(captainOwned.map((task) => task.id), t);\n const completedCount = team.tasks.filter((task) => task.status === "completed").length;\n const allCompleted = team.tasks.length > 0 && completedCount === team.tasks.length;\n const allSettled = team.tasks.length > 0 && team.tasks.every((task) => task.status === "completed" || task.status === "failed" || task.status === "cancelled");\n const unfinishedCount = team.tasks.filter((task) => task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled").length;\n const canStop = !historic && team.phase === "running" && team.halted !== true && teamIsActive(team);\n const stopTeam = async () => {\n if (stopping) return;\n setStopping(true);\n setStopError("");\n try {\n const response = await fetch(ACTIVITY_HALT_URL, {\n method: "POST",\n cache: "no-store",\n headers: { "content-type": "application/json" },\n body: JSON.stringify({\n sessionId: team.captainSessionId,\n teamId: team.teamId\n })\n });\n if (!response.ok) {\n let message = t("team.stopRequestFailed");\n try {\n const body = await response.json();\n if (typeof body.error === "string" && body.error.trim() !== "") message = body.error;\n } catch {}\n throw new Error(message);\n }\n setStopOpen(false);\n } catch (error) {\n setStopError(t("team.stopFailed", { message: error instanceof Error ? error.message : String(error) }));\n } finally {\n setStopping(false);\n }\n };\n return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.team,\n "data-team-id": team.teamId,\n children: [\n (0, react_jsx_runtime.jsxs)("header", {\n className: ActivityPanel_module_css_default.teamHead,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.teamName,\n title: team.name,\n children: team.name\n }),\n historic && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.historicPill,\n children: t(discarded ? "team.discarded" : "team.ended")\n }),\n stopped && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.historicPill,\n children: t("team.stopped")\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.teamStats,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n "data-stat": "members",\n children: t("team.stats.members", { count: team.members.length })\n }),\n (0, react_jsx_runtime.jsx)("span", {\n "data-stat": "tasks",\n children: t("team.stats.completed", {\n completed: completedCount,\n total: team.tasks.length\n })\n }),\n (0, react_jsx_runtime.jsx)("span", {\n "data-stat": "messages",\n children: t("team.stats.messages", { count: team.messageCount })\n })\n ]\n }),\n canStop && (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.teamStopButton,\n "aria-label": t("team.stop"),\n title: t("team.stop"),\n onClick: () => {\n setStopError("");\n setStopOpen(true);\n },\n children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconStopFill16, {})\n })\n ]\n }),\n team.phase === "staged" && !historic && modelDirectory !== void 0 && onContinuePlanning !== void 0 && onDiscarded !== void 0 && (0, react_jsx_runtime.jsx)(StagingPlanEditor, {\n team,\n modelDirectory,\n onContinuePlanning,\n onDiscarded,\n t\n }),\n (0, react_jsx_runtime.jsxs)("section", {\n className: ActivityPanel_module_css_default.delegationSection,\n "aria-label": t("delegation.aria"),\n "data-delegation-map": true,\n children: [\n (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.captainNode,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.captainAvatar,\n children: (0, react_jsx_runtime.jsx)("img", {\n className: ActivityPanel_module_css_default.leadAvatar,\n src: LEAD_ART,\n alt: "",\n "aria-hidden": true\n })\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.captainInfo,\n children: [(0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.captainLine,\n children: [(0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.captainName,\n children: t("captain.name")\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.captainRole,\n children: t("captain.role")\n })]\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.captainSummary,\n children: discarded ? t("captain.summary.discarded", {\n tasks: team.tasks.length,\n members: team.members.length\n }) : captainBusy ? t("captain.summary.withTakeover", {\n tasks: assignedCount,\n captainTasks: captainTaskIds\n }) : team.phase === "staged" ? t(team.planReviewState === "awaiting_feedback" ? "captain.summary.awaitingFeedback" : "captain.summary.staged", {\n tasks: team.tasks.length,\n members: team.members.length\n }) : t("captain.summary", {\n tasks: assignedCount,\n members: team.members.length\n })\n })]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.captainState,\n "data-busy": captainBusy || busyCount > 0,\n 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")]\n })\n ]\n }),\n (0, react_jsx_runtime.jsx)(ProgressOverview, {\n team,\n t,\n discarded\n }),\n (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.membersToggle,\n onClick: () => {\n setMembersOpen((current) => !current);\n },\n "aria-expanded": membersOpen,\n "data-members-toggle": true,\n children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)(Chevron, { open: membersOpen }), t("members.toggle", { count: team.members.length })] }), (0, react_jsx_runtime.jsx)("span", { children: t(membersOpen ? "members.collapse" : "members.expand") })]\n }),\n membersOpen && (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.delegationTree,\n children: [team.members.length === 0 && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.emptyHint,\n children: t("members.empty")\n }), team.members.map((member) => {\n const owned = team.tasks.filter((task) => task.assignee === member.name);\n const memberModel = memberRouteLabel(member);\n return (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.memberBlock,\n "data-activity": member.activity,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberBranch,\n "aria-hidden": true,\n children: (0, react_jsx_runtime.jsx)("span", {})\n }),\n (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.memberRow,\n "data-activity": member.activity,\n onClick: () => {\n if (member.id !== "") onNavigate(team.captainSessionId, member.id);\n },\n children: [\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.memberAvatar,\n "data-unread": member.unread > 0,\n children: [memberArtUrl(member.name, member.role) !== null ? (0, react_jsx_runtime.jsx)("img", {\n className: ActivityPanel_module_css_default.memberArt,\n src: memberArtUrl(member.name, member.role) ?? "",\n alt: "",\n "aria-hidden": true\n }) : (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberInitial,\n style: { background: accentOf(member.id) },\n children: memberInitial(member.name)\n }), (0, react_jsx_runtime.jsx)("img", {\n className: ActivityPanel_module_css_default.stateArt,\n "data-activity": member.activity,\n src: ACTION_ART[member.activity],\n alt: "",\n "aria-hidden": true\n })]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.memberInfo,\n children: [(0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.memberLine,\n children: [\n (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberName,\n children: member.name\n }),\n member.role !== "" && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberRole,\n children: member.role\n }),\n memberModel !== "" && (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberModel,\n role: "img",\n "data-member-model": memberModel,\n title: memberModel,\n "aria-label": memberModel,\n children: compactModelLabel(memberModel)\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.memberState,\n "data-activity": member.activity,\n 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)]\n })\n ]\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.memberStatusLine,\n 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)\n })]\n }),\n (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.memberCount,\n children: [\n member.done,\n "/",\n member.total\n ]\n })\n ]\n }),\n (0, react_jsx_runtime.jsxs)("div", {\n className: ActivityPanel_module_css_default.assignmentLine,\n children: [(0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.assignmentLabel,\n children: t(discarded ? "assignment.discarded" : team.phase === "staged" ? "assignment.staged" : "assignment.label")\n }), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.assignmentTasks,\n children: owned.length === 0 ? (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.taskEmpty,\n children: t("assignment.empty")\n }) : owned.map((task) => {\n const model = taskModelLabel(task, team.members);\n const shortModel = compactModelLabel(model);\n return (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.assignmentChip,\n "data-state": discarded ? "cancelled" : taskTone(task.state, task.status),\n "data-task-model": model || void 0,\n title: taskTitle(task, model),\n children: task.state === "running" && shortModel !== "" ? `${task.id} \xB7 ${shortModel}` : task.id\n }, task.id);\n })\n })]\n })\n ]\n }, member.id || member.name);\n })]\n })\n ]\n }),\n (0, react_jsx_runtime.jsx)(DependencyMap, {\n tasks: team.tasks,\n members: team.members,\n t,\n discarded\n })\n ]\n }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {\n open: stopOpen,\n onClose: () => {\n if (!stopping) setStopOpen(false);\n },\n title: t("team.stopTitle", { team: team.name }),\n closeLabel: t("plan.cancel"),\n description: t("team.stopDescription", {\n tasks: unfinishedCount,\n members: busyCount\n }),\n footer: (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.stopModalActions,\n children: [(0, react_jsx_runtime.jsx)("button", {\n type: "button",\n disabled: stopping,\n onClick: () => {\n setStopOpen(false);\n },\n children: t("team.stopCancel")\n }), (0, react_jsx_runtime.jsxs)("button", {\n type: "button",\n "data-danger": true,\n disabled: stopping,\n onClick: () => {\n stopTeam();\n },\n children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconStopFill16, {}), stopping ? t("team.stopping") : t("team.stopConfirm")]\n })]\n }),\n children: stopError !== "" && (0, react_jsx_runtime.jsxs)("p", {\n className: ActivityPanel_module_css_default.stopModalError,\n role: "alert",\n children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16, {}), stopError]\n })\n })] });\n }\n /** Legacy conversation cards may outlive their host archive. Project their\n * durable roster through the same rebuilt panel instead of a second UI. */\n function historicCardTeam(data, owner) {\n return {\n workspace: "",\n teamId: data.teamId,\n name: data.teamName,\n captainSessionId: data.captainSessionId || owner,\n phase: "running",\n members: data.members.map((member) => ({\n ...member,\n status: "removed",\n activity: "idle",\n progress: 0,\n done: 0,\n total: 0,\n currentTask: "",\n unread: 0\n })),\n tasks: [],\n messageCount: 0,\n captainInbox: []\n };\n }\n function ActivityPanel({ sessionsList, modelDirectories, openMember, t, conversationVisible = true }) {\n const navigateToSession = (parentId, childId) => {\n setOpen(false);\n setWasActive(false);\n openMember(parentId, childId);\n };\n const [open, setOpen] = (0, react.useState)(false);\n const [openOwner, setOpenOwner] = (0, react.useState)();\n const [autoOpened, setAutoOpened] = (0, react.useState)(false);\n const [wasActive, setWasActive] = (0, react.useState)(false);\n const [historic, setHistoric] = (0, react.useState)(/* @__PURE__ */ new Map());\n const [layout, setLayout] = (0, react.useState)(initialPanelLayout);\n const [bounds, setBounds] = (0, react.useState)(initialPanelBounds);\n const [interaction, setInteraction] = (0, react.useState)(null);\n const panelRef = (0, react.useRef)(null);\n const boundsRef = (0, react.useRef)(bounds);\n const gestureRef = (0, react.useRef)(null);\n const frameRef = (0, react.useRef)(null);\n const pendingLayoutRef = (0, react.useRef)(null);\n const current = (0, react.useSyncExternalStore)(sessionsList.subscribe, sessionsList.getSnapshot).current;\n const autoOpenTrackerRef = (0, react.useRef)({\n sessionId: current,\n restoreComplete: false,\n liveTeamIds: /* @__PURE__ */ new Set()\n });\n const monitorTargets = (0, react.useSyncExternalStore)(subscribeActivityMonitorTargets, getActivityMonitorTargetsSnapshot);\n const returnToComposer = () => {\n setOpen(false);\n setOpenOwner(void 0);\n window.requestAnimationFrame(() => {\n document.querySelector("[data-composer-card] [contenteditable=\\"true\\"][role=\\"textbox\\"], [data-composer-card] textarea")?.focus();\n });\n };\n const { teams, archivedTeams } = (0, react.useSyncExternalStore)(subscribeActivitySnapshots, getActivitySnapshotsSnapshot);\n const currentTargets = (0, react.useMemo)(() => current === void 0 ? [] : monitorTargets.filter((target) => target.sessionId === current), [current, monitorTargets]);\n const currentRef = (0, react.useRef)(current);\n (0, react.useEffect)(() => {\n currentRef.current = current;\n }, [current]);\n const mountedAtRef = (0, react.useRef)(performance.now());\n const expanded = conversationVisible && activityPanelExpandedForSession(open, openOwner, current);\n const geometry = (0, react.useMemo)(() => resolvePanelGeometry(layout, bounds), [layout, bounds]);\n const compact = compactPanelForBounds(bounds);\n const commitLayout = (0, react.useCallback)((next) => {\n setLayout(next);\n }, []);\n (0, react.useEffect)(() => {\n window.localStorage.setItem(PANEL_LAYOUT_STORAGE_KEY, JSON.stringify(layout));\n }, [layout]);\n (0, react.useLayoutEffect)(() => {\n const overlay = document.querySelector("[data-shell-overlay]");\n if (overlay === null) return;\n const conversation = document.querySelector("[data-phase=\'active\']");\n let frame = null;\n const measure = () => {\n frame = null;\n const overlayRect = overlay.getBoundingClientRect();\n const conversationRect = conversation?.getBoundingClientRect();\n const next = {\n width: overlayRect.width,\n height: overlayRect.height,\n anchorRight: conversationRect === void 0 ? overlayRect.width : Math.min(Math.max(conversationRect.right - overlayRect.left, 0), overlayRect.width)\n };\n const previous = boundsRef.current;\n if (previous.width === next.width && previous.height === next.height && previous.anchorRight === next.anchorRight) return;\n boundsRef.current = next;\n setBounds(next);\n };\n const scheduleMeasure = () => {\n frame ??= requestAnimationFrame(measure);\n };\n measure();\n const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(scheduleMeasure);\n observer?.observe(overlay);\n if (conversation !== null) observer?.observe(conversation);\n window.addEventListener("resize", scheduleMeasure);\n return () => {\n if (frame !== null) cancelAnimationFrame(frame);\n observer?.disconnect();\n window.removeEventListener("resize", scheduleMeasure);\n };\n }, [current]);\n (0, react.useLayoutEffect)(() => {\n const tracker = autoOpenTrackerRef.current;\n if (tracker.sessionId !== current) {\n tracker.sessionId = current;\n tracker.restoreComplete = false;\n tracker.liveTeamIds = /* @__PURE__ */ new Set();\n setWasActive(false);\n setAutoOpened(false);\n }\n if (openOwner === void 0 || openOwner === current) return;\n setOpen(false);\n setOpenOwner(void 0);\n }, [current, openOwner]);\n (0, react.useLayoutEffect)(() => {\n const root = document.documentElement;\n if (expanded && geometry.mode === "docked" && !compact) {\n root.setAttribute(PANEL_OPEN_ATTRIBUTE, "");\n root.style.setProperty(PANEL_SHIFT_PROPERTY, `${geometry.width + PANEL_CONVERSATION_GAP + 18}px`);\n } else {\n root.removeAttribute(PANEL_OPEN_ATTRIBUTE);\n root.style.removeProperty(PANEL_SHIFT_PROPERTY);\n }\n return () => {\n root.removeAttribute(PANEL_OPEN_ATTRIBUTE);\n root.style.removeProperty(PANEL_SHIFT_PROPERTY);\n };\n }, [\n compact,\n expanded,\n geometry.mode,\n geometry.width\n ]);\n (0, react.useEffect)(() => {\n if (current === void 0) return;\n const controller = startActivityPolling(currentTargets, { discoverySessionId: current });\n let active = true;\n const tracker = autoOpenTrackerRef.current;\n if (tracker.sessionId === current && !tracker.restoreComplete) controller.firstTick.then(() => {\n const latest = autoOpenTrackerRef.current;\n if (!active || latest.sessionId !== current || latest.restoreComplete) return;\n latest.liveTeamIds = new Set(getActivitySnapshotsSnapshot().teams.filter((team) => team.captainSessionId === current).map((team) => team.teamId));\n latest.restoreComplete = true;\n });\n return () => {\n active = false;\n controller.stop();\n };\n }, [current, currentTargets]);\n (0, react.useEffect)(() => {\n const onOpenPanel = (event) => {\n const activeSession = currentRef.current;\n if (activeSession === void 0) return;\n setOpenOwner(activeSession);\n setOpen(true);\n const detail = event.detail;\n if (detail?.teamId !== void 0) {\n const owner = detail.captainSessionId !== "" ? detail.captainSessionId : currentRef.current ?? "";\n const teamKey = `${owner}:${detail.teamId}`;\n setHistoric((previous) => {\n const next = new Map(previous);\n next.set(teamKey, {\n data: detail,\n owner\n });\n return next;\n });\n }\n };\n window.addEventListener(OPEN_PANEL_EVENT, onOpenPanel);\n return () => {\n window.removeEventListener(OPEN_PANEL_EVENT, onOpenPanel);\n };\n }, []);\n const visibleTeams = (0, react.useMemo)(() => current === void 0 ? [] : teams.filter((team) => team.captainSessionId === current), [teams, current]);\n const visibleHistoric = (0, react.useMemo)(() => current === void 0 ? [] : [...historic.values()].filter(({ data, owner }) => owner === current && !teams.some((live) => live.captainSessionId === current && live.teamId === data.teamId) && !archivedTeams.some((archived) => archived.captainSessionId === current && archived.teamId === data.teamId)), [\n historic,\n current,\n teams,\n archivedTeams\n ]);\n const visibleArchived = (0, react.useMemo)(() => current === void 0 ? [] : archivedTeams.filter((team) => team.captainSessionId === current && !teams.some((live) => live.captainSessionId === current && live.teamId === team.teamId)), [\n archivedTeams,\n current,\n teams\n ]);\n const visibleCount = visibleTeams.length + visibleArchived.length + visibleHistoric.length;\n const visibleLiveTeamIds = (0, react.useMemo)(() => visibleTeams.map((team) => team.teamId).sort(), [visibleTeams]);\n (0, react.useEffect)(() => {\n const tracker = autoOpenTrackerRef.current;\n const settled = performance.now() - mountedAtRef.current >= AUTO_OPEN_SETTLE_MS;\n const shouldAutoExpand = tracker.sessionId === current && activityPanelShouldAutoExpand({\n alreadyAutoOpened: autoOpened,\n pageSettled: settled,\n restoreComplete: tracker.restoreComplete,\n previousLiveTeamIds: tracker.liveTeamIds,\n currentLiveTeamIds: visibleLiveTeamIds\n });\n if (tracker.sessionId === current && tracker.restoreComplete) tracker.liveTeamIds = new Set(visibleLiveTeamIds);\n if (visibleCount > 0) {\n setWasActive(true);\n if (shouldAutoExpand) {\n setOpenOwner(current);\n setOpen(true);\n setAutoOpened(true);\n }\n return;\n }\n if (!wasActive) return;\n const timer = setTimeout(() => {\n setOpen(false);\n setOpenOwner(void 0);\n setWasActive(false);\n setAutoOpened(false);\n }, AUTOCLOSE_GRACE_MS);\n return () => {\n clearTimeout(timer);\n };\n }, [\n visibleCount,\n visibleLiveTeamIds.join("\\0"),\n autoOpened,\n wasActive,\n current\n ]);\n const busy = (0, react.useMemo)(() => visibleTeams.some((team) => team.members.some((member) => member.activity === "working")), [visibleTeams]);\n const hasTeams = visibleCount > 0;\n const panelGeometryForGesture = (0, react.useCallback)(() => {\n const measuredHeight = panelRef.current?.getBoundingClientRect().height;\n if (measuredHeight === void 0 || measuredHeight <= 0) return geometry;\n return {\n ...geometry,\n height: measuredHeight\n };\n }, [geometry]);\n const flushScheduledLayout = (0, react.useCallback)(() => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n const pending = pendingLayoutRef.current;\n pendingLayoutRef.current = null;\n if (pending !== null) commitLayout(pending);\n }, [commitLayout]);\n const scheduleLayout = (0, react.useCallback)((next) => {\n pendingLayoutRef.current = next;\n frameRef.current ??= requestAnimationFrame(() => {\n frameRef.current = null;\n const pending = pendingLayoutRef.current;\n pendingLayoutRef.current = null;\n if (pending !== null) commitLayout(pending);\n });\n }, [commitLayout]);\n (0, react.useEffect)(() => () => {\n if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);\n }, []);\n const beginMove = (0, react.useCallback)((event) => {\n if (compact || event.button !== 0 || event.target.closest("button") !== null) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n gestureRef.current = {\n kind: "move",\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n start: panelGeometryForGesture(),\n activated: false\n };\n }, [compact, panelGeometryForGesture]);\n const beginResize = (0, react.useCallback)((edge, event) => {\n if (compact || event.button !== 0 || geometry.mode === "docked" && edge !== "left") return;\n event.preventDefault();\n event.stopPropagation();\n event.currentTarget.setPointerCapture(event.pointerId);\n gestureRef.current = {\n kind: "resize",\n edge,\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n start: panelGeometryForGesture(),\n activated: true\n };\n setInteraction("resizing");\n }, [\n compact,\n geometry.mode,\n panelGeometryForGesture\n ]);\n const updateGesture = (0, react.useCallback)((event) => {\n const gesture = gestureRef.current;\n if (gesture === null || gesture.pointerId !== event.pointerId || !event.currentTarget.hasPointerCapture(event.pointerId)) return;\n const dx = event.clientX - gesture.originX;\n const dy = event.clientY - gesture.originY;\n const activeBounds = boundsRef.current;\n if (gesture.kind === "move") {\n if (!gesture.activated && Math.hypot(dx, dy) < MOVE_THRESHOLD) return;\n if (!gesture.activated) {\n gesture.activated = true;\n setInteraction("dragging");\n }\n scheduleLayout(movePanelLayout(floatPanelLayout(gesture.start, activeBounds), dx, dy, activeBounds));\n return;\n }\n scheduleLayout(resizePanelLayout(gesture.start, gesture.edge ?? "left", dx, dy, activeBounds));\n }, [scheduleLayout]);\n const endGesture = (0, react.useCallback)((event) => {\n const gesture = gestureRef.current;\n if (gesture === null || gesture.pointerId !== event.pointerId) return;\n updateGesture(event);\n flushScheduledLayout();\n if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);\n gestureRef.current = null;\n setInteraction(null);\n }, [flushScheduledLayout, updateGesture]);\n const cancelGesture = (0, react.useCallback)((event) => {\n const gesture = gestureRef.current;\n if (gesture === null || gesture.pointerId !== event.pointerId) return;\n flushScheduledLayout();\n gestureRef.current = null;\n setInteraction(null);\n }, [flushScheduledLayout]);\n const toggleDock = (0, react.useCallback)(() => {\n const liveGeometry = panelGeometryForGesture();\n commitLayout(liveGeometry.mode === "docked" ? floatPanelLayout(liveGeometry, boundsRef.current) : dockPanelLayout(liveGeometry, boundsRef.current));\n }, [commitLayout, panelGeometryForGesture]);\n const autoHeight = panelUsesAutoHeight(geometry, bounds);\n const panelStyle = {\n width: geometry.width,\n height: autoHeight ? "auto" : geometry.height,\n maxHeight: panelMaximumHeight(geometry, bounds),\n transform: `translate3d(${geometry.x}px, ${geometry.y}px, 0)`\n };\n if (!conversationVisible || !hasTeams && !expanded) return null;\n return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [!expanded && (0, react_jsx_runtime.jsx)(CollapsedBadge, {\n count: visibleCount,\n busy,\n t,\n onClick: () => {\n if (current === void 0) return;\n setOpenOwner(current);\n setOpen(true);\n }\n }), expanded && (0, react_jsx_runtime.jsxs)("aside", {\n ref: panelRef,\n className: ActivityPanel_module_css_default.panel,\n style: panelStyle,\n "data-t-team-activity": true,\n "data-panel-mode": geometry.mode,\n "data-height-mode": autoHeight ? "auto" : "manual",\n "data-compact": compact || void 0,\n "data-dragging": interaction === "dragging" || void 0,\n "data-resizing": interaction === "resizing" || void 0,\n "aria-label": t("activity.panelAria"),\n children: [\n (0, react_jsx_runtime.jsxs)("header", {\n className: ActivityPanel_module_css_default.panelHead,\n onPointerDown: beginMove,\n onPointerMove: updateGesture,\n onPointerUp: endGesture,\n onPointerCancel: cancelGesture,\n "data-drag-handle": !compact || void 0,\n children: [(0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.panelTitle,\n children: [t("activity.title"), (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.panelDot,\n "data-busy": busy,\n "aria-hidden": true\n })]\n }), (0, react_jsx_runtime.jsxs)("span", {\n className: ActivityPanel_module_css_default.panelControls,\n children: [!compact && (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.iconButton,\n "data-control": "dock",\n "data-mode": geometry.mode,\n onClick: toggleDock,\n "aria-label": t(geometry.mode === "docked" ? "activity.float" : "activity.dockRight"),\n title: t(geometry.mode === "docked" ? "activity.float" : "activity.dockRight"),\n children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, {})\n }), (0, react_jsx_runtime.jsx)("button", {\n type: "button",\n className: ActivityPanel_module_css_default.iconButton,\n "data-control": "collapse",\n onClick: () => {\n setOpen(false);\n setOpenOwner(void 0);\n },\n "aria-label": t("activity.collapse"),\n title: t("activity.collapse"),\n children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})\n })]\n })]\n }),\n (0, react_jsx_runtime.jsx)("div", {\n className: ActivityPanel_module_css_default.teams,\n children: visibleCount === 0 ? (0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.emptyHint,\n children: t("activity.empty")\n }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [\n visibleTeams.map((team) => (0, react_jsx_runtime.jsx)(TeamSection, {\n team,\n modelDirectory: team.phase === "staged" ? modelDirectories.directoryFor(team.captainSessionId) : void 0,\n onContinuePlanning: returnToComposer,\n onDiscarded: returnToComposer,\n onNavigate: navigateToSession,\n t\n }, team.teamId)),\n visibleArchived.map((team) => (0, react_jsx_runtime.jsxs)("div", {\n "data-team-id": team.teamId,\n "data-historic": true,\n className: ActivityPanel_module_css_default.archivedWrap,\n children: [(0, react_jsx_runtime.jsx)("span", {\n className: ActivityPanel_module_css_default.archiveLabel,\n children: t(team.phase === "staged" ? "archive.discardedLabel" : "archive.label")\n }), (0, react_jsx_runtime.jsx)(TeamSection, {\n team,\n onNavigate: navigateToSession,\n t,\n historic: true\n })]\n }, `${team.captainSessionId}:${team.teamId}`)),\n visibleHistoric.map(({ data: team, owner }) => {\n const teamKey = `${owner}:${team.teamId}`;\n return (0, react_jsx_runtime.jsx)(TeamSection, {\n team: historicCardTeam(team, owner),\n onNavigate: navigateToSession,\n t,\n historic: true\n }, teamKey);\n })\n ] })\n }),\n !compact && (0, react_jsx_runtime.jsx)("div", {\n className: ActivityPanel_module_css_default.resizeHandle,\n "data-resize-edge": "left",\n onPointerDown: (event) => {\n beginResize("left", event);\n },\n onPointerMove: updateGesture,\n onPointerUp: endGesture,\n onPointerCancel: cancelGesture,\n "aria-hidden": true\n }),\n !compact && geometry.mode === "floating" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {\n className: ActivityPanel_module_css_default.resizeHandle,\n "data-resize-edge": "bottom",\n onPointerDown: (event) => {\n beginResize("bottom", event);\n },\n onPointerMove: updateGesture,\n onPointerUp: endGesture,\n onPointerCancel: cancelGesture,\n "aria-hidden": true\n }), (0, react_jsx_runtime.jsx)("div", {\n className: ActivityPanel_module_css_default.resizeHandle,\n "data-resize-edge": "corner",\n onPointerDown: (event) => {\n beginResize("corner", event);\n },\n onPointerMove: updateGesture,\n onPointerUp: endGesture,\n onPointerCancel: cancelGesture,\n "aria-hidden": true\n })] })\n ]\n })] });\n }\n\n\n /**\n * T Team conversation card: a lightweight in-conversation summary shown\n * when a team is created \u2014 the captain\'s name, the member roster with whale\n * avatars, and an entry point that re-activates the top-right activity\n * panel (useful after the floater was closed, or when re-opening an old\n * session for review).\n *\n * The fold anchors to the Harness\'s durable `tool/call` + `tool/result`\n * records for `t_team_create`. Those are first-party session events, so\n * the card survives restarts without writing an out-of-repo event type.\n * @module t-team/client/card\n */\n /** Parse the only create-call fields the historic card owns. */\n function parseTTeamCreateArgs(value) {\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed !== "object" || parsed === null || !("name" in parsed) || typeof parsed.name !== "string") return;\n const name = parsed.name.trim();\n if (name === "") return void 0;\n const cleaned = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");\n return {\n teamId: cleaned === "" ? "team" : cleaned,\n name\n };\n } catch {\n return;\n }\n }\n /** Durable first-party tool events folded into one keyed Chat node. */\n const tTeamCardDefinition = {\n kind: "t-team",\n target: "chat",\n match: (event) => {\n if (event.type === "tool/call" && event.data.name === "t_team_create") return parseTTeamCreateArgs(event.data.arguments) === void 0 ? null : {\n id: String(event.data.callId),\n role: "start"\n };\n if (event.type === "tool/result" && event.data.message.source.kind === "tool") return {\n id: String(event.data.message.source.callId),\n role: "update"\n };\n return null;\n },\n start: (_context, match) => {\n if (match.event.type !== "tool/call") throw new Error("t-team card start requires t_team_create tool/call");\n const parsed = parseTTeamCreateArgs(match.event.data.arguments);\n if (parsed === void 0) throw new Error("t-team card start requires valid create arguments");\n return {\n ...parsed,\n accepted: false\n };\n },\n update: (context, match) => {\n if (match.event.type !== "tool/result") return context.state;\n if (match.event.data.error !== void 0 || match.event.data.message.content.some((block) => block.type === "tool-result" && block.isError === true)) return context.state;\n return {\n ...context.state,\n accepted: true\n };\n },\n buildViewNode: (context) => {\n if (context.start === void 0) return null;\n const state = context.state;\n if (!state.accepted) return null;\n return {\n key: context.key,\n kind: "t-team",\n id: context.id,\n target: "chat",\n anchorSeq: context.start.event.seq,\n location: context.start.location,\n visibility: "visible",\n data: {\n teamId: state.teamId,\n captainSessionId: "",\n teamName: state.name,\n members: []\n }\n };\n }\n };\n\n\n /** `tTeam` namespace dictionaries for every plugin-owned Web surface. */\n /** Dictionary namespace owned by the T Team client plugin. */\n const T_TEAM_LOCALE_NAMESPACE = "tTeam";\n /** Simplified Chinese dictionary (the key-set source of truth). */\n const zh = {\n "card.memberCount": "{count} \u540D\u6210\u5458",\n "action.openActivityPanel": "\u6253\u5F00\u6D3B\u52A8\u9762\u677F",\n "activity.panelButton": "\u6D3B\u52A8\u9762\u677F",\n "activity.badgeAria": "T\u4E13\u5BB6 \u56E2\u961F\u6D3B\u52A8\u4E0E\u5386\u53F2\uFF0C{count} \u6761\u56E2\u961F\u8BB0\u5F55",\n "activity.panelAria": "T\u4E13\u5BB6 \u56E2\u961F\u6D3B\u52A8\u9762\u677F",\n "activity.title": "T\u4E13\u5BB6 \u56E2\u961F\u6D3B\u52A8",\n "activity.float": "\u5207\u6362\u4E3A\u6D6E\u52A8\u9762\u677F",\n "activity.dockRight": "\u505C\u9760\u5230\u53F3\u4FA7",\n "activity.collapse": "\u6536\u8D77\u6D3B\u52A8\u9762\u677F",\n "activity.empty": "\u6682\u65E0\u56E2\u961F\u6D3B\u52A8",\n "team.stop": "\u505C\u6B62\u56E2\u961F",\n "team.stopped": "\u5DF2\u505C\u6B62",\n "team.stopTitle": "\u786E\u8BA4\u505C\u6B62\u201C{team}\u201D\uFF1F",\n "team.stopDescription": "\u5C06\u53D6\u6D88 {tasks} \u9879\u672A\u5B8C\u6210\u4EFB\u52A1\uFF0C\u5E76\u505C\u6B62 {members} \u540D\u6B63\u5728\u5DE5\u4F5C\u7684\u6210\u5458\u3002\u5DF2\u5B8C\u6210\u7684\u7ED3\u679C\u4F1A\u4FDD\u7559\u3002",\n "team.stopCancel": "\u7EE7\u7EED\u8FD0\u884C",\n "team.stopConfirm": "\u786E\u8BA4\u505C\u6B62",\n "team.stopping": "\u6B63\u5728\u505C\u6B62\u2026",\n "team.stopFailed": "\u505C\u6B62\u5931\u8D25\uFF1A{message}",\n "team.stopRequestFailed": "\u670D\u52A1\u5668\u672A\u80FD\u505C\u6B62\u56E2\u961F\uFF0C\u8BF7\u91CD\u8BD5",\n "team.discarded": "\u5DF2\u653E\u5F03",\n "format.listSeparator": "\u3001",\n "task.status.pending": "\u5F85\u9886\u53D6",\n "task.status.claimed": "\u5DF2\u8BA4\u9886",\n "task.status.inProgress": "\u8FDB\u884C\u4E2D",\n "task.status.completed": "\u5DF2\u5B8C\u6210",\n "task.status.failed": "\u5931\u8D25",\n "task.status.cancelled": "\u5DF2\u53D6\u6D88",\n "task.status.notRun": "\u672A\u6267\u884C",\n "member.state.working": "\u5DE5\u4F5C\u4E2D",\n "member.state.failed": "\u6709\u5931\u8D25",\n "member.state.waiting": "\u7B49\u5F85",\n "member.state.delivered": "\u5DF2\u4EA4\u4ED8",\n "member.state.left": "\u5DF2\u79BB\u961F",\n "member.state.removed": "\u5DF2\u79FB\u9664",\n "member.state.pending": "\u5F85\u6267\u884C",\n "member.state.unassigned": "\u5F85\u6D3E\u5DE5",\n "member.state.staged": "\u5F85\u521B\u5EFA",\n "member.state.notCreated": "\u672A\u521B\u5EFA",\n "member.state.stopped": "\u5DF2\u505C\u6B62",\n "member.status.executing": "\u6B63\u5728\u6267\u884C {taskId}",\n "member.status.executingModel": "\u6B63\u5728\u6267\u884C {taskId} \xB7 {model}",\n "member.status.working": "\u6B63\u5728\u5904\u7406\u5DF2\u6D3E\u4EFB\u52A1",\n "member.status.waitingOn": "\u7B49\u5F85 {taskId} \xB7 {assignee}",\n "member.status.waitingPrerequisite": "\u7B49\u5F85\u524D\u7F6E\u4EFB\u52A1",\n "member.status.waitingAssignment": "\u7B49\u5F85\u961F\u957F\u6D3E\u5DE5",\n "member.status.delivered": "\u4EFB\u52A1\u5DF2\u4EA4\u4ED8",\n "member.status.idle": "\u5F85\u7EE7\u7EED\u6267\u884C",\n "member.status.unknown": "\u72B6\u6001\u672A\u77E5",\n "member.status.staged": "\u786E\u8BA4\u540E\u521B\u5EFA\u5E76\u542F\u52A8",\n "member.status.settled": "\u4EFB\u52A1\u5747\u5DF2\u7EC8\u7ED3",\n "member.status.discarded": "\u8BA1\u5212\u5DF2\u653E\u5F03\uFF0C\u672A\u521B\u5EFA",\n "member.status.stopped": "\u56E2\u961F\u5DF2\u505C\u6B62\uFF0C\u9700\u663E\u5F0F\u6062\u590D",\n "task.assignee.unclaimed": "\u5F85\u8BA4\u9886",\n "task.summary.waitingBreakdown": "\u7B49\u5F85\u961F\u957F\u62C6\u89E3\u4EFB\u52A1",\n "task.summary.staged": "{count} \u9879\u8BA1\u5212\u7B49\u5F85\u786E\u8BA4",\n "task.summary.discarded": "{count} \u9879\u8BA1\u5212\u5DF2\u653E\u5F03\uFF0C\u5747\u672A\u6267\u884C",\n "task.summary.allDelivered": "\u5168\u90E8 {count} \u9879\u4EFB\u52A1\u5DF2\u4EA4\u4ED8",\n "task.summary.ended": "\u7EC8\u6001\uFF1A{completed} \u5DF2\u4EA4\u4ED8 \xB7 {cancelled} \u5DF2\u53D6\u6D88 \xB7 {failed} \u5931\u8D25",\n "task.summary.blockedAndRunning": "{tasks}{more} \u7B49\u5F85\u524D\u7F6E\uFF0C\u5176\u4F59\u5DF2\u5F00\u5DE5",\n "task.summary.more": " \u7B49 {count} \u9879",\n "task.summary.running": "{tasks} \u6B63\u5728\u6267\u884C",\n "task.summary.ready": "{tasks} \u5DF2\u5C31\u7EEA\u5F85\u5F00\u5DE5",\n "task.summary.blocked": "{tasks} \u7B49\u5F85\u524D\u7F6E",\n "task.summary.failedSettled": "{count} \u9879\u5DF2\u5931\u8D25\uFF0C\u81EA\u52A8\u5FAA\u73AF\u5DF2\u505C\u6B62",\n "task.summary.waitingSchedule": "\u7B49\u5F85\u4E0B\u4E00\u8F6E\u8C03\u5EA6",\n "progress.aria": "\u56E2\u961F\u603B\u8FDB\u5EA6",\n "progress.title": "\u603B\u8FDB\u5EA6",\n "progress.running": "\u25A0 \u8FDB\u884C\u4E2D {count}",\n "progress.blocked": "\u25A0 \u7B49\u5F85\u4F9D\u8D56 {count}",\n "progress.delivered": "\u25A0 \u5DF2\u4EA4\u4ED8 {count}",\n "dependency.aria": "\u4EFB\u52A1\u4F9D\u8D56\u94FE",\n "dependency.parallel": "\u5E76\u884C\u4EFB\u52A1",\n "dependency.title": "\u4EFB\u52A1\u4F9D\u8D56",\n "dependency.hint.parallel": "\u65E0\u524D\u540E\u4F9D\u8D56 \xB7 \u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",\n "dependency.hint.chain": "\u60AC\u505C\u9AD8\u4EAE\u4F9D\u8D56\u94FE \xB7 \u70B9\u51FB\u56FA\u5B9A",\n "dependency.hint.pinned": "{taskId} \u5DF2\u56FA\u5B9A \xB7 Esc \u53D6\u6D88",\n "task.runningAria": "\u8FD0\u884C\u4E2D",\n "task.model": "{model}",\n "task.detail.completed": "\u5DF2\u5B8C\u6210\u5E76\u4EA4\u4ED8",\n "task.detail.noPrerequisite": "\u65E0\u524D\u7F6E\uFF0C\u53EF\u7ACB\u5373\u5F00\u5DE5",\n "task.detail.ready": "\u524D\u7F6E\u5DF2\u5C31\u7EEA\uFF0C\u53EF\u5F00\u5DE5",\n "task.detail.waitingOn": "\u7B49\u5F85 {tasks}",\n "task.detail.notRun": "\u8BA1\u5212\u5DF2\u653E\u5F03\uFF0C\u4EFB\u52A1\u672A\u6267\u884C",\n "task.detail.noDownstream": "\u65E0\u4E0B\u6E38\u4EFB\u52A1",\n "task.detail.unlocks": "\u5B8C\u6210\u540E\u89E3\u9501 {tasks}",\n "team.ended": "\u5DF2\u7ED3\u675F",\n "plan.badge": "\u5F85\u786E\u8BA4",\n "plan.title": "\u6267\u884C\u524D\u8BA1\u5212\u5BA1\u67E5",\n "plan.description": "\u6210\u5458\u5C1A\u672A\u521B\u5EFA\u3001\u4EFB\u52A1\u5C1A\u672A\u8C03\u5EA6\u3002\u53EF\u76F4\u63A5\u8C03\u6574\u8BA1\u5212\uFF0C\u4E5F\u53EF\u8FD4\u56DE\u5BF9\u8BDD\u544A\u8BC9\u961F\u957F\u54EA\u91CC\u9700\u8981\u4FEE\u6539\u3002",\n "plan.member.role": "\u89D2\u8272",\n "plan.member.provider": "Provider",\n "plan.member.model": "\u6A21\u578B",\n "plan.member.reasoning": "\u63A8\u7406\u7B49\u7EA7",\n "plan.member.reasoningHint": "\u7559\u7A7A\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF1B\u53EF\u7528 low\u3001medium\u3001high\u3001xhigh \u7B49",\n "plan.model.choose": "\u9009\u62E9\u6A21\u578B",\n "plan.model.currentUnavailable": "{provider}/{model}\uFF08\u5F53\u524D\u76EE\u5F55\u4E0D\u53EF\u7528\uFF09",\n "plan.model.route": "\u8DEF\u7531\uFF1A{provider}/{model}",\n "plan.model.defaultReasoning": "\u9ED8\u8BA4\u63A8\u7406\u7B49\u7EA7",\n "plan.model.providerDefault": "Provider \u9ED8\u8BA4\u503C",\n "plan.model.modelDefault": "\u6A21\u578B\u9ED8\u8BA4\u503C\uFF08{effort}\uFF09",\n "plan.model.triggerAria": "\u9009\u62E9\u6210\u5458\u6A21\u578B\uFF0C\u5F53\u524D {model}\uFF0C\u63A8\u7406\u7B49\u7EA7 {effort}",\n "plan.model.back": "\u8FD4\u56DE",\n "plan.model.loading": "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u2026",\n "plan.model.empty": "\u6682\u65E0\u53EF\u7528\u6A21\u578B",\n "plan.model.partialFailure": "{count} \u4E2A Provider \u7684\u6A21\u578B\u76EE\u5F55\u52A0\u8F7D\u5931\u8D25",\n "plan.model.retry": "\u91CD\u8BD5",\n "plan.member.prompt": "\u89D2\u8272\u63D0\u793A\u8BCD",\n "plan.member.roleFallback": "\u672A\u8BBE\u7F6E\u89D2\u8272",\n "plan.task.subject": "\u4EFB\u52A1\u540D\u79F0",\n "plan.task.description": "\u4EFB\u52A1\u8BF4\u660E",\n "plan.task.assignee": "\u8D1F\u8D23\u4EBA",\n "plan.task.dependencies": "\u4F9D\u8D56\u4EFB\u52A1 ID\uFF08\u9017\u53F7\u5206\u9694\uFF09",\n "plan.task.dependenciesHint": "\u4F8B\u5982 task-1, task-2\uFF1B\u4E0D\u5F97\u5F62\u6210\u5FAA\u73AF\u4F9D\u8D56",\n "plan.task.unassigned": "\u5171\u4EAB\u4EFB\u52A1\u6C60",\n "plan.unsaved": "\u672A\u4FDD\u5B58",\n "plan.save": "\u4FDD\u5B58",\n "plan.saving": "\u4FDD\u5B58\u4E2D\u2026",\n "plan.remove": "\u5220\u9664",\n "plan.removed": "\u4EFB\u52A1\u5DF2\u5220\u9664",\n "plan.removeConfirm": "\u786E\u8BA4\u5220\u9664",\n "plan.removeWarning": "\u5220\u9664 {task} \u540E\u5C06\u91CD\u65B0\u8BA1\u7B97\u4F9D\u8D56\u5173\u7CFB\u3002",\n "plan.cancel": "\u53D6\u6D88",\n "plan.addTask": "\u6DFB\u52A0\u4EFB\u52A1",\n "plan.adding": "\u6DFB\u52A0\u4E2D\u2026",\n "plan.taskAdded": "\u4EFB\u52A1\u5DF2\u6DFB\u52A0",\n "plan.newTask": "\u65B0\u4EFB\u52A1\u540D\u79F0",\n "plan.newTaskLabel": "\u65B0\u589E\u8BA1\u5212\u4EFB\u52A1",\n "plan.readySummary": "{members} \u540D\u6210\u5458 \xB7 {tasks} \u9879\u4EFB\u52A1 \xB7 {links} \u6761\u4F9D\u8D56",\n "plan.flow.aria": "\u56E2\u961F\u542F\u52A8\u6D41\u7A0B",\n "plan.flow.review": "\u5BA1\u67E5\u8BA1\u5212",\n "plan.flow.spawn": "\u521B\u5EFA\u6210\u5458",\n "plan.flow.run": "\u5F00\u59CB\u6267\u884C",\n "plan.members.title": "\u6210\u5458\u4E0E\u6A21\u578B\u8DEF\u7531",\n "plan.members.count": "{count} \u540D\u6210\u5458",\n "plan.members.empty": "\u5C1A\u672A\u89C4\u5212\u6210\u5458",\n "plan.tasks.title": "\u4EFB\u52A1\u4E0E\u4F9D\u8D56",\n "plan.tasks.count": "{count} \u9879\u4EFB\u52A1 \xB7 {links} \u6761\u4F9D\u8D56",\n "plan.tasks.empty": "\u5C1A\u672A\u89C4\u5212\u4EFB\u52A1",\n "plan.dependencies.none": "\u65E0\u4F9D\u8D56",\n "plan.dependencies.count": "{count} \u6761\u4F9D\u8D56",\n "plan.approve": "\u786E\u8BA4\u5E76\u542F\u52A8\u56E2\u961F",\n "plan.approving": "\u6B63\u5728\u521B\u5EFA\u6210\u5458\u2026",\n "plan.approveTitle": "\u8BA1\u5212\u68C0\u67E5\u5B8C\u6BD5\uFF1F",\n "plan.approveHint": "\u786E\u8BA4\u540E\u5C06\u521B\u5EFA {members} \u540D\u6210\u5458\u5E76\u8C03\u5EA6 {tasks} \u9879\u4EFB\u52A1\u3002",\n "plan.approveConfirmTitle": "\u786E\u8BA4\u542F\u52A8\u6B64\u56E2\u961F",\n "plan.approveWarning": "\u542F\u52A8\u540E\u4E0D\u80FD\u518D\u5728\u6B64\u5904\u7F16\u8F91\u6210\u5458\u548C\u4F9D\u8D56\u3002",\n "plan.approveConfirm": "\u786E\u8BA4\u542F\u52A8",\n "plan.continue": "\u8FD4\u56DE\u5BF9\u8BDD\u4FEE\u6539",\n "plan.returnToChat": "\u56DE\u5230\u5BF9\u8BDD",\n "plan.feedbackTitle": "\u6B63\u5728\u7B49\u4F60\u8BF4\u660E\u4FEE\u6539\u65B9\u5411",\n "plan.feedbackHint": "\u961F\u957F\u4F1A\u5728\u5BF9\u8BDD\u4E2D\u8FFD\u95EE\uFF1B\u6536\u5230\u4F60\u7684\u56DE\u590D\u540E\uFF0C\u53EA\u4FEE\u6539\u8FD9\u4EFD\u8349\u6848\u5E76\u518D\u6B21\u7B49\u5F85\u786E\u8BA4\u3002",\n "plan.discard": "\u653E\u5F03\u672C\u6B21\u8BA1\u5212",\n "plan.discardConfirmTitle": "\u653E\u5F03\u672C\u6B21\u8BA1\u5212\uFF1F",\n "plan.discardWarning": "\u8BE5\u8BA1\u5212\u4F1A\u7ED3\u675F\u5E76\u5F52\u6863\uFF1B\u5C1A\u672A\u521B\u5EFA\u4EFB\u4F55\u6210\u5458\uFF0C\u4E5F\u4E0D\u4F1A\u6267\u884C\u4EFB\u52A1\u3002",\n "plan.discardConfirm": "\u786E\u8BA4\u653E\u5F03",\n "plan.discarding": "\u6B63\u5728\u653E\u5F03\u2026",\n "plan.pendingEdits": "\u8BF7\u5148\u4FDD\u5B58\u5F53\u524D\u4FEE\u6539\uFF0C\u518D\u542F\u52A8\u56E2\u961F\u3002",\n "plan.saved": "\u8BA1\u5212\u5DF2\u4FDD\u5B58",\n "plan.failed": "\u64CD\u4F5C\u5931\u8D25\uFF1A{message}",\n "team.stats.members": "{count} \u540D\u6210\u5458",\n "team.stats.completed": "{completed}/{total} \u5B8C\u6210",\n "team.stats.messages": "{count} \u6761\u6D88\u606F",\n "delegation.aria": "\u961F\u957F\u6D3E\u5DE5\u5173\u7CFB",\n "captain.name": "\u961F\u957F",\n "captain.role": "\u62C6\u89E3 \xB7 \u6D3E\u53D1 \xB7 \u6C47\u603B",\n "captain.summary": "\u5DF2\u6D3E\u53D1 {tasks} \u9879\u4EFB\u52A1\u7ED9 {members} \u540D\u6210\u5458",\n "captain.summary.staged": "\u5DF2\u89C4\u5212 {tasks} \u9879\u4EFB\u52A1\u4E0E {members} \u540D\u6210\u5458\uFF0C\u7B49\u5F85\u786E\u8BA4",\n "captain.summary.awaitingFeedback": "\u8349\u6848\u5DF2\u4FDD\u7559\uFF0C\u7B49\u5F85\u4F60\u5728\u5BF9\u8BDD\u4E2D\u8BF4\u660E\u4FEE\u6539\u65B9\u5411",\n "captain.summary.discarded": "\u8BA1\u5212\u5DF2\u653E\u5F03\uFF1A{members} \u540D\u6210\u5458\u672A\u521B\u5EFA\uFF0C{tasks} \u9879\u4EFB\u52A1\u672A\u6267\u884C",\n "captain.summary.withTakeover": "\u5DF2\u6D3E\u53D1 {tasks} \u9879\u7ED9\u6210\u5458 \xB7 \u961F\u957F\u63A5\u7BA1 {captainTasks}",\n "captain.state.working": "{count} \u4EBA\u6267\u884C\u4E2D",\n "captain.state.takeover": "\u6B63\u5728\u6267\u884C {tasks}",\n "captain.state.collected": "\u5DF2\u6536\u9F50",\n "captain.state.waiting": "\u7B49\u5F85\u56DE\u62A5",\n "captain.state.staged": "\u5F85\u786E\u8BA4",\n "captain.state.awaitingFeedback": "\u5F85\u53CD\u9988",\n "captain.state.discarded": "\u5DF2\u653E\u5F03",\n "captain.state.settled": "\u5DF2\u7EC8\u7ED3",\n "members.toggle": "{count} \u540D\u6210\u5458",\n "members.collapse": "\u6536\u8D77",\n "members.expand": "\u5C55\u5F00",\n "members.empty": "\u6682\u65E0\u6210\u5458\uFF0C\u7B49\u5F85\u961F\u957F\u7EC4\u5EFA\u56E2\u961F",\n "assignment.label": "\u961F\u957F\u6D3E\u53D1",\n "assignment.staged": "\u8BA1\u5212\u4EFB\u52A1",\n "assignment.discarded": "\u672A\u6267\u884C\u7684\u8BA1\u5212",\n "assignment.empty": "\u6682\u65E0\u4EFB\u52A1",\n "archive.label": "\u5DF2\u7ED3\u675F \xB7 \u5386\u53F2\u5F52\u6863",\n "archive.discardedLabel": "\u8BA1\u5212\u5DF2\u653E\u5F03 \xB7 \u5386\u53F2\u5F52\u6863"\n };\n /** English dictionary, checked complete against the Chinese source key set. */\n const en = {\n "card.memberCount": "{count} members",\n "action.openActivityPanel": "Open activity panel",\n "activity.panelButton": "Activity panel",\n "activity.badgeAria": "T Team activity and history, {count} team records",\n "activity.panelAria": "T Team activity panel",\n "activity.title": "T Team activity",\n "activity.float": "Switch to floating panel",\n "activity.dockRight": "Dock to the right",\n "activity.collapse": "Collapse activity panel",\n "activity.empty": "No team activity",\n "team.stop": "Stop team",\n "team.stopped": "Stopped",\n "team.stopTitle": "Stop \u201C{team}\u201D?",\n "team.stopDescription": "This cancels {tasks} unfinished tasks and stops {members} working members. Completed results are kept.",\n "team.stopCancel": "Keep running",\n "team.stopConfirm": "Stop team",\n "team.stopping": "Stopping\u2026",\n "team.stopFailed": "Could not stop team: {message}",\n "team.stopRequestFailed": "The server could not stop this team. Try again.",\n "team.discarded": "Discarded",\n "format.listSeparator": ", ",\n "task.status.pending": "Unclaimed",\n "task.status.claimed": "Claimed",\n "task.status.inProgress": "In progress",\n "task.status.completed": "Completed",\n "task.status.failed": "Failed",\n "task.status.cancelled": "Cancelled",\n "task.status.notRun": "Not run",\n "member.state.working": "Working",\n "member.state.failed": "Has failures",\n "member.state.waiting": "Waiting",\n "member.state.delivered": "Delivered",\n "member.state.left": "Left team",\n "member.state.removed": "Removed",\n "member.state.pending": "Pending",\n "member.state.unassigned": "Awaiting assignment",\n "member.state.staged": "Not spawned",\n "member.state.notCreated": "Not created",\n "member.state.stopped": "Stopped",\n "member.status.executing": "Working on {taskId}",\n "member.status.executingModel": "Working on {taskId} \xB7 {model}",\n "member.status.working": "Working on assigned tasks",\n "member.status.waitingOn": "Waiting for {taskId} \xB7 {assignee}",\n "member.status.waitingPrerequisite": "Waiting for prerequisites",\n "member.status.waitingAssignment": "Waiting for the captain to assign work",\n "member.status.delivered": "Tasks delivered",\n "member.status.idle": "Ready to continue",\n "member.status.unknown": "Status unknown",\n "member.status.staged": "Will be spawned after approval",\n "member.status.settled": "All assigned work is settled",\n "member.status.discarded": "Plan discarded; member was not created",\n "member.status.stopped": "Team stopped; explicit resume required",\n "task.assignee.unclaimed": "Unclaimed",\n "task.summary.waitingBreakdown": "Waiting for the captain to break down the work",\n "task.summary.staged": "{count} planned tasks awaiting approval",\n "task.summary.discarded": "{count} planned tasks discarded; none ran",\n "task.summary.allDelivered": "All {count} tasks delivered",\n "task.summary.ended": "Final: {completed} delivered \xB7 {cancelled} cancelled \xB7 {failed} failed",\n "task.summary.blockedAndRunning": "{tasks}{more} waiting on prerequisites; other work has started",\n "task.summary.more": " and {count} more",\n "task.summary.running": "{tasks} in progress",\n "task.summary.ready": "{tasks} ready to start",\n "task.summary.blocked": "{tasks} waiting on prerequisites",\n "task.summary.failedSettled": "{count} failed; the automatic loop has stopped",\n "task.summary.waitingSchedule": "Waiting for the next scheduling round",\n "progress.aria": "Overall team progress",\n "progress.title": "Overall progress",\n "progress.running": "\u25A0 In progress {count}",\n "progress.blocked": "\u25A0 Waiting {count}",\n "progress.delivered": "\u25A0 Delivered {count}",\n "dependency.aria": "Task dependency chain",\n "dependency.parallel": "Parallel tasks",\n "dependency.title": "Task dependencies",\n "dependency.hint.parallel": "No dependencies \xB7 Click for details",\n "dependency.hint.chain": "Hover to highlight dependencies \xB7 Click to pin",\n "dependency.hint.pinned": "{taskId} pinned \xB7 Esc to clear",\n "task.runningAria": "Running",\n "task.model": "{model}",\n "task.detail.completed": "Completed and delivered",\n "task.detail.noPrerequisite": "No prerequisites; ready to start",\n "task.detail.ready": "Prerequisites ready; can start",\n "task.detail.waitingOn": "Waiting for {tasks}",\n "task.detail.notRun": "Plan discarded; task was not run",\n "task.detail.noDownstream": "No downstream tasks",\n "task.detail.unlocks": "Unlocks {tasks} when complete",\n "team.ended": "Ended",\n "plan.badge": "Awaiting approval",\n "plan.title": "Pre-run plan review",\n "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.",\n "plan.member.role": "Role",\n "plan.member.provider": "Provider",\n "plan.member.model": "Model",\n "plan.member.reasoning": "Reasoning effort",\n "plan.member.reasoningHint": "Leave blank for default; accepts low, medium, high, xhigh, and more",\n "plan.model.choose": "Choose a model",\n "plan.model.currentUnavailable": "{provider}/{model} (not in the current catalog)",\n "plan.model.route": "Route: {provider}/{model}",\n "plan.model.defaultReasoning": "Default reasoning effort",\n "plan.model.providerDefault": "Provider default",\n "plan.model.modelDefault": "Model default ({effort})",\n "plan.model.triggerAria": "Choose member model, currently {model}, reasoning effort {effort}",\n "plan.model.back": "Back",\n "plan.model.loading": "Loading models\u2026",\n "plan.model.empty": "No models available",\n "plan.model.partialFailure": "{count} provider catalogs could not be loaded",\n "plan.model.retry": "Retry",\n "plan.member.prompt": "Role prompt",\n "plan.member.roleFallback": "Role not set",\n "plan.task.subject": "Task subject",\n "plan.task.description": "Task description",\n "plan.task.assignee": "Assignee",\n "plan.task.dependencies": "Dependency task IDs (comma-separated)",\n "plan.task.dependenciesHint": "For example task-1, task-2; cycles are rejected",\n "plan.task.unassigned": "Shared task pool",\n "plan.unsaved": "Unsaved",\n "plan.save": "Save",\n "plan.saving": "Saving\u2026",\n "plan.remove": "Remove",\n "plan.removed": "Task removed",\n "plan.removeConfirm": "Confirm remove",\n "plan.removeWarning": "Removing {task} will recalculate downstream dependencies.",\n "plan.cancel": "Cancel",\n "plan.addTask": "Add task",\n "plan.adding": "Adding\u2026",\n "plan.taskAdded": "Task added",\n "plan.newTask": "New task subject",\n "plan.newTaskLabel": "Add a planned task",\n "plan.readySummary": "{members} members \xB7 {tasks} tasks \xB7 {links} dependencies",\n "plan.flow.aria": "Team launch flow",\n "plan.flow.review": "Review plan",\n "plan.flow.spawn": "Create members",\n "plan.flow.run": "Start work",\n "plan.members.title": "Members & model routes",\n "plan.members.count": "{count} members",\n "plan.members.empty": "No members planned yet",\n "plan.tasks.title": "Tasks & dependencies",\n "plan.tasks.count": "{count} tasks \xB7 {links} dependencies",\n "plan.tasks.empty": "No tasks planned yet",\n "plan.dependencies.none": "No dependencies",\n "plan.dependencies.count": "{count} dependencies",\n "plan.approve": "Approve & Run",\n "plan.approving": "Creating members\u2026",\n "plan.approveTitle": "Plan ready?",\n "plan.approveHint": "Approval creates {members} members and schedules {tasks} tasks.",\n "plan.approveConfirmTitle": "Confirm team launch",\n "plan.approveWarning": "Member routes and dependencies cannot be edited here after launch.",\n "plan.approveConfirm": "Confirm launch",\n "plan.continue": "Return to chat & revise",\n "plan.returnToChat": "Return to chat",\n "plan.feedbackTitle": "Waiting for your revision direction",\n "plan.feedbackHint": "The Captain will ask in chat. After your reply, it will revise this draft and wait for approval again.",\n "plan.discard": "Discard this plan",\n "plan.discardConfirmTitle": "Discard this plan?",\n "plan.discardWarning": "The plan will end and be archived. No members have been spawned and no tasks will run.",\n "plan.discardConfirm": "Discard plan",\n "plan.discarding": "Discarding\u2026",\n "plan.pendingEdits": "Save the current edits before launching the team.",\n "plan.saved": "Plan saved",\n "plan.failed": "Operation failed: {message}",\n "team.stats.members": "{count} members",\n "team.stats.completed": "{completed}/{total} completed",\n "team.stats.messages": "{count} messages",\n "delegation.aria": "Captain delegation map",\n "captain.name": "Captain",\n "captain.role": "Break down \xB7 Delegate \xB7 Synthesize",\n "captain.summary": "Assigned {tasks} tasks to {members} members",\n "captain.summary.staged": "Planned {tasks} tasks and {members} members; awaiting approval",\n "captain.summary.awaitingFeedback": "Draft preserved; waiting for your revision direction in chat",\n "captain.summary.discarded": "Plan discarded: {members} members were not created and {tasks} tasks did not run",\n "captain.summary.withTakeover": "Assigned {tasks} to members \xB7 Captain owns {captainTasks}",\n "captain.state.working": "{count} active",\n "captain.state.takeover": "Working on {tasks}",\n "captain.state.collected": "All reports received",\n "captain.state.waiting": "Waiting for reports",\n "captain.state.staged": "Awaiting approval",\n "captain.state.awaitingFeedback": "Awaiting feedback",\n "captain.state.discarded": "Discarded",\n "captain.state.settled": "Settled",\n "members.toggle": "Members {count}",\n "members.collapse": "Collapse",\n "members.expand": "Expand",\n "members.empty": "No members yet; waiting for the captain to assemble the team",\n "assignment.label": "Captain assigned",\n "assignment.staged": "Planned task",\n "assignment.discarded": "Plan not run",\n "assignment.empty": "No tasks",\n "archive.label": "Ended \xB7 Archived history",\n "archive.discardedLabel": "Plan discarded \xB7 Archived history"\n };\n\n\n /** Version-tolerant navigation into durable T Team member transcripts. */\n /**\n * Open one member\'s persisted transcript.\n *\n * Harness rc.8 intentionally removed cold subagents from the ordinary session\n * list. They must first be rediscovered in their parent\'s catalog, then opened\n * with the exact parent/child/mode address. Older runtimes have only `open()`;\n * the fallback preserves ordinary-session navigation. New layouts also select\n * the Conversation panel and cancel catalog refreshes superseded by navigation.\n */\n async function openAgentTeamMember(sessions, parentSessionId, childSessionId, layout) {\n const navigation = layout?.beginNavigation?.();\n if (sessions.openSubagent === void 0 || sessions.refreshSubagents === void 0) {\n sessions.open(childSessionId);\n layout?.selectPanel?.(null);\n return "session";\n }\n await sessions.refreshSubagents(parentSessionId);\n if (navigation?.aborted) return "cancelled";\n const retained = sessions.subagentAddress?.(childSessionId);\n sessions.openSubagent(retained?.parentSessionId === parentSessionId ? retained : {\n parentSessionId,\n childSessionId,\n mode: "continuable"\n });\n layout?.selectPanel?.(null);\n return "subagent";\n }\n\n\n /** Required services: conversation nodes, slots, sessions navigation, and locale. */\n const inject = [\n "uiConversation",\n "slots",\n "sessions",\n "locale",\n "modelDirectories",\n "layout"\n ];\n const useLegacyPanelInfo = (select) => select({ activePanelId: null });\n /** The replayed user message is the canonical transcript entry. */\n function HiddenTTeamCommand() {\n return null;\n }\n /**\n * Register the activity monitor in the shell\'s additive overlay and the\n * in-conversation team card. The card\'s activity button re-opens a folded\n * monitor via a window event \u2014 the recovery path for an old session.\n */\n function apply(ctx) {\n ctx.effect(() => ctx.locale.register(T_TEAM_LOCALE_NAMESPACE, {\n zh,\n en\n }), "t-team: dictionaries");\n const openMember = (parentId, childId) => {\n openAgentTeamMember(ctx.sessions, parentId, childId, ctx.layout).catch((error) => {\n console.warn(`t-team: failed to open member transcript ${childId}: ${String(error)}`);\n });\n };\n const Panel = ({ t, usePanelInfo }) => {\n return (0, react_jsx_runtime.jsx)(ActivityPanel, {\n conversationVisible: (usePanelInfo ?? useLegacyPanelInfo)((panel) => panel.activePanelId === null),\n sessionsList: ctx.sessions.list,\n modelDirectories: ctx.modelDirectories,\n openMember,\n t\n });\n };\n ctx.slots.inject("shell.overlay", () => ctx.slots.register({\n name: "shell.overlay",\n id: "t-team-activity",\n order: 80,\n label: () => ctx.locale.bind(T_TEAM_LOCALE_NAMESPACE)("activity.title"),\n locale: T_TEAM_LOCALE_NAMESPACE\n }, Panel));\n ctx.slots.inject("conversation.chat.commandview", () => ctx.slots.register({\n name: "conversation.chat.commandview",\n key: "t-team-hidden"\n }, HiddenTTeamCommand));\n ctx.uiConversation.events.register(tTeamCardDefinition);\n ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({\n name: "conversation.chat.node",\n key: "t-team",\n locale: T_TEAM_LOCALE_NAMESPACE,\n inject: () => ({ openMember })\n }, TTeamCard));\n }\n\n exports.apply = apply;\n exports.inject = inject;\n return module.exports;\n }\n});\n\n';
19721
19721
 
19722
+ // lib/remote-schemas.js
19723
+ var expertSchema = external_exports.object({
19724
+ slug: external_exports.string(),
19725
+ name: external_exports.string(),
19726
+ nameEn: external_exports.string(),
19727
+ description: external_exports.string(),
19728
+ descriptionEn: external_exports.string(),
19729
+ emoji: external_exports.string(),
19730
+ division: external_exports.string(),
19731
+ divisionZh: external_exports.string(),
19732
+ divisionEn: external_exports.string(),
19733
+ conflict: external_exports.boolean().optional(),
19734
+ /** 用户自建专家(可编辑/可删除);内置专家不带此标记。 */
19735
+ custom: external_exports.boolean().optional(),
19736
+ /** 自建专家文件指纹:编辑/删除时回传,用于拦住并发覆盖。 */
19737
+ hash: external_exports.string().optional()
19738
+ });
19739
+ var customExpertInputSchema = external_exports.object({
19740
+ slug: external_exports.string().min(1).max(128).optional(),
19741
+ name: external_exports.string().min(1).max(200),
19742
+ nameEn: external_exports.string().max(200).optional(),
19743
+ description: external_exports.string().min(1).max(1e3),
19744
+ descriptionEn: external_exports.string().max(1e3).optional(),
19745
+ emoji: external_exports.string().max(16).optional(),
19746
+ body: external_exports.string().min(1).max(6e4),
19747
+ /** 落点分区(自建分区目录名);留空=默认分区。服务端仍会自己校验一遍。 */
19748
+ division: external_exports.string().max(128).optional(),
19749
+ /** 新建分区时的中文显示名(落在 <customRoot>/divisions.json)。 */
19750
+ divisionLabel: external_exports.string().max(40).optional()
19751
+ });
19752
+ var catalogSnapshotSchema = external_exports.object({
19753
+ experts: external_exports.array(expertSchema),
19754
+ enabled: external_exports.array(external_exports.string()),
19755
+ revision: external_exports.number().int().min(0),
19756
+ // 这两个字段必须声明:zod 会把 schema 里没有的键**直接剥掉**(实测),
19757
+ // 漏声明时面板拿到的快照里根本没有它们,界面上表现为"分区标签是空的"。
19758
+ customDivision: external_exports.string().optional(),
19759
+ customDivisionLabel: external_exports.string().optional(),
19760
+ /** 可选的落点分类(面板「分类」下拉与管理页):官方在前,其余按目录/声明发现。 */
19761
+ categories: external_exports.array(external_exports.object({
19762
+ key: external_exports.string(),
19763
+ label: external_exports.string(),
19764
+ official: external_exports.boolean(),
19765
+ count: external_exports.number().int().min(0),
19766
+ customCount: external_exports.number().int().min(0)
19767
+ })).optional()
19768
+ });
19769
+ var enabledStateSchema = external_exports.object({
19770
+ enabled: external_exports.array(external_exports.string()),
19771
+ revision: external_exports.number().int().min(0)
19772
+ });
19773
+ var promptSchema = external_exports.object({ prompt: external_exports.string() });
19774
+ var squadMemberSchema = external_exports.object({
19775
+ slug: external_exports.string(),
19776
+ role: external_exports.string(),
19777
+ name: external_exports.string(),
19778
+ nameZh: external_exports.string(),
19779
+ division: external_exports.string(),
19780
+ divisionZh: external_exports.string(),
19781
+ known: external_exports.boolean()
19782
+ });
19783
+ var squadSchema = external_exports.object({
19784
+ key: external_exports.string(),
19785
+ description: external_exports.string(),
19786
+ aliases: external_exports.array(external_exports.string()),
19787
+ taskPlanning: external_exports.enum(["captain", "seed"]),
19788
+ enabled: external_exports.boolean(),
19789
+ members: external_exports.array(squadMemberSchema)
19790
+ });
19791
+ var rosterExpertSchema = external_exports.object({
19792
+ slug: external_exports.string(),
19793
+ name: external_exports.string(),
19794
+ nameZh: external_exports.string(),
19795
+ division: external_exports.string(),
19796
+ divisionZh: external_exports.string(),
19797
+ enabled: external_exports.boolean(),
19798
+ conflict: external_exports.boolean()
19799
+ });
19800
+ var squadsSnapshotSchema = external_exports.object({
19801
+ revision: external_exports.string(),
19802
+ squads: external_exports.array(squadSchema),
19803
+ experts: external_exports.array(rosterExpertSchema),
19804
+ lastBuild: external_exports.object({ at: external_exports.number(), ok: external_exports.boolean(), output: external_exports.string() })
19805
+ });
19806
+ var teamMemberSchema = external_exports.object({
19807
+ name: external_exports.string(),
19808
+ role: external_exports.string(),
19809
+ status: external_exports.string(),
19810
+ activity: external_exports.string(),
19811
+ done: external_exports.number(),
19812
+ total: external_exports.number()
19813
+ });
19814
+ var teamSchema = external_exports.object({
19815
+ teamId: external_exports.string(),
19816
+ name: external_exports.string(),
19817
+ workspace: external_exports.string(),
19818
+ captainSessionId: external_exports.string(),
19819
+ phase: external_exports.string(),
19820
+ halted: external_exports.boolean(),
19821
+ members: external_exports.array(teamMemberSchema),
19822
+ tasks: external_exports.array(external_exports.object({ id: external_exports.string(), subject: external_exports.string(), status: external_exports.string(), assignee: external_exports.string() }))
19823
+ });
19824
+ var teamsSnapshotSchema = external_exports.object({ teams: external_exports.array(teamSchema) });
19825
+ var startResultSchema = external_exports.object({
19826
+ profile: external_exports.string(),
19827
+ label: external_exports.string(),
19828
+ members: external_exports.number()
19829
+ });
19830
+ var stopResultSchema = external_exports.object({
19831
+ teamName: external_exports.string(),
19832
+ cancelledTasks: external_exports.number(),
19833
+ alreadyHalted: external_exports.boolean()
19834
+ });
19835
+ var squadInputSchema = external_exports.object({
19836
+ key: external_exports.string().min(1).max(64),
19837
+ description: external_exports.string(),
19838
+ aliases: external_exports.array(external_exports.string()),
19839
+ taskPlanning: external_exports.enum(["captain", "seed"]),
19840
+ enabled: external_exports.boolean(),
19841
+ members: external_exports.array(external_exports.string())
19842
+ });
19843
+
19722
19844
  // src/client.jsx
19723
19845
  var NS = "t-team";
19724
19846
  var PLUGIN_ID = "dsh-plugin-t-expert";
@@ -19767,7 +19889,7 @@ var zh = {
19767
19889
  "tab.teams": "\u56E2\u961F",
19768
19890
  "tab.roster": "\u961F\u4F0D",
19769
19891
  "roster.squads": "\u5C0F\u961F\u6A21\u677F\uFF08\u53EF\u590D\u7528\uFF09",
19770
- "roster.squadsHint": "\u9884\u5148\u6311\u597D\u7684\u73ED\u5E95\uFF1A\u6210\u5458\u3001\u522B\u540D\u3001\u542F\u505C\u3002\u7528\u5B83\u5C31\u8BF4 /t <\u5C0F\u961F> <\u76EE\u6807>\uFF0C\u6216\u5728\u8F93\u5165\u6846\u5F39\u7A97\u91CC\u70B9\u300C\u586B\u5165\u300D\uFF1B\u6539\u5B8C\u4FDD\u5B58\u540E\u9700\u91CD\u542F DSH \u624D\u80FD\u7528\u4E8E\u5EFA\u961F\uFF08/t \u5217\u8868\u4F1A\u7ACB\u5373\u5237\u65B0\uFF09\u3002",
19892
+ "roster.squadsHint": "\u9884\u5148\u6311\u597D\u7684\u73ED\u5E95\uFF1A\u6210\u5458\u3001\u522B\u540D\u3001\u542F\u505C\u3002\u7528\u5B83\u5C31\u8BF4 /t <\u5C0F\u961F> <\u76EE\u6807>\uFF0C\u6216\u5728\u8F93\u5165\u6846\u5F39\u7A97\u91CC\u70B9\u300C\u586B\u5165\u300D\uFF1B\u6539\u5B8C\u4FDD\u5B58\u540E\u7ACB\u5373\u751F\u6548\u3001\u65E0\u9700\u91CD\u542F\uFF08/t \u5217\u8868\u4F1A\u7ACB\u5373\u5237\u65B0\uFF0C\u5F15\u64CE\u4F1A\u5C31\u5730\u70ED\u91CD\u8F7D\uFF09\uFF1B\u4FDD\u5B58\u5931\u8D25\u4F1A\u56DE\u6EDA\uFF0C\u76D8\u4E0A\u4ECD\u662F\u65E7\u914D\u7F6E\u3002",
19771
19893
  "roster.teams": "\u8FD0\u884C\u4E2D\u7684\u56E2\u961F",
19772
19894
  "roster.teamsHint": "\u6BCF\u6B21\u7528\u6A21\u677F\u8DD1\u8D77\u6765\u7684\u4E00\u6B21\u5B9E\u4F8B\uFF1A\u53EF\u505C\u6B62\u3001\u770B\u8FDB\u5EA6\u3001\u6253\u5F00\u6D3B\u52A8\u9762\u677F\uFF1B\u5F52\u6863\u540E\u4ECD\u53EF\u5728\u8FD9\u91CC\u56DE\u770B\u3002",
19773
19895
  "roster.expertsHint": "\u540D\u518C\uFF1A\u80FD\u88AB @ \u53EC\u5524\u3001\u4E5F\u80FD\u88AB\u5C0F\u961F\u6311\u8FDB\u73ED\u5E95\u7684\u4E13\u5BB6\u3002\u5E26\u300C\u81EA\u5EFA\u300D\u6807\u8BB0\u7684\u53EF\u4EE5\u5728\u8FD9\u91CC\u6539\u6216\u5220\u3002",
@@ -19912,7 +20034,7 @@ var en = {
19912
20034
  "tab.teams": "Teams",
19913
20035
  "tab.roster": "Roster",
19914
20036
  "roster.squads": "Squad templates (reusable)",
19915
- "roster.squadsHint": "A pre-picked roster: members, aliases, enable/disable. Run it with /t <squad> <goal>, or tap Fill in the composer popup. After saving, restart DSH before the squad can start a team (the /t list refreshes immediately).",
20037
+ "roster.squadsHint": "A pre-picked roster: members, aliases, enable/disable. Run it with /t <squad> <goal>, or tap Fill in the composer popup. Saving takes effect immediately, with no restart (the /t list refreshes at once and the engine hot-reloads in place); a failed save rolls back, so the old config stays on disk.",
19916
20038
  "roster.teams": "Running teams",
19917
20039
  "roster.teamsHint": "One instance per run: stop it, watch progress, open the activity panel; archived teams stay reviewable here.",
19918
20040
  "roster.expertsHint": "The roster: experts available for @-mention and for squad templates. Custom ones can be edited or deleted here.",
@@ -20145,56 +20267,6 @@ var CSS = `
20145
20267
  .t-team-pop-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 2px}
20146
20268
  .t-team-pop-head{display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary)}
20147
20269
  `;
20148
- var expertSchema = external_exports.object({
20149
- slug: external_exports.string(),
20150
- name: external_exports.string(),
20151
- nameEn: external_exports.string(),
20152
- description: external_exports.string(),
20153
- descriptionEn: external_exports.string(),
20154
- emoji: external_exports.string(),
20155
- division: external_exports.string(),
20156
- divisionZh: external_exports.string(),
20157
- divisionEn: external_exports.string(),
20158
- conflict: external_exports.boolean().optional(),
20159
- /** 用户自建专家:卡片上给编辑/删除入口。 */
20160
- custom: external_exports.boolean().optional(),
20161
- /** 自建专家内容指纹:编辑/删除时回传,服务端据此拦并发覆盖。 */
20162
- hash: external_exports.string().optional()
20163
- });
20164
- var catalogSchema = external_exports.object({
20165
- experts: external_exports.array(expertSchema),
20166
- enabled: external_exports.array(external_exports.string()),
20167
- revision: external_exports.number().int().min(0),
20168
- /** 自建专家固定落在这个分类(服务端告知,避免两端各写一份常量)。 */
20169
- customDivision: external_exports.string().optional(),
20170
- customDivisionLabel: external_exports.string().optional(),
20171
- /** 全部分类:官方在前(official=true,名字随包内名册、只读),自建在后(可改名/删除)。 */
20172
- categories: external_exports.array(external_exports.object({
20173
- key: external_exports.string(),
20174
- label: external_exports.string(),
20175
- official: external_exports.boolean(),
20176
- count: external_exports.number().int().min(0),
20177
- customCount: external_exports.number().int().min(0)
20178
- })).optional()
20179
- });
20180
- var customExpertInputSchema = external_exports.object({
20181
- slug: external_exports.string().min(1).max(128).optional(),
20182
- name: external_exports.string().min(1).max(200),
20183
- nameEn: external_exports.string().max(200).optional(),
20184
- description: external_exports.string().min(1).max(1e3),
20185
- descriptionEn: external_exports.string().max(1e3).optional(),
20186
- emoji: external_exports.string().max(16).optional(),
20187
- body: external_exports.string().min(1).max(6e4),
20188
- /** 落点分区(自建分区目录名);留空=默认分区。 */
20189
- division: external_exports.string().max(128).optional(),
20190
- /** 新建分区时的中文显示名。 */
20191
- divisionLabel: external_exports.string().max(40).optional()
20192
- });
20193
- var enabledStateSchema = external_exports.object({
20194
- enabled: external_exports.array(external_exports.string()),
20195
- revision: external_exports.number().int().min(0)
20196
- });
20197
- var promptSchema = external_exports.object({ prompt: external_exports.string() });
20198
20270
  function direct(method, parameters, typeSymbol, schema) {
20199
20271
  return {
20200
20272
  id: `${PLUGIN_ID}#tTeam/${method}`,
@@ -20206,78 +20278,10 @@ function direct(method, parameters, typeSymbol, schema) {
20206
20278
  result: { mode: "strict", typeSymbol, schema }
20207
20279
  };
20208
20280
  }
20209
- var squadMemberSchema = external_exports.object({
20210
- slug: external_exports.string(),
20211
- role: external_exports.string(),
20212
- name: external_exports.string(),
20213
- nameZh: external_exports.string(),
20214
- division: external_exports.string(),
20215
- divisionZh: external_exports.string(),
20216
- known: external_exports.boolean()
20217
- });
20218
- var squadSchema = external_exports.object({
20219
- key: external_exports.string(),
20220
- description: external_exports.string(),
20221
- aliases: external_exports.array(external_exports.string()),
20222
- taskPlanning: external_exports.enum(["captain", "seed"]),
20223
- enabled: external_exports.boolean(),
20224
- members: external_exports.array(squadMemberSchema)
20225
- });
20226
- var rosterExpertSchema = external_exports.object({
20227
- slug: external_exports.string(),
20228
- name: external_exports.string(),
20229
- nameZh: external_exports.string(),
20230
- division: external_exports.string(),
20231
- divisionZh: external_exports.string(),
20232
- enabled: external_exports.boolean(),
20233
- conflict: external_exports.boolean()
20234
- });
20235
- var squadsSnapshotSchema = external_exports.object({
20236
- revision: external_exports.string(),
20237
- squads: external_exports.array(squadSchema),
20238
- experts: external_exports.array(rosterExpertSchema),
20239
- lastBuild: external_exports.object({ at: external_exports.number(), ok: external_exports.boolean(), output: external_exports.string() })
20240
- });
20241
- var squadInputSchema = external_exports.object({
20242
- key: external_exports.string(),
20243
- description: external_exports.string(),
20244
- aliases: external_exports.array(external_exports.string()),
20245
- taskPlanning: external_exports.enum(["captain", "seed"]),
20246
- enabled: external_exports.boolean(),
20247
- members: external_exports.array(external_exports.string())
20248
- });
20249
- var teamSchema = external_exports.object({
20250
- teamId: external_exports.string(),
20251
- name: external_exports.string(),
20252
- workspace: external_exports.string(),
20253
- captainSessionId: external_exports.string(),
20254
- phase: external_exports.string(),
20255
- halted: external_exports.boolean(),
20256
- members: external_exports.array(external_exports.object({
20257
- name: external_exports.string(),
20258
- role: external_exports.string(),
20259
- status: external_exports.string(),
20260
- activity: external_exports.string(),
20261
- done: external_exports.number(),
20262
- total: external_exports.number()
20263
- })),
20264
- tasks: external_exports.array(external_exports.object({ id: external_exports.string(), subject: external_exports.string(), status: external_exports.string(), assignee: external_exports.string() }))
20265
- });
20266
- var teamsSnapshotSchema = external_exports.object({ teams: external_exports.array(teamSchema) });
20267
- var startResultSchema = external_exports.object({
20268
- profile: external_exports.string(),
20269
- label: external_exports.string(),
20270
- members: external_exports.number()
20271
- });
20272
- var stopResultSchema = external_exports.object({
20273
- teamName: external_exports.string(),
20274
- cancelledTasks: external_exports.number(),
20275
- alreadyHalted: external_exports.boolean()
20276
- });
20277
20281
  var TYPERT_REMOTE = {
20278
20282
  package: PLUGIN_ID,
20279
20283
  descriptors: [
20280
- direct("getCatalog", [], "TTeamCatalog", catalogSchema),
20284
+ direct("getCatalog", [], "TTeamCatalog", catalogSnapshotSchema),
20281
20285
  direct("setEnabled", [
20282
20286
  { name: "enabled", wire: "enabled", source: "json", codec: { mode: "strict", typeSymbol: "string[]", schema: external_exports.array(external_exports.string()) } },
20283
20287
  { name: "expectedRevision", wire: "expectedRevision", source: "json", codec: { mode: "strict", typeSymbol: "number", schema: external_exports.number().int().min(0) } }
@@ -20303,27 +20307,27 @@ var TYPERT_REMOTE = {
20303
20307
  ], "TTeamStopResult", stopResultSchema),
20304
20308
  direct("createExpert", [
20305
20309
  { name: "expert", wire: "expert", source: "json", codec: { mode: "strict", typeSymbol: "TTeamCustomExpertInput", schema: customExpertInputSchema } }
20306
- ], "TTeamCatalog", catalogSchema),
20310
+ ], "TTeamCatalog", catalogSnapshotSchema),
20307
20311
  direct("updateExpert", [
20308
20312
  { name: "slug", wire: "slug", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } },
20309
20313
  { name: "expert", wire: "expert", source: "json", codec: { mode: "strict", typeSymbol: "TTeamCustomExpertInput", schema: customExpertInputSchema } },
20310
20314
  { name: "expectedHash", wire: "expectedHash", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(64) } }
20311
- ], "TTeamCatalog", catalogSchema),
20315
+ ], "TTeamCatalog", catalogSnapshotSchema),
20312
20316
  direct("deleteExpert", [
20313
20317
  { name: "slug", wire: "slug", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } },
20314
20318
  { name: "expectedHash", wire: "expectedHash", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(64) } }
20315
- ], "TTeamCatalog", catalogSchema),
20319
+ ], "TTeamCatalog", catalogSnapshotSchema),
20316
20320
  direct("createCategory", [
20317
20321
  { name: "key", wire: "key", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } },
20318
20322
  { name: "label", wire: "label", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(40) } }
20319
- ], "TTeamCatalog", catalogSchema),
20323
+ ], "TTeamCatalog", catalogSnapshotSchema),
20320
20324
  direct("updateCategory", [
20321
20325
  { name: "key", wire: "key", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } },
20322
20326
  { name: "label", wire: "label", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(40) } }
20323
- ], "TTeamCatalog", catalogSchema),
20327
+ ], "TTeamCatalog", catalogSnapshotSchema),
20324
20328
  direct("deleteCategory", [
20325
20329
  { name: "key", wire: "key", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } }
20326
- ], "TTeamCatalog", catalogSchema)
20330
+ ], "TTeamCatalog", catalogSnapshotSchema)
20327
20331
  ]
20328
20332
  };
20329
20333
  var catalogCache = /* @__PURE__ */ new Map();