feat(desktop): SkillHub 支持导入本地 zip/SKILL.md - #1232
Conversation
技能页标题旁新增「导入技能」:校验 frontmatter 后经安装位置选择器落盘, registry 记 origin=imported(本地徽标、可离线卸载、可发布);市场安装技能的卸载鉴权不变。 Signed-off-by: codeingforcoffee <garryxia666@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
| Filename | Overview |
|---|---|
| apps/desktop/src/main/skillhub/importLocalSkill.ts | 实现本地技能检查、解压、暂存替换及 registry 登记,但大条目解压仍会在主进程产生接近两倍的内存峰值。 |
| apps/desktop/src/main/skillhub/importLocalSkill.pure.ts | 提供导入源分类、元数据校验、ZIP 包根识别、安装路径约束及声明大小预算辅助逻辑。 |
| apps/desktop/src/main/skillhub/registerIpc.ts | 增加受信任渲染进程校验、主进程文件选择及与发送方绑定的一次性导入授权。 |
| apps/desktop/src/main/skillhub/installService.ts | 根据 registry 来源区分卸载鉴权,本地导入及学习产物可在无云端账号时卸载。 |
| apps/desktop/src/renderer/features/skillhub/SkillhubHomeView.tsx | 增加本地技能选择、检查、目标位置选择、冲突确认和导入结果处理流程。 |
| apps/desktop/src/renderer/features/skillhub/components/InstallTargetPicker.tsx | 泛化安装位置选择器以同时支持市场安装和本地导入。 |
Comments Outside Diff (1)
-
apps/desktop/src/main/skillhub/importLocalSkill.ts, line 1492-1516 (link)当导入包含单个数百 MB 解压后条目的 ZIP 时,
readZipEntryLimited会先把全部数据保存在chunks中,再由Buffer.concat分配并复制一份同等大小的连续 Buffer;首个条目最多可使用完整的 500 MB 额度,因此 Electron 主进程仍会因接近两倍的峰值内存而耗尽内存并崩溃。Context Used: 使用和PR描述相同的语言进行评论 (source)
Prompt To Fix With AI
This is a comment left during a code review. Path: apps/desktop/src/main/skillhub/importLocalSkill.ts Line: 1492-1516 Comment: **解压仍会双倍占用内存** 当导入包含单个数百 MB 解压后条目的 ZIP 时,`readZipEntryLimited` 会先把全部数据保存在 `chunks` 中,再由 `Buffer.concat` 分配并复制一份同等大小的连续 Buffer;首个条目最多可使用完整的 500 MB 额度,因此 Electron 主进程仍会因接近两倍的峰值内存而耗尽内存并崩溃。 **Context Used:** 使用和PR描述相同的语言进行评论 ([source](https://app.greptile.com/review/custom-context?memory=instruction-0)) --- For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/main/skillhub/importLocalSkill.ts:1492-1516
**解压仍会双倍占用内存**
当导入包含单个数百 MB 解压后条目的 ZIP 时,`readZipEntryLimited` 会先把全部数据保存在 `chunks` 中,再由 `Buffer.concat` 分配并复制一份同等大小的连续 Buffer;首个条目最多可使用完整的 500 MB 额度,因此 Electron 主进程仍会因接近两倍的峰值内存而耗尽内存并崩溃。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (3): Last reviewed commit: "fix(desktop): 本地技能导入改为 main 侧文件授权" | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aa39103362
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
🟡 Not ready to approve
main 侧导入逻辑目前未强制 installPath 为绝对路径(相对路径可能导致非预期落盘位置),需要先补齐防御性校验后再合入。
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
本 PR 为 Desktop 的 SkillHub「技能」页新增**从本地导入技能(zip / SKILL.md)**的能力:通过 IPC 在 main 侧进行只读 inspect 与落盘导入,并在 registry 中标记 origin: 'imported',同时在 renderer 侧复用/泛化安装位置选择器与详情页按钮矩阵逻辑;并调整卸载鉴权以允许本地导入/learn 产物离线卸载。
Changes:
- 新增 main 侧本地导入实现(zip 解压/校验 frontmatter/落盘/写 registry),并补齐 IPC + preload + 类型声明。
- renderer 侧在 SkillHub 首页增加「导入技能」入口,复用并泛化
InstallTargetPicker,并扩展来源/按钮状态派生以支持origin='imported'。 - 扩展卸载逻辑与测试覆盖(
origin='imported'可离线卸载;imported/learned 不走市场更新路径),并补充 help-knowledge 文档与 i18n。
File summaries
| File | Description |
|---|---|
| apps/desktop/src/renderer/vite-env.d.ts | 扩展 renderer 侧 ElectronAPI 类型:inspect/import 本地导入 + registry origin 新枚举值 |
| apps/desktop/src/renderer/i18n/locales/zh-CN/common.json | 新增导入入口/选择器/提示文案(zh-CN) |
| apps/desktop/src/renderer/i18n/locales/ko/common.json | 新增导入入口/选择器/提示文案(ko) |
| apps/desktop/src/renderer/i18n/locales/ja/common.json | 新增导入入口/选择器/提示文案(ja) |
| apps/desktop/src/renderer/i18n/locales/en/common.json | 新增导入入口/选择器/提示文案(en) |
| apps/desktop/src/renderer/features/skillhub/SkillhubHomeView.tsx | 技能页新增「导入技能」入口:选文件→inspect→安装位置选择器→import |
| apps/desktop/src/renderer/features/skillhub/SkillhubFeatureLayout.tsx | reconcile 逻辑允许 origin='imported',避免被判为“需要回填/修正” |
| apps/desktop/src/renderer/features/skillhub/SkillhubDetailView.tsx | 更新详情页卸载按钮注释语义(installed/imported) |
| apps/desktop/src/renderer/features/skillhub/lib/skillSource.ts | origin='imported' 视为本地来源(local) |
| apps/desktop/src/renderer/features/skillhub/lib/detailButtons.ts | 按钮派生逻辑支持 imported:可卸载、禁止市场更新、必要时引导发布新版本 |
| apps/desktop/src/renderer/features/skillhub/lib/tests/skillSource.test.ts | 覆盖 imported → local 的来源派生测试 |
| apps/desktop/src/renderer/features/skillhub/lib/tests/detailButtons.test.ts | 覆盖 imported 在按钮矩阵/更新/卸载策略上的关键分支 |
| apps/desktop/src/renderer/features/skillhub/components/InstallTargetPicker.tsx | 泛化安装位置选择器:支持 market clone 与本地导入共用(runAction + i18n key 可配置) |
| apps/desktop/src/preload/preload.ts | 暴露 skillhub:inspect-local / skillhub:import-local 到 renderer |
| apps/desktop/src/main/skillhub/registry/types.ts | main 侧 registry 类型扩展 origin='imported' |
| apps/desktop/src/main/skillhub/registerIpc.ts | 新增 IPC handler:inspect-local / import-local,并在导入后刷新缓存 |
| apps/desktop/src/main/skillhub/installService.ts | 卸载鉴权调整:imported/learned 允许离线卸载;路径匹配更健壮 |
| apps/desktop/src/main/skillhub/installLock.ts | 安装锁 owner 扩展:新增 local-import |
| apps/desktop/src/main/skillhub/importLocalSkill.ts | 新增本地导入实现:校验、解压/写入、registry 记录 origin=imported、备份与回滚 |
| apps/desktop/src/main/skillhub/importLocalSkill.pure.ts | 新增纯函数辅助:frontmatter/命名校验、zip root 定位、路径分类等 |
| apps/desktop/src/main/skillhub/tests/installService.test.ts | 更新/新增卸载鉴权相关单测(market vs imported) |
| apps/desktop/src/main/skillhub/tests/importLocalSkill.pure.test.ts | 为纯函数辅助补齐单测覆盖 |
| apps/desktop/help-knowledge/skills.md | 补充「本地导入技能」用户文档说明 |
Review details
- Files reviewed: 22/23 changed files
- Comments generated: 2
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
|
⏸️ 白名单确认门已拦住此 PR。 触发: product(feat 类型 + UI 路径) + arch(核心路径) 此 PR 新增 SkillHub 本地导入功能,需要 roster 成员确认产品方向与架构设计。 放行方式: 直接在 PR 上 Approve;需要修改就 Request Changes,改完后重新 Approve 即放行。 讨论 issue:#1234 |
按 PR review:解压前校验声明大小并以流式读取限流,避免 zip bomb; installPath 要求绝对路径且落在 .agents/.claude skills 根下;统一 SkillHub 拼写。 Signed-off-by: codeingforcoffee <garryxia666@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
🟡 Human review recommended
变更涉及本地文件解压落盘与卸载鉴权边界调整,尽管已有防御与单测覆盖,仍建议由人工对安全与数据路径风险做最终确认。
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 0 new
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f54d01b4d2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codeingforcoffee 👋 这个 PR 还有 4 条 review conversation 没 resolve(apps/desktop/src/main/skillhub/importLocalSkill.ts / apps/desktop/help-knowledge/skills.md / apps/desktop/src/main/skillhub/registerIpc.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
|
@codeingforcoffee 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/main/skillhub/importLocalSkill.ts / apps/desktop/src/main/skillhub/registerIpc.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
避免 renderer 传入任意路径触发读取/解压,改为在 main 内选文件并签发短期票据后再导入。 Signed-off-by: codeingforcoffee <garryxia666@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
白名单确认门已放行(product / arch,由 MagicLizi 确认),PR 恢复正常推进。 |
There was a problem hiding this comment.
🟡 Human review recommended
该 PR 引入 zip 解压落盘与卸载鉴权分支调整,涉及文件系统与安全边界变更,建议人工做一次端到端导入/卸载路径审阅与确认后再合并。
Review details
- Files reviewed: 24/25 changed files
- Comments generated: 0 new
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1bdcb34ce
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
MagicLizi
left a comment
There was a problem hiding this comment.
审查通过,零 P0/P1。zip 导入安全防护完善:safeJoin 防 zip slip、声明 size 预检 + 流式字节上限防 zip bomb、grant token 绑定发送方身份。
|
grant token 绑 webContents + 单次消费 + TTL 的组合拳把渲染进程的文件注入路径堵得很死,zip 解压那边 safeJoin 也没给遍历留缝。做得漂亮。 |
这次改了什么
目的在于自己本地有一些skill想调试,或者不想上传到skillhub,只想本地使用的技能,希望也能导入到cindy使用,开发过程中发现卸载需要登陆cindy账号,去掉了来自本地上传路径的门禁,允许自己上传,卸载,不受云端账号管控。
摘要
SkillHub「技能」页支持从本地导入 zip 或
SKILL.md:校验 frontmatter(name+description)后,经安装位置选择器落盘,并在 registry 记为origin: 'imported'(「本地」徽标、可离线卸载、可发布)。不上传云端。市场安装技能的卸载鉴权保持不变(仍要求云端账号)。变更类型
feat新功能fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
inspectLocalSkill/importLocalSkill、IPC(skillhub:inspect-local/skillhub:import-local)、registryorigin='imported'、本地导入与蒸馏产物允许离线卸载InstallTargetPicker、详情按钮矩阵与来源徽标UI 变化
DESIGN.md§2 / §10:颜色走语义 token(按钮与页面沿用既有 SkillHub / InstallTargetPicker themed 样式),同时实现 Light / DarkDESIGN.md§3 Buttons:导入入口复用现有次级/页面 header 按钮样式,不新增硬编码色怎么验证的
自动验证
手工验证
未做 Desktop 实机导入流程目检(Light / Dark 均未实机验证);逻辑与按钮矩阵由单测覆盖。
未执行的验证
风险
风险分类
影响与回滚
imported/learned卸载不再要求云端登录;市场installed卸载鉴权不变提交前检查
git commit -s,见 DCO)Made with Cursor