@spzxg/cli-ui 0.6.2 → 0.6.6

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 (133) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +165 -19
  3. package/dist/cli-ui-embed-BAqonuoD.js +45952 -0
  4. package/dist/{cli-ui-index-BY5i3wId.js → cli-ui-index-b8wF7wrN.js} +2 -2
  5. package/dist/{cli-ui-jszip.min-m01fexHW.js → cli-ui-jszip.min-B0uLrCHg.js} +2 -2
  6. package/dist/{cli-ui-jszip.min-BZsUwI-s.js → cli-ui-jszip.min-ggP8OokP.js} +1 -1
  7. package/dist/{cli-ui-xlsx-CpWicJLT.js → cli-ui-xlsx-DEDdHrJJ.js} +1 -1
  8. package/dist/cli-ui.css +32 -1
  9. package/dist/cli-ui.js +1 -1
  10. package/package.json +17 -10
  11. package/src/board/BrowserPane.tsx +346 -115
  12. package/src/board/ChangesPane.tsx +2 -2
  13. package/src/board/CliBoard.tsx +79 -50
  14. package/src/board/FileViewer.tsx +54 -31
  15. package/src/board/FilesPane.tsx +32 -15
  16. package/src/board/PanelControls.tsx +28 -0
  17. package/src/board/blocks.tsx +5 -5
  18. package/src/board/context.ts +65 -0
  19. package/src/board/fileOps.ts +26 -3
  20. package/src/board/fileWatch.ts +94 -0
  21. package/src/board/folderDownload.ts +30 -14
  22. package/src/board/frameQuote.ts +2 -2
  23. package/src/board/panels.ts +33 -0
  24. package/src/board/textLoad.ts +9 -7
  25. package/src/board/workspace.ts +53 -14
  26. package/src/chat/CliChat.tsx +93 -40
  27. package/src/chat/Composer.tsx +44 -42
  28. package/src/chat/RunControls.tsx +99 -0
  29. package/src/chat/configuration.ts +15 -0
  30. package/src/chat/draft.ts +41 -0
  31. package/src/chat/export.ts +2 -2
  32. package/src/components.tsx +13 -0
  33. package/src/core/blocks.ts +17 -6
  34. package/src/core/callbacks.ts +8 -0
  35. package/src/core/client.ts +103 -19
  36. package/src/core/conversation.ts +4 -3
  37. package/src/core/id.ts +15 -0
  38. package/src/core/identity.ts +33 -0
  39. package/src/core/provider.tsx +31 -14
  40. package/src/core/store.ts +151 -53
  41. package/src/core/types.ts +64 -9
  42. package/src/elements.tsx +135 -29
  43. package/src/embed.ts +6 -8
  44. package/src/index.ts +24 -17
  45. package/src/layout/CliSplit.tsx +1 -1
  46. package/src/layout/split.ts +67 -30
  47. package/src/msglist/CliMsgList.tsx +19 -13
  48. package/src/operator/branchFlow.ts +35 -0
  49. package/src/operator/index.ts +9 -0
  50. package/src/operator/liveStream.ts +1 -0
  51. package/src/operator/node/AgentConnect.tsx +624 -0
  52. package/src/operator/node/AppearancePanel.tsx +35 -0
  53. package/src/operator/node/BranchHistory.tsx +67 -0
  54. package/src/operator/node/BranchNavigator.tsx +36 -0
  55. package/src/operator/node/BrowserPane.tsx +128 -0
  56. package/src/operator/node/BrowserPopup.tsx +22 -0
  57. package/src/operator/node/Chat.tsx +517 -0
  58. package/src/operator/node/CommandPalette.tsx +213 -0
  59. package/src/operator/node/Composer.tsx +287 -0
  60. package/src/operator/node/InsightsView.tsx +831 -0
  61. package/src/operator/node/Layout.tsx +190 -0
  62. package/src/operator/node/Markdown.tsx +61 -0
  63. package/src/operator/node/Modal.tsx +179 -0
  64. package/src/operator/node/NeedsYouMenu.tsx +54 -0
  65. package/src/operator/node/OnboardingWizard.tsx +250 -0
  66. package/src/operator/node/Orchestrator.tsx +634 -0
  67. package/src/operator/node/ProjectLanding.tsx +86 -0
  68. package/src/operator/node/ProjectsColumn.tsx +137 -0
  69. package/src/operator/node/ProviderAuth.tsx +561 -0
  70. package/src/operator/node/RunControls.tsx +2 -0
  71. package/src/operator/node/RunSwitch.tsx +113 -0
  72. package/src/operator/node/Services.tsx +245 -0
  73. package/src/operator/node/SessionRail.tsx +260 -0
  74. package/src/operator/node/SessionView.tsx +288 -0
  75. package/src/operator/node/SettingsView.tsx +690 -0
  76. package/src/operator/node/TaskBoard.tsx +352 -0
  77. package/src/operator/node/TaskChanges.tsx +530 -0
  78. package/src/operator/node/TaskHero.tsx +50 -0
  79. package/src/operator/node/TasksColumn.tsx +200 -0
  80. package/src/operator/node/Terminal.tsx +143 -0
  81. package/src/operator/node/Transcript.tsx +468 -0
  82. package/src/operator/node/ViewFile.tsx +79 -0
  83. package/src/operator/node/Welcome.tsx +101 -0
  84. package/src/operator/node/WorktreePrune.tsx +333 -0
  85. package/src/operator/node/agents.ts +58 -0
  86. package/src/operator/node/api.ts +40 -0
  87. package/src/operator/node/boardBackend.ts +82 -0
  88. package/src/operator/node/boardEvents.ts +22 -0
  89. package/src/operator/node/boardInteraction.ts +15 -0
  90. package/src/operator/node/boardState.ts +57 -0
  91. package/src/operator/node/boardWorkspace.ts +12 -0
  92. package/src/operator/node/branchFlow.ts +1 -0
  93. package/src/operator/node/composerDraft.ts +52 -0
  94. package/src/operator/node/fileLinks.ts +81 -0
  95. package/src/operator/node/format.ts +290 -0
  96. package/src/operator/node/github.tsx +234 -0
  97. package/src/operator/node/icons.tsx +88 -0
  98. package/src/operator/node/liveStream.ts +270 -0
  99. package/src/operator/node/modals.tsx +720 -0
  100. package/src/operator/node/navHistory.ts +70 -0
  101. package/src/operator/node/persist.ts +26 -0
  102. package/src/operator/node/protocol/agents/optIn.ts +9 -0
  103. package/src/operator/node/protocol/agents/types.ts +394 -0
  104. package/src/operator/node/protocol/approvalFailure.ts +77 -0
  105. package/src/operator/node/protocol/authFailure.ts +66 -0
  106. package/src/operator/node/protocol/customModels.ts +23 -0
  107. package/src/operator/node/protocol/events.ts +13 -0
  108. package/src/operator/node/protocol/features.ts +70 -0
  109. package/src/operator/node/protocol/internalUsage.ts +1 -0
  110. package/src/operator/node/protocol/promptLimits.ts +52 -0
  111. package/src/operator/node/protocol/storageRetention.ts +13 -0
  112. package/src/operator/node/protocol/types.ts +332 -0
  113. package/src/operator/node/protocol/usageLimit.ts +72 -0
  114. package/src/operator/node/shared.tsx +89 -0
  115. package/src/operator/node/transcriptModel.ts +129 -0
  116. package/src/operator/node/types.ts +296 -0
  117. package/src/operator/node/useGlobalEvents.ts +97 -0
  118. package/src/operator/node/useOrchestrator.ts +696 -0
  119. package/src/operator/node/usePrefs.ts +114 -0
  120. package/src/operator/node/useRecaps.ts +91 -0
  121. package/src/operator/node/useTaskStream.ts +280 -0
  122. package/src/operator.base.css +1806 -0
  123. package/src/operator.css +194 -16
  124. package/src/styles.css +49 -1
  125. package/src/ui/Markdown.tsx +7 -2
  126. package/src/ui/Popover.tsx +82 -0
  127. package/src/ui/TextBlock.tsx +3 -3
  128. package/src/ui/Transcript.tsx +17 -10
  129. package/src/ui/fileLinks.ts +6 -0
  130. package/src/ui/format.ts +1 -1
  131. package/src/ui/shared.tsx +1 -1
  132. package/src/ui/transcriptModel.ts +2 -2
  133. package/dist/cli-ui-embed-6IJ_jRVh.js +0 -41223
package/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ ## 0.6.6 — 本地候选,2026-11-05
4
+
5
+ - 唯一源码归入 `cli-task-center/packages/cli-ui`,节点与中枢在同仓库维护,兼容路径只保留软链接与转发。
6
+ - 手机低高度布局保持输入框与发送操作可达,转录溢出不遮挡引用操作;触摸控件、预览安全区和缩放/平移后的菜单边界适配。
7
+ - 分栏从手机切回桌面时重新计算百分比和最小宽度,保留用户拖动偏好与回调契约,正确分配隐藏/收起栏的空间。
8
+ - 并发渲染中的聊天操作绑定已提交会话;附件解析可取消,中文输入法组合期间不误发。
9
+ - 手机浏览器滑动不唤起键盘;点击先定位再输入。触摸选区可引用,预览读取真正响应取消,下载失败保留有效预览。
10
+ - 业务回调逐监听器隔离数据,连接释放可重入且幂等;切任务后旧传输回调与迟到读取不能污染新工作区。
11
+ - 文档附件读取前限制 10 MiB,提取内容超过 200000 字符明确拒绝;YAML 保留完整正文,不静默截断。
12
+ - 组件开发工具升级到修复版本,独立安装、完整回归与发布构建在唯一目录验证。
13
+
14
+ - 补齐 Ego/YAML 创建配置与 Provider 异步加载,支持 YAML 文档附件并保留原文;执行手册通过 browserPlaybook/browserPacing 显式登记。
15
+ - 停止后撤销未消费输入的自动续跑;保密值保留前后空格、拒绝超长值,输入提交失败可重试;多来源人工等待采用服务端汇总,兼容旧节点事件。
16
+
17
+ - 窄聊天栏按容器宽度换行标题操作区,避免桌面分栏和手机端导出/状态控件被挤出边界。
18
+ - 浏览器按任务展示多个页面,接管后可切换;页面与输入绑定 targetId/targetEpoch,切页和断线清理旧输入、画面、弹窗及复制来源。旧节点保持单页兼容。
19
+ - 节点看板输入额外校验任务与 viewer 的归属,避免向另一任务的连接发送操作。
20
+ - 修复异步新建/续派响应抢回已切换任务,以及旧任务操作错误污染当前聊天;共享 store 与受控选择均保持用户当前选择。
21
+ - 列表和聊天接受服务端结构化 `awaiting_input: true | false | null`,区分运行中等待人工、明确解除和未知状态。
22
+ - 默认中枢适配器接入原生文件事件;服务明确不支持时回退可见文件轮询,鉴权或任务不存在错误不伪装成降级成功。
23
+ - 浏览器多页协议需要同步更新节点及中枢;原生文件事件需要中枢新增代理。单独更新 npm 包不会升级生产服务。
24
+
25
+
26
+ ## 0.6.5 — 2026-11-05
27
+
28
+ - 文件预览按后端、任务和路径隔离,切换不沿用旧正文、选区或短期链接。
29
+ - 文件下载及图片、PDF、HTML、Word 的内存读取校验实际字节数,及时响应取消;ZIP 取消/失败后停止剩余读取,不保存迟到结果。
30
+ - ZIP 失败报告避让用户同名文件;`FolderResult.failedListName` 可选返回真实报告路径。
31
+ - 原生文件事件新增可选 `FileEntry.changeToken`,用于断线恢复时发现同大小、同 mtime 的改写;不是内容版本锁。
32
+ - 看板状态和自动背景原子更新后通知业务;回调内导航保持顺序,新增业务监听可恢复已停止的连接,清理期间重新订阅不进入失效记录。
33
+ - 来源任务文件的选中文字引用明确包含工作区身份,关闭自动背景也保留来源。
34
+ - 浏览器复制引用保留复制时页面来源;远端弹窗错误可重试,输入坐标使用实际显示帧,取消拖动或切换控制权清除旧按压。
35
+ - 首帧未就绪不发送鼠标输入;节点浏览器状态流显示认证、接口和临时断线错误,保留共享连接的降级恢复;自定义 browserEvents 可选提供 onError 通知。
36
+
37
+
38
+ ## 0.6.4 — 2026-11-05
39
+
40
+ - 统一 `CliMsgList`、`CliChat`、`CliBoard` 与完整 Operator 工作区;React、Web Component、embed 使用同一源码,宿主保留协议适配和服务端能力。
41
+ - 文件/浏览器/改动模块可独立关闭和重新打开,改动默认关闭;聊天文件链接可唤起看板,来源任务身份随引用与文件页签保留。
42
+ - 聊天默认附带当前文件、打开页签、最近访问与看板显示状态的元信息背景;支持取消本次附带,手动引用与任务派生保持独立。
43
+ - 新增工作区 `watch/stat/context` 及文件/监听/浏览状态业务回调;原生节点提供文件事件,旧中枢明确降级为可见文件轮询。相同尺寸和 mtime 的原生改写仍触发预览重读。
44
+ - 修复多看板抢占当前文件、迟到恢复覆盖正在使用的看板及历史丢失;重新点击已选文件可重新激活上下文。
45
+ - 修复浏览器重连、接管交还和任务切换时旧输入/动作污染新画面;网页确认弹窗等待远端确认后关闭。
46
+ - 文件监听区分永久错误、认证/限流和暂时断线;保留 WebSocket → SSE 降级,资源恰好释放一次,限制客户端跟踪元数据并准确报告不完整覆盖。
47
+ - 自定义后端文件读取增加最终大小校验和及时取消;业务订阅的文件、看板元信息彼此隔离。
48
+
49
+ 文件预览仍为只读,文件改写由 AI/服务端执行。文件事件是当前状态通知,非持久审计日志或不可变内容版本。旧中枢轮询与扫描上限见 README。此版本为本地构建包;npm 发布需 registry 登录。
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @spzxg/cli-ui
2
2
 
3
- 任务中心(cli-task-center)对话任务(`mode=conversation`)的前端组件,界面与执行节点(Operator)的对话界面一致。数据全部来自中枢。
3
+ 相互联动的三个组件,支持中枢对话和完整 Operator 节点工作区。缺省参数使用中枢协议;`operator` 参数承接节点的完整任务与 Git 工作流。两种后端的能力不同,不显示后端不支持的执行控制。
4
4
 
5
5
  | 组件 | 作用 |
6
6
  | --- | --- |
@@ -75,6 +75,23 @@ location /api/center/ {
75
75
  - **组件自己建**:`<CliChat jobId={null} newConversation={{ title, businessId }} />`,建好后通过 `job_change` 事件把 job_id 交给页面。
76
76
  - **业务后端建**(要带 callback 时):后端调 `POST /api/jobs`,前端只传 `jobId`,这样 callback 的密钥留在服务端。
77
77
 
78
+ ## 启用 Ego 与传递 YAML
79
+
80
+ 新建对话时显式配置 `browser: true`。`browserPlaybook` 是 YAML 正文,`browserPacing` 是节点每次浏览器操作前的随机等待范围:
81
+
82
+ ```tsx
83
+ const yaml = await selectedFile.text(); // 业务选择的 .yaml/.yml 文件,不传文件名或 URL
84
+ <CliChat jobId={null} newConversation={{
85
+ browser: true,
86
+ browserPlaybook: yaml,
87
+ browserPacing: { min_seconds: 1, max_seconds: 2 },
88
+ }} />
89
+ ```
90
+
91
+ 默认适配器把它们映射为创建接口 `tasks[0].browser_playbook` / `browser_pacing`;YAML 校验由任务中心和节点执行,格式不合法或缺少 `browser:true` 会显示错误。React、`CliUI.mountChat` 与 Web Component 的 `new-conversation` JSON 使用相同字段。Provider 的 `newConversation` 默认项也可在文件读取完成后更新,保持原有连接和当前选择。通过同一 Job 的“新对话”入口创建时,手册与间隔沿用首对话;已创建对话的普通消息不支持覆盖这些设置。
92
+
93
+ 加号也接受 `.yaml/.yml` 作为文本附件,保留缩进、空行和结尾换行。附件用于交给 AI 阅读,不会自动启用 Ego 或替换已登记的执行手册。浏览器密码、验证码等用户输入仍走输入卡片/浏览器接管流程。
94
+
78
95
  ## 组合使用(列表 + 对话 + 看板联动)
79
96
 
80
97
  放进同一个 `CliCenterProvider`(Web Component 写同一个 `group`),三个组件互相通信、切换时一起变:列表点哪个对话,对话和看板就切到哪个;对话里新建 / 接续出的新对话,列表跟着加上并选中、看板跟过去;对话里点文件在看板里打开。
@@ -91,12 +108,14 @@ location /api/center/ {
91
108
 
92
109
  - Provider 里的组件不要再传 `jobId` / `taskId`(列表不传 `selectedId`):传了的组件只看自己那个,不跟着切。
93
110
  - Web Component:同一个 `group`,不写 `job-id`;从外面打开某个对话给任意一个元素写 `selected-id="job_x"`,改它就一起切。
94
- - 不用 Provider 也行:页面自己串,每个组件传 `jobId` / `selectedId`,在 `onSelect`、`job_change` 里同步:
111
+ - 不用 Provider 时,完整联动仍需传同一个稳定的 `store`;仅同步 `jobId` / `selectedId` 不会共享文件打开和引用事件。页面可在 `onSelect`、`job_change` 中同步受控选择:
95
112
 
96
113
  ```tsx
97
- <CliMsgList selectedId={key} onSelect={setKey} onNew={() => setKey(null)} />
98
- <CliChat jobId={key} onEvent={(e) => e.type === "job_change" && setKey(e.key)} />
99
- <CliBoard jobId={key} />
114
+ // React 组件内;账号变化时重建 store,并取消旧账号的业务订阅。
115
+ const store = useMemo(() => createCliStore({ baseUrl: "/api/center", namespace: accountId }), [accountId]);
116
+ <CliMsgList store={store} jobIds={ids} selectedId={key} onSelect={setKey} onNew={() => setKey(null)} />
117
+ <CliChat store={store} jobId={key} onEvent={(e) => e.type === "job_change" && setKey(e.key)} />
118
+ <CliBoard store={store} jobId={key} />
100
119
  ```
101
120
 
102
121
  ## 右侧看板
@@ -126,7 +145,7 @@ location /api/center/ {
126
145
  </CliCenterProvider>
127
146
  ```
128
147
 
129
- - 页签:文件(目录、预览、下载)、改动(diff,只读)、浏览器(实时画面,接管后可直接操作)。`tabs={["files","changes"]}` 选页签。
148
+ - 页签:默认文件(目录、预览、下载)和受支持的浏览器;改动(diff,只读)默认关闭,可手动添加。`tabs={["files","changes"]}` 只设置初始打开的模块和顺序;用户仍可从「管理看板模块」打开浏览器。`availableTabs` 才限制允许使用的模块。所有模块都能单独关闭、重新打开,`tabs={[]}` 表示初始全部关闭。
130
149
  - 预览:Markdown、代码、文本、CSV、图片、PDF、HTML(沙箱 iframe)、Word(.docx,mammoth 转 HTML 放进无脚本沙箱)。其他类型下载。
131
150
  - 自动同步:实时流有进展就刷新(节流 1.5 秒),运行中每 15 秒(`pollMs`)兜底再刷一次;改过的文件标「有更新」,打开着的文件改了自动重读。
132
151
  - 没有看板时,对话自己弹窗预览(`<CliChat fileOpen="auto|board|modal|link">`)。宿主也可以 `store.openInBoard(jobId, { kind: "file", path })`。
@@ -136,7 +155,7 @@ location /api/center/ {
136
155
  - 引用到对话:文件预览、浏览器的「引用到对话」把它带进下一条消息(`store.addRef`),对话输入框上方显示、可去掉;发出时合成「看板上下文」附件。自定义页签(`extraTabs`)的 `quote` 同理——终端之类的交互以后都走这条路进对话。
137
156
  - 多个文件页签:点开的文件各占一个页签(最多 8 个,再开关掉最早的),可关闭(× 或鼠标中键),按对话记在 sessionStorage,刷新后还在。
138
157
  - 选中引用:在预览里选中文字浮出「引用到对话」(Markdown / 代码 / 文本 / 表格 / HTML / Word 及其源文件;HTML、Word 在沙箱 iframe 里,预览用 srcdoc 插一段选区小脚本报给宿主,页面自己的脚本仍不执行);在浏览器网页里复制(⌘C / Ctrl+C)后提示里也有「引用到对话」。
139
- - 正在看:打开着的文件 / 浏览器页面缺省随下一条消息带给智能体(换了再带;`autoQuoteOpenFile={false}` 关掉),单独一块「看板正在看」,缺省在输入框上方和对话里都不显示。cli-chat 的 `config.refs` 按种类控制显示:`{ viewing: true }` 显示「正在看」虚线卡片(× 这次不带),`{ selection: false }` 不显示选中引用,`true` / `false` 全部。状态在 `store.getState().viewing`。
158
+ - 被动浏览背景:每条消息自动附带当前文件、仍打开的页签和最近40个实际访问文件的元信息;手机回聊天/收起看板后仍保留,并标记收起状态。输入框可查看摘要、取消本次附带;成功发送后恢复默认。不会自动读取文件正文,也不替换手动引用。`CliChat passiveContext={false}`/`CliBoard autoQuoteOpenFile={false}` 关闭;节点 `board={{autoContext:false}}`。`workspace.context()` 读取完整浏览快照,`config.refs` 继续控制旧式引用的显示。
140
159
  - 浏览器弱网:操作没送达时提示(不自动重发,免得点两次);接管时发了操作 8 秒画面没变化提示并给「重连画面」;按住鼠标切走窗口自动补发松开;地址栏自动补 `https://`。
141
160
  - 数据都经中枢:`/api/jobs/:id/board`、`/files`、`/files/raw/<路径>`、`/diff`、`/browser`(+ `events` / `frames` / `input`)。
142
161
  - 链路、交互、故障与重试的设计见 [BOARD-DESIGN.md](BOARD-DESIGN.md)。
@@ -232,31 +251,158 @@ Agent 回复里指向本地文件的链接(`report.md`、`src/a.ts:12`、`file
232
251
 
233
252
  ## 开发
234
253
 
235
- 源码在 **operator-oss/packages/cli-ui**(这里)。三个工程的关系:
254
+ 所有源码统一在 **`/Users/spzhong/cli-task-center`**,后续只在这里维护:
236
255
 
237
- | 工程 | 放什么 | 和组件的关系 |
238
- | --- | --- | --- |
239
- | `operator-oss` | 执行节点(Operator)+ **组件源码** `packages/cli-ui` | 改组件都在这里改;组件的样式从同仓库的 `app/globals.css` 同步(`css:sync`) |
240
- | `clawbizx` | 业务协同工程,统一发布 `@spzxg/*` 包 | `packages/cli-ui` 是指向 `../../operator-oss/packages/cli-ui` 的链接,`scripts/publish-shared-packages.sh` 从这里发布到 npm |
241
- | `cli-task-center` | 中枢(组件的数据都来自它) | 组件的使用文档在中枢 API 文档的「前端组件」页签(`backend/public/api.html`) |
256
+ | 目录 | 维护内容 |
257
+ | --- | --- |
258
+ | `packages/cli-ui` | 三组件、完整工作区界面、共享状态和适配;唯一组件实现 |
259
+ | `operator` | 配套执行节点、API、runner、浏览器与宿主;`packages/cli-ui` 仅是根组件的兼容软链接 |
260
+ | `backend` | 中枢调度、鉴权、代理、业务回调与 `public/api.html` 接入文档 |
261
+ | `examples/production-workbench` | 消费实际分发包的薄宿主与生产接口联调示例 |
242
262
 
243
- 两个仓库要并排放在同一个目录下(`~/operator-oss`、`~/clawbizx`),链接才有效。组件有自己的依赖,不和 Operator 共用:
263
+ 不再要求旧仓库并排放置。Operator 用 `file:../packages/cli-ui` 依赖根组件,先在组件目录运行 `npm ci`,再在 `operator` 运行 `npm ci`;React 保持宿主 peer dependency。旧外部发布脚本和链接已不作为维护入口。
244
264
 
245
265
  ```bash
246
- cd operator-oss/packages/cli-ui
266
+ cd cli-task-center/packages/cli-ui
247
267
  npm install # 第一次
248
268
  npm test # 测试
249
269
  npm run lint # 类型检查
250
270
  npm run demo # 假中枢 + 演示页 http://localhost:12790(?mode=chat / ?mode=wired / elements.html;看板用 e2e-local.sh 的 ?mode=board,单独集成看 blocks.html?job=…,先 build:embed)
251
- npm run css:sync # Operator 改了样式后重新同步
271
+ npm run css:sync # 从 src/operator.base.css 生成作用域样式
252
272
  npm run build:embed # 第三方一体化产物 dist/cli-ui.js + cli-ui.css
253
273
  bash demo/e2e-local.sh # 连真实 center 联调:本地 center + 假节点 + 一次性本地库,演示页代理过去
254
274
  bash demo/e2e-local.sh stop
255
275
  bash demo/e2e-real.sh # 真实整条链路:本地 center + 源码跑的真实节点 + 本机 ego lite(看板浏览器、故障演练;不跑智能体)
256
276
  bash demo/e2e-real.sh stop
257
277
 
258
- # 发布(在 clawbizx 里)
259
- cd clawbizx && bash scripts/publish-shared-packages.sh
278
+ # 发布前打本地候选(在 packages/cli-ui 中;npm 发布由维护者执行)
279
+ npm pack
280
+ ```
281
+
282
+ 演示使用 `demo/mock-center.mjs` 的内存数据。Operator 的 Next 构建和 Docker 镜像现已包含组件包;不要恢复旧的 packages 全目录排除规则。
283
+
284
+
285
+ ## 完整 Operator 工程与唯一维护位置
286
+
287
+ ```tsx
288
+ "use client";
289
+ import { OperatorWorkspace } from "@spzxg/cli-ui/operator";
290
+ import "@spzxg/cli-ui/operator.css";
291
+ import "@spzxg/cli-ui/styles.css";
292
+ export default function App() { return <OperatorWorkspace />; }
260
293
  ```
261
294
 
262
- 演示用的是 `demo/mock-center.mjs` 里的内存数据,不要把演示页指向生产中枢。Operator 的 `tsconfig.json`、`.dockerignore` 排除了 `packages/`,组件不进 Operator 的构建和镜像。
295
+ `OperatorWorkspace` 使用 `CliMsgList`、`CliChat`、`CliBoard` 的 `operator` 参数组合,三者由同一个 `useOrchestrator` 控制项目、选中任务、运行状态、配置、分支和事件连接。宿主只保留路由、服务端和以上入口。节点的完整客户端实现位于 `src/operator/node`;根工程原有 `app/orchestrator/*`、Markdown、图标、终端和 Git 面板路径均为兼容导出,不再维护另一份界面。
296
+
297
+ 直接使用 `operator` 参数时,宿主负责传入同一个项目/任务控制器及回调,并把三个组件放入 `.cli-ui` 容器,加载上述样式。完整工作区需要 Operator 的 `/api/*`、`/live` 和 PTY 服务;它不是脱离节点服务器的离线演示。
298
+
299
+ | 能力 | 中枢默认模式 | Operator 模式 |
300
+ | --- | --- | --- |
301
+ | 列表、对话、文件/浏览器看板联动 | 同一 `CliCenterProvider`/store | 同一工作区控制器和多路复用实时连接 |
302
+ | 附件、长文本、引用 | 文档转文字与看板/消息引用 | 图片/文本上传、消息引用、草稿与来源恢复 |
303
+ | 模型、推理、权限/规划 | 不伪造中枢没有提供的配置接口 | 能力列表驱动,等待真实 PATCH 成功再允许发送 |
304
+ | `@` 多来源分支 | 中枢协议目前未提供独立 Git 派生接口 | 同项目已完成任务,每个来源一个独立 worktree/分支,固定源提交 |
305
+ | 源对话结尾 → 分支选择 → 子对话 | 不虚构分支数据 | 支持横向切换和递归派生,来源历史只读 |
306
+ | Git 同步、合并、PR、冲突修复 | 只读改动看板 | 保留原完整工作流 |
307
+ | 看板/列表、依赖、自动启动、建议、回顾、设置、认证、用量、终端和服务 | 由宿主业务提供 | 保留在完整工作区中 |
308
+
309
+ `src/operator.base.css` 是共享样式源,`src/operator.css` 是 `css:sync` 的生成结果;根工程 `app/globals.css` 只导入包的样式。迁移与备份清单见仓库的 `docs/CLI_UI_MERGE.md`。
310
+
311
+ npm 已于 2026-11-05 核验发布 `0.6.5`,不能覆盖重发。本地此次候选版本为 `0.6.6`,需要通过组件测试、嵌入构建、真实工程构建和浏览器回归,再发布新的补丁版本;不要运行会连带发布其他共享包的批量脚本。
312
+
313
+
314
+ ### 文件、对话与浏览器看板联动
315
+
316
+ ```tsx
317
+ // 只设置初始可见状态;用户仍能手动打开文件、改动等模块。
318
+ <OperatorWorkspace board={{ tabs: ["browser"], defaultTab: "browser" }} />
319
+ // 中枢组件用相同规则;三个组件放在同一个 Provider 中。
320
+ <CliBoard tabs={["browser"]} defaultTab="browser" />
321
+ // 只有明确限制能力时才设置 availableTabs。
322
+ <CliBoard tabs={["browser"]} availableTabs={["browser", "files"]} />
323
+ ```
324
+
325
+ Web Component 对应 `tabs="browser"`、`available-tabs="browser,files"`;`tabs=""` 表示初始全部关闭。默认配置与用户手动开关分开,模块偏好按任务/配置保存在会话存储中。
326
+
327
+ 对话里的本地文件链接及文件形态的行内代码会打开右侧文件预览;看板收起或在手机上时自动展开/切换。Ctrl/⌘ 点击仍可独立打开。来源历史文件使用来源任务的文件接口,不切换当前任务或分支。文件、选区、网页和网页复制文字可引用回同一个草稿,保留原有输入;手机引用后返回对话。
328
+
329
+ 浏览器关闭页签只隐藏模块和断开画面连接,不结束浏览器任务;重新打开后连接当前状态。「关闭浏览器」才调用实际关闭接口。新浏览器交接能唤起隐藏的模块;旧历史交接、已经消费的打开请求和其他任务的事件不会反复唤起。浏览器模块与独立窗口共用画面/输入实现,保留触摸、键盘/输入法、网页弹窗、剪贴板、重连、接管交还,并保留节点登录配置、弹出窗口和在节点屏幕显示操作。
330
+
331
+ ### v0.6.3 历史验收(当前版本见 CHANGELOG)
332
+
333
+ 组件 308 项测试、lint、嵌入构建,以及宿主生产构建已通过;宿主 873 项测试、24 项常规真实页面回归和 1 项真实 ego lite 看板完整流程通过。宿主默认跳过的 17 项底层浏览器/playbook 环境测试,本轮未重跑;此前单独执行的记录保留在验收包中。未使用付费模型账号测试,不把模拟驱动配置测试等同于所有真实 CLI 环境验证。
334
+
335
+ 该版本已在本地准备,当前执行账户未登录 npm,尚未发布。旧 UI 已归档,47 个兼容入口由宿主 `npm run check:components` 检查;今后 UI 改动只在组件包中维护。
336
+
337
+
338
+ ### 维护前提:组件为唯一标准
339
+
340
+ 开发、修复和发布均以三个公开组件为单位。React/Web Component/embed 统一调用 `src/components.tsx`;文件预览和浏览器独立窗口同样在本包维护。旧界面只留备份和转发,不再改旧工程实现。
341
+
342
+ 宿主普通 `dev`、`build`、`test` 会先执行来源审计:错误转发、新增包外 UI/样式、组件反向引用宿主/备份、分发入口绕过组件都会失败。审计自身有 7 项回退回归;本包的具体维护规则见仓库内 `packages/cli-ui/AGENTS.md`。
343
+
344
+
345
+ ### 高可用接入与恢复
346
+
347
+ 配置保存锁、上传中断恢复和结束确认均绑定任务/会话身份,切走再回来不会提前发送或误操作其他会话。看板正常断流自动重连,主动关闭停连;卸载最后实时消费者会释放连接,卸载文件模块取消 ZIP 下载。宿主事件回调异常记录在控制台,不能阻断组件终态更新或其他通知。
348
+
349
+ Web Component 组内唯一配置源的 URL、token、line、namespace 和新会话配置会完整继承,包括晚挂载或配置旋转;明确不同凭据各用独立 store。继承配置出现歧义时显示错误,调用方需要补齐连接属性,不能依赖“第一个组件”的身份。
350
+
351
+ 标准连接按身份指纹隔离草稿、文件页签及当前 UI,不把原始 token 写入存储键。同配置刷新可恢复,换凭据后旧内容不会自动附到新身份。Cookie 鉴权宿主应提供按账号区分的 namespace,并在账号切换后重建 Provider/client。自定义 client 对象应保持稳定;不同对象保守隔离,不能只凭 URL 推断其隐藏的认证身份。历史没有身份标签的草稿保留在原分区,不自动搬入新增的认证分区。
352
+
353
+ 完整问题与验证边界见仓库 `docs/CLI_UI_RELIABILITY.md`。本轮未进行生产长期浸泡、持续并发容量或付费模型账号验收;部署可用率需结合实际环境监测。
354
+
355
+
356
+ ### 文件通知 → 云端读取 → 业务交付
357
+
358
+ ```tsx
359
+ <CliCenterProvider store={store}
360
+ onFilesChange={event => handleChanges(store.workspace(event.jobId), event)}
361
+ onFilesWatch={status => showWatchStatus(status)}>
362
+ <CliMsgList /><CliChat /><CliBoard />
363
+ </CliCenterProvider>
364
+ ```
365
+
366
+ 也可只在 `CliBoard` 上监听 `onFilesChange`;或无 UI 地订阅:
367
+
368
+ ```ts
369
+ const ws = store.workspace("job_x#task_y");
370
+ const stop = ws.watch(async event => {
371
+ for (const change of event.changes) {
372
+ if (change.kind === "deleted") { removeBusinessFile(change.path); continue; }
373
+ const info = await ws.stat(change.path);
374
+ const blob = await ws.readFile(change.path); // 也可 readText()
375
+ receiveBusinessFile(info, blob);
376
+ }
377
+ }, { onStatus: status => showWatchStatus(status) });
378
+ // 业务生命周期结束时 stop()。
379
+ const view = ws.context(); // current / opened / history / visible / sourceId
380
+ ```
381
+
382
+ 上述业务函数由集成方实现,组件不会自动上传到外部服务。通知是当前状态变化,读取可能遇到后续改写/删除,应处理错误与密集通知;不能将 revision 当成不可变内容版本锁。
383
+
384
+ 节点使用 `createOperatorWorkspace(taskId)`(从 `@spzxg/cli-ui/operator` 导入),或 `<OperatorWorkspace board={{onFilesChange, onFilesWatch}} />`。接口包含 watch/stat/readText/readFile/context/open。`onBoardContextChange` 提供浏览状态;它与文件内容变化分开。
385
+
386
+ Web Component 发出 `cli-files-change`、`cli-files-watch`、`cli-board-context`,detail 与 React 事件一致;也可 `el.workspace(id).watch(...)`。通用 `cli-event` 会包含同类事件,不要重复处理两个入口。`watch-files="false"` 关闭自动订阅,`passive-context="false"` 关闭聊天自动背景。
387
+
388
+ 事件含 `jobId`、`changes[{kind,path,file?,previous?}]`、`revision?`、`mode`、`coverage`、`complete`;创建/修改/删除分别为 created/modified/deleted,初始快照不冒充全部新建。多个组件与业务监听共享连接,最后取消时释放;关闭模块不会关闭会话持有的订阅。
389
+
390
+ 节点支持实际工作区文件事件(含隐藏业务文件,排除Git/Operator内部状态与symlink),经 `/live` 复用。默认中枢适配器通过 `GET /api/jobs/:id/files/events?task=...` 接收文件事件,需要中枢和节点同时部署支持此协议的版本。旧中枢缺少路由或服务明确返回 `501 file_watch_unsupported` 时,降级为约15秒目录快照比对:`mode=poll, coverage=listed-files, complete=false`,不保证隐藏项/瞬时变化/同metadata改写;任务不存在、鉴权失败和代理异常不会冒充正常降级。降级在当前订阅期间保持,升级服务后重新挂载页面即可重新探测事件能力。原生清单默认上限100000项,不完整/异常会明确报告resync;精准路径事件不受初始清单截断遮蔽。完整协议与业务接入见仓库 `docs/CLI_UI_BOARD_FLOW.md`。
391
+
392
+ 列表和聊天可消费中枢任务摘要/实时 task 的可选 `awaiting_input`:`true` 表示节点确认需要人工处理(含浏览器验证码和输入卡片),`false` 表示已确认不等待,`null` 或缺省表示没有有效观测。正在执行的回合也可能需要人工处理,此时显示“需要你处理”,不会把任务误标为完成或暂停。中枢升级后从已有节点对账取得此状态;旧中枢仍兼容原有提问状态。新建/接续的迟到响应与旧操作报错不会抢走用户已切换到的任务。
393
+
394
+ ### v0.6.4 接入加固
395
+
396
+ 多个看板按最近实际操作选择当前文件,历史/远程 metadata 同步不抢占活动看板。文件和浏览状态的业务事件使用独立副本;监听可区分永久错误、认证/限流和暂时断线,保留 WebSocket → SSE 恢复。客户端文件元信息跟踪上限为 100000;超限明确 `complete=false`,完整且未超限快照才恢复。
397
+
398
+ `workspace.readFile()` 对自定义后端也校验实际字节数并及时响应取消,后端仍应正确实现 AbortSignal 以释放内部资源。浏览器重连、接管交还和切换任务不等待或重放旧会话输入。当前看板为只读预览,文件编辑由 AI/服务端执行,再通过事件刷新和交付给业务方。
399
+
400
+ 本地候选版本 `0.6.6`,更新记录见随包 `CHANGELOG.md`。本轮验收记录见仓库 `docs/CLI_UI_UNIFIED_CANDIDATE_2026-11-05.md`;本地打包不等于 npm 或生产服务已更新。
401
+
402
+ ### v0.6.5 文件和业务交付加固
403
+
404
+ 文件预览按 backend/任务/路径隔离;下载和预览读取检查实际字节数,取消 ZIP 不保存迟到结果。部分失败时 `zip()`/`downloadFolder()` 的可选 `failedListName` 返回实际报告名,避让同名用户文件。
405
+
406
+ 原生文件通知的可选 `FileEntry.changeToken` 用于重连对账,可识别同大小并恢复 mtime 的改写;需同步部署支持该字段的节点服务端。它不是不可变内容版本或审计日志。
407
+
408
+ 看板与自动背景一起更新后通知业务,回调内继续导航保持顺序;显式选区引用携带来源任务身份。浏览器复制引用固定复制时页面,取消拖动、控制权切换、弹窗错误和异步帧解码均保持正确状态。