@tea-agent/loop-agent 0.40.0-next.1 → 0.40.0-next.11

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 (213) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +114 -109
  3. package/README.md +2 -2
  4. package/dist/application/dag/generate-task-dag.js +6 -2
  5. package/dist/application/task-lifecycle/advance.js +12 -0
  6. package/dist/build-stamp.json +3 -3
  7. package/dist/cli/update/runtime-activity.js +1 -29
  8. package/dist/commands/dag-rerun.js +1 -1
  9. package/dist/executors/dag-pi-executor.js +69 -7
  10. package/dist/executors/pi-executor.js +4 -2
  11. package/dist/executors/pi-sdk-executor.js +46 -1
  12. package/dist/executors/pi-writer-tool-policy.js +57 -1
  13. package/dist/executors/shell-executor.js +107 -20
  14. package/dist/executors/workspace-write-snapshot.js +68 -0
  15. package/dist/governance/checks.js +1 -0
  16. package/dist/infrastructure/harness/atomic-write.js +23 -0
  17. package/dist/shared/dag-prompt-override.js +4 -5
  18. package/dist/shared/update/npm-client.js +33 -11
  19. package/dist/task/config-types.js +10 -0
  20. package/dist/task/contract/apply.js +11 -1
  21. package/dist/task/contract/constants.js +2 -0
  22. package/dist/task/contract/hash.js +3 -0
  23. package/dist/task/contract/observe.js +25 -4
  24. package/dist/task/contract/paths.js +2 -1
  25. package/dist/task/contract/project.js +15 -1
  26. package/dist/task/contract/schema.js +2 -0
  27. package/dist/task/contract/transaction.js +12 -0
  28. package/dist/task/source-prepare/completeness.js +188 -0
  29. package/dist/task/source-prepare/fragment-inventory.js +474 -0
  30. package/dist/task/source-prepare/index.js +3 -0
  31. package/dist/task/source-prepare/ledger-reconciliation.js +127 -0
  32. package/dist/task/source-prepare/ledger-review.js +214 -0
  33. package/dist/task/source-prepare/ledger.js +545 -0
  34. package/dist/task/source-prepare/prepare.js +262 -1
  35. package/dist/task/source-prepare/semantic-intake.js +19 -3
  36. package/dist/task/source-prepare/source-fidelity-pi.js +384 -0
  37. package/dist/task/source-prepare/types.js +22 -0
  38. package/dist/worker/cli.js +12 -26
  39. package/dist/worker/console/chat/chat-event-store.js +75 -5
  40. package/dist/worker/console/chat/context-panel.js +7 -0
  41. package/dist/worker/console/chat/deferred-turn.js +12 -0
  42. package/dist/worker/console/chat/pi-runtime.js +331 -18
  43. package/dist/worker/console/chat/provider-error.js +98 -0
  44. package/dist/worker/console/chat/routes.js +389 -56
  45. package/dist/worker/console/chat/session-stats.js +179 -0
  46. package/dist/worker/console/chat/session-store.js +93 -63
  47. package/dist/worker/console/chat/todos.js +115 -0
  48. package/dist/worker/console/chat/tool-preview.js +42 -0
  49. package/dist/worker/console/chat/turn-process.js +20 -55
  50. package/dist/worker/console/chat/user-questions.js +266 -0
  51. package/dist/worker/console/chat/workspace-landing.js +79 -0
  52. package/dist/worker/console/console-handoff.js +82 -0
  53. package/dist/worker/console/console-update-and-init.js +115 -0
  54. package/dist/worker/console/console-update-runtime.js +84 -0
  55. package/dist/worker/console/dag-execution-receipt.js +20 -2
  56. package/dist/worker/console/draft-store.js +49 -0
  57. package/dist/worker/console/native-directory-picker.js +13 -0
  58. package/dist/worker/console/operation-store.js +1 -1
  59. package/dist/worker/console/operator-actions.js +133 -7
  60. package/dist/worker/console/operator-surface-health.js +1 -0
  61. package/dist/worker/console/prd-intake-bridge.js +13 -0
  62. package/dist/worker/console/routes.js +312 -1
  63. package/dist/worker/console/security.js +4 -4
  64. package/dist/worker/console/server.js +583 -172
  65. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Br92EGb7.js → abnfDiagram-N423BO3Z-Bs-CDAXM.js} +1 -1
  66. package/dist/worker/console/static/assets/{arc-oulImtQq.js → arc-CAkA3We3.js} +1 -1
  67. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-tyHc6aqO.js → architectureDiagram-T3A2C74G-DEmI_zqr.js} +1 -1
  68. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CY86BSpT.js → blockDiagram-VBNYF7ZC-uDHANebE.js} +1 -1
  69. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BKKsDmNs.js → c4Diagram-5PPSVZJV-Bv97b4_B.js} +1 -1
  70. package/dist/worker/console/static/assets/channel-amxUpk7o.js +1 -0
  71. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CXZdjl3B.js → chunk-2GRJ4B5K-shmQKsFz.js} +1 -1
  72. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B-aIFDQ5.js → chunk-2Q5K7J3B-BAraNvcN.js} +1 -1
  73. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BDgAW_B2.js → chunk-5RXB4S5H-BirhxUop.js} +1 -1
  74. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DABa4UPR.js → chunk-5VM5RSS4-C9LgUJpR.js} +1 -1
  75. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-aGbysVOx.js → chunk-6Q2QTUOP-DrU-s-t7.js} +1 -1
  76. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-B8MSZDVs.js → chunk-GF5L2VYU-Tx-H_FA2.js} +1 -1
  77. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CpelV73g.js → chunk-JWPE2WC7-BjLtNFrR.js} +1 -1
  78. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BE04ty3z.js → chunk-KBJHAD2P-UNLVwSsy.js} +1 -1
  79. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-BUxTkaaR.js → chunk-RYQCIY6F-CBEUX8XD.js} +1 -1
  80. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CYYBVKfX.js → chunk-XXDRQBXY-WTL7IZOq.js} +1 -1
  81. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-bejwBVIz.js +1 -0
  82. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-bejwBVIz.js +1 -0
  83. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CEQF_xmQ.js → cose-bilkent-JH36ORCC-CkHG6W3s.js} +1 -1
  84. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CqpxN5IT.js → cynefin-VYW2F7L2-BRzFqTaL.js} +1 -1
  85. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-B3PzanVi.js → cynefinDiagram-MW4NZA55-2_CFp_i7.js} +1 -1
  86. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BSUGCNx1.js → dagre-VZM6K2ZE-BJtsmdkE.js} +1 -1
  87. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CdLevU5T.js → diagram-7IWD3JNH-DNEFFo6w.js} +1 -1
  88. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BjpF_Kok.js → diagram-B4RE2ZJO-B_IWV7eo.js} +1 -1
  89. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-C4I6NJny.js → diagram-LBJQPF4R-DvvRx2dz.js} +1 -1
  90. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-C8hecCr5.js → diagram-Q27KOJAE-CsibsWLg.js} +1 -1
  91. package/dist/worker/console/static/assets/{diagram-UB23O5K3-Daod6tOS.js → diagram-UB23O5K3-les_djBQ.js} +1 -1
  92. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-BvvmazGv.js → ebnfDiagram-BXEA7PRR-BEm2n7qJ.js} +1 -1
  93. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DeN_vfV4.js → erDiagram-JOGREHBK-BI7vHHVm.js} +1 -1
  94. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-D6dq1t9z.js → flowDiagram-UKHOOZJN-CUFCERrB.js} +1 -1
  95. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DziIdNY4.js → ganttDiagram-PKOTCBZU-wxyLiGWt.js} +1 -1
  96. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Dy4s5CXr.js → gitGraphDiagram-DS77QQ5N-Bt897K8Z.js} +1 -1
  97. package/dist/worker/console/static/assets/index-BHhUOTri.css +1 -0
  98. package/dist/worker/console/static/assets/index-DqJbO3-p.js +407 -0
  99. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Czv5eYx2.js → infoDiagram-6WML65LV-DYNx_IPv.js} +1 -1
  100. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-Bsk3nFRT.js → ishikawaDiagram-WSZJBQD7-CzpLNEu6.js} +1 -1
  101. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DxGmNj5K.js → journeyDiagram-NVQOT4AX-97f9owNU.js} +1 -1
  102. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CYCFqkO_.js → kanban-definition-27J2QSJJ-BxM9hyBn.js} +1 -1
  103. package/dist/worker/console/static/assets/{linear-B0YzRwrd.js → linear-ByuxcHvp.js} +1 -1
  104. package/dist/worker/console/static/assets/{mermaid.core-t3EZtIGh.js → mermaid.core-DwPGvpCv.js} +5 -5
  105. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BTXpTv0T.js → mindmap-definition-FAOFIHXS-DCoqG9RT.js} +1 -1
  106. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DU8UkKqA.js → pegDiagram-VL7TDLO6-BLSBmBMx.js} +1 -1
  107. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DP4y8ohp.js → pieDiagram-7S7Q4E2Y-B0t_0oJW.js} +1 -1
  108. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B07vNaYR.js → quadrantDiagram-CIZ2JOQS-sTzDk7Nt.js} +1 -1
  109. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-xDWktb2i.js → railroadDiagram-AXF67PYL-B3jRdATC.js} +1 -1
  110. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BLNMKqeS.js → requirementDiagram-LRYGKXZP-D-cTtXEN.js} +1 -1
  111. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-n0adalxH.js → sankeyDiagram-W5VNT64P-B25igJRE.js} +1 -1
  112. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BbnS-2DL.js → sequenceDiagram-SI44F4Z6-jW_lM1_D.js} +1 -1
  113. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B4uPpCLu.js → sizeCapture-X5ZJPWSS-CrzTgsHE.js} +1 -1
  114. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA--MMbB0fX.js → stateDiagram-OKZ733FA-B01MvlqE.js} +1 -1
  115. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BvFKEtm2.js +1 -0
  116. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BXUgp2QY.js → swimlanes-SLNWSIFB-YcF12FiU.js} +2 -2
  117. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DIB2eVg-.js +8 -0
  118. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CsaMxki7.js → timeline-definition-Z64GVDOM-ClnRcg2s.js} +1 -1
  119. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-C2IuG9iH.js → vennDiagram-T6HMQDX7-B6gr_z-q.js} +1 -1
  120. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CmEWOXCW.js → wardleyDiagram-T6FBY63Y-CvSgguGH.js} +1 -1
  121. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-D_9LE0MG.js → xychartDiagram-ELKLHX3M-23OtSZCb.js} +1 -1
  122. package/dist/worker/console/static/index.html +2 -2
  123. package/dist/worker/console/static-src/app/console-types.js +68 -4
  124. package/dist/worker/console/static-src/app/useConsoleShell.js +30 -12
  125. package/dist/worker/console/static-src/app/useOperatorActions.js +41 -6
  126. package/dist/worker/console/static-src/app/useRecoveryConsole.js +10 -11
  127. package/dist/worker/console/static-src/app/useRunProgress.js +2 -1
  128. package/dist/worker/console/static-src/app/useTaskWizard.js +74 -2
  129. package/dist/worker/console/static-src/night/useNightBoard.js +8 -5
  130. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +141 -8
  131. package/dist/worker/console/static-src/operator-chat/compaction-message.js +79 -0
  132. package/dist/worker/console/static-src/operator-chat/details-dag-actions.js +122 -0
  133. package/dist/worker/console/static-src/operator-chat/refs.js +3 -0
  134. package/dist/worker/console/static-src/operator-chat/runtime-selection-labels.js +27 -0
  135. package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +1 -2
  136. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +25 -0
  137. package/dist/worker/console/static-src/operator-chat/turn-submission.js +3 -2
  138. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +181 -87
  139. package/dist/worker/console/static-src/operator-chat/useChatStream.js +159 -44
  140. package/dist/worker/console/static-src/operator-chat/useChatThread.js +177 -8
  141. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +63 -9
  142. package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
  143. package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +3 -3
  144. package/dist/worker/console/static-src/shell/useWorkspaces.js +299 -0
  145. package/dist/worker/console/static-src/shell/workspace-route.js +339 -0
  146. package/dist/worker/console/workspace-context.js +234 -0
  147. package/dist/worker/console/workspace-registry.js +214 -0
  148. package/dist/worker/observability/init-runtime-activity.js +26 -0
  149. package/dist/worker/observe/node-input.js +88 -2
  150. package/dist/worker/observe/routes.js +188 -0
  151. package/dist/worker/observe/server.js +4 -0
  152. package/dist/worker/observe/static/api.js +29 -9
  153. package/dist/worker/observe/static/app.js +18 -70
  154. package/dist/worker/observe/static/dag-node-purpose.d.ts +6 -0
  155. package/dist/worker/observe/static/dag-node-purpose.js +203 -0
  156. package/dist/worker/observe/static/format.js +37 -0
  157. package/dist/worker/observe/static/index.html +6 -1
  158. package/dist/worker/observe/static/inspect-workspace.js +307 -0
  159. package/dist/worker/observe/static/operator-chrome.css +145 -20
  160. package/dist/worker/observe/static/operator-chrome.d.ts +20 -3
  161. package/dist/worker/observe/static/operator-chrome.js +330 -100
  162. package/dist/worker/observe/static/prompt-restart-candidates.d.ts +18 -0
  163. package/dist/worker/observe/static/prompt-restart-candidates.js +36 -0
  164. package/dist/worker/observe/static/router.d.ts +46 -0
  165. package/dist/worker/observe/static/router.js +25 -1
  166. package/dist/worker/observe/static/state.d.ts +50 -0
  167. package/dist/worker/observe/static/state.js +174 -2
  168. package/dist/worker/observe/static/styles.css +357 -35
  169. package/dist/worker/observe/static/views/dag-graph.js +4 -2
  170. package/dist/worker/observe/static/views/dag-inspector.js +533 -79
  171. package/dist/worker/observe/static/views/dag.d.ts +13 -0
  172. package/dist/worker/observe/static/views/dag.js +6 -4
  173. package/dist/worker/observe/static/views/dashboard.js +6 -4
  174. package/dist/worker/observe/static/views/night.js +2 -2
  175. package/dist/worker/observe/static/views/pool.js +1 -0
  176. package/dist/worker/observe/static/views/run.js +3 -1
  177. package/dist/worker/observe/static/views/task.js +56 -1
  178. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +186 -8
  179. package/dist/workflows/dag/backend-test-markdown-workflow.js +176 -1
  180. package/dist/workflows/dag/backend-test-pytest-collection.js +168 -16
  181. package/dist/workflows/dag/backend-test-result-contract.js +4 -0
  182. package/dist/workflows/dag/backend-test-scenario-param.js +339 -53
  183. package/dist/workflows/dag/backend-test-writer-completeness.js +28 -17
  184. package/dist/workflows/dag/dynamic-runtime/map.js +1 -0
  185. package/dist/workflows/dag/frontend-implementation-contract.js +88 -2
  186. package/dist/workflows/dag/frontend-plan-render.js +24 -0
  187. package/dist/workflows/dag/frontend-prewrite-gate.js +197 -0
  188. package/dist/workflows/dag/frontend-review-context.js +92 -10
  189. package/dist/workflows/dag/init-hybrid.js +239 -52
  190. package/dist/workflows/dag/interrupt-request.js +3 -3
  191. package/dist/workflows/dag/lifecycle.js +3 -3
  192. package/dist/workflows/dag/node-execution.js +45 -0
  193. package/dist/workflows/dag/types.js +62 -12
  194. package/docs/README.md +2 -0
  195. package/docs/architecture/evolution.md +45 -0
  196. package/docs/init-surface.manifest.json +1 -0
  197. package/docs/operations/local-development-environment.md +21 -0
  198. package/docs/templates/README.md +1 -1
  199. package/docs/templates/agent-dag.schema.json +18 -0
  200. package/docs/templates/backend-test-dag.json +267 -238
  201. package/docs/templates/frontend-implementation-contract.schema.json +681 -24
  202. package/harness.json +3 -3
  203. package/package.json +3 -1
  204. package/skills/loop-agent/references/hybrid-dag.md +7 -0
  205. package/dist/worker/console/static/assets/channel-TY36zt-i.js +0 -1
  206. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Dk7QCChM.js +0 -1
  207. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Dk7QCChM.js +0 -1
  208. package/dist/worker/console/static/assets/index-C3GgHg-g.css +0 -1
  209. package/dist/worker/console/static/assets/index-Ci8ksvBm.js +0 -406
  210. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BqOigMQ4.js +0 -1
  211. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Caxz9UA2.js +0 -8
  212. package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +0 -73
  213. package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +0 -59
@@ -9,15 +9,15 @@
9
9
  */
10
10
 
11
11
  .och {
12
- --och-canvas: var(--canvas, #f7f7f4);
13
- --och-surface: var(--surface, #ffffff);
14
- --och-surface-muted: var(--surface-muted, #f0efe9);
15
- --och-ink: var(--ink, #26251e);
16
- --och-body: var(--body, #5a5852);
17
- --och-muted: var(--muted, #807d72);
18
- --och-muted-soft: var(--muted-soft, #a09c92);
19
- --och-hairline: var(--hairline, #e6e5e0);
20
- --och-hairline-strong: var(--hairline-strong, #cfcdc4);
12
+ --och-canvas: var(--canvas, #f3f4f6);
13
+ --och-surface: var(--surface, #fbfcfd);
14
+ --och-surface-muted: var(--surface-muted, #eceef1);
15
+ --och-ink: var(--ink, #202124);
16
+ --och-body: var(--body, #50545b);
17
+ --och-muted: var(--muted, #767b84);
18
+ --och-muted-soft: var(--muted-soft, #9ca1aa);
19
+ --och-hairline: var(--hairline, #e1e3e7);
20
+ --och-hairline-strong: var(--hairline-strong, #cfd2d8);
21
21
  --och-orange: var(--orange, #f54e00);
22
22
  --och-orange-active: var(--orange-active, #d04200);
23
23
  --och-green: var(--green, #1f8a65);
@@ -40,14 +40,16 @@
40
40
  top: 0;
41
41
  z-index: 50;
42
42
  border-bottom: 1px solid var(--och-hairline);
43
- background: color-mix(in srgb, var(--och-canvas) 88%, transparent);
43
+ background: var(--canvas-soft, var(--och-surface));
44
44
  backdrop-filter: blur(12px);
45
45
  -webkit-backdrop-filter: blur(12px);
46
46
  font-family: inherit;
47
47
  }
48
48
 
49
49
  .och-inner {
50
- width: min(100% - 48px, var(--och-shell-max));
50
+ box-sizing: border-box;
51
+ width: 100%;
52
+ padding-inline: 14px;
51
53
  margin: 0 auto;
52
54
  }
53
55
 
@@ -57,7 +59,8 @@
57
59
  display: flex;
58
60
  align-items: center;
59
61
  gap: 12px;
60
- height: 54px;
62
+ /* DSH 2026-08-23:约 44px 与内容同色的压缩标题栏。 */
63
+ height: 44px;
61
64
  }
62
65
 
63
66
  .och-brand {
@@ -70,6 +73,7 @@
70
73
  color: var(--och-ink);
71
74
  text-decoration: none;
72
75
  white-space: nowrap;
76
+ flex-shrink: 0;
73
77
  }
74
78
  .och-brand-mark {
75
79
  display: block;
@@ -114,6 +118,19 @@
114
118
  color: var(--och-muted);
115
119
  }
116
120
 
121
+ .och-workspace-picker {
122
+ position: relative;
123
+ display: inline-flex;
124
+ min-width: 0;
125
+ flex-shrink: 0;
126
+ }
127
+
128
+ .och-workspace-trigger .och-repo-name {
129
+ max-width: 180px;
130
+ overflow: hidden;
131
+ text-overflow: ellipsis;
132
+ }
133
+
117
134
  .och-pop {
118
135
  position: absolute;
119
136
  top: 50px;
@@ -155,21 +172,122 @@
155
172
  word-break: break-all;
156
173
  }
157
174
 
175
+ .och-workspace-picker .och-pop {
176
+ top: 36px;
177
+ left: 0;
178
+ width: min(340px, calc(100vw - 28px));
179
+ min-width: 260px;
180
+ padding: 8px;
181
+ }
182
+ .och-workspace-picker .och-pop-title {
183
+ padding: 5px 7px 7px;
184
+ margin: 0;
185
+ font-size: 11px;
186
+ font-weight: 700;
187
+ letter-spacing: 0.06em;
188
+ color: var(--och-muted);
189
+ }
190
+ .och-workspace-option {
191
+ appearance: none;
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: space-between;
195
+ gap: 12px;
196
+ width: 100%;
197
+ min-height: 48px;
198
+ padding: 7px 8px;
199
+ border: 0;
200
+ border-radius: 9px;
201
+ background: transparent;
202
+ color: var(--och-body);
203
+ font: inherit;
204
+ text-align: left;
205
+ cursor: pointer;
206
+ }
207
+ .och-workspace-option:hover,
208
+ .och-workspace-option:focus-visible,
209
+ .och-workspace-option[aria-checked="true"] {
210
+ background: color-mix(in srgb, var(--och-ink) 7%, transparent);
211
+ color: var(--och-ink);
212
+ }
213
+ .och-workspace-option-copy {
214
+ display: grid;
215
+ min-width: 0;
216
+ gap: 2px;
217
+ }
218
+ .och-workspace-option strong,
219
+ .och-workspace-option small {
220
+ overflow: hidden;
221
+ text-overflow: ellipsis;
222
+ white-space: nowrap;
223
+ }
224
+ .och-workspace-option strong {
225
+ font-size: 13px;
226
+ font-weight: 650;
227
+ }
228
+ .och-workspace-option small {
229
+ font-size: 11px;
230
+ color: var(--och-muted);
231
+ }
232
+ .och-workspace-option > .och-icon {
233
+ color: var(--och-orange-active);
234
+ flex-shrink: 0;
235
+ }
236
+ .och-workspace-empty {
237
+ margin: 0;
238
+ padding: 12px 8px;
239
+ color: var(--och-muted);
240
+ }
241
+
158
242
  /* 模式分段控件:全局唯一模式入口(重语法:ink 实底) */
159
243
  .och-mode {
160
- display: inline-flex;
244
+ --och-mode-item-width: 92px;
245
+ position: relative;
246
+ display: grid;
247
+ grid-template-columns: repeat(3, var(--och-mode-item-width));
161
248
  padding: 3px;
162
249
  border: 1px solid var(--och-hairline);
163
250
  border-radius: 999px;
164
251
  background: var(--och-surface-muted);
165
252
  flex-shrink: 0;
166
253
  }
254
+
255
+ /* The product-mode switch is viewport-centered in Chat, Operate and Inspect;
256
+ * changing the active workspace must never move this global navigation. */
257
+ @media (min-width: 720px) {
258
+ .och-mode {
259
+ position: fixed;
260
+ top: 3px;
261
+ left: 50vw;
262
+ transform: translateX(-50%);
263
+ }
264
+ }
265
+ /* DSH 2026-08-23:共享椭圆滑块,160-220ms 移动到选中椭圆。 */
266
+ .och-mode-thumb {
267
+ position: absolute;
268
+ left: 0;
269
+ top: 0;
270
+ border-radius: 999px;
271
+ background: var(--och-ink);
272
+ box-shadow: 0 2px 8px rgba(38, 37, 30, 0.25);
273
+ transition: none;
274
+ pointer-events: none;
275
+ }
276
+ .och-mode-thumb.is-ready {
277
+ transition:
278
+ transform 190ms cubic-bezier(0.22, 1, 0.36, 1),
279
+ width 190ms cubic-bezier(0.22, 1, 0.36, 1),
280
+ height 190ms cubic-bezier(0.22, 1, 0.36, 1),
281
+ opacity 160ms ease;
282
+ }
167
283
  .och-mode-btn {
168
284
  display: inline-flex;
169
285
  align-items: center;
170
286
  justify-content: center;
171
287
  gap: 6px;
172
- min-width: 92px;
288
+ box-sizing: border-box;
289
+ width: var(--och-mode-item-width);
290
+ min-width: var(--och-mode-item-width);
173
291
  height: 30px;
174
292
  padding: 0 14px;
175
293
  border-radius: 999px;
@@ -190,9 +308,14 @@
190
308
  }
191
309
  .och-mode-btn.och-on,
192
310
  .och-mode-btn.och-on:hover {
193
- background: var(--och-ink);
311
+ /* 滑块提供选中背景;文字反色保持可读。 */
194
312
  color: #fff;
195
- box-shadow: 0 2px 8px rgba(38, 37, 30, 0.25);
313
+ background: transparent;
314
+ box-shadow: none;
315
+ }
316
+ .och-mode-btn {
317
+ position: relative;
318
+ z-index: 1;
196
319
  }
197
320
 
198
321
  /* 对象上下文 chip:跨模式选中连续性 + 显式返回路径 */
@@ -452,9 +575,6 @@
452
575
  .och-repo-fp {
453
576
  display: none;
454
577
  }
455
- .och-mode-btn {
456
- min-width: 0;
457
- }
458
578
  .och-workspace {
459
579
  overflow-x: auto;
460
580
  }
@@ -481,7 +601,7 @@
481
601
 
482
602
  @media (max-width: 760px) {
483
603
  .och-inner {
484
- width: min(100% - 24px, var(--och-shell-max));
604
+ padding-inline: 12px;
485
605
  }
486
606
  .och-global {
487
607
  gap: 6px;
@@ -502,6 +622,9 @@
502
622
  .och-mode-btn {
503
623
  padding-inline: 10px;
504
624
  }
625
+ .och-mode {
626
+ --och-mode-item-width: 78px;
627
+ }
505
628
  .och-tab {
506
629
  padding-inline: 10px;
507
630
  }
@@ -509,6 +632,8 @@
509
632
 
510
633
  @media (prefers-reduced-motion: reduce) {
511
634
  .och-mode-btn,
635
+ .och-mode-thumb,
636
+ .och-mode-thumb.is-ready,
512
637
  .och-tab,
513
638
  .och-repo,
514
639
  .och-pi {
@@ -25,20 +25,33 @@ export type ChromeRepoInfo = {
25
25
  inspectReady?: boolean;
26
26
  };
27
27
 
28
+ export type ChromeWorkspaceSwitcher = {
29
+ activeId: string | null;
30
+ loading: boolean;
31
+ items: Array<{
32
+ workspaceId: string;
33
+ name: string;
34
+ displayPath: string;
35
+ }>;
36
+ };
37
+
28
38
  export type ChromeModel = {
29
- mode: "operate" | "inspect";
39
+ mode: "chat" | "operate" | "inspect";
30
40
  homeHref: string;
31
41
  brand: string;
32
42
  repo: ChromeRepoInfo | null;
43
+ workspaceSwitcher: ChromeWorkspaceSwitcher | null;
33
44
  modeButtons: Array<{
34
- id: "operate" | "inspect";
45
+ id: "chat" | "operate" | "inspect";
35
46
  label: string;
36
47
  href: string;
37
48
  active: boolean;
38
49
  }>;
39
50
  context: InspectContext | null;
40
51
  freshness: boolean;
52
+ statusVisible: boolean;
41
53
  pi: { state: string; label: string; href: string; title: string };
54
+ workspaceTabsVisible: boolean;
42
55
  tabs: Array<OperatorChromeTab & { active: boolean }>;
43
56
  tabsAriaLabel: string;
44
57
  };
@@ -63,16 +76,20 @@ export function chromeStateFromHealth(body: unknown): {
63
76
  repo: ChromeRepoInfo;
64
77
  };
65
78
  export function buildOperatorChromeModel(config: {
66
- mode: "operate" | "inspect";
79
+ mode: "chat" | "operate" | "inspect";
67
80
  activeTabHref?: string | null;
81
+ chatHref?: string;
68
82
  operateHref?: string;
69
83
  inspectHref?: string;
70
84
  readinessState?: string;
71
85
  readinessHref?: string;
72
86
  readinessTitle?: string;
73
87
  repo?: ChromeRepoInfo | null;
88
+ workspaceSwitcher?: ChromeWorkspaceSwitcher | null;
89
+ statusVisible?: boolean;
74
90
  freshness?: boolean;
75
91
  context?: InspectContext | null;
92
+ onSelectWorkspace?: (workspaceId: string) => void;
76
93
  }): ChromeModel;
77
94
  export function mountOperatorChrome(
78
95
  root: HTMLElement,