Conversation
Signed-off-by: luw2007 <luw2007@gmail.com>
steven-kid
left a comment
There was a problem hiding this comment.
详细中文评审
结论:REQUEST_CHANGES。Exact head:79a5aefb965bc22fe632dc84e4bb272ca00a8227;base:9e2b6d425fff9b8b2ebd69a79c3d8491b12eb7b3。
[P1] 新 user scope 安装成功后,Pi 无法自动发现扩展入口。 新目录采用子目录布局,但入口仍叫 loopx-goal.ts,没有 index.ts 或 package manifest。核心新增用户路径因此未达成,不能仅凭两个文件存在就批准。
动机
#3344 解决的是每个项目重复安装 Pi 适配器的成本:用户希望只安装一次扩展代码,仍然让各项目独立保留 .loopx/pi/ 绑定状态。原有 project scope 有完整的 managed-marker 与安装处理;扩展现有安装器,比另建全局安装器或手动复制更适合维护。
我阅读了 issue 的维护者收敛意见:保持 project 为默认,user scope 使用 Pi 能发现的目录入口,验证受支持 Pi 的 discovery/module aliasing,并纳入安装/升级/卸载与 readback。此次 PR 的参数设计符合这个方向,但“Pi 能实际发现”是用户结果,不是目录名称或安装 JSON 能替代的检查。
改动思路
CLI 新增 --pi-scope {project,user},handler 把选择传给同一个 install_slash_commands。_pi_extension_root 决定项目目录还是用户 .pi/agent/extensions/loopx/;extension 和 runtime 都继续从既有资源包取内容,复用 _target_status、managed marker 与双文件 ownership preflight。默认 all surfaces 仍不包含 Pi,旧 project 范围仍为默认,没有新增 Goal/quota 权限。
本轮对照 base/head 的现有安装器、共享 slash_command_files.py 及未修改的 Pi adapter/runtime。项目绑定仍由 adapter 的 createBindingStore(ctx.cwd) 决定,没有随 extension 文件移到用户目录。以已有 owner 扩展 scope 是合理的最小方案,不需要新增安装数据库。
正向实测:通过真实 LoopX CLI 在隔离目录分别执行 base project、head project、head user 安装,三者都报告成功;base/head project 写出的两个文件逐字节一致。负向发现:Pi v0.83.0 的目录发现逻辑能识别两个 project 安装,却在新 user 根目录返回空列表。由此区分了“安装文件成功”与“host 加载入口成功”。
具体改动
关键代码讲解
cli_commands/slash_commands.py::register_slash_commands_command增加 scope 枚举和 project 默认值;handle_slash_commands_command将args.pi_scope传给安装器。既有 install/uninstall/dry-run 分发路径沿用。slash_command_install.py::_pi_extension_root在 user 模式返回用户扩展子目录,而_pi_extension_path对两种 scope 都返回loopx-goal.ts。平铺项目目录能发现该名称,子目录入口规则则不同,问题发生在这两段组合处。install_slash_commands新增 scope 与测试可覆盖的 user-home 参数,在写入前计算统一 root;安装、卸载和 summary 路径使用该 root。既有双文件预检查对 user-owned 冲突仍然有效;没有改动内容生成器或 runtime。summary 新增 pi_scope,方便识别目标,但不能证明 host 已加载。tests/test_slash_command_install.py增加 user scope 的两个用例:确认两个文件存在/路径正确,以及 runtime 被用户占用时两文件都不写。这些断言证明磁盘布局和冲突前置检查,没有执行 Pi discovery。
docs/guides/getting-started.md 更新 Pi 指南,说明 user scope、reload/restart 与项目私有绑定。四个文件共 +73/-15,均已阅读;没有生成资源变化。指南宣称全项目可用,当前入口缺陷需要先修复。另未见本 PR 实现 issue 提到的 absent/current/stale/dual-scope doctor 读回;安装 summary 的目标路径不能代替 host discovery/状态诊断。
对主干的风险
[P1] user scope 缺少可发现的入口。 位置:loopx/slash_command_install.py:755。Pi v0.83.0 的子目录解析只接受 index.ts、index.js 或 package.json 中声明的 pi.extensions;不会递归找到任意名称的 TS 文件。本次安装写出 loopx/loopx-goal.ts 和 sibling .mjs,三种入口均不存在。
核验使用 Pi v0.83.0 的固定源码 revision 845d6ff1f6643aba440341cce877ce1c43ebbc39,从原始 loader 提取未修改的 isExtensionFile、resolveExtensionEntries、discoverExtensionsInDir,对真实 CLI 写出的目录执行发现逻辑。结果:base project 与 head project 均发现 loopx-goal.ts,head user 发现 []。只在临时目录把 user 入口改成 index.ts 后,同一发现逻辑立即找到 index.ts,随后恢复临时文件名。这个反例没有 mock 文件存在性,也没有把自定义发现规则当作 Pi 行为;但它仍是 loader 边界验证,不等于启动完整 Pi TUI。
来源:Pi v0.83.0 loader。最小修复是只为 user 子目录使用 index.ts,或交付受管理的 manifest;保持 project 路径兼容,同时让 dry-run、升级、卸载、ownership preflight 和读回指向一致入口。回归应从 LoopX CLI 安装走到支持版本的 host discovery,并进一步验证 /reload 后 /loopx 注册和模块 alias 解析。
验证:Pi 聚焦测试 8 项通过;完整 installer 文件 41 passed;slash-command-install smoke 和 diff check 通过;项目默认文件内容 hash 与 base 一致。完整 Pi 启动/reload、模块 aliasing、用户目录覆盖和多 scope readback 尚未完整验证,不能从写文件测试推断通过。现有安装输出中的固定说明仍写成项目目录,也应在修复 user scope 时按 scope 同步,避免成功回执与指南矛盾。
我的整体评价
参数、owner 和 project-local binding 保持方式都较克制,旧默认安装也有独立的文件内容对照证明。问题不需要更大的架构改造:新增 user path 只差一个正确且被完整生命周期管理的 host entrypoint,但这个差异正好决定整个新增功能是否可用。
因此请求修改,而不是把“文件已写入”认定为全局支持完成。建议保留现有安装器,修正入口并补齐真实 discovery/载入与 readback,尤其保留默认 project 模式、用户文件冲突和卸载的边界。当前批准条件未满足;未来 head 应重新对照完整安装生命周期,不能仅重新跑两个新增路径测试。本评审不包含合并授权。
English verdict: REQUEST_CHANGES at exact head 79a5aef. P1: user-scope installation writes loopx/loopx-goal.ts without index.ts or a pi.extensions manifest, so Pi v0.83.0 does not auto-discover it. The real LoopX CLI reported success, but the unmodified discovery functions from pinned Pi loader revision 845d6ff1f6643aba440341cce877ce1c43ebbc39 returned no user extension; a temporary index.ts rename made it discoverable. Preserve project paths while correcting the managed user entrypoint and lifecycle/readback. All 41 installer tests, the installer smoke and diff check passed; baseline/head project files were byte-identical. Full Pi startup/reload and module alias validation remain unverified. No merge authorization.
|
English verdict: REQUEST_CHANGES at exact head 79a5aef. P1: user-scope installation writes loopx/loopx-goal.ts without index.ts or a pi.extensions manifest, so Pi v0.83.0 does not auto-discover it. The real LoopX CLI reported success, but the unmodified discovery functions from pinned Pi loader revision 845d6ff1f6643aba440341cce877ce1c43ebbc39 returned no user extension; a temporary index.ts rename made it discoverable. Preserve project paths while correcting the managed user entrypoint and lifecycle/readback. All 41 installer tests, the installer smoke and diff check passed; baseline/head project files were byte-identical. Full Pi startup/reload and module alias validation remain unverified. No merge authorization. |
Summary
--pi-scope {project,user}while preserving project scope as the default~/.pi/agent/extensions/loopx/for user scope/reloador restart plus project-local private bindingsCloses #3344
Validation
python -m pytest -q tests/test_slash_command_install.py -k pi— 8 passed--surface pi --pi-scope user— exact global paths returnedpython examples/slash-command-install-smoke.py— passedloopx canary premerge --from-git-diff— compile/direct checks and subsequent checks passed;examples/install-local-smoke.pytimed out at 120sBoundaries
Only extension code becomes user-global. Project binding state remains under
<project>/.loopx/pi/; this grants no repository, network, credential, or merge authority.