@easbot/skills 0.3.13 → 0.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.en.md +432 -125
  2. package/README.md +427 -125
  3. package/dist/chunks/blob-RYNC3CVY.cjs +1 -0
  4. package/dist/chunks/{blob-3PZEQWTP.mjs → blob-WZAGX4RO.mjs} +1 -1
  5. package/dist/chunks/chunk-5DAHAO55.mjs +3 -0
  6. package/dist/chunks/{chunk-4D5RQDWJ.mjs → chunk-6OLPTZDO.mjs} +2 -2
  7. package/dist/chunks/{chunk-ZBKGF7PA.mjs → chunk-BQ6QWQEM.mjs} +1 -1
  8. package/dist/chunks/chunk-BWDTT6SA.cjs +3 -0
  9. package/dist/chunks/chunk-DNE3XPCJ.cjs +2 -0
  10. package/dist/chunks/chunk-HI5IN4UL.mjs +265 -0
  11. package/dist/chunks/chunk-HOK3SUH4.cjs +22 -0
  12. package/dist/chunks/{chunk-5BL3KG26.cjs → chunk-IJI72D6W.cjs} +2 -2
  13. package/dist/chunks/{chunk-ISMGLHYS.cjs → chunk-JUNIAQ2A.cjs} +1 -1
  14. package/dist/chunks/{chunk-CY6UI6SJ.cjs → chunk-LJ63Q26N.cjs} +1 -1
  15. package/dist/chunks/{chunk-S6YNGR7S.cjs → chunk-Q2MOP5ZW.cjs} +2 -2
  16. package/dist/chunks/chunk-S5OLAC7X.cjs +265 -0
  17. package/dist/chunks/chunk-UUZB3HCD.mjs +22 -0
  18. package/dist/chunks/chunk-Y6D5Z6AU.mjs +1 -0
  19. package/dist/chunks/chunk-ZJS7IO5V.mjs +2 -0
  20. package/dist/chunks/cli-handler-2G4ZYO2S.cjs +1 -0
  21. package/dist/chunks/cli-handler-F4DUEULA.mjs +1 -0
  22. package/dist/chunks/installer-3ZLHOVAO.cjs +1 -0
  23. package/dist/chunks/{installer-REG45DC2.mjs → installer-UUEXYC7I.mjs} +1 -1
  24. package/dist/chunks/{interfaces-UIS44Q7A.cjs → interfaces-T3TO7GQW.cjs} +1 -1
  25. package/dist/chunks/local-lock-KNX2RUIV.cjs +1 -0
  26. package/dist/chunks/local-lock-UYZTKIET.mjs +1 -0
  27. package/dist/chunks/scan-6EBCZDVK.cjs +1 -0
  28. package/dist/chunks/scan-BZA5LEZN.mjs +1 -0
  29. package/dist/chunks/skill-lock-CDMLVBYH.mjs +1 -0
  30. package/dist/chunks/skill-lock-WPACLO4W.cjs +1 -0
  31. package/dist/chunks/store-2ULHEVHS.cjs +1 -0
  32. package/dist/chunks/{store-IVDLGLET.mjs → store-FRXO6UWU.mjs} +1 -1
  33. package/dist/chunks/telemetry-TAVF3FAM.cjs +1 -0
  34. package/dist/cli.cjs +1 -1
  35. package/dist/cli.mjs +1 -1
  36. package/dist/index.cjs +1 -1
  37. package/dist/index.d.cts +3 -2
  38. package/dist/index.d.ts +3 -2
  39. package/dist/index.mjs +1 -1
  40. package/package.json +7 -8
  41. package/dist/chunks/blob-ZDEX2HRV.cjs +0 -1
  42. package/dist/chunks/chunk-5W7HC7BY.mjs +0 -22
  43. package/dist/chunks/chunk-CXH3OTTQ.cjs +0 -22
  44. package/dist/chunks/chunk-K2XGYOXP.mjs +0 -267
  45. package/dist/chunks/chunk-ML6B4IQL.mjs +0 -1
  46. package/dist/chunks/chunk-NKIQLESR.mjs +0 -3
  47. package/dist/chunks/chunk-ROCFLAYZ.mjs +0 -2
  48. package/dist/chunks/chunk-RVR3DSD2.cjs +0 -2
  49. package/dist/chunks/chunk-SXUY2J75.cjs +0 -3
  50. package/dist/chunks/chunk-UJWB7QQ6.cjs +0 -267
  51. package/dist/chunks/cli-handler-667TYY4I.cjs +0 -1
  52. package/dist/chunks/cli-handler-YSDUNKKZ.mjs +0 -1
  53. package/dist/chunks/installer-SOVGUW3M.cjs +0 -1
  54. package/dist/chunks/local-lock-AWD3LLEY.mjs +0 -1
  55. package/dist/chunks/local-lock-GIZDVF3X.cjs +0 -1
  56. package/dist/chunks/scan-57D2H7LP.cjs +0 -1
  57. package/dist/chunks/scan-WAXGJM5N.mjs +0 -1
  58. package/dist/chunks/skill-lock-DZMA75MY.mjs +0 -1
  59. package/dist/chunks/skill-lock-XTWQYBRG.cjs +0 -1
  60. package/dist/chunks/store-F7PGGZIO.cjs +0 -1
  61. package/dist/chunks/telemetry-LCGTSJDM.cjs +0 -1
  62. /package/dist/chunks/{chunk-VRHWDHQV.cjs → chunk-BWPPLYIF.cjs} +0 -0
package/README.md CHANGED
@@ -2,17 +2,18 @@
2
2
 
3
3
  # @easbot/skills
4
4
 
5
- EASBot 技能管理子系统。负责技能(SKILL.md)的发现、安装、移除、搜索、更新、一次性使用(use),以及 store / cache / index 的运维管理。同时承担 **Plugin Source 注册中心**角色(决策 0044),把 well-known / marketplace / 本地 plugins 等源抽象为 `PluginSource`,供 `@easbot/agent` 注入 `PluginDefinition.skills`。
5
+ EASBot 技能管理子系统。负责技能(`SKILL.md`)的发现、安装、移除、搜索、更新、一次性使用(`use`)、模板初始化(`init`),以及 store / cache / index 的运维管理。同时承担 **Plugin Source 注册中心**角色(决策 0044),把 well-known / marketplace / 本地 plugins 等源抽象为 `PluginSource`,供 `@easbot/agent` 注入 `PluginDefinition.skills`。
6
6
 
7
7
  既可作为独立 CLI(`easbot-skills`),也可被 `@easbot/agent` 主 CLI 通过 Commander.js 委派调用,`easbot skills ...` 与 `easbot-skills ...` 等价。
8
8
 
9
9
  ## 版本
10
10
 
11
- v0.3.11
11
+ v0.3.13
12
12
 
13
13
  ## 目标文件
14
14
 
15
15
  包中只操作 **SKILL.md**(以及可选的本地 `plugin.json`):
16
+
16
17
  - 技能名来自 `SKILL.md` frontmatter 的 `name` 字段
17
18
  - 插件清单来自 `plugin.json`(若存在,否则默认为 `*.md`)
18
19
 
@@ -24,12 +25,13 @@ v0.3.11
24
25
  - **Universal 共享路径**:`eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code` 等 16 个 agent 通过 `"universal"` 作用域共享 `.agents/skills` 目录
25
26
  - **Non-universal agent**:各自维护独立技能目录
26
27
  - **安装矩阵 / 后安装核对**:`AgentInstallMatrix`(agent × skill 二维表,`probeCell` 逐单元格判定),安装后对每个 cell 做 reconcile(缺失补链接,多余移除)
27
- - **依赖注入** (决策 0043):通过 `setGlobalAdapter` / `setInstanceAdapter` / `setAgentAdapter` 注入 `IGlobal.Path` / `IInstance.directory`,让 skills 统一使用宿主的 XDG 数据树
28
+ - **依赖注入**(决策 0043):通过 `setGlobalAdapter` / `setInstanceAdapter` / `setAgentAdapter` 注入 `IGlobal.Path` / `IInstance.directory`,让 skills 统一使用宿主的 XDG 数据树
28
29
  - **增量同步**:基于本地 SHA-256 密文锁文件的 `add` / `remove` / `update` / `store` 增量操作(`skill-lock.ts` / `local-lock.ts`)
29
- - **store 视角运维** (决策 36A):`skills store list / clean / update / remove` 管理 store 物理 + index + cache,**不**动 agent 前端分发
30
+ - **store 视角运维**(决策 36A):`skills store list / clean / update / remove` 管理 store 物理 + index + cache,**不**动 agent 前端分发
30
31
  - **local 源硬保护**:`store clean --force` / `store remove` 对 local 源拒绝删 cache / 用户原目录
31
32
  - **i18n**:内置 zh-CN / en-US 两套翻译;所有用户简文走 `t()`,未命中 key 时回退英文原文
32
33
  - **遥测 + 安全审计**:内置 `skills.sh` partner audit 上报、OpenClaw 风险提示、遥测可冲刷(`flushTelemetry`)
34
+ - **统一交互 Prompt**(Session 4):所有交互走 `@easbot/terminal.Prompt` namespace —— 取消语义收口(`Prompt.cancel` 是 `never` + 内置 `process.exit(0)`),图标统一来自 `Symbol` 命名空间(**禁止**硬编码 `✓✗◆`),颜色统一走 `theme.colorize()`
33
35
 
34
36
  ## 安装
35
37
 
@@ -51,50 +53,52 @@ pnpm add @easbot/skills
51
53
 
52
54
  ```
53
55
  src/
54
- ├── types.ts # AgentTypeSkillAgentConfigParsedSourceRemoteSkill
56
+ ├── types.ts # AgentType, Skill, AgentConfig, ParsedSource, RemoteSkill
55
57
  ├── agents.ts # Agent 配置矩阵(72+ 个)与分类函数
56
- ├── skills.ts # 技能发现: parseSkillMddiscoverSkillsfilterSkills
58
+ ├── skills.ts # 技能发现: parseSkillMd, discoverSkills, filterSkills
59
+ ├── constants.ts # AGENTS_DIR / SKILLS_SUBDIR / UNIVERSAL_SKILLS_DIR
60
+ ├── frontmatter.ts # YAML frontmatter 解析
61
+ ├── hash.ts # 哈希工具: computeFromDir / computeSnapshotHash
62
+ ├── source-parser.ts # 来源标准化: parseSource, parseOwnerRepo, sanitizeSubpath, isRepoPrivate
63
+ ├── interfaces.ts # 依赖注入: setGlobalAdapter / setInstanceAdapter / setAgentAdapter
64
+ ├── detect-agent.ts # 探测运行的 AI Agent: detectAgent / isRunningInAgent
65
+ ├── sanitize.ts # 控制字符净化: sanitizeMetadata / stripTerminalEscapes
66
+ ├── telemetry.ts # 遥测: track / flushTelemetry / fetchAuditData / setVersion
67
+ ├── git.ts # 仓库克隆 / cleanupTempDir / parseGitHubRepoUrl
68
+ ├── blob.ts # GitHub API 回退: fetchRepoTree / tryBlobInstall / toSkillSlug
69
+ ├── skill-lock.ts # 全局安装锁定文件读写 (skill-lock.json)
70
+ ├── local-lock.ts # 项目级锁定文件 (skills-lock.json) 与文件夹 SHA-256
57
71
  ├── installer/
58
- │ ├── installer.ts # 物理安装:installSkillForAgentinstallRemoteSkillForAgentinstallBlobSkillForAgent
59
- │ ├── post-install.ts # 安装后核对矩阵:planActionsbuildMatrixprobeCell
60
- │ ├── store.ts # Store 三层职责(sourcecacheinstall):ensureCachedSource、acquireSourceClone、cleanCache
61
- │ └── types.ts # InstallMode、InstalledSkill
72
+ │ ├── installer.ts # 物理安装: installSkillForAgent / installRemoteSkillForAgent / installBlobSkillForAgent / installWellKnownSkillForAgent / linkSkillDir / copySkillDir / listInstalledSkills / getInstallPath / getCanonicalPath / sanitizeName
73
+ │ ├── post-install.ts # 安装后核对矩阵: planActions / buildMatrix / probeCell / runPostInstallReconcile
74
+ │ ├── store.ts # 三层 source / cache / install 收敛: acquireSourceClone / ensureCachedSource / cleanCache / getCacheRepoDir / getStoreDir
75
+ │ └── store-types.ts # 共享类型: StoreSourceType / SkillEntry / PluginDefinition / MarketDefinition / SkillLocation / STORE_INDEX_VERSION / parsePluginId / storePathForSkillLock
62
76
  ├── add.ts # 添加技能主流程
63
- ├── find.ts # 搜索技能(skills.sh / fuzzy filter / 本地 store 查询)
64
- ├── list.ts # 列出已安装技能(项目/全局/按 agent 过滤)
65
- ├── remove.ts # 移除技能
66
- ├── update.ts # 增量更新(按 filter 更新一个或多个技能)
67
- ├── use.ts # 一次性使用(materializeUseSkillbuildUsePromptlaunchAgentInteractively
68
- ├── doctor.ts # 检查 + 清理断链与坏符号链接
69
- ├── store-cmd.ts # store 运维子命令(list / clean / update / remove
77
+ ├── find.ts # 搜索技能 (skills.sh / fuzzy filter / 本地 store 查询)
78
+ ├── list.ts # 列出已安装技能 (项目/全局/按 agent 过滤)
79
+ ├── remove.ts # 移除技能
80
+ ├── update.ts # 增量更新 (按 filter 更新一个或多个技能)
81
+ ├── use.ts # 一次性使用: materializeUseSkill / buildUsePrompt / launchAgentInteractively
82
+ ├── doctor.ts # 检查 + 清理断链与坏符号链接
83
+ ├── store-cmd.ts # store 运维子命令 (list / clean / update / remove)
70
84
  ├── init-template.ts # 根据 locale 模板创建新技能
71
- ├── sanitize.ts # 控制字符净化:sanitizeMetadata、stripTerminalEscapes
72
- ├── telemetry.ts # 遥测发送:track、flushTelemetry、fetchAuditData、setVersion
73
- ├── detect-agent.ts # 探测运行的 AI Agent(detectAgent、isRunningInAgent)
74
- ├── skill-lock.ts # 全局安装锁定文件读写(skill-lock.json)
75
- ├── local-lock.ts # 项目级锁定文件(skills-lock.json)与文件夹 SHA-256
76
- ├── git.ts # 仓库克隆 / cleanupTempDir / parseGitHubRepoUrl
77
- ├── blob.ts # GitHub API 回退:fetchRepoTree、tryBlobInstall、toSkillSlug
78
- ├── source-parser.ts # 来源标准化:parseSource、parseOwnerRepo、sanitizeSubpath、isRepoPrivate
79
- ├── interfaces.ts # 依赖注入:setGlobalAdapter / setInstanceAdapter / getGlobal / getXdgData
80
- ├── constants.ts # AGENTS_DIR / SKILLS_SUBDIR / UNIVERSAL_SKILLS_DIR
81
- ├── frontmatter.ts # YAML frontmatter 解析
82
- ├── format.ts # ANSI 辅助函数(颜色)
83
85
  ├── providers/
84
86
  │ ├── wellknown.ts # WellKnownProvider: fetch index + scan + 加载
85
87
  │ └── registry.ts # Provider 注册中心 + HostProvider 接口
86
- ├── sources/
87
- │ ├── index.ts # PluginSource 入口:createWellKnownSource / createLocalPluginSource 工厂
88
- │ ├── registry.ts # 注册中心:registerSource / listSources / findSource / listAllEntries
88
+ ├── sources/ # Plugin Source 注册中心 (决策 0044)
89
+ │ ├── index.ts # PluginSource 入口: createWellKnownSource / createLocalPluginSource 工厂
90
+ │ ├── registry.ts # 注册中心: registerSource / listSources / findSource / listAllEntries
89
91
  │ ├── wellknown.ts # wellknown 源适配
90
- │ ├── local.ts # 本地插件目录(plugin.json)适配
92
+ │ ├── local.ts # 本地插件目录 (plugin.json) 适配
91
93
  │ └── types.ts # PluginSource / PluginSourceCategory / PluginSourceEntry 接口
92
- ├── i18n/ # 国际化全套(zh-CN / en-US
93
- ├── prompts/ # 搜索多选提示
94
- ├── utils/ # 辅助工具(ansi / format)
95
- ├── cli.ts # 独立CLI 入口(easbot-skills)
96
- ├── cli-handler.ts # CLI 处理器(供 agent 复用)
97
- └── src/sources/ # PluginSource 注册中心 (决策 0044)
94
+ ├── i18n/ # 国际化全套 (zh-CN / en-US)
95
+ ├── utils/ # 辅助工具
96
+ ├── ansi.ts # 硬编码 SGR 常量 (RESET / BOLD / DIM / TEXT / CYAN / YELLOW / MAGENTA)
97
+ ├── format.ts # 标签工具: pBgLabel / pErrorBadge (Agent badge + ERROR badge)
98
+ ├── color.ts # picocolors 形态兼容层 (dim/red/green/yellow/cyan/bold/... → @easbot/terminal.colorize + theme)
99
+ └── output.ts # 人类输出统一封装: printHuman / wrapJson / emitJson / formatListTruncated
100
+ ├── cli.ts # 独立 CLI 入口 (easbot-skills)
101
+ └── cli-handler.ts # CLI 处理器 (供 agent 复用)
98
102
  ```
99
103
 
100
104
  ## CLI 用法
@@ -106,10 +110,10 @@ src/
106
110
  easbot-skills add houjallen/agent-skills
107
111
  easbot-skills add https://github.com/houjallen/agent-skills -g
108
112
 
109
- # 搜索(交互式 fzf 选出)
113
+ # 搜索 (交互式搜索多选)
110
114
  easbot-skills find typescript --owner houjallen
111
115
 
112
- # 列出已安装(项目级/全局)
116
+ # 列出已安装 (项目级/全局)
113
117
  easbot-skills list --json
114
118
  easbot-skills ls -g -a claude-code
115
119
 
@@ -121,164 +125,461 @@ easbot-skills rm --agent claude-code my-skill
121
125
  easbot-skills update -g
122
126
  easbot-skills update my-skill --all
123
127
 
124
- # 一次性使用(不写锁定文件)
128
+ # 一次性使用 (不写锁定文件)
125
129
  easbot-skills use houjallen/agent-skills@houjallen
126
130
  easbot-skills use --skill my-skill --agent claude
127
131
 
128
- # store 视角运维(store + cache + index
129
- easbot-skills store list [keyword] # 列出 store skills(按 name 过滤)
132
+ # store 视角运维 (store + cache + index)
133
+ easbot-skills store list [keyword] # 列出 store skills (按 name 过滤)
130
134
  easbot-skills store list --json # 完整 index 为 JSON
131
- easbot-skills store clean # 重置 store(删 store 物理 + 清 index
132
- easbot-skills store clean --force # 同上 + 清 cachelocal 源保护)
135
+ easbot-skills store clean # 重置 store (删 store 物理 + 清 index)
136
+ easbot-skills store clean --force # 同上 + 清 cache (local 源保护)
133
137
  easbot-skills store remove <sourceKey> # 移除 source
134
138
  easbot-skills store remove <sourceKey> --force # 额外清 cache
135
139
 
136
- # 健康检查(医生说:检查 + 清理断链符号链接)
140
+ # 健康检查 (检查 + 清理断链符号链接)
137
141
  easbot-skills doctor
138
142
  easbot-skills doctor -a easbot -y # 检查一个 agent + 自动清理
139
143
  easbot-skills dr -g # 仅全局范围
140
144
 
141
- # 健康检查(快速)
142
- easyt-skills init my-skill
145
+ # 模板初始化 (创建新技能的 SKILL.md)
146
+ easbot-skills init my-skill
147
+ easbot-skills init # 在 cwd/<basename>/SKILL.md 创建
148
+ ```
149
+
150
+ ### 子命令清单(独立 CLI 实际行为)
151
+
152
+ ```
153
+ easbot-skills add <source> # 添加技能 (alias: a / install / i)
154
+ easbot-skills find [query] # 搜索技能 (alias: search / f / s)
155
+ easbot-skills list # 列出已安装 (alias: ls)
156
+ easbot-skills remove [skills...] # 移除 (alias: rm / r)
157
+ easbot-skills update [skills...] # 增量更新 (alias: upgrade / check)
158
+ easbot-skills use <source[@skill]> # 一次性使用
159
+ easbot-skills init [name] # 模板初始化
160
+ easbot-skills doctor # 健康检查 (alias: dr)
161
+ easbot-skills store <subcommand> # store 视角运维 (list / clean / update / remove)
143
162
  ```
144
163
 
164
+ ### `store` 子命令族(决策 0049-yyy)
165
+
166
+ ```
167
+ # 列出 store 内的所有 source(人类可读模式展示完整 64 位 hex sourceKey,便于后续 update / remove)
168
+ easbot-skills store list
169
+ easbot-skills store list [keyword] # 按 skill name 过滤
170
+
171
+ # 重置 store(默认重置物理 + index.json;--force 额外清 cache 物理)
172
+ easbot-skills store clean
173
+ easbot-skills store clean --force
174
+
175
+ # 重新拉取 store(不动 agent 前端分发)
176
+ # 不传 source-key → 全量 store 重新拉
177
+ # 传 source-key(64 位 hex,从 `store list` 输出取)→ 仅该 source 整 source 重新拉
178
+ easbot-skills store update
179
+ easbot-skills store update <full-source-key> # 决策 0049-yyy:[keyword] → [source-key]
180
+
181
+ # 移除单个 store source(--force 额外清 cache;local 源 cache = 用户原目录,永远不删)
182
+ easbot-skills store remove <source-key>
183
+ easbot-skills store remove <source-key> --force
184
+ ```
185
+
186
+ **核心语义**:
187
+ - `store` 操作的是**整 source 镜像**(不是单 skill)—— store 真源 = source cp 产物;
188
+ 要么整 source 重拉,要么不动;不存在"只更新 store 某个 skill"的语义。
189
+ - `update <skill-name>` 想"按 skill 触发整 source 拉 + agent 分发"——交给 `skills update <name>`,
190
+ 不该塞进 `store update`(避免语义重叠)。
191
+ - `store list` 输出**完整** sourceKey(决策 0049-yyy:之前是 8 位截断 → 用户无法直接复用)。
192
+
145
193
  ### 被宿主 CLI 委派
146
194
 
147
- `@easbot/agent` 的 `easyt skills ...` 负责通过 `handleSkillsCli(args, deps)` 实现全子命令复用。看看源码:
195
+ `@easbot/agent` 的 `easbot skills ...` 负责通过 `handleSkillsCli(args, deps)` 实现全子命令复用:
148
196
 
149
197
  ```typescript
150
- import { handleSkillsCli, setGlobalAdapter, setInstanceAdapter } from '@easbot/skills';
198
+ import { handleSkillsCli, setAgentAdapter } from '@easbot/skills';
151
199
 
152
- setGlobalAdapter({ Path: Global.Path });
153
- setInstanceAdapter({ directory: ctx.config.directory, worktree: Instance.worktree });
200
+ setAgentAdapter({
201
+ global: Global, // IGlobal
202
+ instance: Instance, // IInstance
203
+ // subAgentRunner / localAgentRunner / triggerEvent 可选
204
+ });
154
205
 
155
206
  const result = await handleSkillsCli(['add', 'houjallen/agent-skills', '-y'], {
156
207
  version: ctx.programVersion,
157
208
  cwd: ctx.config.directory,
158
209
  });
159
- // result.code === 0 时退出进程
210
+ // process.exit(result.code) if result.code !== 0
160
211
  ```
161
212
 
162
- `easyt skills` 在 `packages/agent/src/cli/commands/skills.ts` 的 `registerSkillsCommand()` 中注册,通过 Commander.js `skills.<subcommand>` 把 flag 转为 argv 后 dispatch 给 `handleSkillsCli`。`skills store` 子族也在同一模块注册,并绑定其中的 `registerSkillsCommand()`。
213
+ `easbot skills` 在 `packages/agent/src/cli/commands/skills.ts` 的 `registerSkillsCommand()` 中注册,通过 Commander.js `skills.<subcommand>` 把 flag 转为 argv 后 dispatch 给 `handleSkillsCli`。`skills store` 子族也在同一模块注册。
163
214
 
164
- ## API
215
+ ## API(按模块)
165
216
 
166
- | 模块 | 导出 | 说明 |
167
- |---|---|---|
168
- | `types` | `AgentType`, `Skill`, `AgentConfig`, `ParsedSource`, `RemoteSkill` | 核心类型定义(70+ 个 AgentType 联合类型) |
169
- | `agents` | `agents`, `detectInstalledAgents`, `getAgentConfig`, `getAgentSkillDirs`, `getUniversalAgents`, `getAgentGlobalSkillDirs`, `isUniversalAgent`, `matchesUniversalScope` 等 | Agent 元数据矩阵 + 分类函数 |
170
- | `skills` | `parseSkillMd`, `discoverSkills`, `filterSkills`, `getSkillDisplayName`, `isSubpathSafe`, `shouldInstallInternalSkills` | SKILL.md 发现 / 解析 |
171
- | `installer` | `installSkillForAgent`, `installRemoteSkillForAgent`, `installBlobSkillForAgent`, `installWellKnownSkillForAgent`, `listInstalledSkills`, `isSkillInstalled`, `getCanonicalSkillsDir`, `getInstallPath`, `sanitizeName` | 物理安装接口 |
172
- | `installer/post-install` | `buildMatrix`, `planActions`, `applyActions`, `probeCell`, `runPostInstallReconcile` | 安装矩阵生成 / 差异应用 |
173
- | `installer/store` | `acquireSourceClone`, `ensureCachedSource`, `installFromCache`, `cleanCache`, `getCacheRepoDir`, `getSourceDir` | 三层 source/cache/install 收敛架构 |
174
- | `add` | `runAdd`, `parseAddOptions`, `initTelemetry`, `AddOptions` | 技能添加 |
175
- | `find` | `runFind`, `parseFindOptions`, `searchSkillsAPI`, `FindOptions`, `SearchSkill` | 搜索(skills.sh + 本地 store) |
176
- | `list` | `runList`, `parseListOptions` | 列出 |
177
- | `remove` | `removeCommand`, `parseRemoveOptions`, `RemoveOptions` | 移除 |
178
- | `update` | `runUpdate`, `parseUpdateOptions`, `hasProjectSkills`, `matchesSkillFilter`, `resolveUpdateScope`, `UpdateScope` | 增量更新 |
179
- | `store-cmd` | `runStore`, `parseStoreOptions`, `runStoreList`, `runStoreClean`, `runStoreUpdate`, `runStoreRemove`, `StoreOptions` | 运维:以 store 为视角管理 store / cache / index |
180
- | `use` | `runUse`, `parseUseOptions`, `buildUsePrompt`, `materializeUseSkill`, `launchAgentInteractively`, `UseOptions`, `MaterializedUseSkill` | 一次性使用 |
181
- | `doctor` | `runDoctor` | 健康检查 + 断链清理 |
182
- | `cli-handler` | `handleSkillsCli`, `renderBanner`, `renderHelp`, `SkillsCliDeps`, `SkillsCliResult` | CLI 桥接供 agent 复用 |
183
- | `interfaces` | `setGlobalAdapter`, `setInstanceAdapter`, `setAgentAdapter`, `getGlobal`, `getInstance`, `getHomeDir`, `getXdgData`, `getXdgConfig`, `getXdgState`, `getXdgCache`, `getProjectDirectory`, `resetGlobalAdapter`, `resetInstanceAdapter`, `hasAgentAdapter` | 路径 / Agent 依赖注入 |
184
- | `skill-lock` | `readSkillLock`, `writeSkillLock`, `addSkillToLock`, `removeSkillFromLock`, `getSkillFromLock`, `getGitHubToken`, `getAllLockedSkills`, `dismissPrompt`, `isPromptDismissed`, `resetGhAuthWarning` | 全局锁文件 |
185
- | `local-lock` | `readLocalLock`, `writeLocalLock`, `addSkillToLocalLock`, `removeSkillFromLocalLock`, `computeSkillFolderHash`, `getLocalLockPath` | 项目锁文件 |
186
- | `git` | `cloneRepo`, `cleanupTempDir`, `parseGitHubRepoUrl`, `isGitHubHttpsCloneUrl`, `isGitHubSsoAuthError`, `GitCloneError` | Git/SSH 回退 / 仓库克隆 |
187
- | `blob` | `fetchRepoTree`, `findSkillMdPaths`, `getSkillFolderHashFromTree`, `tryBlobInstall`, `toSkillSlug`, `resetRepoTreeAuthState` | GitHub API blob 回退 |
188
- | `telemetry` | `track`, `flushTelemetry`, `setVersion`, `fetchAuditData`, `setDetectedAgent` | 使用统计 + 安全审计 |
189
- | `sanitize` | `sanitizeMetadata`, `stripTerminalEscapes` | 输出净化 |
190
- | `detect-agent` | `detectAgent`, `getAgentName`, `getAgentType`, `isRunningInAgent` | Agent 环境探测 |
191
- | `providers/wellknown` | `wellKnownProvider`, `WellKnownProvider` | WellKnown 主机提供方:解析索引 + 拉取 SKILL.md |
192
- | `providers/registry` | `findProvider`, `registerProvider`, `getProviders`, `registry` | 提供方注册中心 + 匹配器 |
193
- | `sources` | `registerSource`, `listSources`, `findSource`, `findSourcesByCategory`, `listAllEntries`, `createWellKnownSource`, `createLocalPluginSource` | PluginSource 注册中心(决策 0044) |
194
- | `frontmatter` | `parseFrontmatter` | YAML frontmatter 解析 |
195
- | `constants` | `AGENTS_DIR`, `SKILLS_SUBDIR`, `UNIVERSAL_SKILLS_DIR` | 约定的目录常量 |
196
- | `utils/ansi` | `BOLD`, `DIM`, `RESET`, `TEXT`, `CYAN` 等 | ANSI 终端辅助函数 |
197
-
198
- ## 支持的Agent列表(完整)
199
-
200
- `types.ts` 中的 `AgentType` 联合类型包含 70+ 个 Agent,其中包括:
217
+ > 所有导出均从 `@easbot/skills` 顶层入口([`src/index.ts`](src/index.ts))按主题分组暴露。
218
+
219
+ ### 1. 核心类型
220
+
221
+ ```typescript
222
+ import type { AgentType, Skill, AgentConfig, ParsedSource, RemoteSkill } from '@easbot/skills';
223
+ ```
224
+
225
+ | 类型 | 说明 |
226
+ |---|---|
227
+ | `AgentType` | 70+ Agent 联合类型(含 `universal` 虚拟类型) |
228
+ | `Skill` | 技能模型(name / path / frontmatter / pluginName / subpath 等) |
229
+ | `AgentConfig` | Agent 配置(name / displayName / skillsDir / globalSkillsDir / detectInstalled) |
230
+ | `ParsedSource` | 来源描述(type / url / ref / subpath) |
231
+ | `RemoteSkill` | 远程技能模型 |
232
+
233
+ ### 2. Agent 体系
234
+
235
+ ```typescript
236
+ import {
237
+ agents, // Record<AgentType, AgentConfig>
238
+ EVE_SUBAGENTS_DIR, // 'agent/subagents'
239
+ PROJECT_SKILLS_DIR_PATTERN, // /^\.[^/]+\/skills$/
240
+ detectInstalledAgents,
241
+ getAgentConfig,
242
+ getAgentGlobalSkillDirs, // 项目级 agent 的全局技能目录列表
243
+ getAgentProjectSkillDirs,
244
+ getAgentProjectSkillContainerPrefixes,
245
+ getAgentSkillDirs,
246
+ getEveSubagents,
247
+ getNonUniversalAgents, // universal agent 列表
248
+ getOpenClawGlobalSkillsDir,
249
+ getUniversalAgents,
250
+ isUniversalAgent,
251
+ matchesUniversalScope,
252
+ } from '@easbot/skills';
253
+ import type { AgentSkillDirsResult, UniversalScope } from '@easbot/skills';
254
+ ```
255
+
256
+ ### 3. 技能发现 / 安装
257
+
258
+ ```typescript
259
+ import {
260
+ discoverSkills, filterSkills, getSkillDisplayName,
261
+ isSubpathSafe, parseSkillMd, shouldInstallInternalSkills,
262
+ installSkillForAgent, installRemoteSkillForAgent, installBlobSkillForAgent,
263
+ installWellKnownSkillForAgent,
264
+ linkSkillDir, copySkillDir,
265
+ getAgentBaseDir, getCanonicalPath, getCanonicalSkillsDir,
266
+ getEveSubagentSkillsDir, getInstallPath,
267
+ isSkillInstalled, listInstalledSkills, sanitizeName,
268
+ } from '@easbot/skills';
269
+ import type { DiscoverSkillsOptions, InstallMode, InstalledSkill } from '@easbot/skills';
270
+
271
+ // Post-install 矩阵
272
+ import { applyActions, buildMatrix, planActions, probeCell, runPostInstallReconcile } from '@easbot/skills';
273
+ import type { AgentInstallMatrix, CellAction, CellScope, InstallCell, InstallState,
274
+ PostInstallInput, PostInstallResult } from '@easbot/skills';
275
+ ```
276
+
277
+ ### 4. 来源解析
278
+
279
+ ```typescript
280
+ import { parseSource, parseOwnerRepo, getOwnerRepo, isRepoPrivate, sanitizeSubpath } from '@easbot/skills';
281
+ ```
282
+
283
+ ### 5. 命令入口(CLI 子命令的 `run*` + `parse*`)
284
+
285
+ ```typescript
286
+ import { runAdd, parseAddOptions, initTelemetry } from '@easbot/skills';
287
+ import type { AddOptions } from '@easbot/skills';
288
+
289
+ import { runFind, parseFindOptions, searchSkillsAPI } from '@easbot/skills';
290
+ import type { FindOptions, ParseFindOptionsResult, SearchSkill } from '@easbot/skills';
291
+
292
+ import { runList, parseListOptions } from '@easbot/skills';
293
+ import { removeCommand, parseRemoveOptions } from '@easbot/skills';
294
+ import type { RemoveOptions } from '@easbot/skills';
295
+
296
+ import { runUpdate, parseUpdateOptions, hasProjectSkills, matchesSkillFilter, resolveUpdateScope } from '@easbot/skills';
297
+ import type { UpdateCheckOptions, UpdateScope } from '@easbot/skills';
298
+
299
+ import { runUse, parseUseOptions, buildUsePrompt, materializeUseSkill, launchAgentInteractively } from '@easbot/skills';
300
+ import type { AgentProcess, AgentSpawn, MaterializedUseSkill, ParseUseOptionsResult, UseOptions, UseSkill } from '@easbot/skills';
301
+
302
+ import { runDoctor } from '@easbot/skills';
303
+
304
+ import { runStore, parseStoreOptions, runStoreList, runStoreClean, runStoreUpdate, runStoreRemove } from '@easbot/skills';
305
+ import type { StoreOptions } from '@easbot/skills';
306
+ ```
307
+
308
+ ### 6. 锁文件 / 哈希
309
+
310
+ ```typescript
311
+ import {
312
+ readSkillLock, writeSkillLock, addSkillToLock, removeSkillFromLock, getSkillFromLock,
313
+ getGitHubToken, getAllLockedSkills, getSkillsBySource,
314
+ getSkillLockPath, computeContentHash, storePathFromLockEntry,
315
+ dismissPrompt, isPromptDismissed, resetGhAuthWarning,
316
+ } from '@easbot/skills';
317
+ import type { DismissedPrompts, SkillLockEntry, SkillLockFile } from '@easbot/skills';
318
+
319
+ import {
320
+ readLocalLock, writeLocalLock, addSkillToLocalLock, removeSkillFromLocalLock,
321
+ getLocalLockPath, storePathFromLocalLockEntry,
322
+ } from '@easbot/skills';
323
+ import type { LocalSkillLockEntry, LocalSkillLockFile } from '@easbot/skills';
324
+
325
+ import { computeFromDir, computeSnapshotHash } from '@easbot/skills';
326
+ ```
327
+
328
+ ### 7. Git / Blob 集成
329
+
330
+ ```typescript
331
+ import {
332
+ DEFAULT_CLONE_TIMEOUT, GitCloneError,
333
+ cloneRepo, cleanupTempDir, parseGitHubRepoUrl,
334
+ isGitHubHttpsCloneUrl, isGitHubSsoAuthError,
335
+ } from '@easbot/skills';
336
+
337
+ import {
338
+ BLOB_ALLOWED_REPOS, // Record<string, { downloadUrl }>
339
+ toSkillSlug,
340
+ fetchRepoTree, findSkillMdPaths, getSkillFolderHashFromTree,
341
+ resetRepoTreeAuthState, tryBlobInstall,
342
+ } from '@easbot/skills';
343
+ import type { BlobInstallResult, BlobSkill, RepoTree, SkillDownloadResponse, SkillSnapshotFile, TreeEntry } from '@easbot/skills';
344
+ ```
345
+
346
+ ### 8. Installer 支撑层(三层 source / cache / install)
347
+
348
+ ```typescript
349
+ import {
350
+ acquireSourceClone, ensureCachedSource, installFromCache, cleanCache, cleanCachedRepo,
351
+ getCacheRepoDir, getCacheRoot, getSourceDir,
352
+ } from '@easbot/skills';
353
+ import type { InstallScope } from '@easbot/skills';
354
+
355
+ // store-types 共享类型
356
+ export type {
357
+ StoreSourceType, SkillScope,
358
+ SkillEntry, PluginDefinition, MarketDefinition, SkillLocation,
359
+ DefaultPluginConfig, StoreIndex,
360
+ STORE_INDEX_VERSION,
361
+ parsePluginId, pluginDirFromPluginId, storePathForSkillLock,
362
+ } from '@easbot/skills';
363
+ ```
364
+
365
+ ### 9. 安全 / 遥测 / Agent 探测
366
+
367
+ ```typescript
368
+ import {
369
+ track, flushTelemetry, fetchAuditData, setVersion, setDetectedAgent,
370
+ } from '@easbot/skills';
371
+ import type { AuditResponse, PartnerAudit, SkillAuditData } from '@easbot/skills';
372
+
373
+ import { sanitizeMetadata, stripTerminalEscapes } from '@easbot/skills';
374
+
375
+ import { detectAgent, getAgentName, getAgentType, isRunningInAgent } from '@easbot/skills';
376
+ ```
377
+
378
+ ### 10. Provider 抽象
379
+
380
+ ```typescript
381
+ import { wellKnownProvider, WellKnownProvider } from '@easbot/skills';
382
+ import type {
383
+ WellKnownIndex, WellKnownIndexV1, WellKnownIndexV2,
384
+ WellKnownSkill, WellKnownSkillEntry, WellKnownSkillEntryV1, WellKnownSkillEntryV2,
385
+ WellKnownFileContent,
386
+ } from '@easbot/skills';
387
+
388
+ import { findProvider, getProviders, registerProvider, registry } from '@easbot/skills';
389
+ import type { HostProvider, ProviderMatch, ProviderRegistry, RemoteSkill as ProviderRemoteSkill } from '@easbot/skills';
390
+ ```
391
+
392
+ ### 11. 常量与辅助
393
+
394
+ ```typescript
395
+ import { AGENTS_DIR, SKILLS_SUBDIR, UNIVERSAL_SKILLS_DIR, parseFrontmatter } from '@easbot/skills';
396
+ ```
397
+
398
+ ### 12. CLI 桥接(供 `@easbot/agent` 复用)
399
+
400
+ ```typescript
401
+ import { handleSkillsCli, renderBanner, renderHelp } from '@easbot/skills';
402
+ import type { SkillsCliDeps, SkillsCliResult } from '@easbot/skills';
403
+ ```
404
+
405
+ ### 13. 接口注入(宿主 → skills)
406
+
407
+ ```typescript
408
+ import {
409
+ setGlobalAdapter, setInstanceAdapter, setAgentAdapter,
410
+ resetGlobalAdapter, resetInstanceAdapter,
411
+ getGlobal, getInstance, getAgentAdapter, getHomeDir,
412
+ getXdgConfig, getXdgData, getXdgState, getXdgCache,
413
+ getProjectDirectory,
414
+ hasAgentAdapter, requireAgentAdapter,
415
+ } from '@easbot/skills';
416
+ import type { SkillsAgentAdapter } from '@easbot/skills';
417
+ import type { IGlobal, IInstance, ISubAgentRunner } from '@easbot/skills';
418
+ ```
419
+
420
+ ### 14. Plugin Source 注册中心(决策 0044)
421
+
422
+ ```typescript
423
+ import { registerSource, unregisterSource, listSources, findSource, findSourcesByCategory, listAllEntries,
424
+ createWellKnownSource, createLocalPluginSource } from '@easbot/skills';
425
+ import type {
426
+ PluginSource, PluginSourceCategory, PluginSourceEntry, PluginSourceLoadResult,
427
+ WellKnownSourceOptions, LocalPluginSourceOptions,
428
+ } from '@easbot/skills';
429
+ ```
430
+
431
+ ```typescript
432
+ import { registerSource, createWellKnownSource, createLocalPluginSource } from '@easbot/skills';
433
+
434
+ // 1) 注册 well-known endpoint 作为 plugin source
435
+ registerSource(createWellKnownSource({
436
+ url: 'https://mintlify.com/docs',
437
+ }));
438
+
439
+ // 2) 注册本地 plugin.json 作为 plugin source
440
+ registerSource(createLocalPluginSource({
441
+ basePath: process.cwd(),
442
+ }));
443
+
444
+ // 3) @easbot/agent bootstrap 时拉取所有 source
445
+ import { listSources } from '@easbot/skills';
446
+ for (const source of listSources()) {
447
+ const entries = await source.fetch();
448
+ for (const entry of entries) {
449
+ const { skills } = await source.load(entry);
450
+ // → 注入 PluginDefinition.skills
451
+ }
452
+ }
453
+ ```
454
+
455
+ ## 支持的 Agent 列表(完整)
456
+
457
+ `agents.ts` 中的 `AgentType` 联合类型包含 **72 个 Agent**(含虚拟类型 `universal`):
201
458
 
202
459
  `easbot`, `claude-code`, `cursor`, `codex`, `eve`, `opencode`, `aider-desk`, `amp`, `antigravity`, `astrbot`, `augment`, `autohand-code`, `bob`, `openclaw`, `cline`, `codearts-agent`, `codebuddy`, `codemaker`, `codestudio`, `command-code`, `continue`, `cortex`, `crush`, `deepagents`, `devin`, `dexto`, `droid`, `firebender`, `forgecode`, `gemini-cli`, `github-copilot`, `goose`, `hermes-agent`, `inference-sh`, `iflow-cli`, `jazz`, `junie`, `kilo`, `kimi-code-cli`, `kiro-cli`, `kode`, `lingma`, `loaf`, `zanbura`, `mistral-vibe`, `moxby`, `mux`, `neovate`, `openhands`, `om`, `pi`, `qoder`, `qoder-cn`, `qwen-code`, `replit`, `reasonix`, `roo`, `rovodev`, `tabnine-cli`, `terramind`, `tinycloud`, `trae`, `trae-cn`, `warp`, `windsurf`, `zed`, `zencoder`, `zenflow`, `pochi`, `promptscript`, `adal`, `antigravity-cli`, `mistral`,以及虚拟类型 `universal`。
203
460
 
204
- 所有这些 Agent 的配置(displayName、skillsDir、globalSkillsDir、是否导入universal、安装判断函数等)都在 `src/agents.ts` 中定义。
461
+ **Universal 共享 `.agents/skills` 目录**(16 个 agent):`eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code` 等。
462
+
463
+ 所有这些 Agent 的配置(displayName / skillsDir / globalSkillsDir / 是否导入 universal / 安装判断函数 / `detectInstalled`)都在 `src/agents.ts` 中定义。
205
464
 
206
465
  ## 全局路径依赖注入
207
466
 
208
- 为避免与宿主(agent/gateway)抢 XDG/home 目录,`@easbot/skills` 默认通过依赖注入获取路径:
467
+ 为避免与宿主(agent / gateway)抢 XDG / home 目录,`@easbot/skills` 默认通过依赖注入获取路径:
209
468
 
210
469
  ```typescript
211
470
  import {
471
+ setAgentAdapter, // 推荐:一站式注入(global + instance + 可选 subAgentRunner 等)
212
472
  setGlobalAdapter, // 注入 IGlobal.Path
213
473
  setInstanceAdapter, // 注入 IInstance.directory / worktree
214
- setAgentAdapter, // 注入 SkillsAgentAdapter (subAgentRunner / localAgentRunner / triggerEvent)
215
474
  getHomeDir,
216
475
  getXdgConfig,
217
476
  getXdgData,
218
477
  getProjectDirectory,
219
478
  } from '@easbot/skills';
220
479
 
221
- setGlobalAdapter({
222
- Path: {
223
- home: '/Users/me',
224
- data: '/Users/me/.local/share/easbot',
225
- config: '/Users/me/.config/easbot',
226
- state: '/Users/me/.local/state/easbot',
227
- cache: '/Users/me/.cache/easbot',
228
- log: '/Users/me/.local/state/easbot/log',
229
- bin: '/Users/me/.local/bin',
480
+ setAgentAdapter({
481
+ global: {
482
+ Path: {
483
+ home: '/Users/me',
484
+ data: '/Users/me/.local/share/easbot',
485
+ config: '/Users/me/.config/easbot',
486
+ state: '/Users/me/.local/state/easbot',
487
+ cache: '/Users/me/.cache/easbot',
488
+ log: '/Users/me/.local/state/easbot/log',
489
+ bin: '/Users/me/.local/bin',
490
+ },
230
491
  },
231
- });
232
-
233
- setInstanceAdapter({
234
- directory: '/repo',
235
- worktree: '/repo',
492
+ instance: {
493
+ directory: '/repo',
494
+ worktree: '/repo',
495
+ },
496
+ // 可选
497
+ subAgentRunner: ...,
498
+ triggerEvent: async (event, input, ctx) => ({ success: true, output: undefined, modified: false }),
236
499
  });
237
500
  ```
238
501
 
239
502
  未注入时,skills 包回退到 `xdg-basedir` + `homedir()`,与 v1 独立 CLI 完全兼容。
240
503
 
504
+ **`getHomeDir()` 优先级**(测试隔离):
505
+ 1. `process.env.EASBOT_TEST_HOME`(**测试专用**最高优先级)
506
+ 2. 注入的 `Global.Path.home`
507
+ 3. `os.homedir()` 兜底
508
+
241
509
  ## 数据目录约定
242
510
 
243
- | 路径 | 用途 |
244
- |---|---|
245
- | `$Global.Path.data/skills/` | Agent 运行时加载的技能目录(运行时扫描) |
246
- | `$Global.Path.data/skills/.skill-lock.json` | 全局安装锁定文件(与 store 同根) |
247
- | `$Global.Path.data/skills/store/<sourceKey>/` | **store 物理目录**(按 sourceKey hash 归一化源;add 写一次,update 复用) |
248
- | `$Global.Path.data/skills/store/index.json` | **store defs 索引**(key = skillName;记录 storeKey / type / url / skillPath / computedHash) |
249
- | `$Global.Path.cache/skills/cache/<owner>/<repo>/` | **cache 物理**(remote 源下载/物化缓存;local = 用户原目录) |
250
- | `<cwd>/.agents/skills/` `<cwd>/skills/` | 项目级技能目录 |
251
- | `<cwd>/skills-lock.json` | 项目级锁定文件 |
252
- | `<home>/.config/easbot/skills/` | XDG 配置兜底 |
511
+ > 注入场景下,所有 `getXdgData / getXdgCache / ...` 都走 `Global.Path.*`;默认场景走 `xdg-basedir + easbot` 段。
512
+
513
+ | 路径 | 用途 | 实现位置 |
514
+ |---|---|---|
515
+ | `${getXdgData()}/skills/` | Agent 运行时加载的技能目录(运行时扫描) | `installer/store.ts` |
516
+ | `${getXdgData()}/skills/.skill-lock.json` | 全局安装锁定文件(与 store 同根) | `skill-lock.ts` |
517
+ | `${getXdgData()}/skills/store/<sourceKey>/` | **store 物理目录**(按 sourceKey hash 归一化源;add 写一次,update 复用) | `installer/store.ts::getStoreDir` |
518
+ | `${getXdgData()}/skills/store/index.json` | **store defs 索引**(记录每个 store skill 的 registryKey / type / url / skillPath / computedHash) | `installer/store.ts::getStoreDefinitionsFile` |
519
+ | `${getXdgCache()}/skills/cache/<type>/<owner/repo>/` | **cache 物理**(remote 源下载 / 物化缓存;local 源 = 用户原目录) | `installer/store.ts::getCacheRepoDir` |
520
+ | `<cwd>/.easbot/skills/<skill>/` | EASBot 项目级(universal agent 不命中此路径) | `agents.ts` |
521
+ | `<cwd>/.agents/skills/<skill>/` | claude-code / cursor / gemini-cli 等 universal 项目级 | `agents.ts` |
522
+ | `<cwd>/<agent-glob>/skills/<skill>/` | 各 agent 自定义项目级(如 `~/.trae/skills/`) | `agents.ts` |
523
+ | `<cwd>/skills-lock.json` | 项目级锁定文件 | `local-lock.ts` |
524
+ | `${getXdgConfig()}/easbot/skills/` | EASBot 全局技能目录(注入场景) | `agents.ts::easbot.globalSkillsDir` |
525
+ | `~/.config/easbot/skills/` | EASBot 全局技能目录(默认场景 fallback) | 同上 |
253
526
 
254
527
  > 当被 `@easbot/agent` 委派时,所有路径落到 `{Global.Path.data}` 这颗统一数据树下,与 Gateway / MCP / Session / Contact 等模块并列。
255
528
 
256
529
  ## 链接标头外部审核反馈(skills.sh)
257
530
 
258
531
  `telemetry.ts` 会往回向 skills.sh 发送遥测 / 审计数据(可配置 `SKILLS_API_URL`),用于:
259
- - skill 审计(`fetchAuditData` 返回技能级的 `PartnerAudit` 信息)
532
+
533
+ - 技能审计(`fetchAuditData` 返回技能级的 `PartnerAudit` 信息)
260
534
  - 安全 gate 检查(`.dangerously-accept-openclaw-risks` flag 可跳过)
261
535
 
536
+ ## 交互提示规范(Session 4 改造)
537
+
538
+ 所有 CLI 交互(select / confirm / multiselect / spinner / intro / outro / cancel / Log)统一走 [`@easbot/terminal.Prompt`](../terminal/README.md) namespace:
539
+
540
+ ```typescript
541
+ import { Prompt, Symbol as Glyph } from '@easbot/terminal';
542
+
543
+ // 取消语义收口:Prompt.cancel 是 `never`,内置 process.exit(0)
544
+ const v = await Prompt.select({ message: '选择范围', options: [...] });
545
+ if (Prompt.isCancel(v)) await cleanup();
546
+ Prompt.cancel('用户取消');
547
+
548
+ // 图标统一(**禁止**硬编码 ✓✗◆ 等字面量)
549
+ console.log(`${Glyph.statusIcon('success')} 操作成功`); // ✓ green
550
+ console.log(`${Glyph.colorize(Glyph.bar.bullet, 'error')} bullet`);
551
+
552
+ // 状态流(统一配色到 terminal theme)
553
+ Prompt.Log.info('Installing...');
554
+ Prompt.Log.warn('警告');
555
+ Prompt.Log.error('失败');
556
+ Prompt.Log.step('步骤');
557
+ Prompt.Log.message('普通消息');
558
+ ```
559
+
560
+ 业务方**不**直接调 `pc.green('✓')` 等;**不**调 `console.log(p.theme.error(...))`。所有这些都已收敛到 `utils/color.ts` 的 picocolors 兼容层(**过渡**)和 `Glyph.*` / `Prompt.Log.*`。
561
+
262
562
  ## 开发
263
563
 
264
564
  ```bash
265
565
  # 安装依赖
266
566
  pnpm install
267
567
 
268
- # 构建(产出 dist/ + .d.ts
568
+ # 构建 (产出 dist/ + .d.ts)
269
569
  pnpm build
270
570
 
271
571
  # 监听构建
272
572
  pnpm dev
273
573
 
274
- # 测试(vitest
574
+ # 测试 (vitest)
275
575
  pnpm test
276
576
  pnpm test:run
277
577
 
278
578
  # 代码质量
279
- pnpm biome-lint # biome check .
280
- pnpm biome-fix # biome check --write .
281
- pnpm biome-format # biome format .
579
+ pnpm lint # biome check .
580
+ pnpm lint:fix # biome check --write .
581
+ pnpm format # biome format .
582
+ pnpm format:fix # biome format --write .
282
583
 
283
584
  # 类型检查
284
585
  pnpm type-check
@@ -304,7 +605,8 @@ pnpm publish --access public --git-checks false --registry https://registry.npmj
304
605
  ## 浏览器 / 跨运行时说明
305
606
 
306
607
  - 使用 Node 内置模块(`fs/promises`、`node:os`、`node:path`、`node:child_process`),不能在浏览器运行。
307
- - 依赖 `simple-git`、`@clack/prompts`、`picocolors`、`xdg-basedir`、`zod`、`yaml` 等。
608
+ - 依赖 `simple-git`、`@easbot/terminal`(统一交互 Prompt + 颜色主题 + 图标)、`xdg-basedir`、`zod`、`yaml` 等。
609
+ - **不**再依赖 `@clack/prompts` / `picocolors` —— 全部收敛到 `@easbot/terminal`(见 Session 4 决策)
308
610
  - `engines.node >= 22.22.3` — Node 22 LTS 推荐。
309
611
 
310
612
  ## 许可证