@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.
- package/README.en.md +432 -125
- package/README.md +427 -125
- package/dist/chunks/blob-RYNC3CVY.cjs +1 -0
- package/dist/chunks/{blob-3PZEQWTP.mjs → blob-WZAGX4RO.mjs} +1 -1
- package/dist/chunks/chunk-5DAHAO55.mjs +3 -0
- package/dist/chunks/{chunk-4D5RQDWJ.mjs → chunk-6OLPTZDO.mjs} +2 -2
- package/dist/chunks/{chunk-ZBKGF7PA.mjs → chunk-BQ6QWQEM.mjs} +1 -1
- package/dist/chunks/chunk-BWDTT6SA.cjs +3 -0
- package/dist/chunks/chunk-DNE3XPCJ.cjs +2 -0
- package/dist/chunks/chunk-HI5IN4UL.mjs +265 -0
- package/dist/chunks/chunk-HOK3SUH4.cjs +22 -0
- package/dist/chunks/{chunk-5BL3KG26.cjs → chunk-IJI72D6W.cjs} +2 -2
- package/dist/chunks/{chunk-ISMGLHYS.cjs → chunk-JUNIAQ2A.cjs} +1 -1
- package/dist/chunks/{chunk-CY6UI6SJ.cjs → chunk-LJ63Q26N.cjs} +1 -1
- package/dist/chunks/{chunk-S6YNGR7S.cjs → chunk-Q2MOP5ZW.cjs} +2 -2
- package/dist/chunks/chunk-S5OLAC7X.cjs +265 -0
- package/dist/chunks/chunk-UUZB3HCD.mjs +22 -0
- package/dist/chunks/chunk-Y6D5Z6AU.mjs +1 -0
- package/dist/chunks/chunk-ZJS7IO5V.mjs +2 -0
- package/dist/chunks/cli-handler-2G4ZYO2S.cjs +1 -0
- package/dist/chunks/cli-handler-F4DUEULA.mjs +1 -0
- package/dist/chunks/installer-3ZLHOVAO.cjs +1 -0
- package/dist/chunks/{installer-REG45DC2.mjs → installer-UUEXYC7I.mjs} +1 -1
- package/dist/chunks/{interfaces-UIS44Q7A.cjs → interfaces-T3TO7GQW.cjs} +1 -1
- package/dist/chunks/local-lock-KNX2RUIV.cjs +1 -0
- package/dist/chunks/local-lock-UYZTKIET.mjs +1 -0
- package/dist/chunks/scan-6EBCZDVK.cjs +1 -0
- package/dist/chunks/scan-BZA5LEZN.mjs +1 -0
- package/dist/chunks/skill-lock-CDMLVBYH.mjs +1 -0
- package/dist/chunks/skill-lock-WPACLO4W.cjs +1 -0
- package/dist/chunks/store-2ULHEVHS.cjs +1 -0
- package/dist/chunks/{store-IVDLGLET.mjs → store-FRXO6UWU.mjs} +1 -1
- package/dist/chunks/telemetry-TAVF3FAM.cjs +1 -0
- package/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +1 -1
- package/package.json +7 -8
- package/dist/chunks/blob-ZDEX2HRV.cjs +0 -1
- package/dist/chunks/chunk-5W7HC7BY.mjs +0 -22
- package/dist/chunks/chunk-CXH3OTTQ.cjs +0 -22
- package/dist/chunks/chunk-K2XGYOXP.mjs +0 -267
- package/dist/chunks/chunk-ML6B4IQL.mjs +0 -1
- package/dist/chunks/chunk-NKIQLESR.mjs +0 -3
- package/dist/chunks/chunk-ROCFLAYZ.mjs +0 -2
- package/dist/chunks/chunk-RVR3DSD2.cjs +0 -2
- package/dist/chunks/chunk-SXUY2J75.cjs +0 -3
- package/dist/chunks/chunk-UJWB7QQ6.cjs +0 -267
- package/dist/chunks/cli-handler-667TYY4I.cjs +0 -1
- package/dist/chunks/cli-handler-YSDUNKKZ.mjs +0 -1
- package/dist/chunks/installer-SOVGUW3M.cjs +0 -1
- package/dist/chunks/local-lock-AWD3LLEY.mjs +0 -1
- package/dist/chunks/local-lock-GIZDVF3X.cjs +0 -1
- package/dist/chunks/scan-57D2H7LP.cjs +0 -1
- package/dist/chunks/scan-WAXGJM5N.mjs +0 -1
- package/dist/chunks/skill-lock-DZMA75MY.mjs +0 -1
- package/dist/chunks/skill-lock-XTWQYBRG.cjs +0 -1
- package/dist/chunks/store-F7PGGZIO.cjs +0 -1
- package/dist/chunks/telemetry-LCGTSJDM.cjs +0 -1
- /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
|
|
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
|
+
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
|
-
-
|
|
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
|
|
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 # AgentType
|
|
56
|
+
├── types.ts # AgentType, Skill, AgentConfig, ParsedSource, RemoteSkill
|
|
55
57
|
├── agents.ts # Agent 配置矩阵(72+ 个)与分类函数
|
|
56
|
-
├── skills.ts # 技能发现: parseSkillMd
|
|
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 #
|
|
59
|
-
│ ├── post-install.ts #
|
|
60
|
-
│ ├── store.ts #
|
|
61
|
-
│ └── types.ts
|
|
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 #
|
|
64
|
-
├── list.ts #
|
|
65
|
-
├── remove.ts
|
|
66
|
-
├── update.ts
|
|
67
|
-
├── use.ts #
|
|
68
|
-
├── doctor.ts
|
|
69
|
-
├── store-cmd.ts # store
|
|
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
|
|
88
|
-
│ ├── registry.ts #
|
|
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 #
|
|
92
|
+
│ ├── local.ts # 本地插件目录 (plugin.json) 适配
|
|
91
93
|
│ └── types.ts # PluginSource / PluginSourceCategory / PluginSourceEntry 接口
|
|
92
|
-
├── i18n/ #
|
|
93
|
-
├──
|
|
94
|
-
├──
|
|
95
|
-
├──
|
|
96
|
-
├──
|
|
97
|
-
└──
|
|
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
|
-
#
|
|
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
|
|
129
|
-
easbot-skills store list [keyword] # 列出 store skills
|
|
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
|
|
132
|
-
easbot-skills store clean --force # 同上 + 清 cache
|
|
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
|
-
|
|
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` 的 `
|
|
195
|
+
`@easbot/agent` 的 `easbot skills ...` 负责通过 `handleSkillsCli(args, deps)` 实现全子命令复用:
|
|
148
196
|
|
|
149
197
|
```typescript
|
|
150
|
-
import { handleSkillsCli,
|
|
198
|
+
import { handleSkillsCli, setAgentAdapter } from '@easbot/skills';
|
|
151
199
|
|
|
152
|
-
|
|
153
|
-
|
|
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
|
|
210
|
+
// process.exit(result.code) if result.code !== 0
|
|
160
211
|
```
|
|
161
212
|
|
|
162
|
-
`
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
|
175
|
-
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
|
246
|
-
|
|
247
|
-
| `$
|
|
248
|
-
| `$
|
|
249
|
-
| `$
|
|
250
|
-
|
|
|
251
|
-
|
|
|
252
|
-
| `<
|
|
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
|
-
|
|
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
|
-
#
|
|
568
|
+
# 构建 (产出 dist/ + .d.ts)
|
|
269
569
|
pnpm build
|
|
270
570
|
|
|
271
571
|
# 监听构建
|
|
272
572
|
pnpm dev
|
|
273
573
|
|
|
274
|
-
#
|
|
574
|
+
# 测试 (vitest)
|
|
275
575
|
pnpm test
|
|
276
576
|
pnpm test:run
|
|
277
577
|
|
|
278
578
|
# 代码质量
|
|
279
|
-
pnpm
|
|
280
|
-
pnpm
|
|
281
|
-
pnpm
|
|
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`、`@
|
|
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
|
## 许可证
|