test(packaging): 针对打包产物的验收测试套件 - #6
Closed
chenyida7-prog wants to merge 45 commits into
Closed
Conversation
…SE_INPUT 7ec8a2f fixed the PreToolUse matcher (Bash -> Bash|Write|Edit) so Write/Edit calls actually trigger the hook. But the hook command itself never worked: it POSTed the literal string "$CLAUDE_TOOL_USE_INPUT" as the request body (single-quoted, so the shell never expanded it — and no such env var exists anyway; Claude Code delivers the PreToolUse payload on the hook command's stdin). The backend 422'd on every single call, and curl's exit code stayed 0 on that 422, so Claude Code silently treated every operation as allowed — regardless of matcher, before or after 7ec8a2f. Fix: _hooks_command_claude() now uses `-d @-` to read the POST body from stdin, where Claude Code actually writes it. Also fixes _merge_hook_entry(): it only compared the `matcher` string when deciding whether an existing install was "already current", so once the matcher already read Bash|Write|Edit, a stale `command` (like the broken one above) would survive every future reinstall untouched. It now overwrites the whole entry whenever _matcher_is_mine() recognizes it as ours (also extended to recognize the old broken command, so an existing install upgrades in place instead of getting a duplicate matcher). Verified end-to-end in a live Claude Code session against the real KB: direct Write, Edit, and bare `rm` targeting KB files are now denied with the intended guidance message; MCP tools (write__delete_document, etc.) still pass through normally. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqKnwdnye3njPuxqxvLSi8
cherry-pick c37dc32 后修正 hooks_matcher docstring 残留的 $CLAUDE_TOOL_USE_INPUT 描述,与实际 -d @- 实现一致。
…退出码 0/2/其它) WorkBuddy 官方/实测查证:payload 走 stdin、读 hookSpecificOutput.permissionDecision、 退出码 0/2/其它、配置 ~/.workbuddy/settings.json(须完全重启)。后端不依赖 tool_use_id/call_id,现有 -d @- 命令直接复用,无需单独适配。更新 WorkBuddy.json matcher_note/protocol/notes 与 DEV.md。
需求:同一版本可导出多份 dmg(不同企业),每份的可适配平台与展示名不同。
方案 A(打包期合并):platforms.json 保持默认不动,新增 desktop/enterprises/<name>.json
覆盖配置,build-backend.sh --enterprise <name> 合并后注入产物。
- platforms.json: 每个平台加 enabled 字段(默认 true,向后兼容)
- client_config.py: PLATFORMS 过滤 enabled=false;新增 platforms_meta() 返回
{key: {display, enabled}}(动态读 _load_platforms_data,与 PLATFORMS 一致)
- main.py: 新增 GET /api/platforms-meta(独立于 /api/client-config,检测状态零改动)
- store.js: applyPlatformsMeta() 启动时拉取并覆盖 clientPlatforms 的 label
(失败静默保留硬编码兜底)
- api.js: getPlatformsMeta()
- build-backend.sh: --enterprise <name> 解析 + 临时合并(copytree+JSON merge,
不污染源 platforms.json,trap 清理)+ 未知平台校验 + --add-data 指向合并目录
- release.sh: 一键打包入口(默认全平台 / --enterprise <name>)
- desktop/enterprises/: Acme.json 示例 + README 配置说明
- tests: TestPlatformsMeta + TestEnterpriseMerge 共 8 个测试
验证:合并后 PLATFORMS/detect_all/platforms_meta 三者一致(禁用平台全消失);
116 个 client_config 测试全过;前端构建守门 50/50;脚本语法与错误路径验证通过
- .gitignore: 忽略 desktop/enterprises/*.json(!template.json 白名单) - 删除已提交的 Acme.json(虚构示例名,不应入库) - 新增 template.json 通用模板(YourCompany 占位) - README: 改用 template 示例 + 说明配置文件不进仓库
需求(Apple 企业配置): - default_disabled=true → 未列出的平台全部禁用(只启用显式列出的) 缺省 false → 未列出的沿用 platforms.json 默认(向后兼容) - order 字段控制前端展示顺序(数字小靠前,None 排后保持原序) 改动: - build-backend.sh: 合并逻辑支持 default_disabled + order 透传 - client_config.py: platforms_meta 按 order 稳定排序输出 + 返回 order 字段 - store.js: applyPlatformsMeta 按 order 重排 clientPlatforms(前端兜底) - template.json: 补 default_disabled 语义说明(保留用户缩进风格) - tests: +3(default_disabled 启用/缺省、order 排序) 验证:119 个 client_config 测试全过;Apple 配置合并后仅 Enchante+ClaudeCode, Enchante 第一(order=1)、ClaudeCode 第二且 display=Claude Code (Apple Internal); 前端守门 50/50
需求:MCP/Hooks/Agent 三页保持一致平台清单;不支持某 kind 的平台不隐藏, 而是整行置灰 + 「平台原生不支持」文字解释(不写 kind,因用户已在对应页)。 - client_config.py: platforms_meta 返回 kinds(后端权威能力集) - store.js: applyPlatformsMeta 覆盖 kinds(前端硬编码仅离线兜底); platformsForKind 返回全部启用平台 + supported 标记; platformUnsupportedKinds 返回原生不支持的 kind 标签 - index.html: 设置矩阵不支持行置灰(ai-platform-row--unsupported)+ 状态文字 「平台原生不支持」+ toggle/deeplink 禁用;引导结论行追加 「X / Y 平台原生不支持」灰字 - components.css: 置灰行 + native 文字样式 验证:119 个 client_config 测试全过;platforms_meta kinds 正确 (ClaudeDesktop=[mcp]、Enchante=[mcp,agent]);前端守门 50/50
- enterprises/README.md: 补 default_disabled(未列出平台全禁用)、order(顺序)、 kinds(能力集,三页置灰依据)字段说明与场景表 - template.json: _comment 同步补 kinds 说明(保留用户缩进风格) - DESKTOP_APP.md: P0 记录企业定制打包 + 三页一致置灰完成项; P1「后端启动提速」方向更正(正解=进度挂钩,延迟 import mcp 收益≈0 不单独做)
根因:guideExecute 用 Promise.allSettled 并行执行所有平台的 kind 写入,
但 configureClient 有全局单写锁 clientConfiguring(防连点),并行时后到的
job 因锁被占而静默 return(.catch(()=>{}) 吞错)→ 仅第一个 kind(MCP)成功,
Hooks/Agent 全未配置。
修复:改为 for...of + await 串行执行(逐个 kind 写入,等待完成再下一个);
单 kind 失败 catch 不中断后续。引导批量配置本质是顺序写入,串行最安全
(避免后端同文件并发写),耗时多一两百毫秒无感知。
第 34 行 '企业: $ENTERPRISE(...)':UTF-8 locale 下 bash 把全角左括号
的首字节 \xEF 并入变量名 → 变量名变成未定义的 'ENTERPRISE\xef...',
set -u 触发 unbound variable。
修复:改用 ${ENTERPRISE} 显式分隔。
第 46 行 '✓ 企业定制: $ENTERPRISE($ENTERPRISE_FILE)': UTF-8 locale 下 bash 把全角左括号首字节 \xEF 并入变量名, set -u 触发 unbound variable(与 release.sh 34 行同 bug,本次漏改)。 已用 Python 脚本全量扫描 scripts/*.sh,确认变量后跟全角字符的 隐患已清零。
本地环境 nginx 同时监听 8080/8081、开发版后端占用 8080,桌面 App 从 8080 起协商端口虽能跳开,但 8080-8081 区间与开发环境高冲突。改为从 2030 起协商 (2030-2079),与开发端彻底分家,消除启动超时隐患。
根因:clientPlatforms 是硬编码 6 个平台,applyPlatformsMeta 只覆盖 label/kinds/排序、不删除被禁用的平台 → 企业配置(如 Apple 只启用 2 个) 下,设置 modal 仍显示其他 4 个平台,且因后端不检测它们 → 显示 「检测失败 · 重新检测」残影。 修复:applyPlatformsMeta 先 filter(只保留 meta 中存在的平台)再覆盖, 前端列表/三页矩阵/引导页/结论行全部与后端 enable 一致。 企业固定 dmg 场景下方案足够(App 重启重新过滤,稳定)。
1. 设置 modal:deeplink 按钮 :disabled 补 !clientInstalled —— 未安装时 禁用(状态文字已是「请先安装 X」),与引导页结论行一致 2. 按钮高度:btn--deeplink 固定 height 22px + line-height 20px + inline-flex 居中,与同行 toggle(20px) 对齐,消除每行高度不齐
12px 字号在 20px 高内刚好放下(上下 4px 余量),字号保持 --text-xs 不变, 行高零误差;不再需要缩小字号。
- 去掉整行 opacity 0.55(会把 dot 也淡化,与正常行 dot 不一致) - 名称/状态文字用 --text-secondary (#6b7280),与「请先安装/未配置」同灰阶 - 引导行 native 文字 --text-tertiary → --text-secondary 统一
设置 modal 的 ai-platform-row__state--soft(请先安装/请在安装后使用) 原用最浅灰 #d1d5db,与「平台原生不支持/未配置」的 #6b7280 不一致。 统一到 --text-secondary,消除多种灰色。
问题1(loading 文本不显示):animation:...both 与额外 opacity:0 冲突,
baseline opacity:0 覆盖 to 态 → 文本永久不可见。删多余 opacity:0。
问题3(deeplink 点击后跳转主页):Electron 主窗口 setWindowOpenHandler
只放行 http/https,enchante:// 被 deny → 链接未传给系统唤起 Enchante。
修复:
- main.js: ipcMain.handle('open-external') 协议校验 + shell.openExternal
- preload.js: exposeInMainWorld('__mykOpenExternal__') 桥
- store.js: 桌面端(__MYK_APP_MODE__)走 IPC;网页端保持 a.click()(零影响)
测试:
- +3 静态断言(store 分支 / main IPC / preload 桥)
- 更新 test_enchante_grouping_and_deeplink 为三页一致置灰断言(旧隐藏断言与新行为冲突)
- desktop_server.py: main() 新增 --mcp 分支,构造 Namespace(root=args.root) 复用 cli.cmd_mcp
(自动 init/身份检查/GC/心跳/app.run(transport=stdio)),--mcp 与 --port 互斥(--mcp 优先)
- client_config.py: mcp_entry() 加 sys.frozen 分支(frozen → 二进制 + --mcp),非 frozen 路径零改动
- myknowledge-backend.spec: 修复 datas 过期临时路径 /var/folders/.../tmp.sDf5SYTPPa/AiClientConfig
→ backend/AiClientConfig(该临时目录来自某次 --enterprise 构建,导致 spec 构建直接失败)
- scripts/mcp-smoke.sh(新增): 独立 MCP stdio 冒烟脚本,无需打包即可跑(默认 python -m backend.cli mcp,
--bin 指向 frozen 二进制);select 非阻塞读+close(stdin)优雅退出+wait(timeout)兜底,不挂起
- build-backend.sh: 打包成功后自动调用 mcp-smoke.sh --bin <frozen 二进制>,失败即 exit 1 阻断
- 修复 shell locale 坑: /cd /Users/chrismoray/Desktop/Moray/MyOpenSource/MyKnowledge_PlatForm && git commit -m "桌面版 MCP stdio 支持:--mcp 复用 cmd_mcp + mcp_entry frozen 分支 + 独立冒烟脚本
- desktop_server.py: main() 新增 --mcp 分支,构造 Namespace(root=args.root) 复用 cli.cmd_mcp
(自动 init/身份检查/GC/心跳/app.run(transport=stdio)),--mcp 与 --port 互斥(--mcp 优先)
- client_config.py: mcp_entry() 加 sys.frozen 分支(frozen → 二进制 + --mcp),非 frozen 路径零改动
- myknowledge-backend.spec: 修复 datas 过期临时路径 /var/folders/.../tmp.sDf5SYTPPa/AiClientConfig
→ backend/AiClientConfig(该临时目录来自某次 --enterprise 构建,导致 spec 构建直接失败)
- scripts/mcp-smoke.sh(新增): 独立 MCP stdio 冒烟脚本,无需打包即可跑(默认 python -m backend.cli mcp,
--bin 指向 frozen 二进制);select 非阻塞读+close(stdin)优雅退出+wait(timeout)兜底,不挂起
- build-backend.sh: 打包成功后自动调用 mcp-smoke.sh --bin <frozen 二进制>,失败即 exit 1 阻断
- 修复 shell locale 坑: ${DESC}/${1} 花括号界定变量名(全角标点紧邻 $var 在 UTF-8 locale 下并入变量名)
- 测试: test_client_config.py +2(frozen mcp_entry),新增 test_desktop_server.py +4(dispatch)
- docs/AI-SETUP.md: 桌面版 MCP 入口说明 + MCP command/args 是数组 spawn 无需引号" && echo "COMMITTED" 花括号界定变量名(全角标点紧邻 在 UTF-8 locale 下并入变量名)
- 测试: test_client_config.py +2(frozen mcp_entry),新增 test_desktop_server.py +4(dispatch)
- docs/AI-SETUP.md: 桌面版 MCP 入口说明 + MCP command/args 是数组 spawn 无需引号
- _base64_quote(): safe 从含 /、= 的宽集合收紧为 '-._~'(只留 unreserved),
base64 的 + → %2B、/ → %2F、= → %3D 全部 percent-encode,保证无损 round-trip
(MCP 与 agent deeplink 共用,改动一致安全)
- _agent_template(platform=''): 按平台选模板——Enchante → MyKnowledge-agent-Enchante.md
(精简版,已落盘 563 字符,内容定稿不改);其余/默认 → MyKnowledge-agent.md (完整版)。
agent_content() 非 Enchante 平台走默认完整版,零变化
- enchante_agent_deeplink(): role 改用 _agent_template('Enchante');deeplink 长度
~4206 → 2114,且编码后无裸 /、+、=
- myknowledge-backend.spec 纳入 git:.gitignore 在 *.spec 后加 !myknowledge-backend.spec
例外;spec 是源,PyInstaller 不运行时改写
- 测试: +6 —— _base64_quote 转义 /、= round-trip、_agent_template 精简/完整选择、
agent deeplink 长度 <4206 且无裸 /。后端测试 729 全绿
- docs/DEV.md: 记录 base64 全转义 + 精简模板 + spec 入 git 约定
frozen onedir 冷启动(导入 fastapi/uvicorn/mcp + _auto_init git init)在 8s 内 可能未就绪,导致 8s 默认超时误报失败。select 只在无响应时计时,happy path 仍 立即返回,故提高默认超时不影响正常冒烟速度,仅放宽失败判定上界。
- .codegraph/(CodeGraph 本地索引 db/log/sock/pid)与 .pytest_cache/ 加入忽略 - git rm --cached 移除已误追踪的 .codegraph/.gitignore 与 .codegraph/daemon.pid(本地保留,供 CodeGraph 运行)
- backend/__version__.py → 0.7.7(权威来源),同步 package.json / README(zh) / electron-builder.yml / docs/DESKTOP_APP.md / dmg 背景
- fix(build-backend): mcp-smoke.sh 冒烟用 bash 调用而非 ${PYTHON}(之前误用 python 解释 bash 脚本致 SyntaxError,阻断 release 构建)
Enchante 走 deeplink 安装且无配置文件,后端无法检测其配置状态(clientStatus 恒 false),显示「未配置」不准确。改为中性的「生成专属链接」,与按钮文案呼应。非 deeplink 平台文案不变。
根因:绿条展开(0.6s)后旧代码立即触发 loading-done 切主界面,而文本需 animation-delay 0.55s + 0.3s 淡入(0.85s)才完全显示。浏览器直接打开无 __mykLoadingDone__ 不切换所以正常;桌面 app 里 preload 注入后提前切换,文本 opacity≈0 时主界面已切走,用户看不到文本。 修复:绿条展开后延迟 1.1s 再触发 loading-done(文本 0.85s 完整淡入 + 约 0.85s 停留)。已用真实 preload + contextIsolation 的 Electron 环境实测:loading-done 触发时文本 opacity=1,用户可见约 0.85s。
根因:main.js 的 loading 兜底在后端就绪后固定 3s 就强制切主界面。后端就绪快(1-3s)时, 3s 兜底(t≈4-5s)恰好撞上 loading 动画(约 3.3s 走满 + 绿条展开 0.6s + 文本淡入 ≈ 4.7s) 刚完成的时机,绕过 loading.html 的 __mykLoadingDone__ 延迟,导致「初始化完成」文本 还没完整显示就被切走。 修复:兜底改为后端就绪后 9s(晚于 loading-done ~5s 正常触发),仅作极端兜底防卡死, 正常由 loading.html 进度走满后触发 loading-done 切主界面,保证文本完整显示。 补充 loading.html 注释:进度 setInterval 间隔 150ms(约 3.3s 走满,与后端冷启动同步)。
…--mcp Enchante reported "unrecognized arguments: mcp" when spawning the packaged myknowledge-backend binary in stdio MCP mode — some MCP client configs (e.g. one copied from the pip-installed `myknowledge mcp` CLI docs) invoke it with a bare `mcp` positional instead of the `--mcp` flag the frozen binary's argparse actually defines. Reproduced against the installed v0.7.7 app and confirmed fixed against a freshly built binary (full MCP initialize handshake succeeds either way now).
pip install -e . (editable/dev install path) reads pyproject.toml's dependency list, not requirements.txt — same missing-typer failure mode as the previous commit if that's the install path the build environment uses.
fix(build): use mcp[cli] extra
- main.js open-external 改 async + await shell.openExternal,
捕获系统层异步失败(如无应用注册 enchante://,kLSApplicationNotFoundErr),
避免失败被吞导致前端永远以为打开成功
- store.js 收到 {ok:false} 时不再走自动消失 toast,
改为常驻红色 toast + 「知道了」确认按钮(showStickyToast)
- utils.js 新增 showStickyToast/dismissToast(常驻确认 toast + 统一淡出)
- components.css 新增 .toast--sticky / .toast__confirm 样式
- test_stage3.py 新增 test_utils_sticky_toast,更新 deeplink 断言
- codegraph sync 的 path 是位置参数,--path 会报 unknown option 导致静默失败 - 改用 codegraph sync -q <path>(-q 为 git hook 场景设计) - post-merge 在 git pull/merge 后自动增量同步 CodeGraph 索引
- 企业配置位置 desktop/enterprises/<name>.json(git 忽略,仅 template.json 入库) - 显式声明打包:npm run release -- --enterprise <name> - 本地 shell alias 一键打包示例(每个企业一条,不入库)
- 流程开头先调 maint__check_uncommitted:播报未 commit 的临时草稿 (待处理清单),不阻塞不擅自提交,等用户明确要求才走写入流程 - 会话开始自问距上次 maint__knowledgebase_diagnose 是否超 1h,超时才跑, 避免每次对话全库扫描;有结构问题只播报不擅自修复 - frontmatter.json 各平台 tools 补 maint__check_uncommitted
- Storage(kb_root) / GitManager(repo_root) 传 Path 而非 str/Storage 实例, 注明误传的 AttributeError 表现 - create_mcp_app docstring 补 call_tool 直调返回结构(tuple,文本取 result[0][0].text),附测试通用提取模式
方案 A(注释分区,不改结构): - index.html body 开头新增分区速查表(视图/弹窗行号 + VIEW:/MODAL: 标记) - 11 个弹窗注释统一为 MODAL: <value> 格式(原来散落不统一) - 纯 HTML 注释,不含 ?v=,build 的 _strip_versions/_versionize 不碰,原样进 standalone FRONTEND_ARCHITECTURE.md 新增第 11 章「前端架构待办/Backlog」: - 11.1 记录 index.html 可维护性优化:方案 A 已完成,方案 B(拆模板真瘦身)待立项低优先 - 11.2 既有增强项索引 验证:build.py 通过,注释源/产物保留,前端静态测试 74/74 通过
Enchante 的 Agent deeplink(enchante://agent/install)在真机上验证不可靠 (即便 PR #3 补上了缺失的顶层 name 字段,deeplink 本身对 Enchanté 版本/环境的 依赖仍不稳定),改为引导用户直接看使用手册,避免继续给一个不可靠的安装入口。 改动范围仅 Enchante + agent 这一格: - 设置弹窗 Agent 分组、首次引导 2.2 结论页,Enchante 那一行都改成不可点的置灰 开关(视觉与 Hooks 分组里 Enchante 那行「平台原生不支持」的置灰渲染一致), 描述文字改为「参考使用手册」,旁边加一个「查看手册」链接。 - store.js: usesDeeplink() 收窄为仅 Enchante+MCP;新增 isEnchanteAgentManual() 判定 + openEnchanteAgentManual() 打开手册。 - desktop/main.js + preload.js: 新增独立的 open-manual IPC 通道,用 shell.openPath 打开手册文件。没有复用 open-external,因为那个通道专门 block 了 file: 前缀(避免渲染层任意打开本地文件/命令);手册路径由主进程硬编码, 渲染层不传参,同样是为了不给渲染层传任意本地路径的口子。 TODO(分发前必须替换,已在代码里标注):MANUAL_PATH 目前是本机开发路径占位, 正式版应指向打包进 app 资源目录的手册文件,并加入 electron-builder 的 extraResources / build-backend datas。 Enchante 的 MCP deeplink、其它平台的 Agent 配置均未改动。 测试:只跑了改动直接影响的静态结构测试(不含全局前端/浏览器测试套件): pytest tests/frontend/test_stage3.py::TestStage3StaticStructure # 16 passed pytest tests/frontend/test_stage3.py::TestStage3Build # 1 passed(对新 build 的 standalone 断言) 同时更新了这两类测试里跟 Agent deeplink 按钮相关的断言(按钮已移除、改为手册引导), 以及一个受影响的浏览器测试(TestStage3Browser,未在本地跑,留给 review/CI)。
真机测试反馈:引导页 2.2 结论页里 Enchante 那行只看到开关,看不到「参考使用 手册」文字。根因是文案 span 复用了 .guide-conclusion-row__action(flex:1), 跟同一行「需手动安装」那个 flex:1 元素抢空间,把新文案挤没了——只是 HTML 里 有这段文字,实际渲染不出来,静态文本断言测不出这类布局问题。 改法:去掉那个不可点的置灰开关(本身没有信息量,纯粹会让人以为能点),文案 换成独立的「配置 Agent 参考使用手册」,不复用会抢 flex 的类。设置页 Agent 分组 那处(置灰开关 + 「参考使用手册」)不受影响,本来就没有这个问题,未改动。 测试:仅跑改动直接覆盖的精准测试(不含全局前端/浏览器套件): pytest tests/frontend/test_stage3.py::TestStage3StaticStructure # 17 passed pytest tests/frontend/test_stage3.py::TestStage3Build # 1 passed 同步更新了 TestStage3Browser 里对应的断言(本地未跑,留给 review/CI)。
feat(frontend): Enchante Agent 改为置灰开关 + 参考使用手册链接,停用 agent deeplink
不打包手册了,彻底去掉之前那个占位用的本机微信文件路径 (file:///Users/chenyida/Library/Containers/com.tencent.xinWeChat/...), 避免正式包里残留任何本机路径依赖。 设置页 Agent 分组行 + 引导页结论页,Enchante 的 Agent 项现在都只剩「参考使用 手册」/「配置 Agent 参考使用手册」纯文字,不带任何链接、不带开关。 清理范围: - frontend/js/store.js:删掉 openEnchanteAgentManual() - frontend/index.html:两处都去掉 <a class="ai-platform-row__manual-link"> - frontend/css/components.css:删掉现在没人用的 .ai-platform-row__manual-link - desktop/main.js:删掉 open-manual IPC handler + MANUAL_PATH 常量 - desktop/preload.js:删掉 __mykOpenManual__ 桥 isEnchanteAgentManual() 判定保留(还要用来渲染置灰开关 + 对应文案), Enchante 的 MCP deeplink 完全没动。 测试:只跑改动直接覆盖的精准测试(不含全局前端/浏览器套件): pytest tests/frontend/test_stage3.py::TestStage3StaticStructure # 17 passed pytest tests/frontend/test_stage3.py::TestStage3Build # 1 passed 同步更新了 TestStage3Browser 里对应断言(本地未跑,留给 review/CI)。 node --check 过了 main.js/preload.js/store.js,frontend/build.py 重新打包也过了。
…ual-link chore(frontend): 移除 Enchante Agent 使用手册链接,只留纯文字提示
build-backend.sh 结尾 echo 引用了 但从未定义(43f0cb8 引入,
把 echo "后端: ${OUT_DIR}/..." 改写为 ${BIN} 时漏定义变量)。
set -u 严格模式下触发 BIN: unbound variable → build-backend.sh 非零退出
→ release.sh set -e 中断,electron-builder 从未执行,dmg 一直是旧产物。
在引用前补 BIN="${OUT_DIR}/myknowledge-backend/myknowledge-backend",
release 链可正常走完 electron-builder。
现有 900+ 测试全是源码级单测,桌面重活(uvicorn / MCP stdio / PyInstaller datas / electron 打包)都被 mock —— "只有打包产物才暴露"的问题(裸 mcp 报错、 旧前端被封进包、缺 logo、企业配置没生效、单实例锁丢失)没有任何测试能抓到。 新增 tests/test_packaged_artifact.py,直接检查打好的东西本身: - 测试对象 = dist-backend/ frozen 二进制 + /Applications/MyKnowledge (Apple).app - 独立模块,不 import / 不改动任何现有测试 - 没构建时整模块 skip(提示先跑 make-icon.sh + release.sh --enterprise Apple) - 完整 release 链用例默认 skip,MYK_RUN_RELEASE=1 开启 覆盖《验收清单》9 条: 1. 打包能通:release 链静态校验 + d03d103 回归(BIN unbound)+ 可选真跑 2. 门面:icon.icns 在 app 里、版本号 0.7.7(Info.plist + /api/version + 多来源一致) 3. 后端起得来:subprocess 拉起 frozen 二进制 --port,/api/status 200 4. MCP 能连:--mcp 和裸 mcp 都返回 serverInfo=MyKnowledge〔0783141〕, tools/list 与源码 @mcp.tool() 全集一致,mcp-smoke.sh 真机通过 5. 最新前端:GET / 返回内联 standalone、js/css/vendor 全部 200、 内联内容 = 当前源文件、包内 frontend 与仓库逐字节一致(防旧前端/漏文件) 6. 企业配置:/api/platforms-meta 只有 Enchante+ClaudeCode、display/order 正确, 包内 platforms.json 已按 Apple.json 合并〔bc23341〕 7. 加载动画:loading.html 打进 asar、57efb2c(无 opacity:0 冲突)+ d5d6ef7(transitionend+1100ms 停留、主进程兜底 9s)静态验证;肉眼时长标需人工 8. 打开健壮性:asar 里 findFreePort 递增扫描 + requestSingleInstanceLock 已打包, 两个后端实例互相独立、端口被占不漂移;真机双开标需人工 9. 未签名 → xattr:确认 app 是 adhoc 签名,xattr 放行步骤写进 skip reason 结果:57 passed, 4 skipped(3 人工占位 + 1 完整 release 链)。 完整 release 链单独 MYK_RUN_RELEASE=1 跑过:63s 出新 dmg,未中断。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSMDrsmrXR5kr68SUS5D5P
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
现有 900+ 测试全是源码级单测,桌面重活(uvicorn / MCP stdio / PyInstaller datas / electron 打包)都被 mock —— "只有打包产物才暴露"的问题(裸 mcp 报错、 旧前端被封进包、缺 logo、企业配置没生效、单实例锁丢失)没有任何测试能抓到。
新增 tests/test_packaged_artifact.py,直接检查打好的东西本身:
覆盖《验收清单》9 条:
结果:57 passed, 4 skipped(3 人工占位 + 1 完整 release 链)。
完整 release 链单独 MYK_RUN_RELEASE=1 跑过:63s 出新 dmg,未中断。
Claude-Session: https://claude.ai/code/session_01SSMDrsmrXR5kr68SUS5D5P