Skip to content

feat: Doraemon Skills kit — dt-skill CLI, registry API, and marketplace UISkills kit support#86

Merged
liuxy0551 merged 21 commits into
DTStack:masterfrom
TreeTreeDi:skills-kit-support
Jul 23, 2026
Merged

feat: Doraemon Skills kit — dt-skill CLI, registry API, and marketplace UISkills kit support#86
liuxy0551 merged 21 commits into
DTStack:masterfrom
TreeTreeDi:skills-kit-support

Conversation

@TreeTreeDi

Copy link
Copy Markdown
Contributor

提交的变更类型是

  • 添加新功能
  • 修复 bug
  • 代码重构
  • 增加单元测试
  • 增加依赖库/工具

相关链接

(无外部 issue 链接)

需求描述和解决方案

描述

为 Doraemon Skills 市场补齐端到端工具链:服务端 ClawHub 兼容 API、前端技能详情/列表体验、以及独立的 dt-skill CLI。同时统一 skill fingerprint 规则,并移除已无登录入口的 Registry 鉴权残留。

解决方案

服务端(Egg.js)

  • 扩展 clawhub / skills 服务:搜索、安装、发布、指纹解析、composite list cursor 等 /api/v1/* 能力
  • 新增 skillsStorageReady 中间件,在 /api/v1/* 路由层统一 ensureStorageReady,避免各 handler 重复调用
  • 引入 contracts/skill-fingerprint/ 作为 CLI 与服务端共享的 fingerprint 契约(扩展名白名单 + golden vectors)

CLI(dt-skill/

  • 新增独立 npm 包:install / search / publish / sync / inspect / package 浏览与 pack 等命令
  • Registry 请求统一为无 token 的 HTTP client;删除 login/whoami、authToken、browserAuth、deviceAuth 及依赖鉴权的 moderation/transfer/publisher 命令
  • fingerprint 通过 skillFingerprintContract 适配层复用主仓契约

前端

  • 重构 SkillDetailContent 为 shell + 子组件(文件树、文档区、安装面板、Hero)
  • Skill 卡片与详情页样式调整

测试

  • 主仓:clawhub-contractclawhub-integrationskill-fingerprint-contractskills-storage-ready-middleware
  • dt-skill:Vitest 单元测试 + built CLI artifact 测试

变更规模: 8 commits,master...skills-kit-support,117 files(+46k / −1.4k lines)

自查清单

  • 代码遵循这个项目的风格指南
  • 对代码进行了自我审查
  • 已经在难以理解的代码处做了相关注释
  • 更改不会产生新的警告
  • 任何依赖更改都已合并并发布在下游模块中

Test plan

  • node --test test/clawhub-contract.test.js test/clawhub-integration.test.js test/skill-fingerprint-contract.test.js test/skills-storage-ready-middleware.test.js
  • cd dt-skill && npm run build && npm run test:src
  • npm run check-types(前端 TypeScript)
  • 手动:npm run dev 打开技能详情页,验证安装/文件浏览/子 skill 展示
  • 手动:dt-skill search / install / publish 指向本地 registry(--registry http://127.0.0.1:7001

huaiju and others added 14 commits June 17, 2026 17:16
Drop unimplemented OpenClaw package commands, bulk sync workflow, and
clawdbot workspace discovery so the CLI focuses on core skill operations.

Co-authored-by: Cursor <cursoragent@cursor.com>
Align registry discovery, env vars, and local state with dt-skill naming
and rename backend clawhub modules to skillsRegistry.

Co-authored-by: Cursor <cursoragent@cursor.com>
Revert accidental version bump, rename SkillCard styles to style.scss,
and remove internal plan artifact.

Co-authored-by: Cursor <cursoragent@cursor.com>
prettier 2.7.1 cannot parse the satisfies operator, which broke the
prettier CI step and silently masked downstream lint/typecheck/build
failures. Replace satisfies with an explicit Promise<FetchedGitHubSource>
return type, then format the rest of the repo to match the configured
prettier rules.
With the prettier step finally green, eslint, stylelint, and the rest
of the CI pipeline ran for the first time on this branch and surfaced
pre-existing failures. Address them so the pipeline can be green
end-to-end:

- eslint --fix to apply autofixable rules across the repo
- stylelint --fix to normalize hex casing in scss
- ignore dt-skill/dist/ from eslint (build artifacts)
- drop unused imports/vars and a redundant try/catch
- rename Promise constructor params to (resolve, reject)
- silence no-throw-literal where the test deliberately throws a non-Error
- C2: extract normalizeRelativePath into shared util; normalize stored paths in publish/buildSkillZip to prevent zip-slip
- C3: wrap publishSkill in a transaction and use SkillsSource findOrCreate to remove race and dirty data
- I1: fail loudly on file read errors during publish instead of silently storing empty skills
- I2: persist lockfile inside cmdUpdate loop so a crash no longer drifts it
- I3: guard fetchLikeStatus with a cancel flag to avoid races on fast navigation
- I4: add safeOpenUrl to restrict window.open to http(s)
- I6: stop rendering the placeholder comment as a copyable command
- I8: cap zip entry count and total bytes in extractZipToDir to prevent zip bombs
- UX: show child skill count in multi-skill package import message
@TreeTreeDi

Copy link
Copy Markdown
Contributor Author
  1. 修复路径遍历风险,统一路径归一化,避免 Zip Slip。
  2. 发布流程接入事务,并优化并发创建逻辑,避免竞态和脏数据。
  3. 修复发布时文件读取异常被静默忽略的问题,读取失败直接返回 400。
  4. 修复 CLI 更新过程中 lockfile 漂移的问题,支持增量写入。
  5. 修复点赞状态请求竞态,避免页面切换时状态回退。
  6. 增加 URL 安全校验,仅允许打开 http(s) 和同源相对路径。
  7. 移除占位命令被误渲染为可执行命令的问题。
  8. 增加 ZIP 解压限制,防止 Zip Bomb,并补充对应测试。
  9. 优化多技能包导入文案及上传提示。

验证:

  • dt-skill:174/174 测试通过
  • 主项目:92/92 测试通过
  • Prettier、ESLint、TypeScript 全部通过

未处理:

  • 提取公共工具,减少重复代码
  • CLI 鉴权契约(不需要)
  • 统一错误处理与用户提示
image

huaiju added 4 commits July 1, 2026 10:40
- .detail-main-column.is-package: max-width 1280/1600/1780/2200 via @media (1600/1920/2560)
- min-width: 0 + width: 100% + align-self: center to fix grid item shrink
- .detail-hero-main: padding 24px 32px, border-radius 12px, gap 14px
- .skill-card-unified.is-compact: padding 20px 22px, icon 48px, name 16px, desc 14px
- <Row gutter={[24, 24]}> in SkillDetailHero for wider card gutters
- .skill-card-unified.is-compact min-height 132px
- .prettierignore: ignore dt-skill/dist/ and run/ (build/runtime output,
  already in .gitignore but prettier does not read .gitignore)
- app/web/pages/skills/index.tsx: drop extra space in empty blocks
- app/service/skillsRegistry.js: fix indent in object literal
- test/skills-registry-contract.test.js: drop extra space in empty blocks
- CLAUDE.md: replace duplicated copy with symlink to AGENTS.md
- Extract agent definitions to src/cli/agents/definitions.ts (data layer)
- Add src/cli/installer.ts for canonical .agents/skills physical install
- Update skills command, publish, ui, types, and test kit for the split
- Stage .serena config
- Extract Lockfile module (src/lockfile.ts): own read/write/pin helpers
  and LockfileEntry type; drop the `as { version?... }` cast at the
  lockfile entry read site
- Type package children as SkillChild[] in ApiV1SkillResponseSchema;
  remove the two `as any` casts in the package expand branches
- Extract install pipeline (src/cli/installerPipeline.ts): the
  download→extract→origin→link→lock sequence takes an injected
  InstallPipelineHttp adapter (real in prod, fake in tests) so the
  deepest install logic is its own module, not inlined in the command
- Collapse the duplicated suspicious-moderation decision tree and
  version-verify into checkSuspiciousModeration / verifyVersion helpers,
  preserving the exact pre-flight ordering the tests assert
- Move lockfile unit tests to src/lockfile.test.ts; add pipeline http
  seam test and a package-children schema test
@TreeTreeDi

Copy link
Copy Markdown
Contributor Author

完善 cli 交互
image

huaiju added 3 commits July 1, 2026 19:24
getSkillFileContent used the raw filePath from the request for the DB
lookup without passing it through normalizeRelativePath, unlike
buildSkillZip and the upload flow. Route the query path through the
shared guard and return null on invalid input so the controller's 404
stays uniform. Add a behavior test pinning normalizeRelativePath.
@liuxy0551
liuxy0551 merged commit 7210d5e into DTStack:master Jul 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants