@tea-agent/loop-agent 0.34.3 → 0.34.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/AGENTS.md +8 -3
  2. package/CHANGELOG.md +66 -22
  3. package/README.md +2 -2
  4. package/dist/shared/operator/capabilities.js +0 -7
  5. package/dist/worker/cli.js +21 -27
  6. package/dist/worker/console/app-data.js +2 -0
  7. package/dist/worker/console/chat/chat-event-store.js +134 -4
  8. package/dist/worker/console/chat/pi-runtime.js +308 -63
  9. package/dist/worker/console/chat/resource-preferences-store.js +152 -0
  10. package/dist/worker/console/chat/routes.js +425 -19
  11. package/dist/worker/console/chat/shortcuts.js +208 -9
  12. package/dist/worker/console/chat/tool-preview.js +162 -5
  13. package/dist/worker/console/chat/turn-execution-registry.js +82 -0
  14. package/dist/worker/console/dag-execution-receipt.js +14 -1
  15. package/dist/worker/console/doctor.js +1 -1
  16. package/dist/worker/console/index.js +1 -0
  17. package/dist/worker/console/open-browser.js +134 -0
  18. package/dist/worker/console/recovery-cta.js +1 -1
  19. package/dist/worker/console/server.js +5 -1
  20. package/dist/worker/console/static/assets/index-qpkysQYW.css +1 -0
  21. package/dist/worker/console/static/assets/index-y980PqtP.js +56 -0
  22. package/dist/worker/console/static/index.html +2 -2
  23. package/dist/worker/console/static-src/chat-markdown-security.js +38 -0
  24. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +1 -3
  25. package/dist/worker/console/static-src/operator-chat/format.js +2 -2
  26. package/dist/worker/console/static-src/operator-chat/refs.js +24 -0
  27. package/dist/worker/console/static-src/operator-chat/resource-auto-invocation.js +91 -0
  28. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +690 -0
  29. package/dist/worker/console/static-src/operator-chat/turn-submission.js +158 -0
  30. package/dist/worker/console/static-src/operator-chat/useChatStream.js +535 -86
  31. package/dist/worker/console/static-src/operator-chat/useChatThread.js +11 -5
  32. package/dist/worker/console/static-src/operator-chat/useComposer.js +81 -3
  33. package/dist/workflows/dag/init-hybrid.js +2 -0
  34. package/docs/architecture/evolution.md +1 -1
  35. package/docs/architecture/system-overview.md +1 -1
  36. package/docs/architecture/worker-and-feature.md +1 -1
  37. package/docs/operations/local-development-environment.md +4 -2
  38. package/docs/templates/branch-merge-report.md +9 -0
  39. package/docs/templates/evaluation/agents-map-slim-v1.md +1 -1
  40. package/docs/templates/evaluation/agents-map-verbose-v0.md +2 -2
  41. package/docs/templates/init-managed-agents.md +2 -2
  42. package/package.json +6 -2
  43. package/skills/agent-worker/SKILL.md +1 -1
  44. package/skills/agent-worker/references/agent-worker-operator.md +2 -2
  45. package/skills/loop-agent/references/command-reference.md +2 -3
  46. package/dist/worker/console/static/assets/index-BQkhJpV8.css +0 -1
  47. package/dist/worker/console/static/assets/index-BpuHmlSP.js +0 -29
@@ -15,7 +15,10 @@ const EMPTY_USAGE = {
15
15
  * slices it patches and the derived timeline projections.
16
16
  */
17
17
  export function useChatThread(params) {
18
- const { origin, refs, sessionId, setError, setProcessOpen, onReconcile } = params;
18
+ const { origin, refs, sessionId, setError, onReconcile } = params;
19
+ // setProcessOpen remains on the hook API for session lifecycle close/reset
20
+ // (UI-08); the SSE applier must not open the process panel.
21
+ void params.setProcessOpen;
19
22
  const [messages, setMessages] = useState([]);
20
23
  const [toolCalls, setToolCalls] = useState([]);
21
24
  const [operationCards, setOperationCards] = useState([]);
@@ -37,7 +40,6 @@ export function useChatThread(params) {
37
40
  refs,
38
41
  onReconcile,
39
42
  setError,
40
- setProcessOpen,
41
43
  setInterview,
42
44
  setHumanGateCards,
43
45
  setArtifactCards,
@@ -48,7 +50,7 @@ export function useChatThread(params) {
48
50
  setUsage,
49
51
  setMessages,
50
52
  setToolCalls,
51
- }), [refs, onReconcile, setError, setProcessOpen]);
53
+ }), [refs, onReconcile, setError]);
52
54
  /** Parse + apply one raw SSE block (frames separated by \n\n). Returns the
53
55
  * eventId if the block carried an `id:` line (for Last-Event-ID tracking). */
54
56
  const applySseBlock = useCallback((block, assistantId, options) => {
@@ -138,13 +140,17 @@ export function useChatThread(params) {
138
140
  let statusLabel = "完成";
139
141
  let statusKind = "ok";
140
142
  if (errored.length > 0) {
141
- statusLabel = `${errored.length} 出错`;
143
+ statusLabel = `${errored.length} 次出错`;
142
144
  statusKind = "error";
143
145
  }
144
146
  else if (running.length > 0) {
145
- statusLabel = current ? `正在调用 ${current.toolName}` : "运行中";
147
+ statusLabel = current ? `${current.toolName} 运行中` : "运行中";
146
148
  statusKind = "running";
147
149
  }
150
+ else {
151
+ // Completed is default/neutral; not shown as a permanent green success chip.
152
+ statusLabel = "";
153
+ }
148
154
  return {
149
155
  count: toolCalls.length,
150
156
  statusLabel,
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
2
- import { SHORTCUTS } from "../../chat/shortcuts.js";
2
+ import { filterSlashCommands, mergeSlashCommands, } from "../../chat/shortcuts.js";
3
3
  import { confirmationToken } from "./format.js";
4
4
  import { attachRuntimeSnapshotController } from "./useRuntimeSnapshot.js";
5
5
  /** Composer state: input text, @file palette, image attachments, /shortcuts,
@@ -11,12 +11,86 @@ export function useComposer(params) {
11
11
  const [pendingImages, setPendingImages] = useState([]);
12
12
  const [shortcutOpen, setShortcutOpen] = useState(false);
13
13
  const [shortcutIndex, setShortcutIndex] = useState(0);
14
+ const [dynamicCommands, setDynamicCommands] = useState([]);
15
+ const [dynamicCommandsLoading, setDynamicCommandsLoading] = useState(false);
16
+ const [dynamicCommandsError, setDynamicCommandsError] = useState(null);
17
+ const [commandsEpoch, setCommandsEpoch] = useState(0);
14
18
  const textareaRef = useRef(null);
19
+ const commandsSessionRef = useRef(undefined);
15
20
  const handleInputChange = useCallback((value) => {
16
21
  setInput(value);
17
22
  setShortcutOpen(value.startsWith("/"));
18
23
  setShortcutIndex(0);
19
24
  }, []);
25
+ const loadDynamicCommands = useCallback(async () => {
26
+ if (!sessionId) {
27
+ setDynamicCommands([]);
28
+ setDynamicCommandsError(null);
29
+ setDynamicCommandsLoading(false);
30
+ return;
31
+ }
32
+ const target = sessionId;
33
+ commandsSessionRef.current = target;
34
+ setDynamicCommandsLoading(true);
35
+ setDynamicCommandsError(null);
36
+ try {
37
+ const res = await fetch(`${origin}/api/operator/v1/chat/sessions/${encodeURIComponent(target)}/commands`, { credentials: "include" });
38
+ if (commandsSessionRef.current !== target)
39
+ return;
40
+ if (!res.ok) {
41
+ setDynamicCommandsError("动态命令加载失败");
42
+ setDynamicCommands([]);
43
+ return;
44
+ }
45
+ const body = (await res.json().catch(() => null));
46
+ const items = [];
47
+ for (const raw of body?.commands ?? []) {
48
+ const source = raw.source;
49
+ if (source !== "extension" &&
50
+ source !== "prompt" &&
51
+ source !== "skill") {
52
+ continue;
53
+ }
54
+ const command = String(raw.command ?? raw.name ?? "").trim();
55
+ if (!command)
56
+ continue;
57
+ items.push({
58
+ command: command.startsWith("/") ? command : `/${command}`,
59
+ label: String(raw.label ?? raw.name ?? command),
60
+ description: String(raw.description ?? ""),
61
+ source,
62
+ });
63
+ }
64
+ if (commandsSessionRef.current !== target)
65
+ return;
66
+ setDynamicCommands(items);
67
+ }
68
+ catch {
69
+ if (commandsSessionRef.current !== target)
70
+ return;
71
+ setDynamicCommandsError("动态命令加载失败");
72
+ setDynamicCommands([]);
73
+ }
74
+ finally {
75
+ if (commandsSessionRef.current === target) {
76
+ setDynamicCommandsLoading(false);
77
+ }
78
+ }
79
+ }, [origin, sessionId]);
80
+ // Lazy-load dynamic commands when slash palette opens or session changes.
81
+ useEffect(() => {
82
+ setDynamicCommands([]);
83
+ setDynamicCommandsError(null);
84
+ if (!sessionId)
85
+ return;
86
+ if (!shortcutOpen && commandsEpoch === 0)
87
+ return;
88
+ void loadDynamicCommands();
89
+ }, [sessionId, shortcutOpen, commandsEpoch, loadDynamicCommands]);
90
+ const retryDynamicCommands = useCallback(() => {
91
+ setCommandsEpoch((n) => n + 1);
92
+ void loadDynamicCommands();
93
+ }, [loadDynamicCommands]);
20
94
  useEffect(() => {
21
95
  if (!sessionId)
22
96
  return;
@@ -94,9 +168,10 @@ export function useComposer(params) {
94
168
  }, 400);
95
169
  return () => window.clearTimeout(timer);
96
170
  }, [origin, sessionId, input]);
171
+ const mergedCommands = useMemo(() => mergeSlashCommands(dynamicCommands), [dynamicCommands]);
97
172
  const filteredShortcuts = useMemo(() => input.startsWith("/")
98
- ? SHORTCUTS.filter((item) => item.command.startsWith(input.trim().split(/\s+/, 1)[0].toLowerCase()))
99
- : [], [input]);
173
+ ? filterSlashCommands(mergedCommands, input)
174
+ : [], [input, mergedCommands]);
100
175
  const onCompositionStart = useCallback(() => {
101
176
  refs.isComposingRef.current = true;
102
177
  }, [refs]);
@@ -132,6 +207,9 @@ export function useComposer(params) {
132
207
  shortcutIndex,
133
208
  setShortcutIndex,
134
209
  filteredShortcuts,
210
+ dynamicCommandsLoading,
211
+ dynamicCommandsError,
212
+ retryDynamicCommands,
135
213
  insertFileReference,
136
214
  textareaRef,
137
215
  onCompositionStart,
@@ -3918,6 +3918,7 @@ async function buildBackendTestHybridDag(sources) {
3918
3918
  },
3919
3919
  skillsByRole: BACKEND_TEST_SKILLS_BY_ROLE,
3920
3920
  executorModels: sources.executorModelMatrix ?? DEFAULT_DAG_EXECUTOR_MODELS,
3921
+ verifyStrategy: resolveDagVerifyStrategy(taskConfig),
3921
3922
  tasks: [
3922
3923
  environment,
3923
3924
  generateMdPlan,
@@ -4579,6 +4580,7 @@ function buildFrontendTestHybridDag(sources) {
4579
4580
  closeout: ["verification-before-completion"],
4580
4581
  },
4581
4582
  executorModels: sources.executorModelMatrix ?? DEFAULT_DAG_EXECUTOR_MODELS,
4583
+ verifyStrategy: resolveDagVerifyStrategy(sources.taskConfig),
4582
4584
  tasks,
4583
4585
  };
4584
4586
  applyDefaultReadOnlyRetryPolicy(spec);
@@ -21,7 +21,7 @@
21
21
  | Frontend-test | 默认 short-chain RAG;内容/evidence 质量进入 advisory findings,路径与安全边界仍 fail-closed | `CHANGELOG.md [0.21.0]` / `[0.22.0]` |
22
22
  | Frontend-implementation | Contract / trace / repair / Mock assess;`ai_workspace` + 知识库 + `openspec` 规范发现;lint 基线债务隔离 | `CHANGELOG.md [0.22.0]` |
23
23
  | Inspect(原 Observe) | 统一 Console 的 `/inspect/` 只读运营面与富时间线;独立 `observe serve` 已硬下线 | `website/docs/guides/observe-ui.md`、`CHANGELOG.md [Unreleased]` |
24
- | Local Operator Console | `agent-worker console serve\|doctor`(loopback);Operate + Inspect、Happy Path / Interview / split view / recovery CTA;**0.23.x 起含 General Operator Chat**(Pi SDK services session、operator-only tool surface);**非**远端多用户 Console | unify design;ADR 0005;completed `2026-07-25-console-phase-4-general-operator-chat.md` |
24
+ | Local Operator Console | `agent-worker console\|doctor`(loopback;默认打开系统浏览器,`--no-open` 禁止);Operate + Inspect、Happy Path / Interview / split view / recovery CTA;**0.23.x 起含 General Operator Chat**(Pi SDK services session、operator-only tool surface);**非**远端多用户 Console | unify design;ADR 0005;completed `2026-07-25-console-phase-4-general-operator-chat.md` |
25
25
  | Task Contract / operator surface | journaled `task contract *`;machine envelope;**DagSpec v4 `taskContractBinding`**(exclusive writer 强制) | `CHANGELOG.md [0.17.0]`–`[0.17.2]`;ADR 0005 |
26
26
  | DagSpec / repair | v3 `runtimeContract` + 显式 `repairNodeId`;新 writer 生成默认 v4 binding | `dag-execution.md`、`CHANGELOG.md [0.11.0]` / `[0.17.0]` |
27
27
  | 自适应 liveness | runner lease、Provider/tool/output 活动与 meaningful progress 分离;静默 stall 受控终止,退出未确认时禁止自动重试 | `dag-execution.md`、active `2026-07-23-dag-adaptive-liveness.md` |
@@ -61,7 +61,7 @@ workflow runtime(调度 Pi / shell / static 节点)
61
61
 
62
62
  ### 本地 Operator Console(Official,0.17.x MVP,与 Observe 协作)
63
63
 
64
- - `agent-worker console serve|doctor` 提供 loopback Operator Console(默认 `127.0.0.1:8790`);Happy Path / Interview 策略面、Task Contract 落地与 recovery CTA 已随 **0.17.0–0.17.2** 发布。
64
+ - `agent-worker console|doctor` 提供 loopback Operator Console(默认 `127.0.0.1:8790`;本地图形环境 listen 后默认打开浏览器,`--no-open` 禁止);Happy Path / Interview 策略面、Task Contract 落地与 recovery CTA 已随 **0.17.0–0.17.2** 发布。
65
65
  - canonical mutation 只经 sibling 已发布 `loop-agent`(`LoopAgentClient`),不 in-process 跑 DAG kernel。
66
66
  - Observe 保持**独立**只读进程(默认 `8787`);Console 通过 versioned Observe `/api/health`(`schemaVersion`、`repoFingerprint`、route capabilities)做深链 fail-closed,**不** mount / proxy。
67
67
  - openCode 等主会话仍是 Compatibility / Operator Assist,与 Official Console **不等同**。设计锚点:ADR 0005、`docs/design/archive/2026-07-21-local-operator-console-from-pi-web.md`;handoff `docs/reports/feature/2026-07-22-console-mvp-handoff.md`。
@@ -101,7 +101,7 @@ controller identity 与 DAG skill snapshot 是两个不同冻结层(前者跨
101
101
  - 模块:`src/worker/observe/`、`src/worker/observability/{read-model,event-store}.ts`。
102
102
  - 全局快照:`buildGlobalSnapshot({ repoRoot })`(`src/worker/observability/read-model.ts`),是 **derived** 视图,消费 `.harness/` 与 Task Pool 事实,**不**改变执行成败。
103
103
  - Observe read model 是本地只读 Inspect 能力;snapshot 投影失败返回安全错误摘要而非全零健康状态。
104
- - `agent-worker console serve` 在同一进程挂载 `/inspect/` 与现有 GET `/api/**`;`/api/health` 返回 `OperatorSurfaceHealthV1`。兼容期独立 Observe `:8787` 保持旧 health DTO 与 GET-only 行为。
104
+ - `agent-worker console` 在同一进程挂载 `/inspect/` 与现有 GET `/api/**`;`/api/health` 返回 `OperatorSurfaceHealthV1`。`observe serve` 已硬下线(REMOVED / exit 2)。
105
105
 
106
106
  ### Local Operator Console(Official,0.18.0)
107
107
 
@@ -13,9 +13,11 @@ bash scripts/install-git-hooks.sh
13
13
  | Hook | 行为 |
14
14
  | --- | --- |
15
15
  | `pre-commit` | `bash scripts/check-repo.sh`(快,不含 `npm test`) |
16
- | `pre-push` | `bash scripts/ci.sh`(check-repo + typecheck + 全量 `npm test`) |
16
+ | `pre-push` | `node scripts/pre-push-verify.mjs`:同 tree/env receipt 命中则复用;miss 时 full `bash scripts/ci.sh`(check-repo + typecheck + 全量 `npm test`) |
17
17
 
18
- 编辑与实现阶段只跑 verification-matrix 的「最低验证」;全量测试由 push hook 承担。紧急跳过一次:
18
+ 可选:`npm run verify:tree` 对当前 clean HEAD 提前 full 验证并写 receipt;`node scripts/pre-push-verify.mjs --explain-current-tree` 只读诊断。二者都不是默认必经步骤。
19
+
20
+ 编辑与实现阶段只跑 verification-matrix 的「最低验证」;全量测试由 push 前 hook 或可选 `verify:tree` 承担。紧急跳过一次(非标准去重):
19
21
 
20
22
  ```bash
21
23
  LOOP_AGENT_SKIP_PRE_PUSH_TESTS=1 git push
@@ -88,6 +88,15 @@ Record overlapping or high-risk files that Git merged without conflict. These ar
88
88
 
89
89
  Add focused tests and real init/update/browser/CLI smokes required by the merged capabilities.
90
90
 
91
+ ### Full-suite authority (local same-tree dedupe)
92
+
93
+ - Canonical full-verification authority: `<valid receipt | target pre-push | npm run verify:tree | authorized skip/release workflow>`
94
+ - Verified tree SHA: `<git rev-parse HEAD^{tree} or equivalent>`
95
+ - Receipt status/path: `<matched|missing|expired|invalid|ineligible-dirty|n/a; path if any>`
96
+ - Full-suite local execution count: `<number of full local suite runs for this merge tree>`
97
+ - Additional full run reason: `<none | env drift | new merge tree | command contract change | other>`
98
+ - Apparent duplicate skipped and evidence: `<yes/no; receipt matched log or explain output summary>`
99
+
91
100
  ## Mode Completion Check
92
101
 
93
102
  - Required gates for selected mode: `<list>`.
@@ -37,7 +37,7 @@
37
37
  4. 涉及测试纪律/验证声明/调试时继续读:`docs/harness-methodology-*.md`。
38
38
  5. 查看最近提交、相关 plan/progress/report;`git status --short --branch`;跑最小基线验证。
39
39
  6. 后端/接口/pytest → `taskKind: "backend-test"`(不是 `--profile`);知识回写 `knowledge-sync`;图谱开荒 `knowledge-graph-bootstrap`。`--profile` 仅 `auto|minimal|standard|reviewed|supervised`。
40
- 7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;兼容 `agent-worker console serve --repo . --port 8790`)(`/inspect/` 只读);`observe serve` 已下线(REMOVED / exit 2);`observe snapshot` 仍可用。
40
+ 7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;`--no-open` 禁止自动打开浏览器)(`/inspect/` 只读);`observe serve` 已下线(REMOVED / exit 2);`observe snapshot` 仍可用。
41
41
  8. 分支合并 → 先读 `docs/operations/branch-merge-guideline.md`。
42
42
 
43
43
  ## 会话协议
@@ -54,7 +54,7 @@
54
54
  10. 检查 `git status --short --branch`。
55
55
  11. 运行本次任务相关的最小基线验证。
56
56
  12. 如果用户提到"后端测试"、"接口测试"、"pytest"、"自动化测试",在任务 `task.json` 中设置 `taskKind: "backend-test"` 再 `task advance`;不要用 `--profile backend-test`(CLI 不接受该值,专用模板只走 taskKind)。知识回写用 `taskKind: "knowledge-sync"`(须 `featureId`),图谱开荒用 `taskKind: "knowledge-graph-bootstrap"`。`--profile` 仅表示治理强度:`auto|minimal|standard|reviewed|supervised`。
57
- 13. 如果用户提到"看板"、"observe"、"监控面板"、"启动看板",使用 `agent-worker console` 启动统一 Operator Console(默认 repo=当前目录、port=8790;兼容入口 `agent-worker console serve --repo . --port 8790`);`/inspect/` 提供只读检视。`agent-worker observe serve` 已下线(REMOVED / exit 2)。
57
+ 13. 如果用户提到"看板"、"observe"、"监控面板"、"启动看板",使用 `agent-worker console` 启动统一 Operator Console(默认 repo=当前目录、port=8790;本地图形环境默认打开浏览器,`--no-open` 禁止);`/inspect/` 提供只读检视。`agent-worker observe serve` 已下线(REMOVED / exit 2)。
58
58
  14. 如果用户要求“合并 `<source>` 到 `<target>`”或“合并 origin/main 到当前分支”,先阅读 `docs/operations/branch-merge-guideline.md`,按影响自动选择快速、标准或深度模式;始终冻结 source SHA、审查双方功能、运行 merge-tree、生成 source-SHA 合并报告,并在提交前再次 fetch 防止主干前进。
59
59
 
60
60
  ## 会话协议
@@ -89,7 +89,7 @@
89
89
  - 长期决策写入 `docs/`,不要只留在聊天里。
90
90
  - 分支合并遵循 `docs/operations/branch-merge-guideline.md`;快速模式只用于可证明的低风险/no-op 合并,涉及冲突、init/package/runtime/release/public API 时必须升级为标准或深度模式。
91
91
  - 后端测试、接口/API 测试、pytest 或明确的后端自动化测试,必须把 `.harness/tasks/<task-id>/task.json` 的 `taskKind` 设置为 `"backend-test"`,不得保留默认 `standard`。`backend-test` 是 `taskKind`,不是 `--profile` 的可选值;`task advance` 继续使用 `--profile auto` 选择治理等级。仅说“自动化测试”且前后端不明时,先根据任务源和项目技术栈判断,禁止无条件路由。
92
- - 本地 Operator Console:`agent-worker console`(默认 repo=当前目录、port=8790;兼容 `agent-worker console serve --repo . --port 8790`),访问 `http://127.0.0.1:8790/`;其中 `/inspect/` 为只读运行检视。默认绑定本机 `127.0.0.1`;可用 `--host 0.0.0.0` / `--debug`,不要直接暴露到公开网络。端口被占用时不会自动更换,请用 `--port <port>` 显式指定。
92
+ - 本地 Operator Console:`agent-worker console`(默认 repo=当前目录、port=8790;`--no-open` 可禁止自动打开浏览器),访问 `http://127.0.0.1:8790/`;其中 `/inspect/` 为只读运行检视。默认绑定本机 `127.0.0.1`;可用 `--host 0.0.0.0` / `--debug`,不要直接暴露到公开网络。端口被占用时不会自动更换,请用 `--port <port>` 显式指定。
93
93
  - 面向使用者的新增、修改、删除或修复,应同步更新根目录 `CHANGELOG.md`;保持版本级摘要即可,不写过细技术细节。
94
94
  - 面向用户的中文更新日志、README 和说明文档应使用自然、结果导向的表达:先说明用户能获得什么或问题如何改善,保留必要的命令和产品术语,避免逐字翻译、内部实现细节和无意义的中英混杂。
95
95
  - 涉及 `loop-agent init` 或目标项目投影的改动,必须同步考虑目标项目生成物:`AGENTS.md`、`README.md`、`harness.json`、`ai_workspace/loop-agent/`、`scripts/`、`.agents/skills/`、`.harness/prompts`、`.gitignore`(loop-agent runtime managed block)和 npm 包内置 assets;目标项目根 `docs/` 和根 `skills/` 的旧投影需要由 `init update --apply-safe` 安全迁移或退役。
@@ -127,8 +127,8 @@ loop-agent task status <task-id> --json
127
127
  ### 运行看板(只读)
128
128
 
129
129
  ```bash
130
- agent-worker console # 默认 repo=当前目录,port=8790
131
- agent-worker console serve --repo . --port 8790 # 兼容入口,等价于上面裸入口
130
+ agent-worker console # 默认 repo=当前目录,port=8790;本地图形环境 listen 后默认打开浏览器
131
+ agent-worker console --no-open # 只启动服务,不打开浏览器
132
132
  ```
133
133
 
134
134
  浏览器打开 `http://127.0.0.1:8790/`;检视面为 `http://127.0.0.1:8790/inspect/`。默认绑定本机 `127.0.0.1`;不要直接暴露到公开网络。端口被占用时不会自动更换,请用 `--port <port>` 显式指定。`agent-worker observe serve` 已下线(REMOVED / exit 2)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.34.3",
3
+ "version": "0.34.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -60,7 +60,8 @@
60
60
  "docs:build": "npm --prefix website run build",
61
61
  "docs:serve": "npm --prefix website run serve",
62
62
  "smoke:stale-serial": "node --import tsx/esm scripts/smoke-stale-plan-serial.ts",
63
- "self-host:canary": "node scripts/self-host-canary.mjs"
63
+ "self-host:canary": "node scripts/self-host-canary.mjs",
64
+ "verify:tree": "node scripts/pre-push-verify.mjs --verify-current-tree"
64
65
  },
65
66
  "dependencies": {
66
67
  "commander": "^12.1.0",
@@ -74,12 +75,15 @@
74
75
  "@earendil-works/pi-coding-agent": "0.80.10"
75
76
  },
76
77
  "devDependencies": {
78
+ "@remixicon/react": "^4.9.0",
77
79
  "@types/node": "^24.6.0",
78
80
  "@types/react": "^19.1.8",
79
81
  "@types/react-dom": "^19.1.6",
80
82
  "@types/semver": "^7.7.1",
81
83
  "react": "^19.1.0",
82
84
  "react-dom": "^19.1.0",
85
+ "react-markdown": "^10.1.0",
86
+ "remark-gfm": "^4.0.1",
83
87
  "tsx": "^4.20.6",
84
88
  "typescript": "^5.9.3",
85
89
  "vite": "^7.0.0",
@@ -16,7 +16,7 @@ references:
16
16
  - **允许**:`agent-worker` / `loop-agent` CLI;只读 `pool doctor`、`observe`、status/report;冻结 controller identity;选择 Ready 工作与 recovery 命令。
17
17
  - **禁止**:绕过 CLI 直接 Edit 业务实现;Worker/DAG 失败后主会话「救火改文件」。
18
18
  - **失败时只允许**:保留 evidence → `task retry` / `task reconcile` / `pool mark-failed` / human gate → 再经 CLI 重跑;实现写入仍只经 published `loop-agent` DAG。
19
- - **Official vs Compatibility**:`agent-worker console` 是 Official 本地控制面(裸入口直接启动;默认 repo=当前目录、port=8790;兼容入口 `agent-worker console serve --repo . --port 8790` 等价)。同进程提供 Operate + Inspect,Inspect 路径 `/inspect/#/...`;openCode 等主会话仍是 Compatibility Assist,二者**不是**同等保证。`observe serve` 已硬下线(`OBSERVE_SERVE_REMOVED` + exit 2,不监听端口);只读检视请用 Console `/inspect/`;`observe snapshot` 仍输出 GlobalSnapshot JSON。
19
+ - **Official vs Compatibility**:`agent-worker console` 是 Official 本地控制面唯一启动入口(默认 repo=当前目录、port=8790;本地图形环境 listen 后默认打开系统浏览器,`--no-open` 禁止)。同进程提供 Operate + Inspect,Inspect 路径 `/inspect/#/...`;openCode 等主会话仍是 Compatibility Assist,二者**不是**同等保证。`observe serve` 已硬下线(`OBSERVE_SERVE_REMOVED` + exit 2,不监听端口);只读检视请用 Console `/inspect/`;`observe snapshot` 仍输出 GlobalSnapshot JSON。
20
20
 
21
21
  ## Route the Work
22
22
 
@@ -54,8 +54,8 @@ Leaf DAG nodes 不得递归启动 `agent-worker`。Worker 负责 DAG 之外的 s
54
54
  ```
55
55
 
56
56
  doctor 只读;migrate 默认零写入,apply 失败全回滚且不改 JSONL。
57
- 8. Inspect(原 Observe)只读:仅推荐 `agent-worker console`(或 `console serve`)的 `/inspect/#/...`;`observe snapshot` 仍可用。`observe serve` 已下线(REMOVED / exit 2)。canonical Task 路由为 `/api/features/:featureId/tasks/:taskId` 与 `#/feature/:featureId/task/:taskId`。8790 `/api/health` 为 `OperatorSurfaceHealthV1`。
58
- 9. Official Console:`agent-worker console serve|doctor`(默认 loopback;可 `--host 0.0.0.0` / `--debug`)。Recovery CTA 为 report/doctor/decision/resume/reconcile/regenerate/打开检视;无 Cancel、无主 CTA「直接改代码」。主会话 Compatibility Assist 不得替代 Console/CLI 执法。
57
+ 8. Inspect(原 Observe)只读:仅推荐 `agent-worker console` `/inspect/#/...`;`observe snapshot` 仍可用。`observe serve` 已下线(REMOVED / exit 2)。canonical Task 路由为 `/api/features/:featureId/tasks/:taskId` 与 `#/feature/:featureId/task/:taskId`。8790 `/api/health` 为 `OperatorSurfaceHealthV1`。
58
+ 9. Official Console:`agent-worker console|doctor`(默认 loopback;可 `--host 0.0.0.0` / `--debug` / `--no-open`)。Recovery CTA 为 report/doctor/decision/resume/reconcile/regenerate/打开检视;无 Cancel、无主 CTA「直接改代码」。主会话 Compatibility Assist 不得替代 Console/CLI 执法。
59
59
 
60
60
  ## Feature Packet Scaffold
61
61
 
@@ -575,8 +575,7 @@ agent-worker scheduler clock status --repo <repo-root> [--json] # CLI-only
575
575
  agent-worker scheduler clock uninstall --repo <repo-root> [--json] # CLI-only
576
576
  agent-worker scheduler submit --repo <repo-root> --feature-id <id> --task-id <id> ... # low-level planning fact
577
577
  agent-worker scheduler transition <schedule-id> --repo <repo-root> --to <status> ... # internal lifecycle
578
- agent-worker console [--repo <repo-root>] [--port 8790] [--host 127.0.0.1] # Official 裸入口;repo 默认当前目录
579
- agent-worker console serve --repo <repo-root> [--port 8790] [--host 127.0.0.1] # 兼容入口,等价于裸入口
578
+ agent-worker console [--repo <repo-root>] [--port 8790] [--host 127.0.0.1] [--no-open] # Official 唯一入口;repo 默认当前目录;默认打开浏览器
580
579
  agent-worker console doctor --repo <repo-root> [--json] [--console-url <url>]
581
580
  agent-worker observe serve ... # REMOVED:stderr OBSERVE_SERVE_REMOVED,exit 2,不监听端口;请用 console + /inspect/
582
581
  agent-worker observe snapshot --repo <repo-root> # 输出 GlobalSnapshot JSON 到 stdout
@@ -602,7 +601,7 @@ agent-worker observe snapshot --repo <repo-root> # 输出 GlobalSnapshot JSON
602
601
  - `report metrics` 按 UTC 月去重投影 Feature/Failure/Follow-up/Delivery/AC/decision/recovery/boundary 指标,同时写 JSON 与 Markdown;每项保留 numerator、denominator、sampleSize 和 missingData。
603
602
  - `task draft-followup` 会按全部 failure category 生成 TaskDraft 或人工行动卡:ProductBug/TestBug/FlakyTest/DependencyFailure 可批准;EnvFailure 连续两次后才生成 ENV-CHECK;Spec/Contract/Risk/Human/Unknown 只给行动卡。人工以 `feature approve-followup --dry-run` 预览,再带非空 `--owner` 批准 TaskDraft;行动卡不能批准。批准在 staging validation 后写 TaskSpec、graph、Ready/approval/event,原失败事实不改写,并有 rename/state/approval/index/event 回滚门禁。
604
603
  - `task retry` 是失败 Task 的唯一重试入口。它会保留原有运行记录和 failure handoff,并让下一次 `batch run-ready` 使用新的 `workerRunId`;不要删除运行态文件或手动修改状态来重试。
605
- - **推荐**裸入口 `agent-worker console`(repo 默认当前目录,默认 `127.0.0.1:8790`)提供 Operate + Inspect;`console serve` 是等价兼容入口。Inspect 路径为 `/inspect/#/...`,API 仍为根 `/api/**`。`observe serve` 已硬下线(`OBSERVE_SERVE_REMOVED` + exit 2,不监听);`observe snapshot` 保留。Inspect 本身不会启动、暂停或重试 Task / Worker / DAG。
604
+ - **推荐**裸入口 `agent-worker console`(repo 默认当前目录,默认 `127.0.0.1:8790`)提供 Operate + Inspect;本地图形环境 listen 成功后默认打开系统浏览器,`--no-open` 禁止;`console serve` 已删除。Inspect 路径为 `/inspect/#/...`,API 仍为根 `/api/**`。`observe serve` 已硬下线(`OBSERVE_SERVE_REMOVED` + exit 2,不监听);`observe snapshot` 保留。Inspect 本身不会启动、暂停或重试 Task / Worker / DAG。
606
605
  - Night Scheduler(本地夜间自治):白天 `admission prepare` 冻结 worktree + DAG writeSet gate;`scheduler add` 消费 gate 并预约 Task Pool `Queued`(不立即执行);`scheduler clock install` 安装本机 user-level OS timer(launchd / systemd --user / schtasks)周期调用 `scheduler tick`;tick 写统一 Clock receipt,doctor/morning/status 可解释 missing/stale/error/busy/drift;成功后 `pending-harvest`,早晨 `scheduler harvest`(exact-base FF)或 `scheduler discard`;`report morning --window night` 与 Inspect `#/night` / Operate 夜间面板读取同一套 facts。Clock install/status/uninstall 为 CLI-only。
607
606
  - 当前 Worker 仍是 v0(库 + CLI + dogfood);日间批处理未强制定时/CI 驱动;`report morning` 默认可从 Task Pool runs 汇总,并支持 `--window night` 投影 Scheduler facts。
608
607
 
@@ -1 +0,0 @@
1
- :root{--canvas: #f7f7f4;--canvas-soft: #fafaf7;--surface: #ffffff;--surface-muted: #f0efe9;--ink: #26251e;--body: #5a5852;--muted: #807d72;--muted-soft: #a09c92;--hairline: #e6e5e0;--hairline-strong: #cfcdc4;--orange: #f54e00;--orange-active: #d04200;--orange-soft: color-mix(in srgb, var(--orange) 12%, white);--blue: #3f6ea4;--green: #1f8a65;--amber: #a66a00;--red: #c72d53;--peach: #f1d8cb;--mint: #d8ead5;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--space-12: 48px;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 12px;--radius-xl: 16px;--radius-pill: 999px;--transition-fast: .16s ease;--transition-base: .22s ease;--ease-out: cubic-bezier(.22, 1, .36, 1);--shadow-sm: 0 1px 2px rgb(38 37 30 / 5%);--shadow-panel: 0 1px 2px rgb(38 37 30 / 4%), 0 8px 24px rgb(38 37 30 / 3%);--shadow-soft: 0 10px 30px rgb(38 37 30 / 6%);--shadow-lg: 0 16px 44px rgb(38 37 30 / 10%);--shell-max: 1680px;--text-xs: 11px;--text-sm: 12px;--text-md: 13px;--text-base: 14px;--text-lg: 16px;--text-xl: 20px;--text-2xl: 26px;--font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, "Segoe UI Mono", monospace;--bg: var(--canvas);--border: var(--hairline);--accent: var(--orange);--accent-active: var(--orange-active);--danger: var(--red);--success: var(--green);--warning: var(--amber);--info: var(--blue);--text-muted: var(--muted);--surface-raised: var(--surface);--surface-hover: var(--surface-muted);--surface-sunken: var(--canvas-soft);--oc-tree-guide: 14px;--oc-session-share: 45%;--oc-repo-share: 55%;color-scheme:light;font-family:Segoe UI,PingFang SC,Hiragino Sans GB,Noto Sans SC,system-ui,-apple-system,sans-serif;line-height:1.5}*{box-sizing:border-box}html{background:radial-gradient(1200px 480px at 8% -10%,rgb(241 216 203 / 45%),transparent 55%),radial-gradient(900px 420px at 100% 0%,rgb(216 234 213 / 35%),transparent 50%),var(--canvas);min-height:100%}body{margin:0;min-height:100vh;min-width:320px;background:transparent;color:var(--ink);font-size:14px}button,input,select,textarea{font:inherit}a{color:inherit}::selection{background:color-mix(in srgb,var(--orange) 18%,white)}.oc-messages,.oc-session-scroll,.oc-tree-scroll,.oc-process-timeline,.oc-tools-catalog-body,.oc-runtime-context-body,.inspect-split-panel{scrollbar-width:thin;scrollbar-color:var(--hairline-strong) transparent}.oc-messages::-webkit-scrollbar,.oc-session-scroll::-webkit-scrollbar,.oc-tree-scroll::-webkit-scrollbar,.oc-process-timeline::-webkit-scrollbar,.oc-tools-catalog-body::-webkit-scrollbar,.oc-runtime-context-body::-webkit-scrollbar,.inspect-split-panel::-webkit-scrollbar{width:8px;height:8px}.oc-messages::-webkit-scrollbar-thumb,.oc-session-scroll::-webkit-scrollbar-thumb,.oc-tree-scroll::-webkit-scrollbar-thumb,.oc-process-timeline::-webkit-scrollbar-thumb,.oc-tools-catalog-body::-webkit-scrollbar-thumb,.oc-runtime-context-body::-webkit-scrollbar-thumb,.inspect-split-panel::-webkit-scrollbar-thumb{background:var(--hairline-strong);border-radius:999px;border:2px solid transparent;background-clip:content-box}.oc-messages::-webkit-scrollbar-track,.oc-session-scroll::-webkit-scrollbar-track,.oc-tree-scroll::-webkit-scrollbar-track,.oc-process-timeline::-webkit-scrollbar-track,.oc-tools-catalog-body::-webkit-scrollbar-track,.oc-runtime-context-body::-webkit-scrollbar-track,.inspect-split-panel::-webkit-scrollbar-track{background:transparent}code,.cmd,.kv dd code{font-family:var(--font-mono)}.console-app{display:flex;flex-direction:column;min-height:100dvh}html:has(.console-app.is-chat-focus),body:has(.console-app.is-chat-focus){height:100%;overflow:hidden}.console-app.is-chat-focus{height:100dvh;max-height:100dvh;overflow:hidden}.console-shell{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;width:min(100% - 48px,var(--shell-max));margin:0 auto;padding:var(--space-5) 0 var(--space-12, 48px)}.flash{display:flex;gap:var(--space-3);align-items:flex-start;margin:0 0 var(--space-4);padding:12px 16px;border:1px solid var(--hairline);border-left:3px solid var(--hairline-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-panel);animation:flash-in .22s var(--ease-out)}.flash-error{border-color:color-mix(in srgb,var(--red) 35%,var(--hairline));border-left-color:var(--red);background:color-mix(in srgb,var(--red) 6%,var(--surface));color:var(--red)}.flash-info{border-color:color-mix(in srgb,var(--blue) 30%,var(--hairline));border-left-color:var(--blue);background:color-mix(in srgb,var(--blue) 6%,var(--surface));color:var(--body)}.flash-label{flex:0 0 auto;min-width:3.5rem;font-size:var(--text-xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding-top:1px}.flash-body{margin:0;overflow-wrap:anywhere;font-size:var(--text-md);line-height:1.55}.muted{color:var(--muted)}.console-main{display:grid;gap:var(--space-4)}.console-main--fill{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:var(--space-3)}.console-shell.is-chat-focus{flex:1 1 auto;min-height:0;overflow:hidden;padding-bottom:var(--space-3)}.console-shell.is-chat-focus .console-main--fill{flex:1 1 auto;min-height:0;overflow:hidden}.panel--chat{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;padding:var(--space-3);overflow:hidden}.panel--chat .oc-shell{flex:1 1 auto;min-height:0;height:auto;overflow:hidden}.console-shell.is-chat-focus .panel--chat{padding:var(--space-2)}.console-shell.is-chat-focus .panel--chat .oc-shell{min-height:0;gap:var(--space-2);overflow:hidden}.inspect-split-panel{position:fixed;z-index:50;top:16px;right:16px;bottom:16px;width:min(420px,calc(100vw - 32px));display:grid;align-content:start;gap:var(--space-4);padding:var(--space-5);overflow:auto;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-soft)}.inspect-split-nodes{display:grid;gap:6px;margin:0;padding:0;list-style:none;max-height:220px;overflow:auto}.inspect-split-nodes li{display:grid;grid-template-columns:1fr auto;gap:var(--space-2);align-items:center;padding:6px 8px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--canvas-soft);font-size:12px}.inspect-split-nodes li.is-active{border-color:var(--orange);background:var(--orange-soft)}.inspect-split-nodes code{color:var(--muted);font-size:11px}.inspect-split-header{display:flex;align-items:start;justify-content:space-between;gap:var(--space-3)}.inspect-split-header h2,.inspect-split-panel h3{margin:0}.inspect-split-kicker,.inspect-split-id{margin:0;color:var(--muted);font-size:12px}.inspect-split-facts{display:grid;gap:var(--space-2);margin:0}.inspect-split-facts div{display:grid;grid-template-columns:7rem 1fr;gap:var(--space-2);padding-bottom:var(--space-2);border-bottom:1px solid var(--hairline)}.inspect-split-facts dt{color:var(--muted)}.inspect-split-facts dd{margin:0;overflow-wrap:anywhere}.inspect-split-events{display:grid;gap:8px;margin:0;padding-left:18px;color:var(--body);font-size:12px}.panel{min-width:0;border:1px solid var(--hairline);background:color-mix(in srgb,var(--surface) 96%,transparent);border-radius:var(--radius-lg);padding:var(--space-6);box-shadow:var(--shadow-panel)}.panel h2{margin:0 0 var(--space-2);color:var(--ink);font-size:var(--text-xl);font-weight:700;letter-spacing:-.02em}.panel-lead{margin:0 0 var(--space-5);color:var(--muted);font-size:var(--text-md);line-height:1.55}.panel h3{margin:0 0 var(--space-3);color:var(--ink);font-size:15px;font-weight:700;letter-spacing:-.01em}.empty-state{border:1px dashed var(--hairline-strong);border-radius:var(--radius-lg);padding:var(--space-8) var(--space-6);background:var(--canvas-soft);color:var(--body);text-align:center}.empty-state .cta-row{justify-content:center}.empty-title{margin:0 0 var(--space-2);color:var(--ink);font-size:var(--text-lg);font-weight:700;letter-spacing:-.01em}.empty-state .muted{max-width:52ch;margin-left:auto;margin-right:auto}.checklist{margin:0 0 var(--space-4);padding:var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);list-style:none;color:var(--body)}.checklist li{position:relative;padding:6px 0 6px 22px}.checklist li:before{content:"";position:absolute;left:0;top:12px;width:8px;height:8px;border-radius:50%;background:var(--orange);opacity:.75}.kv{display:grid;gap:var(--space-1);margin:0}.kv div{display:grid;grid-template-columns:9rem 1fr;gap:var(--space-3);padding:10px 0;border-bottom:1px solid var(--hairline)}.kv div:last-child{border-bottom:none}.kv dt{color:var(--muted);font-size:var(--text-sm);font-weight:600}.kv dd{margin:0;color:var(--ink);overflow-wrap:anywhere;font-variant-numeric:tabular-nums}code{font-size:.85rem;color:var(--ink)}.cmd{display:block;width:100%;margin:0;padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);color:var(--ink);font-size:var(--text-sm);line-height:1.55;overflow-x:auto;white-space:pre-wrap;word-break:break-word;max-height:280px}.external-link{color:var(--orange);text-decoration:none;font-weight:600}.external-link:hover{text-decoration:underline}.error{color:var(--red)}.wizard-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:var(--space-2);list-style:none;padding:0;margin:0 0 var(--space-5)}.wizard-steps li{position:relative;min-height:54px;display:grid;align-content:center;gap:3px;border:1px solid var(--hairline);border-radius:var(--radius-md);padding:9px 12px;background:var(--canvas-soft);color:var(--muted);font-size:var(--text-sm);font-weight:600;transition:border-color var(--transition-fast),background-color var(--transition-fast),color var(--transition-fast),box-shadow var(--transition-fast),transform var(--transition-fast)}.wizard-steps li[data-done=true]{border-color:color-mix(in srgb,var(--green) 35%,var(--hairline));background:color-mix(in srgb,var(--mint) 45%,var(--surface));color:var(--green)}.wizard-steps li[data-active=true]{border-color:var(--orange);background:var(--surface);color:var(--ink);box-shadow:0 0 0 3px var(--orange-soft),var(--shadow-panel);transform:translateY(-1px)}.wizard-steps .step-index{font-size:10px;font-weight:700;letter-spacing:.06em;font-variant-numeric:tabular-nums;color:var(--muted-soft)}.wizard-steps li[data-active=true] .step-index{color:var(--orange);opacity:1}.wizard-steps li[data-done=true] .step-index{color:inherit;opacity:.8}.wizard-steps .step-label{line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field{display:grid;gap:var(--space-1);margin:0 0 var(--space-4);width:min(100%,520px)}.field span{font-size:12px;font-weight:600;color:var(--muted)}.field input,.field textarea,.field select{width:100%;border:1px solid var(--hairline-strong);border-radius:var(--radius-md);background:var(--surface);color:var(--ink);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.field input{min-height:40px;padding:0 var(--space-3)}.field select{min-height:40px;padding:0 var(--space-3);cursor:pointer}.field textarea{min-height:120px;padding:var(--space-3);resize:vertical}.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible{outline:none;border-color:var(--orange);box-shadow:0 0 0 3px var(--orange-soft)}.field input:disabled,.field textarea:disabled,.field select:disabled{background:var(--surface-muted);color:var(--muted);cursor:not-allowed}.workflow-hint{margin:calc(var(--space-1) * -1) 0 var(--space-3);color:var(--muted);font-size:12px}.prd-drop-zone{position:relative;width:min(100%,720px);margin:0 0 var(--space-3);padding:var(--space-3);border:1px dashed var(--hairline-strong);border-radius:var(--radius-md);background:var(--surface);transition:border-color var(--transition-fast),background-color var(--transition-fast),box-shadow var(--transition-fast)}.prd-drop-zone.is-dragover{border-color:var(--orange);background:var(--orange-soft);box-shadow:0 0 0 3px var(--orange-soft)}.prd-upload-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3);margin:0 0 var(--space-3)}.prd-upload-btn{display:inline-flex;align-items:center;cursor:pointer;margin:0}.prd-upload-btn.is-disabled,.prd-upload-btn:has(input:disabled){opacity:.55;cursor:not-allowed;pointer-events:none}.prd-upload-btn:focus-within{outline:none;box-shadow:0 0 0 3px var(--orange-soft)}.prd-upload-hint{font-size:12px}.prd-file-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3);margin:0 0 var(--space-3);padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface-muted);font-size:12px;color:var(--ink)}.prd-file-list{list-style:none;margin:0 0 var(--space-3);padding:0;display:grid;gap:var(--space-2)}.prd-file-list li{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface-muted);font-size:12px}.prd-file-list li.is-primary{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline-strong))}.prd-file-item-name{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--space-1);min-width:0}.prd-file-primary-tag{display:inline-flex;align-items:center;padding:0 6px;border-radius:999px;background:var(--orange-soft);color:var(--orange);font-size:11px;font-weight:700}.prd-file-item-actions{display:inline-flex;flex-wrap:wrap;gap:var(--space-1)}.prd-file-item-actions .btn,.prd-file-clear{min-height:28px;padding:0 var(--space-2);font-size:12px}.prd-drop-hint{margin:0 0 var(--space-3);font-size:13px;font-weight:600;color:var(--orange)}.prd-text-field{width:100%;margin-bottom:0}.prd-file-error{width:min(100%,720px);margin:0 0 var(--space-3);padding:var(--space-2) var(--space-3);border:1px solid color-mix(in srgb,var(--orange) 45%,var(--hairline-strong));border-radius:var(--radius-md);background:var(--orange-soft);color:var(--ink);font-size:13px}.meta-row{display:grid;gap:6px;margin:0 0 var(--space-4);padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);font-size:13px}.meta-row code{font-size:12px}.cta-row,.recovery-cta-row{display:flex;flex-wrap:wrap;gap:var(--space-2);align-items:center}.cta-row{margin-top:var(--space-3)}.cta-row .cmd{flex:1 1 100%}.wizard-body{display:grid;gap:var(--space-3);justify-items:stretch;animation:panel-in .24s ease}.wizard-body>div{display:grid;gap:var(--space-3);justify-items:stretch}.wizard-body .field{width:100%;max-width:640px}.wizard-body .cta-row{margin-top:var(--space-1)}.interview-card{width:100%;padding:var(--space-5);border:1px solid var(--hairline);border-radius:var(--radius-lg);background:linear-gradient(180deg,var(--surface),var(--canvas-soft));box-shadow:var(--shadow-panel)}.interview-q{margin:0 0 var(--space-2);color:var(--ink)}.btn,button{appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:34px;padding:0 14px;border:1px solid var(--hairline-strong);border-radius:var(--radius-md);background:var(--surface);color:var(--ink);font-size:var(--text-md);font-weight:600;letter-spacing:.01em;cursor:pointer;transition:border-color var(--transition-fast),background-color var(--transition-fast),color var(--transition-fast),box-shadow var(--transition-fast),transform var(--transition-fast)}.btn:hover:not(:disabled),button:hover:not(:disabled){border-color:color-mix(in srgb,var(--ink) 18%,var(--hairline-strong));background:var(--canvas-soft);outline:none}.btn:focus-visible:not(:disabled),button:focus-visible:not(:disabled){outline:none;box-shadow:0 0 0 3px var(--orange-soft)}.btn:active:not(:disabled),button:active:not(:disabled){transform:translateY(1px)}.btn:disabled,button:disabled{opacity:.48;cursor:not-allowed;transform:none}.btn-primary,button.btn-primary{border-color:var(--orange);background:linear-gradient(180deg,var(--orange),var(--orange-active));color:#fff;font-weight:650;box-shadow:inset 0 1px #ffffff2e,0 6px 16px #f54e002e}.btn-primary:hover:not(:disabled),button.btn-primary:hover:not(:disabled){border-color:var(--orange-active);background:var(--orange-active);color:#fff;box-shadow:inset 0 1px #ffffff1f,0 8px 20px #f54e003d;transform:translateY(-1px)}.btn-primary:active:not(:disabled),button.btn-primary:active:not(:disabled){transform:translateY(0);box-shadow:0 2px 8px #f54e0033}.btn-secondary,button.btn-secondary{border-color:var(--hairline-strong);background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm)}.btn-secondary:hover:not(:disabled),button.btn-secondary:hover:not(:disabled){background:var(--canvas-soft)}.btn-ghost,button.btn-ghost{border-color:transparent;background:transparent;color:var(--body)}.btn-ghost:hover:not(:disabled),button.btn-ghost:hover:not(:disabled){background:var(--surface-muted);color:var(--ink)}.recovery-cta-row{margin-top:var(--space-3)}.recovery-confirm{margin-top:var(--space-3);padding:var(--space-4);border:1px solid color-mix(in srgb,var(--orange) 40%,var(--hairline));border-radius:var(--radius-md);background:color-mix(in srgb,var(--orange-soft) 55%,var(--surface))}.recovery-confirm h3{margin:0 0 var(--space-2);font-size:15px}.recovery-confirm .cta-row{margin-top:var(--space-3)}.recovery-report{margin-top:var(--space-3);padding:var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface)}.recovery-report-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}.recovery-report-header h3{margin:0;font-size:15px}.recovery-report-facts{display:grid;gap:var(--space-2);margin:0 0 var(--space-3)}.recovery-report-facts div{display:grid;grid-template-columns:5.5rem 1fr;gap:var(--space-2)}.recovery-report-facts dt{color:var(--muted);font-size:12px}.recovery-report-facts dd{margin:0;overflow-wrap:anywhere}.recovery-steps{margin:.5rem 0 .75rem 1.25rem;padding:0;line-height:1.5}.recovery-lane{margin-top:var(--space-4);padding-top:var(--space-3);border-top:1px solid var(--hairline)}.recovery-lane h3{margin:0 0 .35rem;font-size:1rem}.recovery-cta-row button[disabled]{opacity:.4}@keyframes flash-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}@keyframes panel-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@media(max-width:800px){.console-shell{width:min(100% - 24px,var(--shell-max));padding-top:var(--space-5)}.inspect-split-panel{inset:auto 0 0;width:100%;max-height:min(76vh,680px);border-radius:var(--radius-lg) var(--radius-lg) 0 0}.kv div{grid-template-columns:1fr}.wizard-steps{grid-template-columns:repeat(2,minmax(0,1fr))}}.oc-shell{display:flex;flex-direction:column;height:100%;min-height:0;gap:var(--space-3);position:relative;overflow:hidden}.oc-workspace{display:flex;flex:1 1 auto;min-height:0;gap:0;position:relative;overflow:hidden}.oc-main{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;min-height:0;overflow:hidden}.oc-main-topbar{display:flex;align-items:center;gap:var(--space-2);flex:0 0 auto;padding:6px 10px;border-bottom:1px solid var(--hairline);background:color-mix(in srgb,var(--surface) 92%,transparent)}.oc-main-topbar-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:36px;min-width:44px;padding:0 12px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);color:var(--ink);font:inherit;font-size:13px;font-weight:600;cursor:pointer}.oc-main-topbar-btn:hover{border-color:color-mix(in srgb,var(--orange) 35%,var(--hairline));background:color-mix(in srgb,var(--orange) 8%,var(--surface))}.oc-main-topbar-btn:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px}.oc-main-topbar-btn:active{transform:translateY(1px)}.oc-sidebar{flex:0 0 280px;width:280px;min-width:0;display:flex;flex-direction:column;gap:var(--space-2);margin-right:var(--space-3);padding:var(--space-2);overflow:hidden;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface)}.oc-sidebar.is-collapsed{flex:0 0 36px;width:36px;padding:6px;overflow:visible;align-items:center}.oc-sidebar-rail{flex:0 0 44px;width:44px;min-width:44px;display:flex;flex-direction:column;align-items:center;gap:6px;margin-right:var(--space-2);padding:8px 4px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface)}.oc-sidebar-rail-btn{appearance:none;display:inline-grid;place-items:center;width:36px;height:36px;min-width:36px;min-height:36px;padding:0;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--muted);cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.oc-sidebar-rail-btn:hover{color:var(--ink);background:color-mix(in srgb,var(--orange) 8%,var(--surface));border-color:var(--hairline)}.oc-sidebar-rail-btn:active{transform:scale(.96)}.oc-sidebar-rail-btn:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px}.oc-overlay-backdrop{position:absolute;inset:0;z-index:6;border:0;padding:0;margin:0;background:color-mix(in srgb,var(--ink) 28%,transparent);cursor:pointer}.oc-overlay-backdrop.is-process{z-index:7}.oc-sidebar-drawer{position:absolute;inset:0 auto 0 0;z-index:8;width:min(320px,calc(100% - 24px));margin-right:0;box-shadow:var(--shadow-soft)}.oc-process.is-process-overlay{position:absolute;top:0;right:0;bottom:0;z-index:9;width:min(380px,calc(100% - 24px));min-width:0;flex:none;margin-left:0;border-radius:var(--radius-md) 0 0 var(--radius-md);box-shadow:var(--shadow-soft)}.oc-sidebar-split{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;gap:0}.oc-sidebar-split>.oc-sessions{flex:1 1 var(--oc-session-share, 45%);max-height:none;min-height:0}.oc-sidebar-split>.oc-sessions .oc-session-scroll{flex:1 1 auto;max-height:none;min-height:0}.oc-sidebar-split>.oc-explorer{flex:1 1 var(--oc-repo-share, 55%);min-height:0;border-top:0;padding-top:0;margin-top:0}.oc-sidebar-split>.oc-explorer .oc-tree-scroll{max-height:none;min-height:0}.oc-sidebar-separator{flex:0 0 8px;height:8px;margin:2px 0;border:0;border-radius:999px;background:color-mix(in srgb,var(--hairline) 80%,transparent);cursor:row-resize;touch-action:none}.oc-sidebar-separator:hover,.oc-sidebar-split[data-dragging=true] .oc-sidebar-separator{background:color-mix(in srgb,var(--orange) 45%,var(--hairline))}.oc-sidebar-separator:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px;background:color-mix(in srgb,var(--orange) 35%,var(--hairline))}.oc-sidebar-header-actions{display:inline-flex;align-items:center;gap:2px}.oc-sidebar-toggle{appearance:none;display:inline-grid;place-items:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--muted);cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.oc-sidebar-toggle:hover{color:var(--ink);background:color-mix(in srgb,var(--orange) 8%,var(--surface));border-color:var(--hairline)}.oc-sidebar-toggle:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px}.oc-sidebar-toggle.is-collapsed{width:100%;height:28px}.oc-sidebar-section{display:flex;flex-direction:column;gap:6px;min-height:0}.oc-sidebar-section>header{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:13px;flex-shrink:0}.oc-sessions{flex:0 1 auto;max-height:min(34vh,320px);display:flex;flex-direction:column;min-height:0}.oc-session-scroll{min-height:0;max-height:min(28vh,260px);overflow:auto;padding:4px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:linear-gradient(180deg,color-mix(in srgb,var(--canvas-soft) 70%,white),var(--canvas-soft))}.oc-session-group{display:flex;flex-direction:column;gap:2px}.oc-session-group>small{margin:4px 6px 2px;color:var(--muted-soft);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.oc-session-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px;align-items:center;border-radius:6px;transition:background-color var(--transition-fast)}.oc-session-item:hover,.oc-session-item:focus-within{background:color-mix(in srgb,var(--orange) 8%,var(--surface))}.oc-session-item.is-active{background:var(--orange-soft)}.oc-session-main{min-width:0;padding:5px 6px;border:0;background:transparent;color:inherit;text-align:left;cursor:pointer}.oc-session-main strong,.oc-session-main span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oc-session-main strong{font-size:12.5px;font-weight:650;line-height:1.25}.oc-session-main span{color:var(--muted-soft);font-size:10px;margin-top:1px;font-variant-numeric:tabular-nums}.oc-session-actions{display:none;align-items:center;gap:0;padding-right:2px}.oc-session-item:hover .oc-session-actions,.oc-session-item:focus-within .oc-session-actions,.oc-session-item.is-active .oc-session-actions{display:inline-flex}.oc-session-menu{padding:3px 4px;border:0;background:transparent;color:var(--muted);cursor:pointer;font:inherit;font-size:10px;white-space:nowrap}.oc-session-menu:hover{color:var(--ink)}.oc-session-delete{color:color-mix(in srgb,var(--red) 75%,var(--muted))}.oc-session-delete:hover{color:var(--red)}.oc-explorer{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:6px;border-top:1px solid var(--hairline);padding-top:var(--space-3);margin-top:2px}.oc-explorer-hint{margin:0 2px;color:var(--muted-soft);font-size:10.5px;letter-spacing:.01em}.oc-tree-scroll{flex:1 1 auto;min-height:120px;max-height:min(52vh,560px);overflow:auto;padding:4px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:linear-gradient(180deg,color-mix(in srgb,var(--canvas-soft) 70%,white),var(--canvas-soft))}.oc-tree,.oc-tree ul{list-style:none;padding:0;margin:0}.oc-tree-node{position:relative}.oc-tree-row{appearance:none;display:grid;grid-template-columns:12px 14px minmax(0,1fr);align-items:center;gap:6px;width:100%;min-height:28px;margin:0;padding:3px 8px;border:0;border-radius:6px;background:transparent;color:var(--ink);text-align:left;cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast)}.oc-tree-row:hover{background:color-mix(in srgb,var(--orange) 8%,var(--surface))}.oc-tree-row:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px}.oc-tree-chevron{color:var(--muted-soft);transition:transform var(--transition-fast);transform:rotate(0)}.oc-tree-chevron.is-open{transform:rotate(90deg)}.oc-tree-chevron-spacer{width:12px;height:12px}.oc-tree-glyph{flex-shrink:0;color:var(--amber)}.oc-tree-glyph.is-folder-open{color:color-mix(in srgb,var(--orange) 70%,var(--amber))}.oc-tree-glyph.is-file{color:var(--muted)}.oc-tree-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;line-height:1.25;font-variant-numeric:tabular-nums}.oc-tree-dir .oc-tree-label{font-weight:650;color:var(--ink)}.oc-tree-file .oc-tree-label{font-family:JetBrains Mono,SFMono-Regular,Consolas,Segoe UI Mono,monospace;font-size:11.5px;font-weight:500;color:var(--body)}.oc-tree-node.is-dot .oc-tree-label{color:var(--muted-soft);font-weight:500}.oc-tree-node.is-dot .oc-tree-glyph{opacity:.7}.oc-tree-children{position:relative;margin:0}.oc-tree-children:before{content:"";position:absolute;top:0;bottom:2px;left:var(--oc-tree-guide, 14px);width:1px;background:color-mix(in srgb,var(--hairline-strong) 55%,transparent);pointer-events:none}.oc-tree-empty,.oc-sidebar-error{margin:8px 6px;color:var(--muted);font-size:12px;line-height:1.45}.oc-sidebar-error{color:var(--red)}.oc-governance{margin-top:auto;border-top:1px solid var(--hairline);padding-top:8px}.oc-governance-links{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}.oc-governance-links button{min-height:28px;padding:4px 6px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--surface);color:var(--muted);cursor:pointer;font:inherit;font-size:11px;font-weight:600;text-align:center}.oc-governance-links button:hover{color:var(--ink);border-color:color-mix(in srgb,var(--ink) 18%,var(--hairline))}.oc-governance-links button.is-active{color:var(--orange-active);border-color:color-mix(in srgb,var(--orange) 35%,var(--hairline))}.oc-resource-backdrop{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:var(--space-4);background:#26251e52}.oc-resource-panel{width:min(880px,calc(100vw - 32px));max-height:min(80vh,760px);display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-lg);color:var(--ink)}.oc-resource-panel-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-3);flex-shrink:0;padding:12px 14px;border-bottom:1px solid var(--hairline);background:var(--surface-raised)}.oc-resource-panel-head-copy{display:grid;gap:2px;min-width:0}.oc-resource-panel-head strong{font-size:14px}.oc-resource-panel-meta{color:var(--muted);font-size:11px;line-height:1.5}.oc-resource-panel-body{flex:1;min-height:0;overflow:auto;display:grid;gap:12px;padding:14px}.oc-resource-panel-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;flex-shrink:0;padding:10px 14px;border-top:1px solid var(--hairline);background:var(--surface-raised)}.oc-resource-panel-actions{display:flex;align-items:center;gap:6px}.oc-resource-error{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border:1px solid color-mix(in srgb,var(--red) 35%,var(--hairline));border-radius:var(--radius-sm);background:color-mix(in srgb,var(--red) 6%,var(--surface));color:var(--red);font-size:var(--text-sm)}.oc-resource-empty{margin:0;padding:14px 10px;border:1px dashed var(--hairline-strong);border-radius:var(--radius-md);color:var(--muted);font-size:var(--text-sm);text-align:center}.oc-resource-lists{display:grid;gap:14px}.oc-resource-group{display:grid;gap:6px}.oc-resource-group-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding-bottom:4px;border-bottom:1px solid var(--hairline);font-size:var(--text-sm);text-transform:capitalize}.oc-resource-group-head span{color:var(--muted);font-size:11px}.oc-resource-list,.oc-resource-sub-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.oc-resource-item{display:grid;gap:4px;padding:10px 12px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface)}.oc-resource-item-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px}.oc-resource-item-head span{color:var(--muted);font-size:11px}.oc-resource-item p{margin:0;color:var(--body);font-size:var(--text-sm)}.oc-resource-item code{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--body);font-size:11px}.oc-resource-sub-list li{display:grid;gap:2px;padding:6px 8px;border-radius:var(--radius-sm);background:var(--surface-muted)}.oc-resource-diagnostic{color:var(--amber);font-size:11px}.oc-package-status{display:inline-block;padding:1px 8px;border-radius:999px;font-size:11px;line-height:1.7;text-transform:uppercase;background:var(--surface-muted);color:var(--muted);white-space:nowrap}.oc-package-status.is-installed{background:color-mix(in srgb,var(--green) 12%,var(--surface));color:var(--green)}.oc-package-status.is-error{background:color-mix(in srgb,var(--red) 12%,var(--surface));color:var(--red)}.oc-package-status.is-disabled{opacity:.7}.oc-package-meta{display:flex;align-items:baseline;gap:8px;margin:0;font-size:11px;min-width:0}.oc-package-meta span{color:var(--muted);min-width:96px;flex:none}.oc-package-meta code{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.oc-package-resources{display:grid;gap:8px}.oc-package-group{display:grid;gap:4px}.oc-package-diagnostics{display:grid;gap:4px;padding:6px 8px;border-radius:var(--radius-sm);background:color-mix(in srgb,var(--amber) 6%,var(--surface));color:var(--amber);font-size:11px;overflow-wrap:anywhere}.oc-resource-diagnostics{display:grid;gap:6px;margin-bottom:12px;padding:8px 10px;border:1px solid color-mix(in srgb,var(--amber) 35%,var(--hairline));border-radius:var(--radius-sm);background:color-mix(in srgb,var(--amber) 5%,var(--surface))}.oc-resource-diagnostic.is-error{color:var(--red)}.oc-resource-panel button:disabled{cursor:wait;opacity:.55}.oc-model-provider{border-bottom:1px solid var(--hairline);padding-bottom:8px}.oc-model-provider-head,.oc-model-row,.oc-model-row-actions{display:flex;align-items:center;justify-content:space-between;gap:8px}.oc-model-provider-head{padding:6px 0}.oc-model-provider-head span{color:var(--muted);font-size:11px}.oc-model-row{padding:4px 0 4px 10px;font-size:var(--text-sm)}.oc-model-row-actions button,.oc-model-provider-remove{border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--surface);color:var(--muted);cursor:pointer;font:inherit;font-size:11px;padding:3px 8px}.oc-model-row-actions button:hover,.oc-model-provider-remove:hover{color:var(--ink);border-color:var(--hairline-strong)}.oc-model-provider-remove{margin:6px 0 6px 10px}.oc-model-form{display:grid;gap:6px;margin-top:10px}.oc-model-form input{min-width:0;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink);padding:6px 8px;font:inherit;font-size:12px}.oc-model-form button{justify-self:start}.oc-model-test-result{padding:6px 8px;border-radius:var(--radius-sm);background:var(--surface-muted);font-size:12px}@media(max-width:800px){.oc-resource-backdrop{padding:var(--space-2)}.oc-resource-panel{width:100%;max-height:calc(100vh - 32px)}.oc-resource-panel-body{padding:10px}}@media(max-width:640px){.oc-resource-panel-foot{flex-direction:column;align-items:stretch}.oc-resource-panel-actions{justify-content:flex-end}.oc-resource-item-head,.oc-model-row{flex-direction:column;align-items:flex-start}.oc-model-row-actions{justify-content:flex-start}}.oc-file-preview{position:absolute;z-index:4;inset:0;display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-panel)}.oc-file-preview header{display:flex;align-items:center;gap:var(--space-2);padding:10px 12px;border-bottom:1px solid var(--hairline)}.oc-file-tabs{display:flex;min-width:0;gap:2px;overflow-x:auto}.oc-file-tabs button{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--muted);padding:4px 7px;cursor:pointer}.oc-file-tabs button.is-active{background:var(--surface-muted);color:var(--ink);font-weight:650}.oc-file-preview header span{flex:1;color:var(--muted);font-size:11px}.oc-file-preview pre{flex:1;min-height:0;margin:0;padding:var(--space-3);overflow:auto;font-size:12px;line-height:1.5;white-space:pre-wrap}.oc-file-preview-loading{position:absolute;z-index:5;right:12px;top:12px;padding:6px 8px;border-radius:var(--radius-sm);background:var(--surface-muted);color:var(--muted);font-size:12px}.oc-process{display:flex;flex-direction:column;flex:0 0 min(360px,42%);width:min(360px,42%);min-width:280px;min-height:0;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-panel);margin-left:var(--space-3);overflow:hidden;animation:panel-in .18s ease}.oc-turn-group{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}.oc-process-inline{margin:0 0 4px 44px;max-width:min(720px,100%)}.oc-process-inline-summary{display:inline-flex;align-items:center;gap:6px;min-height:24px;padding:2px 0;border:none;background:transparent;color:var(--muted);cursor:pointer;font-size:12px;text-align:left}.oc-process-inline-summary:hover,.oc-process-inline-summary.is-open{color:var(--ink)}.oc-process-inline-summary.is-running{color:var(--accent, #2563eb)}.oc-process-inline-summary.is-error{color:var(--danger, #dc2626)}.oc-process-inline-summary .oc-tool-chevron{width:12px;height:12px;flex-shrink:0;transition:transform .15s ease}.oc-process-inline-summary.is-open .oc-tool-chevron{transform:rotate(90deg)}.oc-process-inline-body{display:flex;flex-direction:column;gap:8px;margin-top:8px}.oc-tool-duration{flex-shrink:0;font-size:11px;font-variant-numeric:tabular-nums;color:var(--muted)}.oc-tool-expand-result{margin-top:4px;font-size:12px}.oc-process-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:10px 12px;border-bottom:1px solid var(--hairline);flex-shrink:0}.oc-process-title{display:inline-flex;align-items:center;gap:8px;font-weight:700;font-size:13px;color:var(--ink)}.oc-process-title-mark{width:8px;height:8px;border-radius:50%;background:var(--orange)}.oc-process-count{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:18px;padding:0 6px;border-radius:var(--radius-pill);background:var(--surface-muted);color:var(--muted);font-size:11px;font-weight:650}.oc-process-close{font-size:12px}.oc-process-timeline{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--space-3);display:flex;flex-direction:column;gap:0}.oc-process-empty{padding:var(--space-4);color:var(--muted);font-size:12.5px;line-height:1.5;text-align:center}.oc-process-item{display:grid;grid-template-columns:20px 52px minmax(0,1fr);gap:8px;align-items:start;padding:4px 0}.oc-process-rail{position:relative;display:grid;place-items:center;min-height:34px}.oc-process-rail:before{position:absolute;top:0;bottom:0;width:1px;background:var(--hairline);content:""}.oc-process-item.is-first .oc-process-rail:before{top:50%}.oc-process-item.is-last .oc-process-rail:before{bottom:50%}.oc-process-dot{position:relative;z-index:1;width:8px;height:8px;border-radius:50%;background:var(--surface);border:2px solid color-mix(in srgb,var(--orange) 55%,var(--hairline))}.oc-process-item.is-running .oc-process-dot{border-color:var(--orange-active);background:var(--orange-soft)}.oc-process-item.is-error .oc-process-dot{border-color:var(--red);background:color-mix(in srgb,var(--red) 18%,var(--surface))}.oc-process-time{padding-top:10px;font-size:11px;color:var(--muted-soft);font-variant-numeric:tabular-nums;white-space:nowrap}.oc-process-body{min-width:0}.oc-process-toggle{cursor:pointer;font:inherit}.oc-process-toggle.is-active{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline));background:color-mix(in srgb,var(--orange) 10%,var(--surface));color:var(--orange-active)}.oc-process-toggle.is-running{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline));color:var(--orange-active)}.oc-process-toggle.is-error{border-color:color-mix(in srgb,var(--red) 35%,var(--hairline));background:color-mix(in srgb,var(--red) 8%,var(--surface));color:var(--red)}.oc-process-summary{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border:1px solid var(--hairline);border-radius:var(--radius-pill);background:var(--surface);color:var(--muted);font-size:11.5px;font-weight:650;cursor:pointer;font:inherit;max-width:min(420px,100%);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oc-process-summary:hover,.oc-process-summary.is-open{border-color:color-mix(in srgb,var(--orange) 35%,var(--hairline));color:var(--orange-active)}.oc-process-summary.is-running{color:var(--orange-active);border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline));background:var(--orange-soft)}.oc-process-summary.is-error{color:var(--red);border-color:color-mix(in srgb,var(--red) 35%,var(--hairline));background:color-mix(in srgb,var(--red) 8%,var(--surface))}.oc-process-summary.is-ok{color:var(--green);border-color:color-mix(in srgb,var(--green) 30%,var(--hairline))}@media(max-width:900px){.oc-workspace:not([data-layout-mode]) .oc-sidebar{position:absolute;inset:0 auto 0 0;z-index:7;width:min(300px,calc(100% - 24px));margin-right:0;box-shadow:var(--shadow-soft)}.oc-workspace:not([data-layout-mode]) .oc-sidebar.is-collapsed{position:static;width:auto}.oc-workspace:not([data-layout-mode]).has-process .oc-process{position:absolute;top:0;right:0;bottom:0;z-index:8;width:min(360px,calc(100% - 24px));min-width:0;flex:none;margin-left:0;border-radius:var(--radius-md) 0 0 var(--radius-md);box-shadow:var(--shadow-soft)}}.oc-banner{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3);padding:10px 14px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 94%,transparent);box-shadow:var(--shadow-panel)}.oc-shell>.oc-alert:first-child{margin-top:0}.oc-banner-title{display:inline-flex;align-items:center;gap:6px;font-weight:700;color:var(--ink)}.oc-banner-dot{width:8px;height:8px;border-radius:50%;background:var(--orange)}.oc-banner-body{color:var(--body);font-size:12.5px;line-height:1.45}.oc-banner-body strong{color:var(--ink)}.oc-cap-chips{display:inline-flex;flex-wrap:wrap;gap:6px;margin-left:auto;align-items:center}.oc-cap-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border:1px solid color-mix(in srgb,var(--green) 30%,var(--hairline));border-radius:var(--radius-pill);background:color-mix(in srgb,var(--mint) 50%,var(--surface));color:var(--green);font-size:11.5px;font-weight:650}button.oc-cap-chip{font:inherit;cursor:pointer}.oc-tools-menu{position:relative}.oc-tools-menu--composer .oc-tools-catalog{top:auto;bottom:calc(100% + 8px)}.oc-tools-toggle.is-active{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline));background:color-mix(in srgb,var(--orange) 10%,var(--surface));color:var(--orange-active)}.oc-tools-catalog{position:absolute;top:calc(100% + 8px);right:0;z-index:20;width:min(420px,calc(100vw - 48px));max-height:min(480px,60vh);display:flex;flex-direction:column;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-soft);animation:panel-in .16s ease;overflow:hidden}.oc-tools-catalog-head{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--hairline);flex-shrink:0}.oc-tools-catalog-head strong{font-size:13px;color:var(--ink)}.oc-tools-catalog-meta{font-size:11.5px;color:var(--muted-soft)}.oc-tools-catalog-close{margin-left:auto;font-size:12px}.oc-tools-catalog-body{overflow-y:auto;padding:var(--space-3);display:flex;flex-direction:column;gap:var(--space-3)}.oc-tools-group-title{margin:0 0 8px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted-soft)}.oc-tools-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}.oc-tools-item{padding:8px 10px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--surface-muted) 55%,var(--surface))}.oc-tools-item-head{display:flex;align-items:center;gap:8px;margin-bottom:4px}.oc-tools-name{font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:12.5px;font-weight:650;color:var(--ink)}.oc-tools-kind{margin-left:auto;font-size:10.5px;font-weight:650;padding:1px 7px;border-radius:var(--radius-pill);color:var(--muted);background:var(--surface);border:1px solid var(--hairline)}.oc-tools-kind.is-explore,.oc-tools-kind.is-read{color:var(--green);border-color:color-mix(in srgb,var(--green) 28%,var(--hairline));background:color-mix(in srgb,var(--mint) 45%,transparent)}.oc-tools-kind.is-mutation{color:var(--orange-active);border-color:color-mix(in srgb,var(--orange) 35%,var(--hairline));background:var(--orange-soft)}.oc-tools-kind.is-long-running{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 35%,var(--hairline));background:color-mix(in srgb,var(--amber) 10%,var(--surface))}.oc-tools-desc{margin:0;font-size:12px;line-height:1.45;color:var(--body)}.oc-tools-cli{margin:4px 0 0;font-size:11px;color:var(--muted-soft)}.oc-tools-cli code{font-size:11px;color:var(--muted)}.oc-alert{padding:10px 14px;border-radius:var(--radius-md);font-size:var(--text-md);line-height:1.5;animation:panel-in .18s var(--ease-out)}.oc-alert-warning{border:1px solid color-mix(in srgb,var(--amber) 35%,var(--hairline));border-left:3px solid var(--amber);background:color-mix(in srgb,var(--amber) 8%,var(--surface));color:var(--amber)}.oc-alert-error{border:1px solid color-mix(in srgb,var(--red) 35%,var(--hairline));border-left:3px solid var(--red);background:color-mix(in srgb,var(--red) 7%,var(--surface));color:var(--red)}.oc-messages{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--space-3) var(--space-3) var(--space-2);display:flex;flex-direction:column;gap:var(--space-3)}.oc-messages.has-thread:before{content:"";flex:1 1 auto;min-height:0}.oc-messages.is-empty{justify-content:center;align-items:center;padding:var(--space-5) var(--space-4) var(--space-4);background:radial-gradient(640px 300px at 50% 28%,rgb(241 216 203 / 34%),transparent 68%),radial-gradient(520px 240px at 78% 78%,rgb(216 234 213 / 26%),transparent 62%)}.oc-main.is-landing{position:relative}.oc-day-sep{display:flex;align-items:center;gap:var(--space-3);color:var(--muted-soft);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;margin:var(--space-2) 0}.oc-day-sep:before,.oc-day-sep:after{content:"";flex:1;height:1px;background:var(--hairline)}.oc-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:0 1 auto;gap:var(--space-5);text-align:center;width:min(100%,680px);padding:var(--space-2) var(--space-2) var(--space-4);animation:oc-empty-in .28s ease both}@keyframes oc-empty-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@media(prefers-reduced-motion:reduce){.oc-empty{animation:none}}.oc-empty-hero{display:flex;flex-direction:column;align-items:center;gap:var(--space-3)}.oc-empty-icon{display:grid;place-items:center;width:56px;height:56px;border-radius:50%;background:linear-gradient(145deg,color-mix(in srgb,var(--orange) 18%,white),color-mix(in srgb,var(--mint) 35%,white));color:var(--orange-active);font-size:26px;font-weight:800;font-family:var(--font-mono, "JetBrains Mono", monospace);box-shadow:0 0 0 1px color-mix(in srgb,var(--orange) 18%,transparent)}.oc-empty-copy{display:flex;flex-direction:column;align-items:center;gap:var(--space-2)}.oc-empty h3{margin:0;font-size:20px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}.oc-empty p{margin:0;max-width:48ch;color:var(--muted);font-size:13px;line-height:1.55}.oc-suggestions{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2);width:100%}@media(max-width:560px){.oc-suggestions{grid-template-columns:1fr}}.oc-suggestion{appearance:none;display:flex;flex-direction:column;gap:5px;text-align:left;min-height:0;padding:14px 16px;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:color-mix(in srgb,var(--surface) 88%,transparent);color:var(--ink);cursor:pointer;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:border-color var(--transition-fast),background var(--transition-fast),transform var(--transition-fast),box-shadow var(--transition-fast)}.oc-suggestion:hover:not(:disabled){border-color:color-mix(in srgb,var(--orange) 45%,var(--hairline));background:var(--surface);box-shadow:0 0 0 3px var(--orange-soft),var(--shadow-panel);transform:translateY(-1px)}.oc-suggestion:disabled{opacity:.55;cursor:not-allowed}.oc-suggestion strong{font-size:var(--text-md);font-weight:700}.oc-suggestion span{color:var(--muted);font-size:var(--text-sm);line-height:1.45}.oc-empty-tips{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-2) var(--space-3);margin:0;padding:0;list-style:none;color:var(--muted-soft);font-size:12px}.oc-empty-tips li{display:inline-flex;align-items:center;gap:6px}.oc-empty-tips kbd{display:inline-grid;place-items:center;min-width:1.4em;padding:1px 6px;border:1px solid var(--hairline);border-radius:5px;background:var(--surface);color:var(--body);font-family:var(--font-mono, "JetBrains Mono", monospace);font-size:11px;font-weight:600;line-height:1.4}.oc-empty-cta{margin-top:calc(var(--space-1) * -1)}.oc-empty.is-landing-compact{gap:var(--space-3);padding:var(--space-1) var(--space-2) var(--space-2)}.oc-empty.is-landing-compact .oc-empty-icon{width:44px;height:44px;font-size:22px}.oc-empty.is-landing-compact h3{font-size:17px}.oc-empty.is-landing-compact p{font-size:12px;line-height:1.45}.oc-empty.is-landing-compact .oc-suggestion{padding:10px 12px;gap:3px}.oc-empty.is-landing-extra-compact{gap:var(--space-2);padding:0 var(--space-1) var(--space-2)}.oc-empty.is-landing-extra-compact .oc-empty-icon{width:36px;height:36px;font-size:18px}.oc-empty.is-landing-extra-compact h3{font-size:15px}.oc-empty.is-landing-extra-compact p{font-size:11.5px;line-height:1.4;max-width:42ch}.oc-empty.is-landing-extra-compact .oc-suggestion{padding:8px 10px;gap:2px}.oc-empty.is-landing-extra-compact .oc-empty-tips{gap:var(--space-1) var(--space-2);font-size:11px}.oc-messages.is-empty[data-landing-density=extra-compact]{justify-content:flex-start;padding:var(--space-2);overflow-y:auto}.oc-row{display:flex;flex-direction:column;gap:4px;max-width:100%}.oc-row.is-user{align-self:flex-end;align-items:flex-end;width:auto;max-width:min(100%,720px)}.oc-row.is-assistant,.oc-row.is-tool{align-self:stretch;align-items:stretch;width:100%;max-width:100%}.oc-meta{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--muted-soft)}.oc-row.is-assistant .oc-meta,.oc-row.is-user .oc-meta{width:100%;max-width:100%}.oc-message-copy{appearance:none;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:26px;height:26px;margin-left:auto;padding:0;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--muted-soft);cursor:pointer;opacity:0;transition:opacity var(--transition-fast),background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.oc-row:hover .oc-message-copy,.oc-row:focus-within .oc-message-copy,.oc-message-copy:focus-visible{opacity:1}.oc-message-copy:hover{color:var(--body);background:color-mix(in srgb,var(--ink) 6%,transparent);border-color:var(--hairline)}.oc-message-copy.is-copied{opacity:1;color:var(--green, #1a7f37);border-color:color-mix(in srgb,var(--green, #1a7f37) 35%,transparent)}@media(hover:none){.oc-message-copy{opacity:.5}}.oc-avatar{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;font-size:11px;font-weight:700;flex-shrink:0}.oc-avatar-user{background:var(--ink);color:#fff}.oc-avatar-assistant{background:var(--orange);color:#fff}.oc-role{font-weight:700;color:var(--body)}.oc-time{font-variant-numeric:tabular-nums}.oc-bubble{padding:10px 14px;border-radius:var(--radius-lg);font-size:14px;line-height:1.6;overflow-wrap:anywhere;word-break:break-word;animation:bubble-in .16s ease}@keyframes bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.oc-bubble-user{background:var(--ink);color:#fff;border-bottom-right-radius:4px;box-shadow:0 4px 14px #26251e1f}.oc-bubble-assistant{background:var(--surface);color:var(--ink);border:1px solid var(--hairline);border-bottom-left-radius:4px}.oc-bubble-tool{background:var(--canvas-soft);color:var(--body);border:1px solid var(--hairline)}.oc-bubble-error{border-color:color-mix(in srgb,var(--red) 40%,var(--hairline));background:color-mix(in srgb,var(--red) 7%,var(--surface));color:var(--red)}.oc-md{display:flex;flex-direction:column;gap:var(--space-2)}.oc-md>*:first-child{margin-top:0}.oc-md>*:last-child{margin-bottom:0}.oc-md p{margin:0}.oc-md h1,.oc-md h2,.oc-md h3,.oc-md h4{margin:var(--space-3) 0 var(--space-2);color:inherit;font-weight:700;line-height:1.3}.oc-md h1{font-size:1.3em}.oc-md h2{font-size:1.18em}.oc-md h3{font-size:1.06em}.oc-md h4{font-size:1em}.oc-md ul,.oc-md ol{margin:0;padding-left:1.4em;display:flex;flex-direction:column;gap:2px}.oc-md li{margin:0}.oc-md blockquote{margin:0;padding:2px 0 2px 12px;border-left:3px solid var(--hairline-strong);color:var(--body)}.oc-bubble-user .oc-md blockquote{border-left-color:#ffffff59;color:#ffffffd1}.oc-md code{font-size:.86em;padding:1px 5px;border-radius:4px;background:color-mix(in srgb,var(--ink) 8%,transparent)}.oc-bubble-user .oc-md code{background:#ffffff29}.oc-md pre{margin:0;padding:0;background:transparent}.oc-codeblock{margin:0;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface-muted);overflow:hidden}.oc-bubble-assistant .oc-codeblock{background:#f3efe8}.oc-codeblock-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:5px 6px 5px 10px;border-bottom:1px solid var(--hairline);font-size:11px;color:var(--muted);background:color-mix(in srgb,var(--ink) 4%,transparent)}.oc-codeblock-lang{font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-weight:600;text-transform:lowercase}.oc-codeblock-copy{appearance:none;display:inline-flex;align-items:center;gap:5px;min-height:26px;padding:0 9px;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--muted);font-size:11px;font-weight:600;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.oc-codeblock-copy:hover{background:var(--surface);color:var(--ink);border-color:var(--hairline-strong)}.oc-codeblock pre{margin:0;padding:var(--space-3) var(--space-4);overflow-x:auto;font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:12.5px;line-height:1.55;white-space:pre;color:var(--ink)}.oc-md a{color:var(--orange);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--orange) 40%,transparent)}.oc-md a:hover{border-bottom-color:var(--orange)}.oc-md hr{margin:var(--space-2) 0;border:none;border-top:1px solid var(--hairline-strong)}.oc-stream{white-space:pre-wrap;font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:13px;line-height:1.55}.oc-cursor{display:inline-block;width:7px;height:1.05em;margin-left:2px;vertical-align:text-bottom;background:var(--orange);animation:oc-blink 1s steps(2,start) infinite;border-radius:1px}@keyframes oc-blink{to{opacity:0}}.oc-tool{border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);overflow:hidden;animation:panel-in .16s ease;transition:border-color var(--transition-fast),background-color var(--transition-fast)}.oc-tool:hover{border-color:var(--hairline-strong);background:var(--surface)}.oc-tool.is-error{border-color:color-mix(in srgb,var(--red) 38%,var(--hairline))}.oc-tool.is-running{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline))}.oc-tool-head{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:7px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font:inherit;color:var(--ink)}.oc-tool-head:hover{background:var(--surface-muted)}.oc-tool-chevron{flex-shrink:0;width:12px;height:12px;transition:transform var(--transition-fast)}.oc-tool-head[aria-expanded=true] .oc-tool-chevron{transform:rotate(90deg)}.oc-tool-icon{display:grid;place-items:center;width:22px;height:22px;border-radius:6px;background:var(--surface-muted);color:var(--orange-active);flex-shrink:0}.oc-tool-name{font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:12.5px;font-weight:650;flex-shrink:0}.oc-tool-args{color:var(--muted);font-size:11.5px;font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-right:8px;min-width:0}.oc-tool-status{margin-left:auto;flex-shrink:0;font-size:11px;font-weight:650;padding:2px 8px;border-radius:var(--radius-pill)}.oc-tool-waiting{color:var(--muted);font-size:12px;animation:pulse 1.5s infinite}.oc-tool-status.is-running{color:var(--orange-active);background:var(--orange-soft)}.oc-tool-status.is-ok{color:var(--green);background:color-mix(in srgb,var(--mint) 60%,transparent)}.oc-tool-status.is-error{color:var(--red);background:color-mix(in srgb,var(--red) 10%,transparent)}.oc-tool-body{padding:0 var(--space-4) var(--space-3);border-top:1px solid var(--hairline)}.oc-tool-section{display:flex;flex-direction:column;gap:4px;padding-top:var(--space-3)}.oc-tool-label{font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--muted-soft)}.oc-tool-code{margin:0;padding:var(--space-3);border-radius:var(--radius-sm);background:var(--surface-muted);font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:260px;overflow-y:auto;color:var(--body)}.oc-composer{flex:0 0 auto;flex-shrink:0;border-top:1px solid var(--hairline);padding:var(--space-2) var(--space-3) var(--space-3);background:color-mix(in srgb,var(--canvas) 92%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:2}.oc-composer-inner{display:flex;flex-direction:column;gap:var(--space-2);max-width:1080px;margin:0 auto;position:relative}.console-shell.is-chat-focus .oc-composer-inner{max-width:none}.oc-composer-shell{position:relative;display:flex;align-items:flex-end;gap:var(--space-2);padding:8px 8px 8px 14px;border:1px solid var(--hairline-strong);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-panel);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.oc-composer-shell:focus-within{border-color:var(--orange);box-shadow:0 0 0 3px var(--orange-soft)}.oc-composer-shell.is-busy{opacity:.78}.oc-textarea{flex:1 1 auto;min-width:0;min-height:52px;max-height:280px;padding:8px 0;border:none;background:transparent;color:var(--ink);font:inherit;font-size:14px;line-height:1.5;resize:none;outline:none}.oc-textarea::placeholder{color:var(--muted-soft)}.oc-send{appearance:none;display:grid;place-items:center;width:38px;height:38px;flex-shrink:0;padding:0;border:1px solid var(--orange);border-radius:50%;background:linear-gradient(180deg,var(--orange),var(--orange-active));color:#fff;cursor:pointer;box-shadow:inset 0 1px #fff3,0 4px 12px #f54e003d;transition:background var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast),transform var(--transition-fast)}.oc-send:hover:not(:disabled){background:var(--orange-active);border-color:var(--orange-active);box-shadow:0 6px 16px #f54e004d;transform:translateY(-1px)}.oc-send:active:not(:disabled){transform:scale(.94)}.oc-send:disabled{opacity:.4;cursor:not-allowed}.oc-stop{appearance:none;display:grid;place-items:center;width:38px;height:38px;flex-shrink:0;padding:0;border:1px solid var(--hairline-strong);border-radius:50%;background:var(--surface);color:var(--red);cursor:pointer;transition:background var(--transition-fast),border-color var(--transition-fast)}.oc-stop:hover{background:color-mix(in srgb,var(--red) 8%,var(--surface));border-color:var(--red)}.oc-composer-foot{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;font-size:11.5px;color:var(--muted)}.oc-composer-hint{display:inline-flex;align-items:center;gap:5px}.oc-kbd{display:inline-block;padding:1px 6px;border:1px solid var(--hairline-strong);border-bottom-width:2px;border-radius:4px;background:var(--surface);color:var(--body);font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:10.5px;line-height:1.4}.oc-operation-card{width:min(720px,calc(100% - 42px));margin:var(--space-3) auto;padding:var(--space-4) var(--space-5);border:1px solid var(--hairline-strong);border-left:4px solid var(--blue);border-radius:var(--radius-lg);background:color-mix(in srgb,var(--surface) 96%,var(--blue) 4%);box-shadow:var(--shadow-panel)}.oc-operation-card.is-succeeded{border-left-color:var(--green)}.oc-operation-card.is-failed,.oc-operation-card.is-timed-out{border-left-color:var(--red)}.oc-operation-card.is-needs-reconcile{border-left-color:var(--orange)}.oc-operation-head,.oc-operation-actions{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}.oc-operation-kicker{margin-bottom:2px;color:var(--muted);font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase}.oc-operation-state{padding:3px 9px;border-radius:999px;background:color-mix(in srgb,var(--blue) 12%,transparent);color:var(--blue);font-size:11px;font-weight:700}.oc-operation-state.is-succeeded{background:color-mix(in srgb,var(--green) 12%,transparent);color:var(--green)}.oc-operation-state.is-failed,.oc-operation-state.is-timed-out{background:color-mix(in srgb,var(--red) 12%,transparent);color:var(--red)}.oc-operation-state.is-needs-reconcile{background:color-mix(in srgb,var(--orange) 14%,transparent);color:var(--orange-active)}.oc-operation-id,.oc-operation-controller{margin-top:var(--space-2);color:var(--muted);font-size:12px;overflow-wrap:anywhere}.oc-operation-identities{display:flex;flex-wrap:wrap;gap:6px;margin-top:var(--space-3)}.oc-operation-identities span{padding:3px 8px;border:1px solid var(--hairline);border-radius:var(--radius-pill);background:var(--surface);color:var(--muted);font-size:var(--text-xs);font-weight:600}.oc-operation-identities b{color:var(--body)}.oc-operation-preview{max-height:150px;margin:var(--space-3) 0 0;padding:var(--space-2) var(--space-3);overflow:auto;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);color:var(--body);font-family:var(--font-mono);font-size:var(--text-xs);line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}.oc-operation-preview.is-error{border-color:color-mix(in srgb,var(--red) 30%,var(--hairline));color:var(--red)}.oc-operation-actions{justify-content:flex-start;margin-top:var(--space-3)}.oc-operation-actions time{margin-left:auto;color:var(--muted-soft);font-size:11px}.oc-interview-start{margin:var(--space-3) auto}.oc-draft-card{width:min(720px,calc(100% - 42px));margin:var(--space-3) auto;padding:var(--space-4) var(--space-5);border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-panel)}.oc-draft-card>header{display:flex;align-items:center;gap:var(--space-3);justify-content:space-between}.oc-draft-card>header strong{font-size:15px;font-weight:700;letter-spacing:-.01em}.oc-draft-card>header span{padding:3px 10px;border-radius:var(--radius-pill);background:var(--surface-muted);color:var(--muted);font-size:var(--text-xs);font-weight:700;letter-spacing:.05em;text-transform:uppercase}.oc-interview-bubble{margin:var(--space-3) 0;padding:var(--space-3) var(--space-4);border-left:3px solid var(--orange);border-radius:0 var(--radius-md) var(--radius-md) 0;background:var(--canvas-soft)}.oc-interview-bubble textarea{width:100%;min-height:72px;margin:var(--space-2) 0;resize:vertical;border:1px solid var(--hairline-strong);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);font:inherit;font-size:var(--text-md)}.oc-interview-bubble textarea:focus-visible{outline:none;border-color:var(--orange);box-shadow:0 0 0 3px var(--orange-soft)}.oc-interview-bubble .btn+.btn{margin-left:var(--space-2)}.oc-draft-card pre{max-height:300px;overflow:auto;white-space:pre-wrap;font-size:var(--text-xs)}.oc-assessment{margin:var(--space-3) 0;color:var(--orange);font-size:var(--text-md)}.oc-assessment.is-fresh,.oc-task-kind-card.is-confirmed{color:var(--green)}.oc-task-kind-card{display:flex;align-items:center;gap:var(--space-3);justify-content:space-between;flex-wrap:wrap;margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft)}.oc-task-kind-card small{color:var(--muted)}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}.oc-human-gate-card{position:relative;width:min(720px,calc(100% - 42px));margin:var(--space-3) auto;padding:var(--space-4) var(--space-5);border:1px solid color-mix(in srgb,var(--orange) 38%,var(--hairline));border-left:4px solid var(--orange);border-radius:var(--radius-lg);background:linear-gradient(180deg,color-mix(in srgb,var(--orange) 4%,var(--surface)),var(--surface) 40%);box-shadow:var(--shadow-soft);animation:panel-in .2s var(--ease-out)}.oc-human-gate-card.is-prepared,.oc-human-gate-card.is-confirmed{position:sticky;bottom:var(--space-2);z-index:6}.oc-human-gate-card header,.oc-human-gate-card footer{display:flex;justify-content:space-between;align-items:center;gap:var(--space-3)}.oc-human-gate-card header div{display:grid;gap:3px}.oc-human-gate-card header small{color:var(--muted);font-size:var(--text-xs);font-weight:600;letter-spacing:.04em}.oc-human-gate-card header strong{font-size:15px;font-weight:700;letter-spacing:-.01em}.oc-human-gate-card header>span{flex-shrink:0;padding:3px 10px;border-radius:var(--radius-pill);font-size:var(--text-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;border:1px solid transparent}.oc-human-gate-card.is-prepared header>span{color:var(--orange-active);background:var(--orange-soft);border-color:color-mix(in srgb,var(--orange) 35%,transparent)}.oc-human-gate-card.is-confirmed header>span,.oc-human-gate-card.is-dispatched header>span{color:var(--blue);background:color-mix(in srgb,var(--blue) 10%,transparent);border-color:color-mix(in srgb,var(--blue) 30%,transparent)}.oc-human-gate-card.is-consumed header>span{color:var(--green);background:color-mix(in srgb,var(--green) 10%,transparent);border-color:color-mix(in srgb,var(--green) 30%,transparent)}.oc-human-gate-card.is-stale header>span,.oc-human-gate-card.is-expired header>span,.oc-human-gate-card.is-error header>span{color:var(--red);background:color-mix(in srgb,var(--red) 8%,transparent);border-color:color-mix(in srgb,var(--red) 30%,transparent)}.oc-human-gate-card>p{margin:var(--space-3) 0 0;color:var(--body);font-size:var(--text-md);line-height:1.55}.oc-human-gate-card>div:has(>b){margin-top:var(--space-3);padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft);font-size:var(--text-sm)}.oc-human-gate-challenges,.oc-human-gate-card ol{max-height:160px;overflow:auto}.oc-human-gate-card ul,.oc-human-gate-card ol{margin:var(--space-2) 0 0;padding-left:1.3em;color:var(--body)}.oc-human-gate-card footer{margin-top:var(--space-4);padding-top:var(--space-3);border-top:1px solid var(--hairline)}.oc-human-gate-card footer a{color:var(--muted);font-size:var(--text-sm);font-weight:600;text-decoration:none}.oc-human-gate-card footer a:hover{color:var(--orange-active);text-decoration:underline}.oc-human-gate-error{margin-top:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--red) 8%,transparent);color:var(--red);font-size:var(--text-sm);font-weight:600}.oc-human-gate-card.is-confirmed{border-left-color:var(--blue)}.oc-human-gate-card.is-consumed{border-left-color:var(--green);box-shadow:var(--shadow-panel)}.oc-human-gate-card.is-stale,.oc-human-gate-card.is-expired,.oc-human-gate-card.is-error{border-left-color:var(--red)}.oc-task-context{margin:var(--space-3);padding:var(--space-3);border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface)}.oc-task-context>header{display:flex;justify-content:space-between;gap:var(--space-2);align-items:center}.oc-task-context>header div{display:grid;gap:2px}.oc-task-context>header small,.oc-task-context>header span,.oc-task-context-empty{color:var(--muted)}.oc-task-context-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-2);margin-top:var(--space-3)}.oc-task-context-grid>div{display:grid;gap:4px;min-width:0;padding:var(--space-2);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--canvas-soft)}.oc-task-context-grid span,.oc-task-context-grid small{overflow-wrap:anywhere}.oc-shortcut-palette{position:absolute;z-index:12;left:0;right:0;bottom:calc(100% + 8px);display:grid;padding:6px;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-soft)}.oc-shortcut-palette button{display:flex;gap:var(--space-3);align-items:center;border:0;border-radius:var(--radius-md);padding:9px 10px;color:inherit;background:transparent;text-align:left;min-height:0}.oc-shortcut-palette button:hover,.oc-shortcut-palette button.is-active{background:var(--surface-muted)}.oc-shortcut-palette button span{display:grid;gap:2px}.oc-shortcut-palette button small{color:var(--muted)}.oc-composer-inner{position:relative}@media(max-width:800px){.oc-task-context-grid{grid-template-columns:1fr}}.oc-file-palette{position:absolute;z-index:13;left:0;right:0;bottom:calc(100% + 8px);display:grid;max-height:240px;overflow:auto;padding:6px;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-soft)}.oc-file-palette button{border:0;padding:8px 10px;color:inherit;background:transparent;text-align:left;border-radius:var(--radius-md);min-height:0}.oc-file-palette button:hover{background:var(--surface-muted)}.oc-runtime-controls{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px}.oc-composer.is-compact-controls .oc-composer-toolbar{display:flex;flex-wrap:nowrap;align-items:center;gap:8px;min-height:36px}.oc-composer.is-compact-controls .oc-composer-primary-model{min-width:0;flex:0 1 auto}.oc-composer.is-compact-controls .oc-composer-primary-model .oc-select-trigger{max-width:140px}.oc-composer-more{position:relative;margin-left:auto;flex-shrink:0}.oc-composer-more-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:32px;min-width:44px;padding:0 10px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);color:var(--body);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer}.oc-composer-more-btn:hover,.oc-composer-more-btn.is-open{border-color:color-mix(in srgb,var(--orange) 40%,var(--hairline));color:var(--orange-active);background:color-mix(in srgb,var(--orange) 8%,var(--surface))}.oc-composer-more-btn:focus-visible{outline:2px solid color-mix(in srgb,var(--orange) 45%,transparent);outline-offset:1px}.oc-composer-more-btn:active{transform:translateY(1px)}.oc-composer-more-menu{position:absolute;right:0;bottom:calc(100% + 6px);z-index:12;display:flex;flex-direction:column;gap:8px;min-width:min(320px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 24px));max-height:min(360px,50vh);overflow:auto;padding:10px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-soft)}.oc-composer-more-menu .oc-runtime-context-menu{margin-left:0}@media(prefers-reduced-motion:reduce){.oc-process,.oc-sidebar-drawer,.oc-suggestion,.oc-send{animation:none!important;transition:none!important}}.oc-select-menu{position:relative;flex-shrink:0}.oc-select-trigger{display:inline-flex;align-items:center;gap:6px;max-width:min(260px,calc(100vw - 32px));min-height:30px;padding:0 var(--space-2);border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);color:var(--body);font:inherit;font-size:var(--text-sm);cursor:pointer;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.oc-select-trigger:hover{border-color:var(--hairline-strong)}.oc-select-trigger:focus-visible{outline:none;border-color:var(--orange);box-shadow:0 0 0 3px var(--orange-soft)}.oc-select-trigger:disabled{cursor:not-allowed;opacity:.55}.oc-select-trigger-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono)}.oc-select-panel{position:absolute;left:0;bottom:calc(100% + 8px);z-index:18;width:min(340px,calc(100vw - 24px));max-height:min(60vh,440px);display:flex;flex-direction:column;gap:2px;padding:6px;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-soft);overflow:auto}.oc-select-search{flex-shrink:0;margin-bottom:4px;padding:7px 9px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--surface-muted);color:var(--ink);font:inherit;font-size:var(--text-sm);outline:none}.oc-select-search:focus{border-color:var(--orange);box-shadow:0 0 0 3px var(--orange-soft)}.oc-select-status{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;color:var(--muted);font-size:var(--text-sm)}.oc-select-status.is-error{color:var(--red)}.oc-model-group-head{padding:6px 10px 2px;color:var(--muted);font-size:11px;font-weight:650;letter-spacing:.04em;text-transform:uppercase}.oc-select-option{display:flex;align-items:center;gap:8px;width:100%;border:0;border-radius:var(--radius-md);padding:8px 10px;background:transparent;color:inherit;font:inherit;font-size:var(--text-sm);text-align:left;cursor:pointer;min-height:0}.oc-select-option.is-highlighted{background:var(--surface-muted)}.oc-select-option.is-active{color:var(--orange-active)}.oc-model-option-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono)}.oc-model-option-check{flex-shrink:0;color:var(--orange)}.oc-thinking-option-label{flex:1}.oc-thinking-badge{flex-shrink:0;padding:1px 7px;border:1px solid var(--hairline);border-radius:var(--radius-pill);color:var(--muted);font-size:11px}.oc-reload-status{color:var(--muted);font-size:var(--text-sm)}.oc-reload-banner{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border:1px solid color-mix(in srgb,var(--red) 35%,var(--hairline));border-radius:var(--radius-sm);background:color-mix(in srgb,var(--red) 6%,var(--surface));color:var(--red);font-size:var(--text-sm)}.oc-runtime-controls .oc-process-summary{margin-left:0}.oc-usage{color:var(--muted);font-size:var(--text-sm);font-variant-numeric:tabular-nums}.oc-runtime-context-menu{position:relative;margin-left:auto;flex-shrink:0}.oc-runtime-context-toggle.is-active{color:var(--orange-active);background:color-mix(in srgb,var(--orange) 10%,var(--surface))}.oc-runtime-context-panel{position:absolute;right:0;bottom:calc(100% + 8px);z-index:16;width:min(760px,calc(100vw - 24px));max-height:min(72vh,720px);display:flex;flex-direction:column;border:1px solid var(--hairline);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-soft);animation:panel-in .16s ease;overflow:hidden}.oc-runtime-context-head{display:flex;align-items:flex-start;gap:12px;flex-shrink:0;padding:12px 14px;border-bottom:1px solid var(--hairline);background:var(--surface-raised)}.oc-runtime-context-head-copy{flex:1;min-width:0;display:grid;gap:2px}.oc-runtime-context-head strong{font-size:14px}.oc-runtime-context-meta{font-size:11px;color:var(--muted)}.oc-runtime-context-close{flex-shrink:0;min-height:28px;padding:0 8px;font-size:12px}.oc-runtime-context-body{flex:1;min-height:0;overflow:auto;padding:12px 14px 14px;display:grid;gap:14px}.oc-runtime-context-chips{display:flex;flex-wrap:wrap;gap:6px}.oc-runtime-context-chip{display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:4px 8px;border:1px solid var(--hairline);border-radius:999px;background:var(--canvas-soft);color:var(--body);font-size:11px;line-height:1.3}.oc-runtime-context-chip code{font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oc-runtime-context-section{display:grid;gap:8px;min-width:0}.oc-runtime-context-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.oc-runtime-context-section-head strong{font-size:12px}.oc-runtime-context-hash{display:inline-block;margin-left:6px;font-size:11px;color:var(--muted)}.oc-runtime-context-text{margin:0;max-height:min(36vh,360px);overflow:auto;padding:10px 12px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--canvas-soft);color:var(--body);font-size:12px;line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}.oc-runtime-context-empty{margin:0;color:var(--muted);font-size:12px}.oc-runtime-context-tools{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:6px}.oc-runtime-context-tools li code{display:inline-block;padding:3px 7px;border:1px solid var(--hairline);border-radius:6px;background:var(--canvas-soft);font-size:11px}.oc-runtime-context-raw{padding-top:10px;border-top:1px solid var(--hairline);font-size:12px;color:var(--muted)}.oc-runtime-context-raw summary{cursor:pointer;-webkit-user-select:none;user-select:none}.oc-runtime-context-raw pre{margin:8px 0 0;max-height:180px;overflow:auto;padding:8px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--canvas-soft);font-size:11px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.oc-runtime-context-resources{display:grid;gap:6px;margin:0;padding:0;list-style:none}.oc-runtime-context-resources li{display:grid;gap:3px;padding:7px 9px;border:1px solid var(--hairline);border-radius:var(--radius-sm);background:var(--surface);font-size:var(--text-sm)}.oc-runtime-context-resources code{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--body);font-size:11px}.oc-runtime-context-resolved{white-space:normal!important;overflow-wrap:anywhere}.oc-runtime-context-diag{color:var(--amber);font-size:11px;line-height:1.5}.oc-runtime-context-diag.is-error{color:var(--red);display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.oc-runtime-context-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;flex-shrink:0;padding:10px 14px;border-top:1px solid var(--hairline);background:var(--surface-raised)}@media(max-width:800px){.oc-runtime-context-menu{margin-left:0;width:100%}.oc-runtime-context-panel{left:0;right:0;width:auto;max-height:min(78vh,680px)}}.oc-artifact-card{max-width:100%;margin:var(--space-3) 0;padding:var(--space-4);overflow:hidden;border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-panel)}.oc-artifact-card header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-3)}.oc-artifact-card header strong{font-size:var(--text-md);font-weight:700}.oc-artifact-card header>span{padding:2px 9px;border-radius:var(--radius-pill);background:var(--surface-muted);color:var(--muted);font-size:var(--text-xs);font-weight:700;letter-spacing:.05em;text-transform:uppercase}.oc-artifact-card pre{max-height:320px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--text-xs)}.oc-artifact-card iframe{width:100%;min-height:280px;border:1px solid var(--hairline);border-radius:var(--radius-md);background:#fff}.oc-load-history{display:block;margin:var(--space-2) auto}.oc-attach-button{display:inline-flex;min-height:26px;align-items:center;padding:0 var(--space-2);border:1px solid var(--hairline);border-radius:var(--radius-pill);background:var(--surface);color:var(--muted);cursor:pointer;font-size:var(--text-sm);font-weight:600;transition:border-color var(--transition-fast),color var(--transition-fast),background-color var(--transition-fast)}.oc-attach-button:hover{border-color:var(--orange);color:var(--orange-active);background:var(--orange-soft)}.oc-composer-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:10px 14px;margin-bottom:6px;font-size:11.5px;color:var(--muted)}.oc-composer-toolbar .oc-attach-button{margin-bottom:0}.oc-attachment-list{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}.oc-attachment-list span{display:inline-flex;align-items:center;gap:5px;max-width:100%;padding:4px 8px;border:1px solid var(--hairline);border-radius:999px;overflow-wrap:anywhere}.oc-attachment-list button{border:0;color:inherit;background:transparent;cursor:pointer}@media(max-width:640px){.oc-runtime-controls,.oc-composer-foot{align-items:stretch;flex-direction:column}.oc-runtime-controls .oc-select-trigger,.oc-runtime-controls button{width:100%;max-width:100%;min-height:44px}.oc-runtime-controls .oc-select-menu{width:100%}.oc-select-panel{width:min(340px,calc(100vw - 24px))}.oc-artifact-card{width:100%}.oc-composer{padding-inline:8px}}.night-workbench .night-health{margin:var(--space-4) 0;padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-sm)}.night-health-main{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3)}.night-health-pill{display:inline-flex;align-items:center;gap:6px;padding:3px 12px;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--green) 14%,white);color:var(--green);font-size:var(--text-sm);font-weight:700;letter-spacing:.02em}.night-health-pill:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.night-health-pill.is-bad{background:color-mix(in srgb,var(--red) 14%,white);color:var(--red)}.night-health-hint{margin:var(--space-2) 0 0}.night-aux-ticker{margin-top:var(--space-3);padding-top:var(--space-3);border-top:1px solid var(--hairline)}.night-aux-ticker-label{margin:0;color:var(--body);font-size:var(--text-md)}.night-doctor-list{margin:var(--space-2) 0 0;padding-left:1.2em;color:var(--body);font-size:12.5px}.night-kpi{display:flex;flex-wrap:wrap;gap:var(--space-2);margin:var(--space-3) 0;color:var(--body);font-size:var(--text-md)}.night-kpi span{padding:4px 12px;border:1px solid var(--hairline);border-radius:var(--radius-pill);background:var(--canvas-soft);font-variant-numeric:tabular-nums;font-weight:600}.night-board,.night-wizard,.night-discard-card,.night-advanced{margin-top:var(--space-5)}.night-schedule-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--space-3)}.night-schedule-row{padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-lg);background:var(--surface);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.night-schedule-row:hover{border-color:var(--hairline-strong);box-shadow:var(--shadow-panel)}.night-schedule-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-2)}.night-status-chip{padding:2px 10px;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--blue) 10%,transparent);border:1px solid color-mix(in srgb,var(--blue) 25%,transparent);font-size:var(--text-xs);color:var(--blue);font-weight:700;letter-spacing:.03em}.night-schedule-row[data-status=failed] .night-status-chip,.night-schedule-row[data-status=human_required] .night-status-chip{color:var(--red);background:color-mix(in srgb,var(--red) 8%,transparent);border-color:color-mix(in srgb,var(--red) 28%,transparent)}.night-schedule-row[data-status=succeeded] .night-status-chip{color:var(--green);background:color-mix(in srgb,var(--green) 10%,transparent);border-color:color-mix(in srgb,var(--green) 28%,transparent)}.night-schedule-row[data-status=running] .night-status-chip,.night-schedule-row[data-status=dispatching] .night-status-chip{color:var(--orange-active);background:var(--orange-soft);border-color:color-mix(in srgb,var(--orange) 30%,transparent)}.night-next-action{font-size:var(--text-sm);overflow-wrap:anywhere}.night-review-card,.night-discard-card{padding:var(--space-4) var(--space-5);border:1px solid var(--hairline-strong);border-radius:var(--radius-lg);background:var(--canvas-soft)}.night-writeset{margin:0;padding-left:1.1em}.night-advanced{border-top:1px solid var(--hairline);padding-top:var(--space-3)}.night-advanced summary{cursor:pointer;color:var(--body);font-weight:600}.checkbox-field{display:flex;align-items:center;gap:var(--space-2)}.models-page .panel-lead{margin-top:var(--space-2)}.models-header{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3)}.models-header h2{margin:0}.models-status-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 14px;border-radius:var(--radius-pill);font-size:var(--text-sm);font-weight:700;letter-spacing:.02em}.models-status-pill:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.models-status-pill[data-state=ready]{background:color-mix(in srgb,var(--green) 14%,white);color:var(--green)}.models-status-pill[data-state=setup-required]{background:color-mix(in srgb,var(--red) 14%,white);color:var(--red)}.models-status-pill[data-state=degraded]{background:color-mix(in srgb,var(--orange) 16%,white);color:var(--orange-active)}.models-status-pill[data-state=unknown]{background:var(--canvas-soft);color:var(--muted)}.models-subtitle{margin:0 0 var(--space-2);font-size:var(--text-md);font-weight:700;color:var(--ink)}.models-probe-card,.models-setup-card,.models-blocked-card{margin-top:var(--space-4);padding:var(--space-3) var(--space-4);border:1px solid var(--hairline);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 55%,transparent)}.models-probe-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--space-2)}.models-probe-item{display:grid;grid-template-columns:28px 1fr;gap:var(--space-2);align-items:start;padding:var(--space-2) 0;border-bottom:1px solid var(--hairline)}.models-probe-item:last-child{border-bottom:none;padding-bottom:0}.models-probe-badge{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;font-size:14px;font-weight:800;line-height:1;background:var(--canvas-soft);color:var(--muted)}.models-probe-item.is-ok .models-probe-badge{background:color-mix(in srgb,var(--green) 16%,white);color:var(--green)}.models-probe-item.is-bad .models-probe-badge{background:color-mix(in srgb,var(--red) 14%,white);color:var(--red)}.models-probe-body{display:grid;gap:2px;min-width:0}.models-probe-body strong{font-size:var(--text-md);color:var(--ink)}.models-probe-body .muted{font-size:var(--text-sm)}.models-probe-detail{margin:var(--space-1) 0 0;font-size:var(--text-sm);color:var(--body);line-height:1.45}.models-setup-steps{margin:0 0 var(--space-3);padding-left:1.25em;color:var(--body);font-size:var(--text-md);line-height:1.5}.models-setup-steps li+li{margin-top:var(--space-2)}.models-degraded-note{margin:var(--space-4) 0 0;padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);border:1px solid color-mix(in srgb,var(--orange) 35%,var(--hairline));background:color-mix(in srgb,var(--orange) 8%,white);color:var(--body);font-size:var(--text-md)}.models-blocked-list{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:var(--space-2)}.models-blocked-list li{padding:4px 10px;border-radius:var(--radius-pill);border:1px solid var(--hairline);background:var(--surface)}.models-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3);margin-top:var(--space-4)}.models-generated-at{font-size:var(--text-sm)}.models-raw-details{margin-top:var(--space-4);font-size:var(--text-sm);color:var(--muted)}.models-raw-details summary{cursor:pointer;font-weight:600;color:var(--body)}.models-raw-json{margin-top:var(--space-2);max-height:240px;overflow:auto}