@spzxg/cli-ui 0.6.6 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -1
- package/README.md +90 -21
- package/dist/cli-ui-embed-Be9_d9jB.js +49691 -0
- package/dist/{cli-ui-index-b8wF7wrN.js → cli-ui-index-CzNfiynu.js} +2 -2
- package/dist/{cli-ui-jszip.min-B0uLrCHg.js → cli-ui-jszip.min-BL0mSekN.js} +2 -2
- package/dist/{cli-ui-jszip.min-ggP8OokP.js → cli-ui-jszip.min-DjCIAfse.js} +1 -1
- package/dist/{cli-ui-xlsx-DEDdHrJJ.js → cli-ui-xlsx-CscI4xk0.js} +1 -1
- package/dist/cli-ui.css +1 -1
- package/dist/cli-ui.js +1 -1
- package/package.json +3 -1
- package/src/board/CliBoard.tsx +128 -100
- package/src/board/FileViewer.tsx +259 -132
- package/src/board/FilesPane.tsx +129 -40
- package/src/board/HtmlReadingPreview.tsx +52 -0
- package/src/board/MarkdownPreview.tsx +134 -0
- package/src/board/PanelControls.tsx +19 -7
- package/src/board/fileKind.ts +138 -0
- package/src/board/fileOps.ts +9 -2
- package/src/board/fileScope.ts +29 -0
- package/src/board/fileSync.ts +343 -0
- package/src/board/fileSyncCache.ts +250 -0
- package/src/board/fileSyncProcessor.ts +71 -0
- package/src/board/fileSyncQueue.ts +56 -0
- package/src/board/fileSyncTransport.ts +85 -0
- package/src/board/fileWatch.ts +177 -76
- package/src/board/folderDownload.ts +39 -5
- package/src/board/frameQuote.ts +10 -8
- package/src/board/htmlReading.ts +148 -0
- package/src/board/textLoad.ts +14 -39
- package/src/board/useBoardUpload.tsx +51 -0
- package/src/board/useBoardVisibility.ts +35 -0
- package/src/board/workspace.ts +38 -6
- package/src/chat/CliChat.tsx +121 -51
- package/src/chat/Composer.tsx +54 -22
- package/src/chat/GroupChat.tsx +113 -0
- package/src/chat/RunControls.tsx +143 -46
- package/src/chat/draft.ts +12 -4
- package/src/chat/useExecutionConfig.ts +93 -0
- package/src/components.tsx +1 -1
- package/src/core/blocks.ts +2 -1
- package/src/core/client.ts +65 -61
- package/src/core/config.ts +6 -2
- package/src/core/documentUpload.ts +196 -0
- package/src/core/execution.ts +24 -0
- package/src/core/store.ts +81 -20
- package/src/core/types.ts +3 -1
- package/src/index.ts +4 -0
- package/src/msglist/CliMsgList.tsx +9 -2
- package/src/operator/node/Chat.tsx +11 -9
- package/src/operator/node/Composer.tsx +103 -75
- package/src/operator/node/Orchestrator.tsx +1 -1
- package/src/operator/node/SessionRail.tsx +71 -32
- package/src/operator/node/SessionView.tsx +31 -28
- package/src/operator/node/Transcript.tsx +21 -9
- package/src/operator/node/boardBackend.ts +0 -19
- package/src/operator/node/boardEvents.ts +21 -3
- package/src/operator/node/boardState.ts +18 -1
- package/src/operator/node/boardWorkspace.ts +4 -1
- package/src/operator/node/composerDraft.ts +6 -2
- package/src/operator/node/format.ts +4 -2
- package/src/operator/node/liveStream.ts +14 -2
- package/src/operator/node/useTaskStream.ts +3 -1
- package/src/operator.base.css +150 -43
- package/src/operator.css +150 -43
- package/src/styles.css +253 -39
- package/src/ui/Markdown.tsx +2 -2
- package/src/ui/Popover.tsx +25 -12
- package/src/ui/QueuedMessages.tsx +69 -0
- package/src/ui/ReferenceCard.tsx +28 -0
- package/src/ui/TextBlock.tsx +6 -4
- package/src/ui/Transcript.tsx +20 -10
- package/src/ui/UploadProgress.tsx +46 -0
- package/src/ui/WorkspaceDrawer.tsx +64 -0
- package/src/ui/WorkspaceTabs.tsx +60 -0
- package/src/ui/format.ts +3 -1
- package/src/ui/reference.ts +40 -0
- package/src/ui/useChatScrollbar.ts +29 -0
- package/src/ui/useComposerAutosize.ts +54 -0
- package/dist/cli-ui-embed-BAqonuoD.js +0 -45952
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.6.
|
|
3
|
+
## 0.6.8 — 本地候选,2026-11-06
|
|
4
|
+
|
|
5
|
+
- 普通 `CliChat` 默认展示附件加号、执行类型和智能体入口,支持 `fileUpload`、`executionMode`、`agentSelector` 显式关闭;Operator 入口同步遵守配置。控件复用同一二级菜单,右侧只显示智能体名称。
|
|
6
|
+
- 发送与停止统一为 44px 正圆,仅显示图标;提交、停止、排队、禁用、悬停和键盘焦点状态一致,运行中空草稿仅显示停止。
|
|
7
|
+
- 新增执行配置读取/保存适配,首轮和同工作区新对话携带设置;配置按对话隔离,保存完成前阻止发送,冲突或失败保留草稿并支持重新读取。旧服务明确显示能力缺失,保留原有聊天。
|
|
8
|
+
- 配套中枢保存独立执行配置和并发版本,节点原子应用智能体、账号、模型、推理与权限;新建、续聊、重试和远端重建沿用配置。启用此链路需要配套中枢迁移和节点升级,组件 npm 发布不等于服务端已部署。
|
|
9
|
+
|
|
10
|
+
## 0.6.7 — 2026-11-05
|
|
11
|
+
|
|
12
|
+
- 大文件HTML默认原样预览,完整重组当前修订;读取或排版期间可主动切换分段阅读,排版12秒未就绪提示切换。512KiB首段读取仅用于可选分段阅读、Markdown和源码;HTML分段只保留当前页的静态正文,翻页不重下已读内容。Markdown按16Ki字符和结构预算逐批排版,近视口挂载,表格续页保留表头、代码不做昂贵高亮。小文档仍即时显示。增加暂停/继续、片段异常原文回退与HTML排版状态;修复HTML首部伪标签导致策略插入错误和正则回溯卡顿。极端iframe排版阻塞时提示可能延迟,不承诺计时器能强制中断渲染。
|
|
13
|
+
|
|
14
|
+
- `CliChat` 增加可选群消息适配:按条显示发言人,所有输入经宿主统一发送;按账号/群组隔离草稿,并消费同一 store 中明确授权的看板引用,失败保留正文并恢复引用。未传 `group` 的单 AI、中枢和 Operator 分支保持原有能力。
|
|
15
|
+
|
|
16
|
+
- 完善大文件多轮修订与弱网追赶:失败期间已校验块跨修订复用,手动刷新只核对当前文件且不借用旧请求;修复冷却期和最后失败期间丢失轮末事件的问题,保留一次待同步事件,仍不启用轮询。多文件暂时故障不会被另一文件的永久错误遮蔽,遵守最长Retry-After。修复HTML加载中切换源码后刷新按钮无法恢复的问题。
|
|
17
|
+
|
|
18
|
+
- 补强文件同步故障恢复:浏览器缓存停滞有截止并降级、轮末检查避开旧请求及迟到预览、损坏重复块只修复缺失内容;权限恢复可重新加载,旧订阅重复清理不影响新订阅。配套节点上传半块支持同会话恢复,并安全回收崩溃残留;中枢附件认领保护已提交的业务结果。
|
|
19
|
+
|
|
20
|
+
- 增加客户端与配套中枢/节点文件请求有界队列、排队超时、慢响应容量占用及取消清理;正文组装、哈希、上传和快照构建分别限并发,同文件请求合并。暂时故障按有限预算和随机退避恢复,遵守Retry-After;自动事件不重置重试预算,耗尽后等待真实事件,不启用周期轮询。快照读取期间保护缓存块,修复旧修订损坏误删新修订的问题。容量与验证边界见README及仓库并发验收记录。
|
|
21
|
+
|
|
22
|
+
- 文件同步取消全部周期轮询:复用聊天每轮结束与恢复事件核对已打开文件,普通输出不触发;打开、手动刷新和回到前台仍走增量链路。并发事件合并补查,多文件按已预览范围串行同步,单文件失败隔离;独立宿主可在其流结束时调用工作区 refresh。图片/PDF短链也改为按需续签,不留空闲定时器。
|
|
23
|
+
|
|
24
|
+
- 看板加号与Chat统一支持现有类型原件上传:HTML/Markdown100MiB,其余类型10MiB;显示实际字节进度、校验、取消与重试。看板只保存并打开当前任务文件,Chat在点击发送时才要求AI先读附件;未绑定工作区时仅Chat暂存。
|
|
25
|
+
- 工作区新增「输入文件」分页入口,关闭页签后可重新找到原件;节点执行权限只开放本任务输入目录,计划模式保持只读,预览与Agent编辑同一原件。
|
|
26
|
+
- HTML/Markdown 原件支持100MiB分片上传与哈希校验,中枢首条消息支持暂存、认领后向节点传送原件,消息只携带文件引用。
|
|
27
|
+
- 文件打开、刷新与重复修订使用短HTTP、内容分块和IndexedDB持久缓存,仅请求缺失块;修复首部/中间改写被尾部重叠误判的问题,拒绝混合修订和越权缓存展示。
|
|
28
|
+
- 文件通知改为按当前可见/显式订阅范围短请求查询;目录200项分页与至多80行窗口显示,取消递归全树自动读取。工作区SDK新增listPage与watch的paths/dirs选项。
|
|
29
|
+
- Markdown、HTML分段阅读与源码按需读取;HTML原样预览完整修订安全重组,选区引用携带来源修订。此能力需配套升级中枢及独立节点,不代表npm或生产已发布。
|
|
30
|
+
|
|
31
|
+
- 自动看板背景默认随消息带入,移除输入区重复的背景摘要和勾选行,保留手动引用与宿主关闭配置。
|
|
32
|
+
|
|
33
|
+
- 智能体选择精简为 Codex、Claude、Grok、PI,模型与推理设置分级展示;输入框仅显示智能体名称,保留自动执行、计划模式等权限选项。
|
|
34
|
+
- 输入框默认两行、最多八行,统一附件、权限与智能体弹窗;消息排队置于输入框上方,移除底部快捷键提示,将“新上下文”收进加号菜单。
|
|
35
|
+
- 引用统一为可展开、可移除的紧凑卡片,保留原文和来源任务;改善发送后的滚动定位与手机引用操作。
|
|
36
|
+
- 看板使用“工作区”名称,移除历史时钟和多余信息栏,文件操作收进更多菜单;优化文件导航、选择引用、错误重试及窄屏预览。
|
|
37
|
+
- 弱化聊天、看板与正文分割线,消除看板收起时的重复边框,保留选中、焦点和错误反馈。
|
|
38
|
+
- 右侧看板收起或未集成时,桌面顶部切换对话、工作区、浏览器和已打开文件;手机使用右侧工作区抽屉,支持关闭、遮罩和 Esc 返回。页签跟随当前对话,切换布局保留草稿、附件及打开的文件。
|
|
39
|
+
- 正文、输入框与排队消息使用一致列宽:侧栏展开时充分利用中间区域,两侧收起时宽屏居中、最大约半屏;手机和窄容器保留紧凑边距。
|
|
40
|
+
- 删除看板中重复的文件信息栏与工作区标题栏,文件更多操作和目录打包入口并入页签栏;空目录仍可返回上一级,放大预览与独立弹窗保留标题。
|
|
41
|
+
|
|
42
|
+
## 0.6.6 — 2026-11-05
|
|
4
43
|
|
|
5
44
|
- 唯一源码归入 `cli-task-center/packages/cli-ui`,节点与中枢在同仓库维护,兼容路径只保留软链接与转发。
|
|
6
45
|
- 手机低高度布局保持输入框与发送操作可达,转录溢出不遮挡引用操作;触摸控件、预览安全区和缩放/平移后的菜单边界适配。
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @spzxg/cli-ui
|
|
2
2
|
|
|
3
|
-
相互联动的三个组件,支持中枢对话和完整 Operator 节点工作区。缺省参数使用中枢协议;`operator` 参数承接节点的完整任务与 Git
|
|
3
|
+
相互联动的三个组件,支持中枢对话和完整 Operator 节点工作区。缺省参数使用中枢协议;`operator` 参数承接节点的完整任务与 Git 工作流。输入框默认显示附件、执行类型和智能体;后端缺少配置能力时明确说明并禁用设置,仍可按原有默认配置聊天。
|
|
4
4
|
|
|
5
5
|
| 组件 | 作用 |
|
|
6
6
|
| --- | --- |
|
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
## 快速开始
|
|
14
14
|
|
|
15
|
+
0.6.8 的普通 `CliChat` 默认包含「+、执行类型、智能体」和圆形图标发送按钮。AI 回复期间显示停止按钮,输入补充消息时可以排队。可按需显式关闭:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<CliChat config={{ composer: { fileUpload: false, executionMode: false, agentSelector: false } }} />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`createCenterClient` 自动对接配套中枢的 `GET /api/execution-config`、`GET/PATCH /api/jobs/:id/execution-config?task_id=...`。升级时先在中枢执行随仓库提供的 Prisma migration,再部署支持原子执行配置的节点和中枢。组件包本身不会迁移数据库。配置保存只适用于普通对话;已有一次性任务的暂停/继续保持原协议。旧中枢可以继续聊天,但无法使用新配置选择。
|
|
22
|
+
|
|
23
|
+
自定义 `ConversationBackend` 实现 `getExecutionConfig`、`setExecutionConfig` 即可使用默认菜单,无需自建 `composerToolbar`。能力列表由服务端返回,不在组件中写死模型或权限。新对话选择通过 `NewConversationOptions.executionConfig` 随首轮提交;自定义 `createConversation(text, options)` 回调需转发第二个参数中的设置。宿主提供的 `group` 是多发言人群聊,执行目标仍由群适配器管理。
|
|
24
|
+
|
|
15
25
|
```tsx
|
|
16
26
|
import { CliChat, CliMsgList } from "@spzxg/cli-ui";
|
|
17
27
|
import "@spzxg/cli-ui/styles.css";
|
|
@@ -63,7 +73,7 @@ location /api/center/ {
|
|
|
63
73
|
|
|
64
74
|
## 数据怎么流转
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
**缺省中枢适配不依赖 callback,也不依赖业务系统。** 它在浏览器里直接和中枢收发:
|
|
67
77
|
|
|
68
78
|
- **发消息**:新对话 `POST /api/jobs`(`mode: "conversation"`),之后每条 `POST /api/jobs/:id/messages`。
|
|
69
79
|
- **收消息**:`GET /api/jobs/:id/stream`(SSE 长连接)推送 Agent 的输出、工具调用、提问和状态变化。
|
|
@@ -118,6 +128,24 @@ const store = useMemo(() => createCliStore({ baseUrl: "/api/center", namespace:
|
|
|
118
128
|
<CliBoard store={store} jobId={key} />
|
|
119
129
|
```
|
|
120
130
|
|
|
131
|
+
## 可选群消息适配
|
|
132
|
+
|
|
133
|
+
React 宿主可给同一个 `CliChat` 传 `group`,复用共享消息、输入框和引用交互。宿主提供消息并接收唯一的 `onSend`;正文中的多个 `@` 不会在组件内分流。每条消息的 `actor` 指定实际发言人;不传 `group` 时继续使用原有中枢/Operator 能力。
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
<CliChat store={store} group={{
|
|
137
|
+
scopeKey: `${accountId}:${jobId}`,
|
|
138
|
+
messages: [{ id: "m1", role: "assistant", content: "我来记录并协调。",
|
|
139
|
+
actor: { id: secretaryTaskId, name: "我的秘书" } }],
|
|
140
|
+
onSend: sendGroupMessage,
|
|
141
|
+
referenceKeys: [`${jobId}#${secretaryTaskId}`],
|
|
142
|
+
}} />
|
|
143
|
+
<CliBoard store={store} jobId={jobId} taskId={secretaryTaskId}
|
|
144
|
+
readOnly quoteToChat autoQuoteOpenFile={false} />
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`scopeKey` 应包含账号和群组身份,用于隔离草稿;发送失败保留当前正文与引用,切换群组时临时消息引用重置。群聊和看板使用同一个稳定 `store`,`referenceKeys` 只列出当前群允许引用的成员对话键;看板引用随下一条消息发送,失败恢复到原键。可选 `onOpenFile(path, message)` 沿用共享 Markdown 的本地文件链接与行内路径解析,宿主核对 `message.actor.id` 的授权后打开该成员的 `CliBoard`;用户消息和无明确发言人的文件不自动猜测工作区。群适配自身不打开单任务转录流,鉴权、消息订阅和秘书协调由宿主完成。`GroupChatAdapter`、`GroupChatMessage`、`GroupChatReference` 类型可从包入口导入。
|
|
148
|
+
|
|
121
149
|
## 右侧看板
|
|
122
150
|
|
|
123
151
|
核心是两块,都能单独放到任何地方(React、Web Component、无需构建的一体化 JS):
|
|
@@ -147,23 +175,24 @@ const store = useMemo(() => createCliStore({ baseUrl: "/api/center", namespace:
|
|
|
147
175
|
|
|
148
176
|
- 页签:默认文件(目录、预览、下载)和受支持的浏览器;改动(diff,只读)默认关闭,可手动添加。`tabs={["files","changes"]}` 只设置初始打开的模块和顺序;用户仍可从「管理看板模块」打开浏览器。`availableTabs` 才限制允许使用的模块。所有模块都能单独关闭、重新打开,`tabs={[]}` 表示初始全部关闭。
|
|
149
177
|
- 预览:Markdown、代码、文本、CSV、图片、PDF、HTML(沙箱 iframe)、Word(.docx,mammoth 转 HTML 放进无脚本沙箱)。其他类型下载。
|
|
150
|
-
-
|
|
151
|
-
-
|
|
178
|
+
- 自动同步:每轮聊天流结束时,用短 HTTP 检查当前看板已打开文件与可见目录;内容变化后只补缺失块。打开文件、手动刷新、回到前台和网络恢复时也会检查。没有运行中或空闲周期轮询;`pollMs`、`fileWatchIntervalMs` 仅保留参数兼容,不再安排定时请求。后台只同步实际读过的预览范围,未打开文件不预取正文。
|
|
179
|
+
- 同一 `CliCenterProvider` / store 中,右侧看板展开时保持双栏;看板收起、通过 CSS 隐藏或未集成时,桌面聊天顶部显示对话、工作区、受支持的浏览器及已打开文件页签。手机或不超过 640px 的聊天容器使用「打开工作区」按钮唤起右侧抽屉,引用后返回对话继续输入。页签随当前对话切换,布局变化保留草稿和附件。
|
|
180
|
+
- 默认 `fileOpen="auto"` 优先使用上述工作区;显式 `fileOpen="modal"` 保留弹窗,`"link"` 保留链接,`"board"` 仅在看板打开。隐藏整个聊天头部时不显示内置页签/抽屉入口,自动模式仍可回退弹窗。宿主也可以 `store.openInBoard(jobId, { kind: "file", path })`;文件和浏览器能力仍由后端及 `availableTabs` 决定。
|
|
152
181
|
- 下载:单个文件;文件夹(页签右上角 / 文件夹行尾)在浏览器里打包成 ZIP,最多 2000 个文件、共 300 MB。
|
|
153
182
|
- 弱网 / 节点忙:读文件 30 秒没响应、或传输中 60 秒没收到数据就报错,预览里有「重试」;读超过 8 秒提示「网络较慢」。打包下载时每个文件失败会自动重试 3 次,一直读不到的跳过,其余照样打包,失败清单在压缩包里的 `_下载失败的文件.txt`。
|
|
154
183
|
- 放大:文件预览、浏览器画面都能放大到整页(Esc 还原);接管浏览器时自动放大。图片可缩放(Ctrl / ⌘ + 滚轮)。
|
|
155
184
|
- 引用到对话:文件预览、浏览器的「引用到对话」把它带进下一条消息(`store.addRef`),对话输入框上方显示、可去掉;发出时合成「看板上下文」附件。自定义页签(`extraTabs`)的 `quote` 同理——终端之类的交互以后都走这条路进对话。
|
|
156
185
|
- 多个文件页签:点开的文件各占一个页签(最多 8 个,再开关掉最早的),可关闭(× 或鼠标中键),按对话记在 sessionStorage,刷新后还在。
|
|
157
186
|
- 选中引用:在预览里选中文字浮出「引用到对话」(Markdown / 代码 / 文本 / 表格 / HTML / Word 及其源文件;HTML、Word 在沙箱 iframe 里,预览用 srcdoc 插一段选区小脚本报给宿主,页面自己的脚本仍不执行);在浏览器网页里复制(⌘C / Ctrl+C)后提示里也有「引用到对话」。
|
|
158
|
-
- 被动浏览背景:每条消息自动附带当前文件、仍打开的页签和最近40
|
|
187
|
+
- 被动浏览背景:每条消息自动附带当前文件、仍打开的页签和最近40个实际访问文件的元信息;手机回聊天/收起看板后仍保留,并标记收起状态。后台默认带入,不在输入框上方展示摘要或勾选项。不会自动读取文件正文,也不替换手动引用。`CliChat passiveContext={false}`/`CliBoard autoQuoteOpenFile={false}` 关闭;节点 `board={{autoContext:false}}`。`workspace.context()` 读取完整浏览快照,`config.refs` 继续控制旧式引用的显示。
|
|
159
188
|
- 浏览器弱网:操作没送达时提示(不自动重发,免得点两次);接管时发了操作 8 秒画面没变化提示并给「重连画面」;按住鼠标切走窗口自动补发松开;地址栏自动补 `https://`。
|
|
160
189
|
- 数据都经中枢:`/api/jobs/:id/board`、`/files`、`/files/raw/<路径>`、`/diff`、`/browser`(+ `events` / `frames` / `input`)。
|
|
161
190
|
- 链路、交互、故障与重试的设计见 [BOARD-DESIGN.md](BOARD-DESIGN.md)。
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
- HTML
|
|
165
|
-
-
|
|
166
|
-
-
|
|
191
|
+
- 普通工作区图片、PDF与HTML相对资源继续使用既有鉴权地址或中枢30分钟短期链接;上传原件的图片和Word读取使用授权分块缓存。HTML/Markdown正文预览、下载使用下文的增量协议;上传原件在看板沙箱预览或下载,不另开同源可执行页面。
|
|
192
|
+
- 预览大小与显示方式:
|
|
193
|
+
- HTML/Markdown最多100MiB;HTML默认原样预览,需完整重组当前修订,读取或排版期间可主动切换分段阅读。512KiB首段读取仅适用于分段阅读、Markdown和源码,继续阅读时按需补块。具体缓存、兼容和性能边界见下文“0.6.7 大文件原件与增量读取”。
|
|
194
|
+
- 其他文本、代码、日志、CSV保留32MiB读取上限;刷新按当前修订重新验证,不再依赖尾部重叠猜测整篇是否只追加。
|
|
195
|
+
- Markdown分段窗口显示;CSV表格先画2000行、可继续显示;代码512KiB以内高亮,更大的按纯文本显示;Word最大50MiB。
|
|
167
196
|
|
|
168
197
|
## 对接业务数据
|
|
169
198
|
|
|
@@ -183,6 +212,7 @@ await ws.zip(dir); // { blob, name, files, failed }
|
|
|
183
212
|
await ws.download(path); await ws.downloadFolder(dir);
|
|
184
213
|
await ws.fileUrl(path, { download: true });
|
|
185
214
|
ws.openFile(); ws.openFiles(); ws.open(path); await ws.info();
|
|
215
|
+
ws.refresh(); // 每轮完成后请求一次已打开文件的增量检查;不创建连接或周期轮询
|
|
186
216
|
|
|
187
217
|
store.appendContext(jobId, text, { title, id }); // 随下一条消息带给智能体;null = 新对话的第一条
|
|
188
218
|
store.removeContext(jobId, id);
|
|
@@ -210,7 +240,7 @@ cli-chat 的顶部栏(面包屑、标题、智能体、用量、模型、状
|
|
|
210
240
|
|
|
211
241
|
`header.export: true` 在标题栏操作区显示「导出」,点击直接下载 Markdown(初始上下文、消息和工具记录)。导出范围为已加载的记录;还有未加载历史时按钮显示「导出已加载」。输入区把附件、发送和执行控制分开显示。任务运行 / 暂停期间保留可编辑输入框,新消息排队执行;后端不支持发送或连接错误时仍保留输入框和草稿,并提示原因。宿主显式设置 `composer: false` 或 `readOnly` 时隐藏输入框。
|
|
212
242
|
|
|
213
|
-
上传附件(`composer.fileUpload
|
|
243
|
+
上传附件(`composer.fileUpload`,缺省开)与看板共用原件通道:HTML/HTM、MD/Markdown 上限100MiB;图片(PNG/JPEG/GIF/WebP)、Word(.docx)、Excel(.xlsx/.xlsm)、TXT/YAML/JSON/CSV/TSV及现有代码文本格式上限10MiB。原始字节、扩展名和文件名保留,上传完成不会触发AI;用户点击发送后,消息要求AI先读取附件再处理正文。PDF、压缩包和旧版.doc/.xls仍不在上传范围。自定义客户端未提供 `uploadDocument` 时保留旧文档转文字适配,内置适配器不退回转换或全量上传。
|
|
214
244
|
|
|
215
245
|
## 事件
|
|
216
246
|
|
|
@@ -247,7 +277,7 @@ cli-chat 的顶部栏(面包屑、标题、智能体、用量、模型、状
|
|
|
247
277
|
|
|
248
278
|
## 本地文件链接
|
|
249
279
|
|
|
250
|
-
Agent 回复里指向本地文件的链接(`report.md`、`src/a.ts:12`、`file:///…`),识别规则与 Operator
|
|
280
|
+
Agent 回复里指向本地文件的链接(`report.md`、`src/a.ts:12`、`file:///…`),识别规则与 Operator 相同。缺省在当前工作区打开(右侧看板、顶部文件页签或手机抽屉),按住 ⌘/Ctrl 点按地址在新窗口打开;`fileUrl={(path, jobId) => 地址}` 可以自己给地址。
|
|
251
281
|
|
|
252
282
|
## 开发
|
|
253
283
|
|
|
@@ -299,7 +329,7 @@ export default function App() { return <OperatorWorkspace />; }
|
|
|
299
329
|
| 能力 | 中枢默认模式 | Operator 模式 |
|
|
300
330
|
| --- | --- | --- |
|
|
301
331
|
| 列表、对话、文件/浏览器看板联动 | 同一 `CliCenterProvider`/store | 同一工作区控制器和多路复用实时连接 |
|
|
302
|
-
| 附件、长文本、引用 |
|
|
332
|
+
| 附件、长文本、引用 | 原件上传与看板/消息引用,草稿暂存 | 同一原件上传通道,消息引用、草稿与来源恢复 |
|
|
303
333
|
| 模型、推理、权限/规划 | 不伪造中枢没有提供的配置接口 | 能力列表驱动,等待真实 PATCH 成功再允许发送 |
|
|
304
334
|
| `@` 多来源分支 | 中枢协议目前未提供独立 Git 派生接口 | 同项目已完成任务,每个来源一个独立 worktree/分支,固定源提交 |
|
|
305
335
|
| 源对话结尾 → 分支选择 → 子对话 | 不虚构分支数据 | 支持横向切换和递归派生,来源历史只读 |
|
|
@@ -308,7 +338,7 @@ export default function App() { return <OperatorWorkspace />; }
|
|
|
308
338
|
|
|
309
339
|
`src/operator.base.css` 是共享样式源,`src/operator.css` 是 `css:sync` 的生成结果;根工程 `app/globals.css` 只导入包的样式。迁移与备份清单见仓库的 `docs/CLI_UI_MERGE.md`。
|
|
310
340
|
|
|
311
|
-
|
|
341
|
+
`0.6.7` 已发布,本地此次候选版本为 `0.6.8`,不能覆盖重发旧版本。发布前须通过组件测试、嵌入构建、真实工程构建和浏览器回归;不要运行会连带发布其他共享包的批量脚本。配套 Skill/MCP 各自为 `0.1.1` 本地候选,版本独立。
|
|
312
342
|
|
|
313
343
|
|
|
314
344
|
### 文件、对话与浏览器看板联动
|
|
@@ -324,7 +354,7 @@ npm 已于 2026-11-05 核验发布 `0.6.5`,不能覆盖重发。本地此次
|
|
|
324
354
|
|
|
325
355
|
Web Component 对应 `tabs="browser"`、`available-tabs="browser,files"`;`tabs=""` 表示初始全部关闭。默认配置与用户手动开关分开,模块偏好按任务/配置保存在会话存储中。
|
|
326
356
|
|
|
327
|
-
|
|
357
|
+
对话里的本地文件链接及文件形态的行内代码会打开当前工作区预览:桌面右侧看板展开时在右侧打开,收起时切到顶部文件页签;手机使用右侧抽屉。Ctrl/⌘ 点击仍可独立打开。来源历史文件使用来源任务的文件接口,不切换当前任务或分支。文件、选区、网页和网页复制文字可引用回同一个草稿,保留原有输入;手机引用后返回对话。
|
|
328
358
|
|
|
329
359
|
浏览器关闭页签只隐藏模块和断开画面连接,不结束浏览器任务;重新打开后连接当前状态。「关闭浏览器」才调用实际关闭接口。新浏览器交接能唤起隐藏的模块;旧历史交接、已经消费的打开请求和其他任务的事件不会反复唤起。浏览器模块与独立窗口共用画面/输入实现,保留触摸、键盘/输入法、网页弹窗、剪贴板、重连、接管交还,并保留节点登录配置、弹出窗口和在节点屏幕显示操作。
|
|
330
360
|
|
|
@@ -374,20 +404,22 @@ const stop = ws.watch(async event => {
|
|
|
374
404
|
const blob = await ws.readFile(change.path); // 也可 readText()
|
|
375
405
|
receiveBusinessFile(info, blob);
|
|
376
406
|
}
|
|
377
|
-
}, { onStatus: status => showWatchStatus(status) });
|
|
407
|
+
}, { paths: ["reports/a.md"], onStatus: status => showWatchStatus(status) });
|
|
378
408
|
// 业务生命周期结束时 stop()。
|
|
379
409
|
const view = ws.context(); // current / opened / history / visible / sourceId
|
|
380
410
|
```
|
|
381
411
|
|
|
382
|
-
|
|
412
|
+
上述业务函数由集成方实现,组件不会自动上传到外部服务。通知是当前状态变化,读取可能遇到后续改写/删除,应处理错误与密集通知;通知中的 revision 是元数据批次标识,正文 manifest 的 SHA-256 revision 才标识不可变内容快照。
|
|
383
413
|
|
|
384
|
-
节点使用 `createOperatorWorkspace(taskId)`(从 `@spzxg/cli-ui/operator` 导入),或 `<OperatorWorkspace board={{onFilesChange, onFilesWatch}} />`。接口包含 watch/stat/readText/readFile/context/open。`onBoardContextChange` 提供浏览状态;它与文件内容变化分开。
|
|
414
|
+
节点使用 `createOperatorWorkspace(taskId)`(从 `@spzxg/cli-ui/operator` 导入),或 `<OperatorWorkspace board={{onFilesChange, onFilesWatch}} />`。接口包含 watch/refresh/stat/readText/readFile/context/open。`onBoardContextChange` 提供浏览状态;它与文件内容变化分开。
|
|
415
|
+
|
|
416
|
+
独立节点 `CliBoard` 只旁听组件现有任务消息流的轮末与重连快照,不另开连接或服务端订阅。宿主自行管理聊天流时,应在每轮结束(包括停止/失败)和重连完成后调用 `createOperatorWorkspace(taskId).refresh()`;中枢对应 `store.workspace(conversationKey).refresh()`。该方法按已订阅范围检查,并同步已打开文件此前读取过的内容范围;节点会包括已打开的来源任务文件。多个请求会合并,在途检查期间的新轮末会补查一次。自动事件调用 `refresh()`,用户点击重试才调用 `refresh({ manual: true })`,后者重新开始有限重试预算,但仍遵守服务端 `Retry-After`。没有看板时,先用 `ws.watch(listener, { paths: [...] })` 指定范围;没有订阅范围时不会发起文件请求。
|
|
385
417
|
|
|
386
418
|
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
419
|
|
|
388
|
-
事件含 `jobId`、`changes[{kind,path,file?,previous?}]`、`revision?`、`mode`、`coverage`、`complete`;创建/修改/删除分别为 created/modified/deleted
|
|
420
|
+
事件含 `jobId`、`changes[{kind,path,file?,previous?}]`、`revision?`、`mode`、`coverage`、`complete`;创建/修改/删除分别为 created/modified/deleted,初始快照不冒充全部新建。多个组件与业务监听共享短请求调度,最后取消时释放;每个订阅者的显式路径独立释放。
|
|
389
421
|
|
|
390
|
-
|
|
422
|
+
0.6.7 的文件同步由事件触发,使用会结束的短 HTTP;没有文件 SSE、WebSocket、长轮询或周期轮询。每轮聊天流结束(含失败、停止)、流重连后的快照、打开/手动刷新、页面恢复会触发一次检查;普通输出片段不触发。相邻事件合并,在途检查期间再结束一轮会补查一次。只检查当前看板已打开文件、当前目录可见行和宿主显式订阅范围;已预览的多个文件逐个核对修订并同步其已读范围,未变化文件不下载正文,未读文件不预取。隐藏页面停止文件检查。网络类错误最多退避重试3次,权限错误等待显式事件。旧返回值 `mode=poll, coverage=listed-files, complete=false` 仅为兼容的短 HTTP 传输标签,不代表定时轮询,也不是整个工作区的审计日志。无 UI 订阅可通过 `ws.watch(listener, { paths: ["reports/a.md"], dirs: ["reports"] })` 指定范围。目录更新仍按页拉取元数据;不批量取正文。外部独立修改若没有传入结束/更新事件,只能在重新打开、手动刷新或页面恢复时发现。聊天和远程浏览器现有连接保持不变。
|
|
391
423
|
|
|
392
424
|
列表和聊天可消费中枢任务摘要/实时 task 的可选 `awaiting_input`:`true` 表示节点确认需要人工处理(含浏览器验证码和输入卡片),`false` 表示已确认不等待,`null` 或缺省表示没有有效观测。正在执行的回合也可能需要人工处理,此时显示“需要你处理”,不会把任务误标为完成或暂停。中枢升级后从已有节点对账取得此状态;旧中枢仍兼容原有提问状态。新建/接续的迟到响应与旧操作报错不会抢走用户已切换到的任务。
|
|
393
425
|
|
|
@@ -397,7 +429,7 @@ Web Component 发出 `cli-files-change`、`cli-files-watch`、`cli-board-context
|
|
|
397
429
|
|
|
398
430
|
`workspace.readFile()` 对自定义后端也校验实际字节数并及时响应取消,后端仍应正确实现 AbortSignal 以释放内部资源。浏览器重连、接管交还和切换任务不等待或重放旧会话输入。当前看板为只读预览,文件编辑由 AI/服务端执行,再通过事件刷新和交付给业务方。
|
|
399
431
|
|
|
400
|
-
|
|
432
|
+
当前本地候选版本 `0.6.8`,已发布版本为 `0.6.7`,更新记录见随包 `CHANGELOG.md`。默认控件与执行配置验收见仓库 `docs/CLI_UI_068_DEFAULT_CONTROLS_VALIDATION_2026-11-06.md`;原件上传历史验收见 `docs/CLI_UI_UNIFIED_UPLOAD_VALIDATION_2026-11-05.md`。本地打包不等于 npm 或生产服务已更新。
|
|
401
433
|
|
|
402
434
|
### v0.6.5 文件和业务交付加固
|
|
403
435
|
|
|
@@ -406,3 +438,40 @@ Web Component 发出 `cli-files-change`、`cli-files-watch`、`cli-board-context
|
|
|
406
438
|
原生文件通知的可选 `FileEntry.changeToken` 用于重连对账,可识别同大小并恢复 mtime 的改写;需同步部署支持该字段的节点服务端。它不是不可变内容版本或审计日志。
|
|
407
439
|
|
|
408
440
|
看板与自动背景一起更新后通知业务,回调内继续导航保持顺序;显式选区引用携带来源任务身份。浏览器复制引用固定复制时页面,取消拖动、控制权切换、弹窗错误和异步帧解码均保持正确状态。
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
### 0.6.7 大文件原件与增量读取(需配套服务)
|
|
444
|
+
|
|
445
|
+
HTML/HTM、MD/Markdown 原件最多 **100 MiB(104857600字节)**,按1MiB分片上传、完成后核验SHA-256;保留原始类型、文件名和字节,不把整份文档放入聊天消息。中枢新对话先按账号/产品线/草稿暂存,在任务派发前认领并传到节点;其他现有支持类型原件上限10MiB,文件名不超过240个UTF-8字节。Word支持现有预览,Excel原件可下载或交给Agent读取,本次未增加表格预览器。
|
|
446
|
+
|
|
447
|
+
看板「+ → 上传文件」仅对已有Agent工作区开放:上传至当前会话的「输入文件」,成功自动打开文件页签,只保存文件,不发送消息或启动AI。当前打开文件按既有看板背景规则随之后的消息带入,也可选区引用。Chat上传同样保存原件并打开页签,另保留待发送附件;点击发送后才要求AI先读附件。新对话Chat先显示原件暂存,首次发送时才落到节点。
|
|
448
|
+
|
|
449
|
+
两处共享有界上传队列、实际接收字节进度、校验阶段、取消和失败重试。看板上传按当前任务定向,即使浏览的是来源任务目录也不会上传到来源任务;切任务或卸载取消未完成上传。刷新后未完成项需重新选择本地文件,浏览器不会持久保存File对象。关闭预览后,可从工作区「输入文件」重新打开,目录仍按200项分页,不预加载正文。
|
|
450
|
+
|
|
451
|
+
输入文件沿用节点现有任务附件目录(Git工作树外),不复制第二份;看板、附件标记和Agent指向同一原件。执行模式只授予当前任务输入目录写权限,计划模式保持只读;已运行的Agent进程不会热修改隔离规则,下次正常启动轮次采用新规则。服务端更新后,旧图片/文本附件地址取消immutable缓存,避免同一路径编辑后仍显示旧版本。
|
|
452
|
+
|
|
453
|
+
看板预览、手动刷新、重新打开和 `workspace.readText/readFile` 的HTML/Markdown读取使用同一套修订同步:先授权查询manifest,再读取本地没有的内容块。节点按内容分块(16–256KiB,平均目标64KiB),中间插入、删除或跨越中间修订都可复用相同块;批次最多1MiB、同步器并发最多3。每块校验,完整文件重组再校验总hash,失败保留上一份完整内容;401/403撤下旧预览。选区引用携带复制时的修订和来源路径。
|
|
454
|
+
|
|
455
|
+
正文块保存在IndexedDB,默认256MiB预算并按LRU淘汰;无持久存储或配额不足时使用会话缓存。缓存已存在且文件未改时正文传输为0;首次打开、缓存被浏览器/预算清除或整文件重写,仍可能需要下载大部分或全部正文。每次仍先校验当前权限,缓存不代替鉴权。宿主明确注销时可用 `clearFileSyncNamespace(backend.fileSync, namespace)` 清除指定授权空间;任意宿主的登录生命周期不会由组件自行推断。
|
|
456
|
+
|
|
457
|
+
缓存打开、读写或事务停滞最多等待5秒后降级到会话缓存,存储配额估算最多等待1秒;这些是单次操作的截止时间,不是轮询。取消预览无需等待缓存恢复。聊天轮末核对不会复用该事件之前已经发出的旧清单请求,迟到旧修订不回退最新缓存指针,必要时触发一次预览纠正;损坏的重复内容块修复后复用同一份校验结果,避免反复下载。
|
|
458
|
+
|
|
459
|
+
大文件反复修订不依赖逐版补丁历史:拿到当前授权清单后,用本地已校验块直接重组最新修订;弱网漏过多轮、旧节点快照被淘汰后仍走相同流程。失败请求中已完整校验的块可以保留,半响应或校验失败的块不会进入缓存;未完成修订不替换上次完整内容。文件页签的刷新按钮及更多菜单中的“刷新内容”仅刷新该文件,重新核对最新清单,不唤醒其他文件;聊天轮末仍同步已打开且预览过的文件范围。
|
|
460
|
+
|
|
461
|
+
并发采用有界队列:同一客户端传输的manifest和分块请求各最多3个,正文组装最多2个,后台预览同步串行;元数据核对每个backend最多4个,同一fetcher的上传及哈希串行。每个客户端队列最多128项、最多等待180秒,取消排队立即移除;已开始的工作直到真正结束才释放名额,避免宿主忽略取消时突破限制。排队不提前分配100MiB组装缓冲区。
|
|
462
|
+
|
|
463
|
+
配套服务端也限制容量:中枢文件代理每进程最多32个活跃请求、每节点8个,最多128个排队、同节点64个;独立节点每进程8个活跃、64个排队。服务端排队超过5秒或队满返回429与`Retry-After`,二进制响应传输结束或取消后才释放名额。节点快照构建最多2个同时执行、在途与排队合计32个;同文件构建合并,缓存仍受1GiB和过期时间约束。中枢原件暂存每进程16个活跃、同身份4个,排队最多128个、同身份32个。
|
|
464
|
+
|
|
465
|
+
暂时断网、408/429和明确可恢复的5xx采用有限次数、带随机抖动的退避,并尊重`Retry-After`;协议损坏、校验失败和权限错误不盲目重试。请求层与元数据检查层分别最多追加3次,整个链路可能包含两层预算;202构建/校验中的等待也有180秒上限。检查预算耗尽且没有新事件时不再安排检查;冷却期间或最后一次失败期间到达的新事件会保留并合并,在至少30秒冷却及服务端`Retry-After`结束后补查一次,仍有有限重试预算。单次事件可等待超过180秒的服务端冷却,不建立周期轮询,也不截短服务端冷却;超过JavaScript定时器安全上限的提示保留错误,等待后续真实事件。多文件中单个永久错误不阻断其他文件的暂时故障恢复,并遵守这些暂时错误中最长的冷却。队满、等待超时和恢复失败保留明确错误及人工重试入口。容量限制按进程/传输生效,不是分布式配额,也不承诺100份100MiB冷文件同时即时完成;首次下载、缓存淘汰和复杂HTML渲染仍受实际网络、磁盘与设备内存限制。
|
|
466
|
+
|
|
467
|
+
目录首屏200项,滚动/点击才取下一页,显示行数最多80;`workspace.listPage(dir,{cursor,limit,signal})` 返回 `nextCursor`,适合业务列表。`list()` / `listAll()` / ZIP 是用户显式全量列目录操作,逐页读取并保留数量/内存限制,不会自动预取正文。游标失效会提示重读目录,不返回混合页面。
|
|
468
|
+
|
|
469
|
+
Markdown与HTML源码先读取512KiB,继续阅读按需扩大范围(单次增量至多8MiB),只下载新块。Markdown每片至多16Ki字符,并限制表格行、单元格和标记复杂度;一次事件循环只启用一片,离屏正文卸载,32片合为一组占位。表格续页保留表头,长代码分段显示且不高亮。小于4Ki且结构简单的Markdown和小于16Ki源码直接显示,不引入排版等待。片段解析异常只回退该片原文;超长行、复杂跨段脚注等会明确提示简化显示,普通引用式链接复用已加载文本定义。每次扩大范围仍需本地重组/校验当前已读前缀。
|
|
470
|
+
|
|
471
|
+
HTML默认直接原样预览,包括超过2MiB或大小未知的文件;通过同一增量协议完整重组当前修订。用户可在读取或排版期间主动切换“分段阅读”。分段阅读复用同一缓存与修订,先读512KiB;正文块边界可能使实际下载略大。静态流式解析每批8Ki字符、约8ms让出主线程,只保留目标页和最后页,每页最多64块/16Ki正文。保留标题、段落、代码、列表和表格文字,不执行原件脚本、不应用原件CSS、不自动加载图片;布局因此简化,选中引用仍携带原文件修订。翻页只重新整理本地已读前缀,需要后续内容才继续取缺块。嵌套超过32层、超长未完成标记(例如大于约64Ki的内嵌图片属性)等返回明确提示,可切源码或原样预览;不能将该受限阅读模式视为任意HTML的完整排版替代。
|
|
472
|
+
|
|
473
|
+
文件读取和HTML整理均可暂停、继续,旧完整内容在网络失败时保留;读取与排版各自管理取消信号,翻页不会覆盖仍在下载的请求。原样HTML通过受限引用桥在DOM就绪及绘制机会后报告状态,排版12秒未收到就提示切换分段阅读;该提示不是周期轮询。iframe自身的极端排版可能阻塞所在浏览器渲染进程,此时提示也可能延迟,计时器不能强制中断它或保证主页面始终响应。
|
|
474
|
+
|
|
475
|
+
HTML完整原貌预览要重组完整文档;网络只取缺块,更新后在沙箱iframe中替换完整修订并尽量恢复滚动。任意100MiB复杂DOM在手机上的排版成本不能由增量传输消除,超大样本的桌面测试不等于所有手机设备的性能保证。HTML自身脚本继续被阻止,相对资源按原有鉴权文件链路加载。
|
|
476
|
+
|
|
477
|
+
**需要配套升级中枢和独立节点服务端的 `file-sync/*` 接口。** 内置适配器遇到旧服务端会明确报不支持,不静默改回重复全量拉取。自定义BoardBackend未提供fileSync时保留原来的有限读取兼容行为。本次没有发布npm、部署或数据库变更。
|