feat: ship skill and MCP workflows with signed updater for v0.0.7
This commit is contained in:
1 parent
1b52df0603
commit
a01085c656
136 files changed
+18646
-217
No files matched your search
@@ -0,0 +1,122 @@
|
||||
# Claude 追加与压缩协议本地验证
|
||||
|
||||
日期:2026-10-20
|
||||
验证状态:SDK/CLI 协议探针和生产 ClaudeKernel 追加、压缩集成回归通过;Electron 主进程端到端结果另见本轮交接记录,不代表 WorkBuddy 1:1 验收。
|
||||
|
||||
## 1. 验证对象
|
||||
|
||||
- `@anthropic-ai/claude-agent-sdk`:`0.3.304`
|
||||
- SDK 内置 Claude Code:`2.1.304`
|
||||
- `node_modules/@anthropic-ai/claude-agent-sdk-win32-x64/claude.exe`
|
||||
- Claude Code SHA-256:`019E5174D5D954585EDB1A946FE280E44A973050B4897034ADF0E16306F85FDD`
|
||||
- 运行平台:Windows x64
|
||||
|
||||
本验证使用本机回环模拟的 Anthropic Messages SSE,不连接真实模型服务。HOME、USERPROFILE、
|
||||
`CLAUDE_CONFIG_DIR` 和 `CLAUDE_SECURESTORAGE_CONFIG_DIR` 均重定向到临时目录,仅使用 dummy key。
|
||||
因此本文件证明的是当前 SDK/CLI 的消息协议和帧归属行为,不是模型质量、真实供应商行为或
|
||||
WorkBuddy 原版行为。WorkBuddy 原版结论仍必须通过 REA 采集并记录其 Evidence ID。
|
||||
|
||||
## 2. 追加协议探针
|
||||
|
||||
探针文件:
|
||||
|
||||
- `scripts/claude-append-protocol-probe.ts`
|
||||
- `scripts/build-claude-append-probe.mjs`
|
||||
|
||||
探针通过 SDK 原始 `query()` API 创建一个保持打开的异步输入流,流程如下:
|
||||
|
||||
1. 发送带 UUID `INITIAL` 的 `PROBE_INITIAL`。
|
||||
2. 挂起首个模型请求的 SSE 响应。
|
||||
3. 在首个请求仍在途时,向同一输入流追加带 UUID 的 `PROBE_APPEND_A`、`PROBE_APPEND_B`。
|
||||
4. 不调用 `interrupt()`,不关闭输入流;释放首个响应后等待全部逻辑回合结束。
|
||||
5. 对照捕获的模型请求体、SDK 运行时帧和 `result` 帧。
|
||||
|
||||
本次生成报告:`.tmp/claude-append-protocol-probe.json`,顶层结果为 `PASS`。
|
||||
|
||||
### 请求侧结果
|
||||
|
||||
请求 1 只包含 `PROBE_INITIAL`,且正常完成,未被追加消息取消或改写。
|
||||
|
||||
请求 2 包含:
|
||||
|
||||
1. 初始用户消息 `PROBE_INITIAL`;
|
||||
2. 首轮 assistant 文本 `answer-1:PROBE_INITIAL`;
|
||||
3. 同一个 user message 中按顺序合并的 A、B 文本块。
|
||||
|
||||
本次 CLI 将 A 序列化为 `PROBE_APPEND_A\n`,B 保持 `PROBE_APPEND_B`。因此追加消息不会注入
|
||||
已经在途的 HTTP 请求,而是在首轮完成后成为下一逻辑回合的输入;相邻追加可合并为一个 user message。
|
||||
|
||||
### 结果与归属
|
||||
|
||||
本次观察到两个 `result`:
|
||||
|
||||
- `result[0]` 只归属 `INITIAL` UUID;
|
||||
- `result[1]` 同时归属 A、B 两个 UUID,其中 `user_message_uuid` 是最后一条 B 的 UUID。
|
||||
|
||||
两个 `assistant` 帧也按相同边界归属:首轮 assistant 不包含 A/B UUID,合并后的第二轮 assistant
|
||||
同时包含 A/B UUID。输入文本没有产生 SDK `user` echo 帧。
|
||||
|
||||
当前版本的 assistant/result 帧未观察到 `prompt_id`。可用的稳定归属键是
|
||||
`user_message_uuid` / `user_message_uuids`;在合并回合中,`user_message_uuid` 只是
|
||||
`user_message_uuids` 的最后一项,不能代表该 result 只覆盖 B。
|
||||
|
||||
关键结论:
|
||||
|
||||
- 一个 `result` 可能覆盖多个追加 UUID;不能用“收到一次 result”直接结算所有排队发送。
|
||||
- 在途请求和后续追加属于不同逻辑回合,当前观察到一个逻辑回合对应一个 `assistant` 和一个 `result`。
|
||||
- 该协议结论来自 SDK 原始异步输入流;生产 `ClaudeKernel` 的实现和验证单独记录在第 4 节。
|
||||
|
||||
## 3. 原生压缩边界复验
|
||||
|
||||
使用 `scripts/claude-kernel-integration.ts` 的 `compact` 分支,设置
|
||||
`CLAUDE_PROTOCOL_PROBE=1` 后运行真实 SDK + 内置 CLI + 回环假模型。观察到
|
||||
`system/compact_boundary`,后续收到成功 `result`,探针断言通过。
|
||||
|
||||
集成回归同时继续发送压缩后的请求,断言旧 ASK 内容不再出现在上游请求中。生产命令专用路径不附加普通聊天提醒,成功必须同时收到原生边界和成功结果;应用可见历史不随压缩删除。没有证明:
|
||||
|
||||
- 真实模型压缩后的内容质量或语义完整性;
|
||||
- 自动压缩的 token 阈值和触发条件;
|
||||
- 并发追加用户消息与压缩同时发生时的行为;
|
||||
- 压缩失败、重试和真实供应商错误分类。
|
||||
|
||||
## 4. 对 YCode 内核的影响
|
||||
|
||||
生产 `src/main/agent/claude/claude-kernel.ts` 保留单个活动根运行,新增 `appendInput()`,不放开并发 `runTurn()`:
|
||||
|
||||
1. 输入带独立 UUID 推入同一原生输入流,不取消当前请求,不声称改写已发出的上游请求。
|
||||
2. 按 `user_message_uuid(s)` 路由后续输入组;首个 result 不会提前结算仍待交付的追加项。
|
||||
3. 前一组完成后先保存旧 assistant;匹配到新组的原生身份帧后,由宿主原子保存完整用户消息及新 assistant,再确认对应队列项交付。A/B 可合并到同一原生组,但正式历史保留两条用户消息。
|
||||
4. 后续组沿用根运行的冻结模型、权限和工作区;新组保存期间工具/审批等待交接,避免挂到旧 assistant。
|
||||
5. 取消会关闭并排空原生生产者,再允许下一运行;推入前失败可明确重试,推入后未确认的消息标记 unknown,不自动重放。
|
||||
|
||||
`scripts/claude-kernel-integration.ts` 直接调用生产内核验证双追加、不打断首请求、身份归属、交接回调、空闲追加拒绝、原生压缩和压缩后请求。2026-10-20 重新构建后运行 `CLAUDE_PROTOCOL_PROBE=1`,输出 PASS(16 requests / 43 events / 9 turns)。这些数字属于确定性回环夹具,不是实际模型效果或完整 UI 验收。
|
||||
|
||||
## 5. 复验命令
|
||||
|
||||
在仓库根目录执行:
|
||||
|
||||
```powershell
|
||||
npx tsc --ignoreConfig --noEmit --target ES2023 --module ESNext --moduleResolution Bundler --strict --skipLibCheck --types node --lib ES2023 scripts/claude-append-protocol-probe.ts
|
||||
node scripts/build-claude-append-probe.mjs
|
||||
node .tmp/claude-append-protocol-probe.mjs
|
||||
node scripts/build-claude-kernel-regression.mjs
|
||||
$env:CLAUDE_PROTOCOL_PROBE='1'
|
||||
node .tmp/claude-kernel-integration.mjs
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- 追加探针输出 `result: PASS`,报告写入 `.tmp/claude-append-protocol-probe.json`;
|
||||
- 压缩探针输出 `probe: compact`、`boundary: true`,随后 integration 输出 `result: PASS`;
|
||||
- `npm run typecheck` 通过。
|
||||
|
||||
`node .tmp/claude-append-protocol-probe.mjs` 使用随机回环端口和临时配置目录;报告中的端口、
|
||||
UUID 和消息 UUID 每次运行都会变化。稳定复验依据是版本、二进制哈希、帧结构和上述断言。
|
||||
|
||||
## 6. 限制与后续
|
||||
|
||||
- 探针只覆盖 Windows x64 和当前 SDK/CLI 版本,不能外推到其他平台或版本。
|
||||
- 假模型只返回固定文本,不覆盖真实长上下文、网络重试、限流和供应商差异。
|
||||
- 没有验证 WorkBuddy 原版是否采用相同的追加/压缩交互;该比较需另行通过 REA 完成并记录证据。
|
||||
- 原生追加与压缩混发被产品入口拒绝;真实网络故障、工具密集追加、多平台进程崩溃注入仍需要进一步验证。
|
||||
@@ -0,0 +1,42 @@
|
||||
# MCP、技能与统一输入区接入
|
||||
|
||||
日期:2026-10-20。执行来源:会话 `01a158f5-eea4-7e43-893c-21217cb00ed5` 最后确认计划。
|
||||
|
||||
## Dev 反馈补漏:管理页面
|
||||
|
||||
用户在 Dev 中发现技能/连接器页面仍显示维护:上一轮只接通了后端及输入区,没有恢复管理页,这是实施遗漏。现从本仓库已有版本恢复 SkillsPage / ConnectorsPage 的组件、图标和样式,不重新采集或绕过 REA;技能页补传 cwd、使用/创建/查找回调,ChatPane 恢复对应事件接收及返回能力管理页后的目录刷新。Dev 的 Vite HMR 日志已确认页面更新;专家页面不在本次开放范围内。
|
||||
|
||||
技能隔离 Electron 回归 `node scripts/test-skills-ui.mjs` 37 项通过,使用真实生产 skills 模块、隔离文件存储及受控文件选择器,覆盖导入/覆盖冲突、启停、详情、导出、卸载、回调与无效包。报告 `.tmp/skills-ui-3FPN3y/report.json`;已检查已安装技能截图。远程技能市场仍明确未连接,不伪造目录数据。
|
||||
|
||||
连接器页面隔离 Electron 回归 `node scripts/test-connectors-page.mjs` 26 项通过(最终报告 `.tmp/connectors-page-5zSU8J/report.json`):真实页面/样式,受控 MCP 宿主,覆盖列表、详情、管理弹窗、批准/启用、工具开关、重连、配置编辑入口、搜索、删除取消及弹窗内错误显示;不是外部 MCP 服务连接验收。主线程已检查卡片与弹窗错误截图;隐藏窗口截图已增加预绘制以避免捕获旧帧。类型检查、会话组件回归和最新完整构建通过;构建日志 `.tmp/capability-management-build.log`。
|
||||
|
||||
## 实现
|
||||
|
||||
- 继续使用 Claude Agent SDK / Claude Code,不切换内核。YCode 自有配置目录、模型、凭据和会话管理保留;停止发现项目 `.claude/skills`,保留受启停和校验约束的 `.agents/skills`。这不是 OS 文件系统隔离。
|
||||
- 技能管理和 MCP 管理 IPC 恢复真实实现。MCP 宿主维护唯一连接,Claude 通过四个小型桥接工具按需发现、调用 MCP、加载技能正文及相对资源;执行前重新校验启用、批准哈希、工具开关和连接身份。技能脚本仍需原生执行工具及权限流程。
|
||||
- 加号与斜杠共用能力目录、搜索和选择状态,消息级技能/MCP/压缩标签贯通草稿、排队、正式历史和重发。选择标签不代表能力已经运行。
|
||||
- 统一输入区决定交互、错误提示、队列与普通输入的优先级;接管时隐藏而不删除队列或草稿。权限位置为加号之后;Esc 不停止生成,明确停止按钮保留。
|
||||
- 生成中有效输入进入会话持久队列(最多 19 条);排序、删除、编辑取回、恢复与状态推送已接通。编辑取回保留磁盘暂存记录,直到实际提交确认,不先删除唯一副本。崩溃恢复或交付不明会暂停,不自动重试 unknown。
|
||||
- 立即发送走同一原生输入流,不取消重发。按 UUID 识别后续组,宿主提交历史后才从队列移除;允许 A/B 合并原生组,历史保留两条输入。首个结果不结算后续消息。当前运行配置冻结,普通队列实际派发时读取后续设置。
|
||||
- 模型/思考设置串行保存,生成期间只允许改下一请求设置,不能改工作区、模式或权限;首次建会话期间的选择也保留。当前消息的模型和上下文窗口不跟随下次选择改变。
|
||||
- 原生 `/compact` 专用路径必须得到压缩边界和成功结果,不用总结请求代替;禁止忙碌、队列未处理、无历史或混合附件/能力/正文时执行。保留可见历史。
|
||||
- 上下文采用真实流式用量及已有内核 summary 分类估计,不按输出字符计算,不把跨多请求的 result 聚合用量当作当前上下文。查询单会话单在途,结果绑定运行、模型和输入组。
|
||||
|
||||
## 已验证
|
||||
|
||||
- `npm run typecheck` 和完整 `npm run build`(最终日志 `.tmp/composer-final-build.log`)。
|
||||
- `npm run test:composer-capabilities`:队列常规/并发/故障恢复、输入区组合、能力选择器 30 项、请求设置 5 组、上下文、能力桥接 36 项(含根运行取消传播);对抗队列 16 组。
|
||||
- `npm run test:chat`、`npm run test:conversation`、`npm run test:sessions`、`npm run test:tool-approvals`、`npm run test:workbench-escape`、`npm run test:references`、`npm run test:persistence`。
|
||||
- 真实 SDK/CLI 回环协议和生产内核集成:无打断双追加、身份合并/归属、交接回调、取消后续聊、空闲追加拒绝、真实原生压缩边界和压缩后请求。`CLAUDE_PROTOCOL_PROBE=1` 输出 PASS(16 requests / 43 events / 9 turns)。环境和探针细节见 [Claude 追加与压缩协议验证](Claude追加与压缩协议验证-2026-10-20.md)。
|
||||
- `npm run test:claude-append:app`:加载真实生产 main/preload/renderer,隔离用户数据及配置,回环 SSE 挂起首响应,通过界面发送两条队列消息并连续点击立即发送,确认两项保持 delivering 直到原生身份交付;首请求未中断、A/B 合并后续原生组、两条稳定身份写入历史、正确分段 assistant、最后队列清空。26 项通过,0 renderer 错误,报告 `.tmp/claude-append-app-DFYbsq/report.json`;主线程已查看 `append-queue.png` 与 `append-final.png`,该次为浅色桌面截图。
|
||||
- 最终扩展回归:`.tmp/claude-append-app-s0u84t/report.json`,39 项通过、0 renderer 错误。在首个请求仍挂起时通过真实 IPC 选择 B 再 C,请求端点顺序为 A / A / C,助手元数据也分别为 A / A / C;下一独立请求完成后才截最终图。主线程已查看深色、720px 窄窗截图;窄窗发现长模型标签遮住权限入口,修为权限图标紧跟加号、模型名称截断,并加入权限按钮可见且中心命中不被遮挡的 DOM 检查。该响应式修正是 YCode 可用性处理,未宣称是原版同尺寸实测规则。
|
||||
|
||||
## 证据与未验证边界
|
||||
|
||||
- 原版静态依据:WorkBuddy 5.8.2 JS Evidence `ev_717fa5e846e64d67ac19c8925d121bff632c0d3aefb3603b10858559cabb2dcb`;CSS Evidence `ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94`。队列最大高度 224px、顶部圆角及向下重叠沿用静态依据,不新增数量标题或折叠卡片。
|
||||
- REA 对 `http://127.0.0.1:9223` 返回 endpoint_unreachable / provider_unavailable,未绕过 REA 获取原版页面。实际激活调用链、图标精确差异、浮层尺寸和动态截图仍待原版可达后补证。
|
||||
- 任务组合策略已有独立测试,但当前 Claude 内核没有完整团队成员/后台任务事件来源,未伪造数据接线;这部分不能宣称完整任务功能或 1:1。
|
||||
- 自动能力桥接通过宿主注入测试;真实外部 MCP 服务故障/真实供应商长上下文/真实压缩质量/多平台进程崩溃与独立安全审查未完成。
|
||||
- 全部回环测试使用隔离配置及 dummy key,不证明真实模型效果。UI fixture 不等于真实后端,真实 Electron 后端回环也不等于供应商线上验收。
|
||||
- 能力选择器的键盘/IME 等通过组件回归,尚未完成全矩阵真实 Electron 键盘交互;图片/工具密集引导、实际上游断连与取消不在本次 Electron 文本回环范围内。原生 UUID 帧直接断言在内核协议测试中,Electron 测试通过请求合并、持久身份、分段历史与队列移除交叉确认。
|
||||
- 本轮不提交 Git、不发布、不安装、不重启用户安装版;保留工作区已有升级模块等修改。
|
||||
@@ -0,0 +1,283 @@
|
||||
# YCode 更新发布说明
|
||||
|
||||
> 2026-10-20 23:53(Asia/Shanghai)追加发布:线上 latest 已更新为 **0.0.7**。包含技能/MCP 输入引用、Archify 内置推荐与官方 GitHub API 固定包安装、仓库 owner 本地头像、统一详情与全局遮罩、原位安装及新任务“去使用”、斜杠原子消费和焦点恢复修正。以下旧版本条目保留为历史,不代表当前 latest。
|
||||
>
|
||||
> 安装包:`release/publish/0.0.7/YCode-0.0.7-Setup-x64.exe`,**237351255 字节**,SHA-256 **506768934c92979ba38c4ab922b58d2de98b590a125fd1a5dacd8dadd2ddaff3**。公开地址:`http://192.168.10.6/ycode/releases/versions/0.0.7/YCode-0.0.7-Setup-x64.exe`。
|
||||
>
|
||||
> 完成升级回归、发布流程17项自测、类型检查与完整构建。使用官方 checksums.json 校验过的 Electron 37.10.3 缓存 ZIP,通过命令行 electronDist 打包,未更改全局下载配置;包内版本、固定 GitHub 来源与 commit、新详情/遮罩/安装状态/Slate 删除接口、离线头像哈希和公钥一致性检查通过。先生成 Ed25519 签名清单,再以 `npm run release -- --version 0.0.7 --resume` 执行部署预检、SSH 发布与 HTTP 清单复核,历史目录不覆盖,暂存目录已清理。
|
||||
>
|
||||
> 正式 `0.0.7` 生产 EXE 使用隔离数据启动,真实 IPC 检查服务器返回 up-to-date;模拟旧版本通过正式更新后端实际完整下载,大小/SHA-256 一致、状态 ready,安装器适配器调用为0,真实安装文件/注册表状态未变化。报告:`.tmp/updates-live/2026-10-20T15-53-57-094Z/report.json`。已检查生产包启动截图。此验证没有执行 NSIS 安装/覆盖升级。
|
||||
>
|
||||
> 安装包 Authenticode 状态为 **NotSigned**,不能将 Ed25519 清单签名表述为 Windows 代码签名。日志:`.tmp/release-0.0.7-updates.log`、`.tmp/release-0.0.7-build.log`、`.tmp/release-0.0.7-package.log`、`.tmp/release-0.0.7-package-verification.json`、`.tmp/release-0.0.7-prepare.log`、`.tmp/release-0.0.7-publish.log`、`.tmp/release-0.0.7-live-verification.log`。本地版本与 lock 更新为0.0.7,未 Git 提交或打 tag,未安装或重启用户安装版。
|
||||
|
||||
> 2026-10-20 追加发布:线上 latest 已更新为 `0.0.6`,移除升级前的原生二次确认窗。
|
||||
> 安装包为 `release/publish/0.0.6/YCode-0.0.6-Setup-x64.exe`,大小 `237189173` 字节,
|
||||
> SHA-256 `7e672b4a76349fb799e6c509c2901a199e5e6bb4266dc4e78d6bffe978c33c5c`。
|
||||
> 更新测试、完整构建、打包内版本/公钥/旧弹窗移除/ASAR修复检查、SSH 发布、HTTP 签名清单和完整安装包哈希复核通过。
|
||||
> 首次一键执行在打包时访问 GitHub 超时;使用本机已有 Electron 37.10.3 缓存 ZIP(按 electron 包自带 checksums.json 验证 SHA-256)完成打包,
|
||||
> 生成签名清单后通过 `npm run release -- --version 0.0.6 --resume` 完成发布。未修改发布脚本或全局下载配置。
|
||||
> 日志:`.tmp/release-0.0.6.log`、`.tmp/release-0.0.6-package-retry.log`、`.tmp/release-0.0.6-resume.log`。
|
||||
> 未执行安装器、覆盖升级或重启用户应用;下方 `0.0.5` 状态保留为历史记录。
|
||||
|
||||
日期:2026-10-20
|
||||
状态:发布工具、服务端与推荐版本 `0.0.5` 已发布;隔离启动和真实签名下载已验收,
|
||||
尚未执行真实覆盖升级验收
|
||||
|
||||
## 1. 当前结果
|
||||
|
||||
- 更新服务器:`local001`,HTTP 基址 `http://192.168.10.6/ycode/releases/`。
|
||||
- 发布根目录:`/srv/ycode`;不可变版本目录:`/srv/ycode/releases/versions/`。
|
||||
- SSH 暂存目录:`/srv/ycode-staging`,不对外提供 HTTP 访问。
|
||||
- nginx 独立片段:`/etc/nginx/snippets/ycode-releases.conf`。
|
||||
- nginx 首次变更前备份:`/var/backups/nginx/ycode-before-20261020T091317Z-default`。
|
||||
- 下载页路由变更前备份:`/var/backups/nginx/ycode-before-20261020T092709Z-default`。
|
||||
- `/srv/baocode` 和原有 `/baocode/` location 未改动。
|
||||
- `/ycode/releases/latest.json` 当前返回 200、`Cache-Control: no-store`,版本为 `0.0.5`。
|
||||
- `/ycode/releases/` 当前返回 200,显示从签名清单生成的 `0.0.5` 下载页;页面无脚本。
|
||||
- 线上 `latest.json` 于 `2026-10-20T10:27:49.041Z` 发布,SHA-256 为
|
||||
`d985b7b94ed9e4661eec03489e801ba41aff295b4d9ea6be8a6930edf8247245`;下载页
|
||||
SHA-256 为 `42fb30160c2250ff04f23b3505a6fb0bb97aa3a1a91cb91ef4dd0cf0c314f285`。
|
||||
- 推荐线上安装包实测 `237106337` 字节,SHA-256 为
|
||||
`a3b8ece96077af81f9c8c676cb7d0d71f16a5d73332bc48b865c5cba7e92fd0d`。
|
||||
- `0.0.2`、`0.0.3`、`0.0.4` 安装包作为不可变历史版本保留,均已被 `0.0.5` 取代。
|
||||
- 发布完成后 `/srv/ycode-staging` 为空;所有访问和文件校验均已完成。
|
||||
- 公钥:`resources/updates/public-key.pem`;Electron `extraResources` 会把它打包为
|
||||
`resources/updates/public-key.pem`。
|
||||
- 公钥 SPKI SHA-256 指纹:`320a1f9016e9fbb7097074a68e1d3d15633fe05da5cb418f448372d37a8c3ea5`。
|
||||
- 私钥:`%USERPROFILE%\.ycode-release\update-signing.key`,仅当前 Windows 账户可访问,不在仓库内。
|
||||
|
||||
当前 `package.json` 为内部版本 `0.0.5`,安装包名为
|
||||
`YCode-${version}-Setup-${arch}.${ext}`。`0.0.5` 已构建、签名清单验证并发布到
|
||||
`local001`。本轮未执行安装包 Authenticode 复验,不能把该发布包声明为已做代码签名。
|
||||
|
||||
## 2. 清单契约
|
||||
|
||||
完整契约见 `resources/updates/manifest-contract.md`。
|
||||
|
||||
```json
|
||||
{
|
||||
"payload": {
|
||||
"schemaVersion": 1,
|
||||
"version": "0.0.5",
|
||||
"publishedAt": "2026-10-20T10:00:00.000Z",
|
||||
"notes": { "zh": "更新说明", "en": "Release notes" },
|
||||
"platforms": {
|
||||
"windows-x64": {
|
||||
"url": "http://192.168.10.6/ycode/releases/versions/0.0.5/YCode-0.0.5-Setup-x64.exe",
|
||||
"size": 123456789,
|
||||
"sha256": "64-lowercase-hex"
|
||||
}
|
||||
}
|
||||
},
|
||||
"signature": "base64-ed25519-signature"
|
||||
}
|
||||
```
|
||||
|
||||
- Ed25519 签名覆盖且仅覆盖 `Buffer.from(JSON.stringify(payload), "utf8")`。
|
||||
- payload 字段插入顺序属于签名契约,发布脚本固定为 `schemaVersion, version, publishedAt, notes, platforms`。
|
||||
- SHA-256 为小写十六进制;大小是实际安装包字节数。
|
||||
- 安装包 URL 必须是绝对 HTTP(S)、无查询、无片段、无凭据,并精确位于
|
||||
`<base>/versions/<version>/` 下。
|
||||
- 客户端只接受与清单同源的安装包 URL 和同源重定向。
|
||||
- `latest.json` 禁止缓存;版本目录和安装包内容不可覆盖。
|
||||
|
||||
## 3. 发布命令
|
||||
|
||||
### 一键打包发布(推荐)
|
||||
|
||||
在 Windows x64 发布机的项目目录运行:
|
||||
|
||||
```powershell
|
||||
npm run release
|
||||
```
|
||||
|
||||
按提示输入新的正式版本号,例如 `0.0.6`,随后自动执行预检、更新本地版本、升级回归测试、
|
||||
完整构建、NSIS 打包、签名清单生成、部署预检、SSH 发布与 HTTP 清单复核。默认发布到
|
||||
`local001`,继续使用现有用户目录中的私钥和仓库公钥,不需要手动复制安装包或清单。
|
||||
只输入版本号时会使用通用更新说明,也可以直接传参:
|
||||
|
||||
```powershell
|
||||
npm run release -- --version 0.0.6 --notes-zh '移除升级前的二次确认窗。' --notes-en 'Remove the upgrade confirmation dialog.'
|
||||
npm run release -- --help
|
||||
```
|
||||
|
||||
- 仅接受 `x.y.z` 正式版本;新发布版本必须高于服务器 latest,且不得低于仓库版本。
|
||||
- 安装包、签名清单保存在 `release/publish/<版本>/`;不会覆盖历史安装包,也不会自动安装或重启应用。
|
||||
- 同步更新 `package.json`、`package-lock.json` 的项目版本,不执行 Git 提交或打 tag。
|
||||
- 任一步失败即停止。本地目标版本和已有产物保留,不自动回滚服务器。
|
||||
- 已完成安装包和签名清单、但发布中断时,可复用原始产物重试;不会重新打包或重新签名:
|
||||
|
||||
```powershell
|
||||
npm run release -- --version 0.0.6 --resume
|
||||
```
|
||||
|
||||
复用模式仍校验版本、签名、大小、哈希和安装包身份;服务器同版本必须与本地清单完全一致,
|
||||
更高版本或同版本不同内容都会被拒绝。若失败时尚未生成完整签名清单,不能使用复用模式。
|
||||
若已留下不完整的版本输出目录,普通模式不会覆盖它;可使用更高版本重新发布,或确认该版本
|
||||
未发布后手动移走不完整产物,再重新运行同版本发布。
|
||||
脚本使用本地独占锁避免重复运行;异常终止留下锁时,应先确认没有发布进程运行,再处理报错指出的锁文件。
|
||||
`npm run test:release` 使用隔离的假执行器验证流程,不连接升级服务器、不实际打包或发布。
|
||||
|
||||
以下为手动分步命令,便于排障;通常无需执行。
|
||||
|
||||
先完成协调方构建,确认安装包已经包含 updater 并完成基础启动验收。不要发布当前
|
||||
`release/YCode-v0.01-Setup-x64.exe`:它的 ProductVersion 是 `0.0.1`,且没有更新能力。
|
||||
|
||||
### 3.1 准备签名清单
|
||||
|
||||
```powershell
|
||||
Set-Location 'C:\Users\Administrator\code\YCode'
|
||||
|
||||
node scripts/updates/prepare-release.mjs `
|
||||
--installer 'release\YCode-0.0.5-Setup-x64.exe' `
|
||||
--version '0.0.5' `
|
||||
--notes-zh '修复 Electron ASAR 安装标记误判,恢复重启升级。' `
|
||||
--notes-en 'Fix Electron ASAR installation-marker misclassification and restore restart-based upgrades.' `
|
||||
--output '.tmp\updates\0.0.5\latest.json'
|
||||
```
|
||||
|
||||
该命令在生成清单前强制检查:
|
||||
|
||||
1. 文件名安全且为 `.exe`。
|
||||
2. 实际 EXE ProductVersion 等于 `--version`。
|
||||
3. `package.json` 的版本等于 `--version`。
|
||||
4. 版本高于无 updater 的 `0.0.1` 基线。
|
||||
5. 安装包大小为 20 MiB 到 4 GiB,SHA-256 从实际文件计算。
|
||||
6. 签名能被仓库公钥验证。
|
||||
|
||||
### 3.2 只读预检
|
||||
|
||||
```powershell
|
||||
node scripts/updates/deploy.mjs `
|
||||
--manifest '.tmp\updates\0.0.5\latest.json' `
|
||||
--installer 'release\YCode-0.0.5-Setup-x64.exe' `
|
||||
--transport ssh `
|
||||
--ssh-host local001 `
|
||||
--dry-run
|
||||
```
|
||||
|
||||
预检会重新计算安装包哈希、验证清单签名、读取并验证服务器现有
|
||||
`latest.json`,然后检查版本单调性;不会修改服务器。
|
||||
|
||||
### 3.3 正式发布
|
||||
|
||||
```powershell
|
||||
node scripts/updates/deploy.mjs `
|
||||
--manifest '.tmp\updates\0.0.5\latest.json' `
|
||||
--installer 'release\YCode-0.0.5-Setup-x64.exe' `
|
||||
--transport ssh `
|
||||
--ssh-host local001
|
||||
```
|
||||
|
||||
发布顺序:
|
||||
|
||||
1. 安装包和清单先上传到 `/srv/ycode-staging/<随机 ID>/`。
|
||||
2. 服务端重新校验大小和 SHA-256。
|
||||
3. 新版本先以目录重命名方式进入不可变 `versions/<version>/`。
|
||||
4. 从已验签 payload 生成转义后的静态 `index.html`,包含版本、安装包链接、SHA-256 和中英文说明。
|
||||
5. 在文件锁下再次确认现有 `latest.json` 未在发布期间变化。
|
||||
6. 先原子替换 `index.html`,再原子替换 `latest.json`;最后一步失败时回滚旧页面。
|
||||
|
||||
任何一步失败,旧 `latest.json` 保持不变。已落盘但未成为 latest 的版本目录可以作为
|
||||
同版本重试的幂等产物;若同版本目录中的包哈希不同,发布会被拒绝。
|
||||
|
||||
### 3.4 发布后复核
|
||||
|
||||
```powershell
|
||||
node scripts/updates/deploy.mjs `
|
||||
--manifest '.tmp\updates\0.0.5\latest.json' `
|
||||
--installer 'release\YCode-0.0.5-Setup-x64.exe' `
|
||||
--transport ssh `
|
||||
--ssh-host local001 `
|
||||
--dry-run
|
||||
|
||||
Invoke-WebRequest 'http://192.168.10.6/ycode/releases/latest.json' -UseBasicParsing |
|
||||
Select-Object StatusCode,Headers,Content
|
||||
```
|
||||
|
||||
## 4. 验证命令
|
||||
|
||||
### 4.1 发布工具自测
|
||||
|
||||
```powershell
|
||||
node scripts/updates/selftest.mjs
|
||||
node scripts/updates/contract-selftest.mjs
|
||||
```
|
||||
|
||||
`selftest.mjs` 使用临时目录、临时密钥和本地 HTTP 服务,不上传 SSH,也不会写正式站点。
|
||||
当前覆盖:
|
||||
|
||||
- 密钥生成、公钥格式和 Windows ACL。
|
||||
- SemVer 优先级和 build metadata 规则。
|
||||
- 签名精确载荷、说明/哈希/签名篡改拒绝。
|
||||
- URL 查询、片段、凭据、跨版本路径、时间格式和小写哈希策略。
|
||||
- 本地假传输发布、HTTP 拉取、大小与 SHA-256 复核。
|
||||
- 幂等重发、同版本冲突、降级拒绝、失败前旧 latest 保持。
|
||||
- 下载页文本转义、无脚本、latest/页面同步切换和失败时页面回滚。
|
||||
|
||||
`contract-selftest.mjs` 用 esbuild 加载 `src/main/updates/manifest.ts`,验证发布端清单能被
|
||||
后端实际解析、验签和路径策略接受。
|
||||
|
||||
### 4.2 服务端验证
|
||||
|
||||
```powershell
|
||||
ssh local001 "nginx -t"
|
||||
|
||||
Invoke-WebRequest 'http://192.168.10.6/ycode/releases/latest.json' -Method Head -UseBasicParsing
|
||||
Invoke-WebRequest 'http://192.168.10.6/ycode/releases/' -UseBasicParsing
|
||||
Invoke-WebRequest 'http://192.168.10.6/baocode/' -Method Head -UseBasicParsing
|
||||
```
|
||||
|
||||
当前预期状态:YCode latest 为 200 且版本为 `0.0.5`,下载页为 200 并包含线上版本、链接和哈希,
|
||||
`/baocode/` 为 403;YCode 不能开启目录浏览。
|
||||
|
||||
`0.0.5` 的隔离启动和真实 LAN 清单/安装包下载验证已通过:
|
||||
|
||||
- 脚本:`node scripts/verify-updates-live.cjs --expected-version 0.0.5`
|
||||
- 结果:PASS;实际启动、签名清单校验、完整下载、大小和 SHA-256 均通过。
|
||||
- 报告:`.tmp/updates-live/2026-10-20T10-28-49-489Z/report.json`。
|
||||
- 产物验证:`app.asar` 内版本为 `0.0.5`,更新实现包含修复后的 ASAR 安装标记判定,打包公钥与仓库一致。
|
||||
- 边界:本轮没有启动 NSIS 安装器,没有重启或修改当前用户安装,因此这不等于真实覆盖升级验收。
|
||||
|
||||
## 5. 首次更新基线
|
||||
|
||||
现有 `0.0.1` 客户端没有 updater,不能通过更新服务器升级到 `0.0.5`。
|
||||
|
||||
正在运行的 `0.0.3`、`0.0.4` 客户端受旧版检查器的 ASAR 安装标记误判影响,应手工安装
|
||||
`0.0.5` 引导包,不能把“发现更新”视为该路径已经可用。`0.0.1` 同样需要手工安装
|
||||
`0.0.5`。其他旧版客户端的真实覆盖路径仍以隔离环境复测为准。引导到 `0.0.5` 后:
|
||||
|
||||
```text
|
||||
0.0.1(无 updater,手动安装 0.0.5)
|
||||
0.0.3 / 0.0.4(检查器存在已知问题,手动安装 0.0.5)
|
||||
→ 启动 0.0.5 并确认实际版本
|
||||
→ 后续版本由 0.0.5 检查、下载、签名校验
|
||||
→ 用户在应用中确认重启
|
||||
→ NSIS 覆盖安装
|
||||
→ 新版本启动后核对实际版本
|
||||
```
|
||||
|
||||
不能把“上传成功”“清单可下载”或“客户端显示发现更新”当作端到端升级验收。至少还需要一次
|
||||
隔离安装目录的真实 `0.0.4 → 0.0.5` 覆盖安装测试。
|
||||
|
||||
## 6. 密钥管理
|
||||
|
||||
- 私钥只允许存在于发布机用户目录或离线加密备份,不进入仓库、服务器、构建产物、聊天记录和日志。
|
||||
- 公钥随客户端分发并作为固定信任锚。
|
||||
- 当前私钥 ACL 仅授予 `WIN-JA8HHLU9216\Administrator`。
|
||||
- 发布前可运行 `init-key.mjs` 的默认路径检查;路径已存在时脚本会拒绝覆盖。
|
||||
- 私钥丢失或泄露时,不能用旧客户端认可的常规更新完成轮换。需要构建一个包含新公钥的
|
||||
临时安装包,手工分发并安装,同时提升版本;之后再由新密钥继续发布。
|
||||
- 不要为了“省事”在服务器上保留私钥,也不要将私钥复制到 `/srv/ycode`。
|
||||
|
||||
## 7. 已知限制
|
||||
|
||||
- 当前为 LAN HTTP,仅适用于能访问 `192.168.10.6` 的设备。没有 TLS、登录鉴权、限流和外部 CDN。
|
||||
- 签名可防止安装包和清单被替换,但不能防止同网段攻击者阻断下载或造成拒绝服务。
|
||||
- 尚未接入 HTTPS 域名、证书、灰度发布、多渠道、增量更新或正式 Authenticode 签名。
|
||||
- 服务端没有回滚命令;发布后需要回退时必须发布一个更高版本,不能覆盖已发布版本目录。
|
||||
- `resources/updates/public-key.pem` 已进入 Electron `extraResources`;正式包仍需做一次资源存在性验收。
|
||||
- 推荐 `0.0.5` 安装包的 Authenticode 状态本轮未复验;真实性目前以 Ed25519 签名清单、
|
||||
文件大小和 SHA-256 为已验证边界。
|
||||
- 本轮没有执行真实 `0.0.4 → 0.0.5` 覆盖升级,也没有在独立用户目录完成完整安装/卸载验收。
|
||||
- 专用 NSIS 运行时探针没有执行;安装器写入、覆盖、重启和卸载行为仍是测试缺口。
|
||||
@@ -0,0 +1,49 @@
|
||||
# 升级模块落地(2026-10-20)
|
||||
|
||||
## 真实升级反馈:ASAR 标记误判
|
||||
|
||||
用户在 `0.0.3 → 0.0.4` 测试中实际遇到 `NSIS 安装标记不是文件`。物理安装文件正常;原实现使用 Electron patched `fs.stat`,将 `resources/app.asar` 当作虚拟目录。此前 Node 后端测试和未调用安装器的启动/下载验证没有覆盖这个语义差异。
|
||||
|
||||
修复通过 `physical-files.ts` 的 Electron `node:original-fs` 适配器执行物理 `stat/realpath`,由生产更新入口注入。没有全局关闭 ASAR,也没有移除 `isFile`、注册表或路径校验。真实 Electron 只读测试 `node scripts/verify-updates-installer-marker.cjs` 已通过:当前真实安装目录校验成功,真实目录 marker 和错误 registry 仍被拒绝;未启动安装器、未修改用户安装。报告 `.tmp/updates-installer-marker/2026-10-20T10-23-07-489Z/report.json`。
|
||||
|
||||
修正版为 `0.0.5`。旧版 `0.0.3/0.0.4` 的运行中检查器无法通过服务器目标包自我修复,需要手动覆盖安装一次修正版后,再测试后续自动升级。
|
||||
|
||||
`0.0.5` 已构建并发布,237106337 字节,SHA-256 `a3b8ece96077af81f9c8c676cb7d0d71f16a5d73332bc48b865c5cba7e92fd0d`。最终 ASAR 已核对包含物理文件适配器;生产包隔离启动与正式 IPC、服务器签名清单及完整下载校验通过,报告 `.tmp/updates-live/2026-10-20T10-28-49-489Z/report.json`。没有替用户执行安装或重启,真实覆盖安装仍待用户继续验证。
|
||||
|
||||
## 实现与边界
|
||||
|
||||
- Windows x64、Electron + NSIS 按用户安装;账号菜单、关于页与侧栏共享真实更新状态。
|
||||
- 启动 10 秒后检查,此后每 5 分钟检查;发现更新后后台下载,已忽略版本不自动下载。
|
||||
- 检查中、下载进度、就绪、失败重试、按版本忽略/折叠、手动下载及安装诊断日志已接通。
|
||||
- 原版参考为 WorkBuddy 5.8.3,ASAR SHA-256 `3e50fcb5b060deba4f1ea9a8c293cf955bf12d7e52d971985de914350afd9077`;主要 REA Evidence 为 `ev_6f16b9ef02d9c5fb142e7d686ea8caeeec79797b621d615aaa532b49b65d7ad9`(renderer)与 `ev_e41b1e44cb0c430be5d8caa14b4e3a4710a6925e0bdff870d42ffa73b5e1a5c8`(Windows 更新模块)。本轮复用历史静态 REA 结论,没有通过其他渠道查看原版。
|
||||
- 强制升级、商店/企业分支、启动 splash 与架构纠正仍在后续完整复刻清单中。本轮普通更新交互不是完整 1:1 验收;缺少原版全状态运行态布局/动效/像素证据。
|
||||
|
||||
## 安全与退出
|
||||
|
||||
- 完整 payload 使用独立 YCode Ed25519 密钥签名;客户端先验签再采用版本、说明、大小、下载地址与哈希。公钥随包分发;私钥仅在仓库外保存。
|
||||
- 同源、固定版本目录、严格 SemVer、响应体上限、超时、大小与 SHA-256 校验;断点续传检查 Content-Range;缓存和安装前再次校验。
|
||||
- 多窗口 IPC 仅接受主窗口/设置窗口的主 frame;渲染层不接收 Node 能力或安装路径参数。
|
||||
- 用户确认前不启动安装器。确认后暂停新任务/终端创建,停止调度并取消、等待当前任务落库;该准备阶段不销毁全局 Claude 内核/MCP。
|
||||
- 准备超时后,不会在旧 stop 尚未结束时恢复服务;安装标记写入或 spawn 失败后允许恢复。
|
||||
- 安装器成功 spawn 是不可回退提交点;后端拒绝重复安装/检查/忽略,不再恢复后台任务。随后有界清理资源并退出,避免已启动的安装器和恢复后的工作并存。
|
||||
- NSIS 等待指定 PID 后检查残留实例;不使用进程名批量结束其他实例。真实执行行为以专项安装 QA 结果为准。
|
||||
- 安装位置绑定当前用户注册表 GUID、当前 EXE、卸载器与 app.asar,支持用户选择的目录;便携解压/开发模式不执行覆盖安装。
|
||||
- 记录目标版本,下次启动仍低于目标则提示升级未完成。安装器执行失败不会被误报为已升级。
|
||||
|
||||
## 验证
|
||||
|
||||
- `npm run test:updates`:后端 14 组;运行时门禁与生命周期专项;发布工具 12 组;发布清单与真实后端验签/路径契约检查通过。
|
||||
- `npm run build`:完整主进程、preload、renderer 构建和 Node/Web 类型检查通过。
|
||||
- `npm run test:updates:ui`:真实 Electron 主/设置窗口、正式 preload、注入确定性 updates IPC,验证渲染交互和跨窗口状态;最终报告 `.tmp/updates-ui-ZnQVYZ/report.json`,无 renderer 错误。该验证不等价于真实下载或安装。
|
||||
- `npm run test:chat`:消息顺序、聊天状态、流式提交旧回归通过。
|
||||
- `0.0.2` 的真实生产包隔离启动与 HTTP 下载验证通过;报告 `.tmp/updates-live/2026-10-20T09-43-52-041Z/report.json`。前代版本号为注入模拟,安装器调用为零,不是实际版本升级。
|
||||
- 审查发现并修复安装失败后内核永久关闭、超时清理继续破坏恢复、确认期间并发忽略、spawn 后回滚、NSIS 错误码与残留进程检查问题;修正版内部版本递增为 `0.0.3`,不覆盖不可变 `0.0.2` 发布。
|
||||
- `0.0.3` 已构建并发布,安装包 `release/YCode-0.0.3-Setup-x64.exe`,237105798 字节,SHA-256 `6f7565fcc152a99899bf74a795c8e91417516980f143fb9fccb61bde2b490200`。
|
||||
- `0.0.3` 真实生产包隔离启动与正式 preload IPC 检查通过(idle → checking → up-to-date);真实服务器签名清单及全量安装包下载/哈希通过,模拟旧版本最终 ready/100。报告 `.tmp/updates-live/2026-10-20T10-02-05-040Z/report.json`。安装器/安装回调调用均为零;真实用户注册表与安装 EXE 指纹前后未变。
|
||||
- 完整 NSIS 真机覆盖安装、原生确认取消、安装后重启/版本回查,以及等待宏的不存在 PID/睡眠 PID/第二实例/拒绝访问动态探针仍未执行。独立 QA 安装方案仅完成设计,没有构建或安装 fixture;不能把单元、渲染或真实下载测试当作已完成安装验收。
|
||||
|
||||
## 发布与使用
|
||||
|
||||
服务器为 `local001`,客户端更新入口为 `http://192.168.10.6/ycode/releases/latest.json`,手动下载页为 `http://192.168.10.6/ycode/releases/`。SSH 仅用于发布维护,客户端不需要 SSH 凭据。HTTP 限内网使用;真实性依赖内置公钥,不能防止网络阻断/旧清单重放导致的更新延迟。
|
||||
|
||||
参见 [升级发布说明](升级发布说明-2026-10-20.md)。`0.0.1` 未包含 updater,必须先关闭旧 YCode 并手动安装首个安全验收完成的基线包,之后才有自动更新能力。安装包尚未 Authenticode 签名,系统可能显示 SmartScreen 警告。没有替换或重启当前用户安装版,也没有修改其配置/会话或提交 Git。
|
||||
@@ -0,0 +1,53 @@
|
||||
# 技能详情、安装与使用链路修正(2026-10-20)
|
||||
|
||||
## 本轮实现
|
||||
|
||||
### 头像与详情
|
||||
|
||||
- 核对 GitHub 官方仓库 owner 为 `tt-a1i`(ID `53142663`),下载官方头像并随 renderer 打包,不在运行时请求 GitHub。来源、URL 和文件哈希见[头像来源](推荐技能头像来源-2026-10-20.md)。
|
||||
- 推荐卡片、详情和带推荐来源的已安装卡片/详情统一显示头像,普通同名本地导入不套用。图片损坏降级首字母;未修改技能包、原 ZIP 哈希或内容 digest。
|
||||
- `SkillDetailShell` 统一推荐与已安装详情:头像/标题/主操作、可展开简介、真实元信息及按内容收缩的正文。移除仅展示来源却沿用正文最小高度导致的大块空白;完整 commit、包路径和哈希折叠展示,不编造安装数、使用数或市场 ID。
|
||||
- 已安装技能说明仍读取真实本地 SKILL.md。未安装时只展示内置精选简介,不提前下载整个包。
|
||||
|
||||
### 全局弹层与安装
|
||||
|
||||
- 根因:能力中心 `isolation:isolate` 限制了内部 fixed 遮罩的层叠范围,而侧栏 sticky 标题拥有独立层级。
|
||||
- 详情、导入及卸载确认使用 body 级 `SkillModalPortal`,保留源主题变量和 CSS 作用域;背景设为 inert / aria-hidden 并在退出后按原值恢复。没有降低全部侧栏层级。
|
||||
- 共用焦点栈,Esc 只关闭顶层,Tab/ShiftTab 包含折叠区 summary 并跳过闭合 details 内的不可见按钮,关闭后恢复焦点。技能弹层存在时不响应背景的应用导航快捷键。
|
||||
- 推荐卡片和详情共用操作状态。首次安全确认在原详情内展示;下载、校验、提交、失败、取消和成功均原位呈现,提交阶段不可取消。关闭详情不取消已确认安装,重新打开继续显示同一操作。
|
||||
- 成功按钮切换为“去使用”,成功提示也提供相同入口;移除列表底部重复的永久完成面板。失败可明确重试,覆盖确认仍展示当前来源、本地修改及启停保留。
|
||||
- 沿用操作 ID / 单调时间戳、防重复与跨窗口互斥。GitHub 官方 API、固定提交及 ZIP 安全/事务校验保持不变。
|
||||
|
||||
### 新草稿与斜杠
|
||||
|
||||
- 管理页各“去使用”入口统一调用 App 的新任务 intent:继承工作空间和模型,清除原任务专家绑定;带目标 owner 的 intent 将技能加入新草稿并聚焦,不发送、不创建持久会话。已有会话草稿不被覆盖。
|
||||
- 无效或仅模型调用技能不提供可执行的使用动作;禁用技能显示“启用后使用”,等待启用和状态确认成功后再跳转。
|
||||
- 斜杠问题根因:只修改 `text`,旧 `userContent` 在切换至 Slate 时重建了斜杠;菜单因检测到旧文本重新出现。
|
||||
- `withCapabilitySelection` 将技能选择、纯文本和结构化草稿合并为同一次草稿更新。斜杠采用 add-once 语义,加号菜单仍为多选 toggle。
|
||||
- 已有 Slate 编辑器通过文本叶事务删除触发区间,PointRef 保留光标与引用的相对位置,不删除附件或技能标签;恢复原生焦点以处理移除 picker 后 Slate 焦点缓存仍为 true 的情况。选择后可以直接继续输入。
|
||||
- Esc 记录当前触发文本的关闭状态,只有用户编辑后才重新检测;中文输入法组合期间不弹菜单。
|
||||
|
||||
## 接口与文件边界
|
||||
|
||||
- SkillsApi 不变;`RecommendedSkill.avatarResource` 新增可选受限标识 `archify-owner`,不是任意本地路径或 URL。
|
||||
- 输入区内部回调增加可选 `CapabilitySelectionIntent`(slash/menu 来源及已消费的 text/userContent);ReferenceContentEditor 增加删除文本区间的宿主方法。
|
||||
- 新增公共详情/portal/头像及源文件选择 helper。未修改 WorkBuddy 安装文件,也未改变技能下载的主进程信任边界。
|
||||
|
||||
## 原版依据与限制
|
||||
|
||||
- 本轮按用户选择仅做原版只读源码调查,没有启动额外 WorkBuddy 实例或安装原版技能。
|
||||
- WorkBuddy 5.8.2 已保存 REA 证据 `ev_717fa5e846e64d67ac19c8925d121bff632c0d3aefb3603b10858559cabb2dcb` 的恢复源码中,`ActionRow` 随安装状态切换安装/使用;`toastSkillInstallSuccess` 带使用动作;`useTrySkill` 普通分支进入新任务草稿。
|
||||
- 本次 REA 请求 `127.0.0.1:9223` 返回 endpoint_unreachable。当前安装包 SHA-256 为 `3e50fcb5b060deba4f1ea9a8c293cf955bf12d7e52d971985de914350afd9077`,与历史技能证据不同;REA inventory 记录 45 项完整性矛盾,历史文件路径不能直接选中。此次 inventory 仅作身份/限制记录,不据此宣称分析了当前版本的详情实现。父 Evidence:`ev_1908879a0d710764cd53bd08c36bd9d70d07a004c08ee8f711ca6f849a3b6244`。
|
||||
- 因此是“历史 REA 源码行为依据 + YCode 实现及动态验收”,不是当前原版同场景动态或完整 1:1 验收。安装完成也不意味着 Archify 的执行依赖和全部绘图能力已验证。
|
||||
|
||||
## 验证
|
||||
|
||||
- `npm run test:capability-slash:ui`:真实 ComposerControls / Slate / 生产选择 helper 的隔离 Electron 测试 **21 项通过**,`.tmp/capability-slash-3UD46Z/report.json`。覆盖鼠标、Enter、裸斜杠、句中光标及后文、已有与重复技能、继续输入、多行、附件、Esc、IME;零 renderer 错误。
|
||||
- `npm run test:recommended-skills:ui`:**48 项通过**,`.tmp/recommended-skills-ui-LGtBA4/report.json`。受控宿主覆盖确认与同一详情 DOM、成功入口、取消、关闭再打开保留操作、提交不能取消、禁用后启用使用、冲突替换、错误重试、外部操作、过期事件、Tab 焦点和深/浅色窄窗。不是实际网络安装。
|
||||
- `node scripts/test-skills-ui.mjs`:既有管理/真实隔离文件系统与受控 picker **37 项通过**,最终单独复跑 `.tmp/skills-ui-10SOjj/report.json`;并发运行曾发生一次坐标点击未切换批量态的测试失败,独立复跑通过,不将其隐藏为从未失败。
|
||||
- `npm run test:recommended-skills`:后端 **66 项通过**,包括离线缓存的 Archify 实包组;没有更改下载与导入校验策略。
|
||||
- `npm run test:composer-capabilities`、`npm run test:conversation`、`npm run test:persistence`、`npm run test:sessions` 均通过。输入区回归日志 `.tmp/skills-flow-composer-regression.log`。
|
||||
- 类型检查及完整构建通过,日志 `.tmp/skills-flow-build.log`。
|
||||
- 正式 main/preload/renderer 真实 GitHub 下载隔离验收 **20 项通过**,最终报告 `.tmp/recommended-app-RFA1cK/report.json`;包含 body 级遮罩、背景 inert、侧栏命中测试、全窗深色/720px 截图、离线头像、原位安装、新草稿引用、原会话草稿恢复及无持久会话新增。主线程查看同批实现的全窗/窄窗、安装成功和输入区截图。
|
||||
|
||||
所有技能安装、启停和草稿测试均使用 `.tmp` 隔离数据,未操作用户技能库、执行技能脚本或请求模型。保留既有修改,未提交、发布或重启用户安装版。
|
||||
@@ -1,5 +1,19 @@
|
||||
# YCode 接手状态(2026-10-15)
|
||||
|
||||
> 2026-10-20 23:53(Asia/Shanghai)0.0.7已发布:[发布记录与验证](升级发布说明-2026-10-20.md)。包含本轮推荐技能/GitHub安装、头像、详情遮罩、原位安装/去使用、新任务草稿、斜杠菜单及既有技能/MCP输入区接入。local001 latest从0.0.6升至0.0.7,历史版本保留;237351255字节,SHA-256 `506768934c92979ba38c4ab922b58d2de98b590a125fd1a5dacd8dadd2ddaff3`。升级回归、发布17项、完整构建、包内内容、公钥、签名清单、SSH/HTTP、正式生产EXE隔离启动与真实全量下载校验通过,报告 `.tmp/updates-live/2026-10-20T15-53-57-094Z/report.json`。安装包Authenticode为NotSigned;仅更新清单Ed25519签名。未执行安装器、覆盖升级或重启用户安装版,未Git提交。
|
||||
|
||||
> 2026-10-20 技能详情/安装/使用链路修正:[实现与验证](技能详情安装与使用链路修正-2026-10-20.md)。Archify 改用本地打包的 GitHub owner 头像;推荐和已安装共用紧凑详情,body portal + inert 修复侧栏 sticky 标题穿透。安装确认、进度及成功“去使用”原位衔接,成功提示也可用;使用进入新任务草稿、保留旧会话草稿、不自动发送。斜杠选择原子消费 text/userContent,Slate 文本事务保留引用及光标、修复原生焦点,Esc/IME/重复选择和加号多选语义区分。真实 Slate 21项、推荐UI48项、既有技能管理37项、后端66项、最终正式Electron真实GitHub安装/遮罩/草稿保留20项及类型检查、构建、输入区/对话/持久化/会话回归通过;最终报告 `.tmp/recommended-app-RFA1cK/report.json`。原版仅依据历史5.8.2 REA源码,当前runtime不可达,不是当前原版动态1:1验收。隔离验证,未改用户技能、执行包内脚本、请求模型、提交、发布或重启安装版。
|
||||
|
||||
> 2026-10-20 推荐技能 GitHub 下载修复:用户网络对 raw.githubusercontent.com 直链 ECONNRESET,改用 GitHub 官方 Contents API 的 raw 响应,仍固定完整 commit、原 ZIP 大小及 SHA-256,不引入镜像或修改代理。后端66项、官方API真实下载实包48项、正式Electron隔离安装与引用11项、类型检查及构建通过;重启仓库dev加载修复,未动安装版或用户技能。见[修复与证据](推荐技能GitHub安装-2026-10-20.md#github-直链连接失败修复)。
|
||||
|
||||
> 2026-10-20 内置推荐技能与 GitHub 安装:[实现与验证边界](推荐技能GitHub安装-2026-10-20.md)。技能页推荐接固定 Archify 3.2.0 包,主进程下载、哈希/元数据校验、取消、覆盖确认及原子回滚,来源同次登记,安装/启停/卸载实时刷新输入区目录。后端62项、实包48项、推荐UI37项(含深色/窄窗/外部操作/过期事件)、既有技能UI37项、最终生产Electron真实GitHub下载与输入框回填11项,以及类型检查、完整构建和相关回归通过;已看真实截图,零renderer错误。仅验证文件安装与引用,不宣称Archify全部运行能力或完整1:1。隔离验收,未改用户技能、执行包内脚本、提交、发布或重启用户安装版。
|
||||
|
||||
> 2026-10-20 MCP/技能与对话输入区接入:[实现与验证边界](MCP技能与输入区接入-2026-10-20.md)、[原生追加/压缩协议](Claude追加与压缩协议验证-2026-10-20.md)。启用宿主管理能力桥接、加号/斜杠引用、统一输入区、持久追加队列与不打断的原生立即发送;支持下一请求模型设置、真实上下文统计和原生压缩。完整构建、相关回归及真实 Electron 主进程/预加载/渲染器+本地 Claude SDK/CLI 回环追加验证通过,主线程已检查队列和最终历史截图。原版 REA 运行时不可达,团队/后台任务来源未完整接线,不能宣称完整 1:1;真实外部服务和故障注入仍有边界。保留升级模块等既有修改,未提交、发布、安装或重启用户安装版。
|
||||
|
||||
> 2026-10-20 真实升级 ASAR 标记误判修复:用户 `0.0.3 → 0.0.4` 报“NSIS安装标记不是文件”,已确认 Electron patched fs 将正常物理 `app.asar` 显示为虚拟目录。改为由生产入口注入 `node:original-fs` 的物理 stat/realpath,保留全部安装身份检查。真实Electron只读 marker 回归、后端14组、发布与契约、完整构建通过;`0.0.5` 已构建发布,生产包隔离启动及真实全量下载校验通过,未执行安装。旧3/4检查器不能靠服务器目标包修复,须手动覆盖安装一次5;详细记录见[升级模块落地](升级模块落地-2026-10-20.md#真实升级反馈asar-标记误判)。
|
||||
|
||||
> 2026-10-20 普通升级模块落地:[实现与验证边界](升级模块落地-2026-10-20.md)、[发布与密钥说明](升级发布说明-2026-10-20.md)。账号菜单/关于页/侧栏接共享更新状态,签名清单、后台下载/续传、大小与哈希校验、退出确认、任务收尾、NSIS 定点等待和安装失败回查已实现;更新源为 local001 的独立 `/ycode/`,最终修正版 `0.0.3` 已构建并发布,不覆盖不可变 `0.0.2`。后端14组、门禁/生命周期、发布12组、真实后端契约、NSIS静态安全检查、真实Electron UI21项(0renderer错误)、聊天回归及完整构建通过。完整真实NSIS覆盖安装/重启尚未验收,不是完整1:1;强制升级/商店/企业/启动splash继续待补。未替换当前用户安装版;原0.0.1无更新器,需先手动安装基线。未提交Git。
|
||||
|
||||
> 2026-10-20 文件所有权租约移除:[范围与验证](文件所有权租约移除记录-2026-10-20.md)。按用户要求删除子智能体调度器的 `leases`、`rootIntents`、`rootLeases` 和 root 等待队列;主智能体工具、子智能体工具以及父子同文件写入不再因所有权被拒绝或串行。保留 `spawn_agent` 的声明文件列表校验,`write` 模式仍只能写自己声明的路径。`npm run typecheck`、`npm run test:subagents`(31 项)和完整 `npm run build` 通过。移除后并发写同一文件按工具实际执行顺序生效,无跨工具锁;需要原子一致性时由调用方或更高层流程处理。
|
||||
|
||||
> 2026-10-20 自建 AppContainer 沙盒移除:[范围与验证](沙盒移除记录-2026-10-20.md)。按用户要求删除 `src/main/sandbox`、`native/sandbox`、`resources/sandbox`、`sandbox_workspace`/`sandbox_git` 工具、相关构建/测试/维护脚本、打包 extraResources 和忽略规则;保留 Electron `webPreferences.sandbox` 渲染进程隔离及“默认权限/完全访问”权限界面。`npm run typecheck` 与 `npm run build` 通过,`out/main/index.mjs` 不再包含 `windows-appcontainer`、`sandbox_workspace`、`sandbox_git`、`ycode-sandbox`;`release/win-unpacked/resources/sandbox` 已清理。本仓库不再提供自建 OS 级沙盒;此前所有沙盒验收结果只作为历史记录,不代表当前代码能力。
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
# 内置推荐技能与 GitHub 安装(2026-10-20)
|
||||
|
||||
## 实现范围
|
||||
|
||||
- 技能页“推荐”改用随应用发布的精选目录;首发 Archify。SkillHub、套件仍明确未接入,不伪装联网市场。
|
||||
- 复用现有技能卡片、详情及主题;提供安装确认、下载/校验/安装进度、取消、错误重试、查看已安装和使用技能。替换确认展示当前来源、本地修改及启停状态。
|
||||
- 主进程只接受推荐 ID 和操作 ID/覆盖确认,不接受渲染器提供下载地址、哈希或安装目录。
|
||||
- 固定 HTTPS GitHub 官方来源,最多三次白名单域名重定向,20 MB 下载上限、120 秒下载超时;校验 SHA-256、名称、版本、许可证,再复用 ZIP 安全检查及暂存/备份/回滚事务。
|
||||
- 全进程最多一个推荐安装,不排队、不自动重试。下载/校验可取消,原子提交不可取消;停服或退出中止尚未提交的操作。启动清理可确认所属进程已退出的遗留临时目录,不续装。
|
||||
- 来源元数据和技能登记同次提交;旧登记兼容。同名导入、不同版本或修改后的技能须明确替换,保留启停状态;同来源同版本且完整的安装直接返回现有记录。手动导入覆盖会清除推荐来源。
|
||||
- 安装、卸载、启停广播变更,刷新推荐、已安装列表及输入框能力目录,无需重启。
|
||||
|
||||
## 固定包
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 推荐 ID / 名称 | archify |
|
||||
| 仓库 | tt-a1i/archify |
|
||||
| commit | 25cf37080fc8b1dbe758a4efc3935b55f3327083 |
|
||||
| 包路径 | archify.zip |
|
||||
| SHA-256 | 70e210265c59f24dcbdf2a502ff671104b5454e7ee7d3554aecd86bad32384f5 |
|
||||
| 下载字节数 | 5,271,959 |
|
||||
| ZIP 文件数 / 展开字节数 | 200 / 17,812,933 |
|
||||
| 许可证 / 显示版本 | MIT / 3.2.0 |
|
||||
|
||||
实包 `SKILL.md` 中的 `metadata.version` 为 `3.2`,`package.json` 为 `3.2.0`;仅将数字形式的 major.minor 与 major.minor.patch 归一比较,未改用最新分支。包含 101 个 JS/MJS 脚本;安装不执行包内脚本,也不读取其更新地址。
|
||||
|
||||
## 代码入口
|
||||
|
||||
- `src/main/capabilities/skill-recommendations.ts`:版本化精选目录。
|
||||
- `src/main/capabilities/recommended-skills.ts`:下载、安全边界、进度和生命周期;注入端口仅作测试隔离。
|
||||
- `src/main/capabilities/skills.ts`:来源保存、嵌套版本解析、现有导入器复用及提交前冲突检查。
|
||||
- `src/shared/capabilities.ts`、`src/main/ipc.ts`、`src/preload/index.ts`:目录、安装、取消、当前操作快照、进度及变更事件。
|
||||
- `src/renderer/src/capabilities/RecommendedSkills.tsx`:卡片与安装 UI,使用操作 ID 和单调时间戳抵御旧状态覆盖。
|
||||
- `src/renderer/src/workbuddy/composer/useCapabilityCatalog.ts`:变更后刷新输入框目录。
|
||||
|
||||
## 已验证
|
||||
|
||||
- `npm run typecheck` 和完整 `npm run build` 通过;构建日志 `.tmp/recommended-skills-build.log`。
|
||||
- `npm run test:recommended-skills`:62 项通过;包含模拟网络错误/重定向/超限/超时/断连/取消,真实隔离技能库中的同名覆盖、禁用保留、来源清除、安装中被修改、登记写入失败回滚与停服恢复。实包组使用本地缓存,没有缓存会明确 SKIP。
|
||||
- `npm run test:recommended-skills:ui`:最终 37 项通过,`.tmp/recommended-skills-ui-ED7GR0/report.json`;使用隔离 Electron 和受控宿主,覆盖其他窗口操作互斥、过期事件不回退终态、深色主题及 720px 窄窗无横向溢出。主线程检查深色/窄窗截图;不冒充真实网络安装或完整应用壳的深色验收。
|
||||
- `node scripts/test-skills-ui.mjs`:既有技能管理 37 项通过,`.tmp/skills-ui-NeLZZW/report.json`。
|
||||
- `npm run test:recommended-skills:package`:实包隔离审计 48 项通过,最终复跑 `.tmp/archify-package-ZtYztG/report.json`(使用已下载固定 ZIP)。
|
||||
- 最终构建执行 `npm run test:recommended-skills:app`:11 项通过,`.tmp/recommended-app-G08DdX/report.json`。使用正式 main/preload/renderer、真实固定 GitHub 下载与隔离目录,确认阶段事件、正文/CLI 资源、来源、幂等、禁用保留,以及“使用技能”回填真实输入框;零 renderer 错误。主线程检查已安装及输入框截图。
|
||||
- `npm run test:composer-capabilities`、`npm run test:persistence`、`npm run test:sessions`、`npm run test:conversation` 通过。
|
||||
|
||||
## 明确边界
|
||||
|
||||
- 固定哈希说明下载内容一致,不构成技能代码安全审计;本次没有执行 Archify 命令、准备其运行依赖或验证全部绘图能力。
|
||||
- 不支持任意地址、私有仓库、自动更新或后台安装队列;后续推荐通过目录条目随 YCode 发布。
|
||||
- 所有验收使用隔离技能库,没有改动用户现有技能,也没有请求模型 API。未提交 Git、发布安装包或重启用户安装版;保留原有 MCP、输入区和升级模块等工作区修改。
|
||||
- 本次不新增 WorkBuddy 原版采集或完整 1:1 结论。
|
||||
|
||||
## GitHub 直链连接失败修复
|
||||
|
||||
用户实际 dev 安装报 `fetch failed`;同机重现 `raw.githubusercontent.com` 返回 `ECONNRESET`。改用 GitHub 官方 Contents API,完整 commit 放在 `ref` 参数,通过 `Accept: application/vnd.github.raw+json` 获取 ZIP 原始字节。实测 5,271,959 字节及登记哈希完全一致,不是 JSON 元数据,也未切换分支或第三方代理镜像。
|
||||
|
||||
下载仅放行 `api.github.com` 和 `raw.githubusercontent.com` 的 HTTPS 请求/跳转,原有大小、哈希、ZIP 安全、取消和事务保护保持不变。不自动重试或改变 Windows 代理配置。连接失败提供网络/代理提示,API 限流提供稍后重试提示;未加入 token 或私有仓库认证。
|
||||
|
||||
后端新增官方 API、固定提交、raw Accept 和限流回归,共 66 项通过。类型检查及完整构建通过(`.tmp/recommended-github-api-build.log`)。实包审计通过官方 API 真实下载 48 项通过:`.tmp/archify-package-kTQcPp/report.json`,未使用本地缓存。
|
||||
|
||||
最终正式 main/preload/renderer 隔离验收 11 项通过(`.tmp/recommended-app-kwzDyE/report.json`),实际经新 API 完成安装及输入框引用回填,零 renderer 错误。重启了本仓库的 dev 进程以加载修复,未重启安装版、修改系统代理或改动用户技能。
|
||||
@@ -0,0 +1,10 @@
|
||||
# Archify 推荐头像来源
|
||||
|
||||
- 核对接口:GitHub 官方 `GET https://api.github.com/repos/tt-a1i/archify`。
|
||||
- 仓库 owner:`tt-a1i`,GitHub 用户 ID `53142663`,类型 `User`。使用仓库所有者头像,不推断所有 contributors 都是维护者。
|
||||
- 头像 URL:`https://avatars.githubusercontent.com/u/53142663?v=4&s=192`。
|
||||
- 响应类型 `image/jpeg`,9,461 字节;本地文件 `src/renderer/src/capabilities/assets/archify-owner-avatar.jpg`。
|
||||
- SHA-256:`72e7c333a86d7954786fbb6782a6090ff1524964db50e7f293c6ba77f46ab85e`。
|
||||
- 随应用打包,页面不实时请求 GitHub;加载失败降级为首字母。推荐及带 Archify 推荐来源的已安装技能使用此图,普通同名本地技能不自动套用。
|
||||
- 图片只用于标识公开仓库所有者,不作为 YCode 自有商标或已获头像许可的声明;后续若收到权利人请求应更换或移除。
|
||||
- 未注入技能 ZIP、未改动包哈希或安装内容 digest。推荐记录的可选 `avatarResource` 为受限资源标识,不接受任意本地路径。
|
||||
Reference in new issue
Block a user