chore: establish YCode replication baseline and TODO
This commit is contained in:
commit
6dc59f89ba
1118 files changed
+196002
No files matched your search
@@ -0,0 +1,120 @@
|
||||
# 专家本地包契约与 REA 原文恢复(2026-10-16)
|
||||
|
||||
本轮已取得 WorkBuddy 5.8.2 本地专家扫描、激活、依赖、安装/导出实现,以及完整 expert-manager 技能、4 份规范和 5 个 Python 脚本。11 份技能资源已逐字恢复,另提供可静态 import 的 JSON;未运行原版技能/Python、未安装或启用原版专家。YCode host/环境适配与实际 backend 验收是后续独立工作,不能算本次原文导出已验证。
|
||||
|
||||
## 身份、范围与文件
|
||||
|
||||
固定根 ASAR SHA `035254bc76310ea46317433e4840602094543ef323d2d5c5aff7c131729de918`。版本依旧以已存 REA package.json(`ev_2caae424199a38371af743ef9111db835504c2dae54c1f02e1f9e5511032cc6b`)的 5.8.2 为准。起点为 `.tmp/rea-workbuddy-takeover-2026-10-15.json` 的 relevant-file inventory,Evidence `ev_df8468f8f31100525395ec493367a16770371db119cce47ca3ce19aacfd89eb7`。未重新全量分析;路径定位、原包读取均经 public REA CLI,未直接读取安装目录/用户目录、手写 ASAR extractor 或 CDP/evaluate。
|
||||
|
||||
| REA Evidence | 定向成员 | SHA-256 |
|
||||
|---|---|---|
|
||||
| `ev_81de6f628a156599f26ca795f6747ad3f8ec108de66fdba6e3723705905716f3` | `main/module.app-server.js` | `281666dbf81b76d64f95162a19dd2d02a41b35ec54239e0efc4e8e52419eb125` |
|
||||
| 同上 | `main/runtime-handlers.js` | `6567dd0f9ffdc78fd22a540e993590aa47190be6b6a9501a5fd0115392b0f5cf` |
|
||||
| `ev_75c9f1cb7975a8d61135abe7d4348024f305be540b10ba789094b0729a20358f` | `main/server.js` | `7e2a95d0615cce057e3076c57730f713bd42b63b146702f14cbf04d8671b7bef` |
|
||||
| `ev_1b2c1146db5458f4e7e163150512ece87e656c09dba5cffaa5d4cee367525ccc` | `main/tar.js` | `e252bf614cb59ffa96e16ad0ab8cfd8796f5ab920289ca9bd67376e1d9836cf3` |
|
||||
| `ev_c3df29dcb19c5fcaa9e458b1b9acff92e8c75ac935791e0c81900733e61b6282` | daemon bootstrap/main/entry、expert-manager metadata、builtin marketplace | 每项 SHA/bytes 在同名 `.tmp/rea-expert-package-ev_*.json`;daemon-main SHA `a3b9d6f3ca17954a89d4e442137348b230c8ea9c74181625556bfae2ffe98154` |
|
||||
| `ev_3cba49fcb15fefc59f54c7691500ad1121a937edb55e606addae17e4186ebfef` | `resources/plugins/workbuddy-builtin/skills/expert-manager/SKILL.md` | `18b0655c3e7573fe9402fd00a605d2dc94918c9eecd028f9f3923e74da17bc45` |
|
||||
| `ev_a4b0f399496f62f4dc41998e8327fb219ab84f3dca536ec6554553605b106735` | `references/plugin-json-spec.md` | `14e1a6b99c74815c22772a54725ba6d34750a6c9db4c75746c1188e31d2504f3` |
|
||||
| 同上 | `references/agent-md-spec.md` | `ec7373578a5f84d73ba16dcc71e73755e57aa4170cb07cd9bf379627c0f9c007` |
|
||||
| 同上 | `references/team-spec.md` | `1400af007c6b1179429c6d8c856dc1d45ae25dae63645097ddbc801d25d324f9` |
|
||||
| 同上 | `references/avatar-spec.md` | `0b42762e05e311632b2f89af35f34458f851a03cce3fcc0300ca0a75e9f8890e` |
|
||||
| `ev_25ded03a70790361a3f4fef21a3bd2466d5f7d3d118b7b7aada33b07efcf5cf8` | `scripts/register_expert.py` | `b2dd1a0141c2dc88ed7203246335fd261eca97a17f91f4e280d3ce8b10a65b1e` |
|
||||
| 同上 | `scripts/init_expert.py` | `742fe9b70085a31850caf327d83f416ff19e9ee7482053e7aa99bd9b780206e4` |
|
||||
| 同上 | `scripts/validate_expert.py` | `6e85c716af94d6ee2ffc86a24a7230d15cd675a0fbaaf45a8980fd51d9c1c6fd` |
|
||||
| 同上 | `scripts/package_expert.py` | `e3d82044fd5fc7b749d65c178af0bed18bbc0375a952b878cfa019b09e04d8fb` |
|
||||
| 同上 | `scripts/batch_create.py` | `c926d7b8721c4ec4179a3d481271bdb01d41764c3301e01cdafd9e96c37e154c` |
|
||||
|
||||
恢复目录 `src/main/capabilities/assets/expert-manager/` 含上述 SKILL、refs、scripts、`.codebuddy-plugin/plugin.json`。metadata 的 SHA 为 `6908b9cd71687525e342c2500fa9d32a847f72e3e263190655ca9347402cb389`,声明 `name:skill-expert-manager`、category skill、workbuddy.kind builtin-skill、legacyResourceName expert-manager 与 bundleSegments。该 metadata 是技能资源包装,不是用户创建专家的 plugin schema。
|
||||
|
||||
`rea-source-manifest.json` 逐文件记录原 member/Evidence/SHA/bytes/export;目录外 `src/main/capabilities/assets/expert-manager-source.json` 为 `{files:Record<relativePath,string>}`,11 份原文共 82,929 bytes,方便打包时静态导入。完整正文已读;原文没有替换路径、工具、ImageGen 或业务语义。Root 后续 adapter 会明确处理 YCode config/session/受控工具和不可用的头像生成。
|
||||
|
||||
## Handler、扫描与会话 marker
|
||||
|
||||
所有下列 JS offset 为 UTF-16 code units、end exclusive。`.tmp/rea-expert-package-contracts.json` 为 SHA-verified AST 定义索引,含有限函数正文与函数体 SHA,可直接 review。
|
||||
|
||||
`main/server.js` `createExpertServiceObject` `[226652,230495)` 绑定真实服务;`registerExpertServiceHandlers` `[231650,231794)` 与 registerExpertHandlers `[231794,232500)` 注册 expert 通道。它把 scan/get/delete/addUser/clearMarker 转给 ExpertDesktopService.custom,把 fromPath/fromUrl 转给 package manager,把 activate 交给 ExpertPluginService。不能只凭 renderer 的 API 名判断本地实现不存在。
|
||||
|
||||
`main/module.app-server.js`:
|
||||
|
||||
| 定义 | offset | 已观察行为 |
|
||||
|---|---|---|
|
||||
| ExpertCustomRuntime.doScanCustomExperts | 58588–60184 | 读取 `plugins/marketplaces/my-experts/.codebuddy-plugin/marketplace.json` 的 plugins;不任意扫描未注册目录。source 去 `./plugins/`,拒绝含分隔符/上级路径的 ID,忽略缺目录/manifest,修复 trailing comma 与陈旧索引。可按 user ID 清单过滤。 |
|
||||
| readCustomExpertFromDir | 65233–66184 | plugin manifest 展开;tags/quickPrompts/triggerPrompts 兼容 locale-array,members/connectorIds/bin/references 归一;补 version=1.0.0、id/name/目录名、expertRootDir、isCustomExpert、marketplace。成员缺 id 可从 agent 字段补。 |
|
||||
| addUserExperts / getUserExpertsJsonPath | 62525–62912 / 64072–64169 | 用户已收录 ID 数组存 `experts/custom/<userId>/experts.json`。不存在返回 null,扫描不强制过滤;现存空数组会过滤掉全部。 |
|
||||
| archiveCustomExpertSessionMarker | 63187–63574 | `.created-by-session` rename 为 `.pending-preview-session`,清 DTO cache。 |
|
||||
| clearCustomExpertSessionMarker | 63574–63996 | 删除这两种 marker,清 DTO cache。 |
|
||||
| readPluginManifestAsync | 58204–58352 | 顺序尝试 `.codebuddy-plugin/plugin.json`、`.workbuddy-plugin/plugin.json`。 |
|
||||
| deleteCustomExpert | 61604–62525 | 删除磁盘专家、用户索引/marketplace条目并 deactivate;原版行为需与 host 安全校验单独对照。 |
|
||||
|
||||
`createdBySession` 从 `.created-by-session` 优先,否则 `.pending-preview-session` 读取 trim 后纯文本。`main/server.js` createCustomExpertWatcher `[203613,205817)` 采用 marker 收录用户专家、archive marker 并广播变化;renderer 预览消费后再 clear。因此 marker 不只是短暂 Toast 标记。
|
||||
|
||||
## 激活与依赖
|
||||
|
||||
ExpertPluginService.activateExpert `[80288,81496)` 根据身份/缓存映射解析 bundle;my-experts 直接本地目录,官方包可能下载;要求可读 plugin manifest,expertType 缺省 skill。agentName 优先 manifest.agentName,team fallback teamInfo.leadAgent,否则从 agents 路径/Markdown frontmatter匹配。它增量注册 marketplace、移除旧自动 agent override、记录 active set、通知 runtime config 变化,并返回 `{success,expertType,agentName,localPath,pluginRegisteredName}`。这是本地准备/注册的契约,不等于 OMP 已有等价插件运行时。
|
||||
|
||||
ExpertBundleRuntime.updateMarketplaceManifest `[51566,52437)` 写 `{name,description,plugins:[{name,source:'./plugins/<bundle>',description}]}`,按 name/source 去重,保留其他项。resolveAgentMarkdownFiles `[88525,88876)` 支持声明数组的目录或 `.md`,无声明时列 agents/*.md。具体 session switch 在同文件 SessionPluginSwitcher,通过 session host 插件端点启停,不能从返回 localPath 推断指令已注入。
|
||||
|
||||
ExpertDependencyRuntime `[67977,70095)`:
|
||||
|
||||
- `dependencies.connectors` 是非空字符串 ID 数组,产生 `{type:'connector',id}`。
|
||||
- MCP 声明优先 `dependencies.mcpServers`,再 `manifest.mcpServers`,无声明才用 `.mcp.json`。可为相对 JSON 文件、多个文件路径(后者覆盖同名)、或 object;JSON 同时接受 `{mcpServers:{...}}` 与直接服务器 map。
|
||||
- 输出 `{type:'mcp',name,displayName,description,icon,config,workbuddy}`;`x-workbuddy` 本地化包括 auth.tokenSchema 标题/说明/字段 label/placeholder。
|
||||
- `resolveExpertMcpLaunchConfig` `[67472,67614)` 仅处理 args:以 `./` 起始且 resolve 后仍在插件根内的参数转绝对路径,其他值保留。并非把任意 command/cwd 自动改写。
|
||||
- 相对图标在插件根内解析,特殊 local-file 协议元数据被去除;http/data/file 分支分别处理。这里没有真实连接/授权执行。
|
||||
|
||||
## 本地导入、打包
|
||||
|
||||
`main/tar.js` installExpertZipFromPath `[42138,44806)`:在临时目录解 ZIP,接受根 manifest 或唯一顶层目录的 manifest;manifest.name 优先确定最终 ID,规范化旧展示数组。最终 ID regex `^[a-zA-Z0-9._-]+$` 且排除 `.`/`..`,目标必须在 my-experts/plugins 内。重复未 overwrite 时返回 duplicate_expert,同时补 marketplace 索引;overwrite 会先删除旧目录再移动新目录,不能将其称为已证实原子回滚。成功 touch manifest、写 marketplace,finally 清理临时目录及按 cleanupZip 选择清 ZIP。
|
||||
|
||||
`main/module.app-server.js` BundleRuntime 的下载路径是另一实现:downloadAndExtract `[53066,55378)` 有旧目录备份恢复;extractZipArchive `[56027,56753)` 校验 zip-slip;normalizeExtractedPluginRoot `[56753,57120)` 允许单层包装。应区分市场下载和本地 import 的覆盖语义。
|
||||
|
||||
源 Python package_expert.py 先完整 validate,再 ZIP;entry 含 `<expert-dir-name>/` 前缀。除 `.codebuddy-plugin` 外隐藏文件/目录、node_modules、__pycache__ 和常见垃圾文件排除,session marker 不分享。daemon exportExpertZip `[39906,40498)` 使用独立 collectExpertPackageEntries/export,不能假称两个 exporter 完全同一实现。
|
||||
|
||||
## expert-manager 创建、编辑与校验
|
||||
|
||||
SKILL v2.0 的真实流程:收集角色信息/资料转化 → init → 填 Agent/manifest/可选 skills → 头像生成 → validate → register → package。修改保持 name、agentName、目录名和 Agent 文件名身份,修改后仍 validate/register。Team prompt 要求真实 TeamCreate/Agent/SendMessage,不允许模拟多角色;本轮未实现或运行该调度。
|
||||
|
||||
init_expert.py 只允许固定 config/my-experts/plugins 路径、kebab-case 名、agent/team;同名目录拒绝。Agent 模板创建 `.codebuddy-plugin/plugin.json`、agents/<name>.md、avatars/.gitkeep、README;Team 增加主理人/成员占位与 settings.json。模板 TODO 必须后续生成填充。batch_create.py 是流程范例,**明确没有内容生成逻辑**,不是可以一键生成成品的实现。
|
||||
|
||||
plugin-json-spec 与 full validator 存在严格程度差异,应分别保留:
|
||||
|
||||
| validator 核心 | 实际 error / warning |
|
||||
|---|---|
|
||||
| name/version/description | 检查 key 存在;name 非空时 regex至少2字符。version 未真正校验 semver。 |
|
||||
| expertType / agentName | 只 agent/team;agentName 必须对应 agents/<name>.md,禁止通用 team-lead。 |
|
||||
| i18n 展示 | displayName/profession/displayDescription/defaultInitPrompt 必须 object、en/zh 非空。 |
|
||||
| tags / quickPrompts | 若为数组要求各3个;原 validator 对错误的非数组类型并未全面报错,不应夸称完整 schema parser。 |
|
||||
| 中文描述/首次提示/头像/README | 40–50字、defaultInitPrompt与首条一致、头像存在、README推荐均 warning,不能当原版已做硬拦截。 |
|
||||
| team | teamInfo与members必需、memberAgents不含lead、members含role=lead;settings.json必需,存在agent时须匹配agentName。 |
|
||||
| 结构 | fullvalidate只认.codebuddy-plugin/plugin.json;不许hooks/commands/.lsp.json;agents/skills/bin/avatars不能放metadata里。声明agents存在,skills含SKILL.md。 |
|
||||
| Agent Markdown | 简单frontmatter regex/key:value抽取,源码承认不解析完整YAML;name若提供须同文件名,description缺失warning,tools字段error。 |
|
||||
| 固定位置 | 专家目录须在WORKBUDDY_CONFIG_DIR(fallback ~/.workbuddy)my-experts/plugins下。 |
|
||||
|
||||
register_expert.py 另有 completeness 检查:两种 metadata 都可;name/description/expertType、displayName 不能留 TODO,agents 目录至少一份文件的 TODO 数≤2。它不是直接调用 full validator;所以 fullvalidate 与 register 必须分别验收。session ID 优先 `--session-id`,否则 CODEBUDDY_SESSION_ID,空值/未展开变量忽略。marketplace 可显式指定或从目录推断,按 source/name 更新,写 `.created-by-session`,无 session 时注册成功也提示未必自动进入当前用户列表。
|
||||
|
||||
Avatar 规范要求真实 ImageGen 及文件落盘,生成失败要说明需手补并提供 prompt。本轮没有头像生成服务,不能沿用原文收尾语伪称头像已生成。Root host adapter 将明确表达此限制。
|
||||
|
||||
## REA 扩展与验证
|
||||
|
||||
正式本地 `SelectedArtifactText` adapter 增加 `.md/.txt/.yaml/.yml/.py`,仍只接精确 canonical member、固定根 SHA、strict UTF-8、每文件8MiB/合计16MiB/最多16项、校验 declared size/SHA;Python仅作为文本,不执行。`prepare-css-runtime.mjs` 将正式 patch装入隔离 runtime;全局 REA/registration 不变,没有旁路 extractor。
|
||||
|
||||
验证命令:
|
||||
|
||||
- `node scripts/rea/expert-package-text-regression.mjs`:自有真实 ASAR public CLI **9/9 PASS**,`.tmp/rea-expert-package-fixture-SNFddk/report.json`,Evidence `ev_bd82287b057029647c8c15910ee079b59bd2616158a7deb2d2b97c3d92468275`;5种新后缀 bytes/SHA、根pin、路径、UTF8、预算、缺member/重复及未选缺unpacked。未执行Python。
|
||||
- `node scripts/rea/selected-artifact-text-regression.mjs`:原有JS/CSS/JSON/binary、声明SHA tamper、预算、未选unpacked回归 PASS。
|
||||
- `node scripts/rea/css-runtime-contract-regression.mjs`、`node scripts/rea/css-runtime-integrity.mjs`:PASS,19模块校验、对应global文件未变。
|
||||
- expert-package-inventory/export/contracts/recover:所有选中正文 SHA、对应已存 inventory SHA 和恢复 bytes核验 PASS;原文bundle逐字等价,manifest提供完整复查链。
|
||||
|
||||
未知边界:原版实际创建/编辑/安装运行仍未执行;市场/安全扫描/付费/企业/cloud均有服务依赖;两种包导出器完整排除规则、第三方包兼容和原版所有异常未逐一执行;YCode的真实专家backend/会话模型指令/tool/team能力需另行测试。本轮不把“源码取到”称为功能1:1完成。
|
||||
|
||||
## 后续独立 YCode backend QA
|
||||
|
||||
Root 实施 `src/main/capabilities/experts.ts` 后,本 worker 新增 `scripts/test-experts-backend.mjs`,没有编辑该生产 service。该测试使用真实 Electron app.getPath(userData) 与真实磁盘包/草稿/marketplace,数据目录、sessionData、OMP home 都在新建 `.tmp/experts-backend-*` 下;不读写真实用户注册表、不调用模型或原版。
|
||||
|
||||
`node scripts/test-experts-backend.mjs` 最终 **73/73 PASS**:exercise **59/59**、全新 Electron reload-remove **14/14**,`.tmp/experts-backend-XllrUB/report.json`。被测 service SHA `6ba3fe0b9d489635b2f7c9846aabbe1f3f43206a9beaf150e8d497ca452a0dd3`,独立 esbuild module SHA `10ddff6ea9ef70f5a51c5928d8acc2eb9b4765b623fe170648a9f6f8e2a22806`。
|
||||
|
||||
真实链路覆盖 write→validate→register→source-shaped marketplace→list→read Agent prompt→activate identity→编辑/声明 skill preload→重启→remove。另验证二进制资源在文本编辑中保留、null 删除文档、marker、TODO 拦截、Windows/上级路径/会话ID越界、伪造 marker、单文件限额、YAML/tools拒绝、描述长度 warning、可校验 Team 包但明确拒绝激活、目录 junction/包内junction拒绝且外部目标未改,以及完整11份 manager源资源 SHA。
|
||||
|
||||
QA 曾捕获真实 stale edit bug:初次 read 不保存 baseHash,两个会话先 read 后编辑时旧用户视图可覆盖新包;`.tmp/experts-backend-QMunm2` 记录 FAIL,不能算通过。Root 修复 read 持久草稿与显式 `refresh:true` 后,最终同一反例拒绝陈旧 register;refresh 丢弃旧草稿、取得最新包后成功编辑并保留先前 Agent 变更。首次修复版 `.tmp/experts-backend-1WVd0H` 为55+14 PASS,最终新增 refresh闭环与source/build SHA后以XllrUB为准。
|
||||
|
||||
这是 YCode 后端模块的独立验证。没有驱动完整生产 preload/IPC/UI→真实 OMP 创建专家、图片生成、第三方 ZIP 导入、所有资源执行或专家团调度;这些跨模块/产品验收仍归 Root。REA 源恢复与自有 backend PASS 分开记账。
|
||||
Reference in new issue
Block a user