@easbot/skills 0.3.12 → 0.3.14
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 +433 -126
- package/README.md +428 -126
- package/dist/chunks/blob-SCUVTYVE.cjs +1 -0
- package/dist/chunks/blob-WZAGX4RO.mjs +1 -0
- package/dist/chunks/chunk-2E6BHPFV.cjs +265 -0
- package/dist/chunks/chunk-5BDDXFOF.mjs +1 -0
- package/dist/chunks/chunk-5RWSXDNO.cjs +3 -0
- package/dist/chunks/chunk-6NTEYECA.mjs +22 -0
- package/dist/chunks/chunk-AQYRRXU5.mjs +5 -0
- package/dist/chunks/{chunk-2VZUPTI7.cjs → chunk-DFBKA5A6.cjs} +1 -1
- package/dist/chunks/chunk-DNE3XPCJ.cjs +2 -0
- package/dist/chunks/chunk-E7AHWFZN.cjs +2 -0
- package/dist/chunks/chunk-ISMGLHYS.cjs +1 -0
- package/dist/chunks/chunk-J6PRUXFG.mjs +265 -0
- package/dist/chunks/chunk-JCOXRETY.cjs +22 -0
- package/dist/chunks/chunk-ML6B4IQL.mjs +1 -0
- package/dist/chunks/chunk-NH4TYEPW.mjs +3 -0
- package/dist/chunks/{chunk-S6YNGR7S.cjs → chunk-Q2MOP5ZW.cjs} +2 -2
- package/dist/chunks/{chunk-OWG6N2K6.cjs → chunk-UGHF4GOW.cjs} +2 -2
- package/dist/chunks/chunk-ZJS7IO5V.mjs +2 -0
- package/dist/chunks/chunk-ZYDDQV73.mjs +2 -0
- package/dist/chunks/cli-handler-3FSM4C7L.mjs +1 -0
- package/dist/chunks/cli-handler-B6H4RZEM.cjs +1 -0
- package/dist/chunks/{installer-FB26E7JZ.mjs → installer-NJN3PT5F.mjs} +1 -1
- package/dist/chunks/installer-YDJBZTQ7.cjs +1 -0
- package/dist/chunks/{interfaces-UIS44Q7A.cjs → interfaces-5BH4K5TM.cjs} +1 -1
- package/dist/chunks/local-lock-SPZB3AB7.cjs +1 -0
- package/dist/chunks/local-lock-ZHTDWYXF.mjs +1 -0
- package/dist/chunks/scan-6W47D2KJ.mjs +1 -0
- package/dist/chunks/scan-L6UNVP3V.cjs +1 -0
- package/dist/chunks/skill-lock-MNRZ7TIX.mjs +1 -0
- package/dist/chunks/skill-lock-VX2HGPTY.cjs +1 -0
- package/dist/chunks/store-TSS4BMBF.cjs +1 -0
- package/dist/chunks/store-UJPPYDBG.mjs +1 -0
- package/dist/chunks/telemetry-B4PS27S5.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 +53 -9
- package/dist/index.d.ts +53 -9
- package/dist/index.mjs +1 -1
- package/package.json +5 -7
- package/dist/chunks/blob-DOVEGVIE.cjs +0 -1
- package/dist/chunks/blob-JSMTOYEN.mjs +0 -1
- package/dist/chunks/chunk-2YVJ7YP6.mjs +0 -22
- package/dist/chunks/chunk-4R6NKPNW.mjs +0 -3
- package/dist/chunks/chunk-676OG55M.mjs +0 -5
- package/dist/chunks/chunk-6PJ3YQA7.mjs +0 -2
- package/dist/chunks/chunk-72DXY4B7.mjs +0 -1
- package/dist/chunks/chunk-GR2NJUJ6.mjs +0 -255
- package/dist/chunks/chunk-JFEBB5CL.cjs +0 -22
- package/dist/chunks/chunk-KV7EP6AW.cjs +0 -255
- package/dist/chunks/chunk-RWSBKHQ2.cjs +0 -3
- package/dist/chunks/chunk-TCFGU43L.cjs +0 -2
- package/dist/chunks/cli-handler-RAJ42VDN.mjs +0 -1
- package/dist/chunks/cli-handler-YAJ5J5VA.cjs +0 -1
- package/dist/chunks/installer-GOQTCUJ4.cjs +0 -1
- package/dist/chunks/local-lock-4AA55ORE.cjs +0 -1
- package/dist/chunks/local-lock-LG5YL33V.mjs +0 -1
- package/dist/chunks/scan-QEVID2TF.mjs +0 -1
- package/dist/chunks/scan-XWU3FCE3.cjs +0 -1
- package/dist/chunks/skill-lock-KHPVP7AD.mjs +0 -1
- package/dist/chunks/skill-lock-LET33FVT.cjs +0 -1
- package/dist/chunks/store-3NRBE47N.mjs +0 -1
- package/dist/chunks/store-EHYH46YY.cjs +0 -1
- package/dist/chunks/telemetry-LCGTSJDM.cjs +0 -1
- /package/dist/chunks/{chunk-VRHWDHQV.cjs → chunk-GWUDKZEH.cjs} +0 -0
package/README.en.md
CHANGED
|
@@ -2,34 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
# @easbot/skills
|
|
4
4
|
|
|
5
|
-
Skill management subsystem for the EASBot ecosystem. Handles discovery, installation, removal, search, update, one-shot use (use), and store/cache/index operations for skills (SKILL.md). Also acts as the **Plugin Source Registry** (decision 0044), abstracting well-known, marketplace, and local plugin sources into `PluginSource` for `@easbot/agent` to inject into `PluginDefinition.skills`.
|
|
5
|
+
Skill management subsystem for the EASBot ecosystem. Handles discovery, installation, removal, search, update, one-shot use (`use`), template initialization (`init`), and store/cache/index operations for skills (SKILL.md). Also acts as the **Plugin Source Registry** (decision 0044), abstracting well-known, marketplace, and local plugin sources into `PluginSource` for `@easbot/agent` to inject into `PluginDefinition.skills`.
|
|
6
6
|
|
|
7
|
-
Usable both as a standalone CLI (`easbot-skills`) and as a library delegated to by the `@easbot/agent` main CLI via Commander.js
|
|
7
|
+
Usable both as a standalone CLI (`easbot-skills`) and as a library delegated to by the `@easbot/agent` main CLI via Commander.js — `easbot skills ...` and `easbot-skills ...` are equivalent.
|
|
8
8
|
|
|
9
9
|
## Version
|
|
10
10
|
|
|
11
|
-
v0.3.
|
|
11
|
+
v0.3.13
|
|
12
12
|
|
|
13
13
|
## Target Files
|
|
14
14
|
|
|
15
15
|
The package only operates on **SKILL.md** (and optional local `plugin.json`):
|
|
16
|
+
|
|
16
17
|
- Skill name comes from the `name` field in the `SKILL.md` frontmatter
|
|
17
18
|
- Plugin manifest comes from `plugin.json` (if present; otherwise defaulting to `*.md`)
|
|
18
19
|
|
|
19
20
|
## Features
|
|
20
21
|
|
|
21
|
-
- **Type Safety**:
|
|
22
|
+
- **Type Safety**: full TypeScript types + Zod frontmatter validation + Zod remote-skill payload validation
|
|
22
23
|
- **Multi-Source**: GitHub shorthand (`owner/repo`) / HTTPS / SSH / Well-Known index / local path / GitHub API blob fallback
|
|
23
|
-
- **Multi-Agent**: 72+ agent types (`easbot`, `claude-code`, `cursor`, `codex`, `amp`, `eve`, `gemini-cli`, `github-copilot`, `opencode`, `qwen-code`, `trae`, `trae-cn`, `windsurf`, `zed`, `roo`, `cline`, `iflow-cli`, `kimi-code-cli`, `augment`, `devin`, `goose`, `
|
|
24
|
-
- **Universal shared path**: `eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code`
|
|
24
|
+
- **Multi-Agent**: 72+ agent types (`easbot`, `claude-code`, `cursor`, `codex`, `amp`, `eve`, `gemini-cli`, `github-copilot`, `opencode`, `qwen-code`, `trae`, `trae-cn`, `windsurf`, `zed`, `roo`, `cline`, `iflow-cli`, `kimi-code-cli`, `augment`, `devin`, `goose`, `dexto` etc.)
|
|
25
|
+
- **Universal shared path**: 16 agents (`eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code` etc.) share `.agents/skills` via the `universal` scope
|
|
25
26
|
- **Non-universal agents**: each maintains independent skill directories
|
|
26
|
-
- **Install Matrix / Post-Install Reconcile**: `AgentInstallMatrix` (agent × skill 2D table, `probeCell` cell-by-cell)
|
|
27
|
-
- **Dependency Injection** (
|
|
28
|
-
- **Incremental Sync**:
|
|
29
|
-
- **Store-Centric Ops** (
|
|
27
|
+
- **Install Matrix / Post-Install Reconcile**: `AgentInstallMatrix` (agent × skill 2D table, `probeCell` cell-by-cell); post-install cell reconcile (missing → link, excess → remove)
|
|
28
|
+
- **Dependency Injection** (decision 0043): `setGlobalAdapter` / `setInstanceAdapter` / `setAgentAdapter` inject `IGlobal.Path` / `IInstance.directory` so skills uses the host's unified XDG data tree
|
|
29
|
+
- **Incremental Sync**: lockfile-based `add` / `remove` / `update` / `store` with local SHA-256 hashing (`skill-lock.ts` / `local-lock.ts`)
|
|
30
|
+
- **Store-Centric Ops** (decision 36A): `skills store list / clean / update / remove` manage store dirs + index + cache without touching agent distributions
|
|
30
31
|
- **Local Source Hard Protection**: `store clean --force` / `store remove` refuse to delete cache / user directory for local sources
|
|
31
|
-
- **i18n**:
|
|
32
|
-
- **Telemetry + Audit**:
|
|
32
|
+
- **i18n**: built-in zh-CN / en-US translations; all user-facing strings go through `t()`, with fallback to English literal when the key is missing
|
|
33
|
+
- **Telemetry + Audit**: built-in `skills.sh` partner-audit reporting, OpenClaw risk scoping, telemetry flush (`flushTelemetry`)
|
|
34
|
+
- **Unified Prompt namespace** (Session 4): every interactive flow goes through [`@easbot/terminal.Prompt`](../terminal/README.en.md) — cancellation contract centralized (`Prompt.cancel` returns `never` and calls `process.exit(0)` internally), icons centralized through `Symbol` (writing `✓✗◆` literals is **forbidden**), colors centralized through `theme.colorize()`
|
|
33
35
|
|
|
34
36
|
## Installation
|
|
35
37
|
|
|
@@ -54,47 +56,49 @@ src/
|
|
|
54
56
|
├── types.ts # AgentType, Skill, AgentConfig, ParsedSource, RemoteSkill
|
|
55
57
|
├── agents.ts # Agent config matrix (72+) + classification functions
|
|
56
58
|
├── skills.ts # Skill discovery: parseSkillMd, discoverSkills, filterSkills
|
|
59
|
+
├── constants.ts # AGENTS_DIR / SKILLS_SUBDIR / UNIVERSAL_SKILLS_DIR
|
|
60
|
+
├── frontmatter.ts # YAML frontmatter parser
|
|
61
|
+
├── hash.ts # Hashing helpers: computeFromDir / computeSnapshotHash
|
|
62
|
+
├── source-parser.ts # Source normalization: parseSource, parseOwnerRepo, sanitizeSubpath, isRepoPrivate
|
|
63
|
+
├── interfaces.ts # Dependency injection: setGlobalAdapter / setInstanceAdapter / setAgentAdapter
|
|
64
|
+
├── detect-agent.ts # Detect running AI agent: detectAgent / isRunningInAgent
|
|
65
|
+
├── sanitize.ts # Control-char sanitization: sanitizeMetadata / stripTerminalEscapes
|
|
66
|
+
├── telemetry.ts # Telemetry: track, flushTelemetry, fetchAuditData, setVersion
|
|
67
|
+
├── git.ts # Repo clone / cleanupTempDir / parseGitHubRepoUrl
|
|
68
|
+
├── blob.ts # GitHub API fallback: fetchRepoTree, tryBlobInstall, toSkillSlug
|
|
69
|
+
├── skill-lock.ts # Global lockfile (skill-lock.json)
|
|
70
|
+
├── local-lock.ts # Project lockfile (skills-lock.json) + folder SHA-256
|
|
57
71
|
├── installer/
|
|
58
|
-
│ ├── installer.ts # Physical install: installSkillForAgent
|
|
59
|
-
│ ├── post-install.ts # Post-install reconcile matrix: planActions
|
|
60
|
-
│ ├── store.ts # Three-layer
|
|
61
|
-
│ └── types.ts
|
|
72
|
+
│ ├── installer.ts # Physical install: installSkillForAgent / installRemoteSkillForAgent / installBlobSkillForAgent / installWellKnownSkillForAgent / linkSkillDir / copySkillDir / listInstalledSkills / getInstallPath / getCanonicalPath / sanitizeName
|
|
73
|
+
│ ├── post-install.ts # Post-install reconcile matrix: planActions / buildMatrix / probeCell / runPostInstallReconcile
|
|
74
|
+
│ ├── store.ts # Three-layer source/cache/install convergence: acquireSourceClone / ensureCachedSource / cleanCache / getCacheRepoDir / getStoreDir
|
|
75
|
+
│ └── store-types.ts # Shared types: StoreSourceType / SkillEntry / PluginDefinition / MarketDefinition / SkillLocation / STORE_INDEX_VERSION / parsePluginId / storePathForSkillLock
|
|
62
76
|
├── add.ts # Skill add pipeline
|
|
63
77
|
├── find.ts # Search (skills.sh / fuzzy filter / local store query)
|
|
64
|
-
├── list.ts # List installed (project/global/agent filtered)
|
|
65
|
-
├── remove.ts
|
|
66
|
-
├── update.ts
|
|
67
|
-
├── use.ts # One-shot use: materializeUseSkill
|
|
68
|
-
├── doctor.ts
|
|
78
|
+
├── list.ts # List installed skills (project/global/agent filtered)
|
|
79
|
+
├── remove.ts # Remove skills
|
|
80
|
+
├── update.ts # Incremental update (by filter, update one or more)
|
|
81
|
+
├── use.ts # One-shot use: materializeUseSkill / buildUsePrompt / launchAgentInteractively
|
|
82
|
+
├── doctor.ts # Health check + dangling symlink cleanup
|
|
69
83
|
├── store-cmd.ts # Store ops subcommands (list / clean / update / remove)
|
|
70
84
|
├── init-template.ts # Create a new skill from locale template
|
|
71
|
-
├── sanitize.ts # Control char sanitization: sanitizeMetadata, stripTerminalEscapes
|
|
72
|
-
├── telemetry.ts # Telemetry: track, flushTelemetry, fetchAuditData, setVersion
|
|
73
|
-
├── detect-agent.ts # Detect running AI agent: detectAgent, isRunningInAgent
|
|
74
|
-
├── skill-lock.ts # Global lockfile (skill-lock.json)
|
|
75
|
-
├── local-lock.ts # Project lockfile (skills-lock.json) + folder SHA-256
|
|
76
|
-
├── git.ts # Repo clone / cleanupTempDir / parseGitHubRepoUrl
|
|
77
|
-
├── blob.ts # GitHub API fallback: fetchRepoTree, tryBlobInstall, toSkillSlug
|
|
78
|
-
├── source-parser.ts # Source normalization: parseSource, parseOwnerRepo, sanitizeSubpath, shRepoPrivate
|
|
79
|
-
├── interfaces.ts # Dependency injection: setGlobalAdapter / setInstanceAdapter / getGlobal / getXdgData
|
|
80
|
-
├── constants.ts # AGENTS_DIR / SKILLS_SUBDIR / UNIVERSAL_SKILLS_DIR
|
|
81
|
-
├── frontmatter.ts # YAML frontmatter parser
|
|
82
|
-
├── format.ts # ANSI color helpers
|
|
83
85
|
├── providers/
|
|
84
86
|
│ ├── wellknown.ts # WellKnownProvider: fetch index + scan + load
|
|
85
87
|
│ └── registry.ts # Provider registry + HostProvider interface
|
|
86
|
-
├── sources/
|
|
88
|
+
├── sources/ # Plugin Source registry (decision 0044)
|
|
87
89
|
│ ├── index.ts # PluginSource entry: createWellKnownSource / createLocalPluginSource factories
|
|
88
90
|
│ ├── registry.ts # Registry: registerSource / listSources / findSource / listAllEntries
|
|
89
91
|
│ ├── wellknown.ts # Wellknown source adapter
|
|
90
92
|
│ ├── local.ts # Local plugin dir (plugin.json) adapter
|
|
91
93
|
│ └── types.ts # PluginSource / PluginSourceCategory / PluginSourceEntry interfaces
|
|
92
94
|
├── i18n/ # Full i18n (zh-CN / en-US)
|
|
93
|
-
├──
|
|
94
|
-
├──
|
|
95
|
+
├── utils/ # Helpers
|
|
96
|
+
│ ├── ansi.ts # Hardcoded SGR constants (RESET / BOLD / DIM / TEXT / CYAN / YELLOW / MAGENTA)
|
|
97
|
+
│ ├── format.ts # Label helpers: pBgLabel / pErrorBadge (agent badge + ERROR badge)
|
|
98
|
+
│ ├── color.ts # picocolors-shape bridge (dim/red/green/yellow/cyan/bold/... → @easbot/terminal.colorize + theme)
|
|
99
|
+
│ └── output.ts # Human-output helpers: printHuman / wrapJson / emitJson / formatListTruncated
|
|
95
100
|
├── cli.ts # Standalone CLI entry (easbot-skills)
|
|
96
|
-
|
|
97
|
-
└── src/sources/ # PluginSource registry (voting 0044)
|
|
101
|
+
└── cli-handler.ts # CLI handler (for agent reuse)
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
## CLI Usage
|
|
@@ -106,7 +110,7 @@ src/
|
|
|
106
110
|
easbot-skills add houjallen/agent-skills
|
|
107
111
|
easbot-skills add https://github.com/houjallen/agent-skills -g
|
|
108
112
|
|
|
109
|
-
# Search (interactive
|
|
113
|
+
# Search (interactive search-multi-select)
|
|
110
114
|
easbot-skills find typescript --owner houjallen
|
|
111
115
|
|
|
112
116
|
# List installed (project/global)
|
|
@@ -135,19 +139,71 @@ easbot-skills store remove <sourceKey> --force # Extra clear cache
|
|
|
135
139
|
|
|
136
140
|
# Health check (check + cleanup dangling symlinks)
|
|
137
141
|
easbot-skills doctor
|
|
138
|
-
easbot-skills doctor -a easbot -
|
|
139
|
-
easbot-skills dr -g #
|
|
142
|
+
easbot-skills doctor -a easbot -y # Check one agent + auto-cleanup
|
|
143
|
+
easbot-skills dr -g # Global only
|
|
144
|
+
|
|
145
|
+
# Template initialization (create SKILL.md from locale template)
|
|
146
|
+
easbot-skills init my-skill
|
|
147
|
+
easbot-skills init # Creates SKILL.md under cwd/<basename>/skills
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Subcommand list (standalone CLI)
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
easbot-skills add <source> # Add a skill (aliases: a / install / i)
|
|
154
|
+
easbot-skills find [query] # Search (aliases: search / f / s)
|
|
155
|
+
easbot-skills list # List installed (aliases: ls)
|
|
156
|
+
easbot-skills remove [skills...] # Remove (aliases: rm / r)
|
|
157
|
+
easbot-skills update [skills...] # Incremental update (aliases: upgrade / check)
|
|
158
|
+
easbot-skills use <source[@skill]> # One-shot use
|
|
159
|
+
easbot-skills init [name] # Template initialization
|
|
160
|
+
easbot-skills doctor # Health check (aliases: dr)
|
|
161
|
+
easbot-skills store <subcommand> # Store-centric ops (list / clean / update / remove)
|
|
140
162
|
```
|
|
141
163
|
|
|
164
|
+
### `store` subcommands (Decision 0049-yyy)
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
# List all sources inside the store (human-readable mode shows full 64-hex sourceKey for downstream update / remove)
|
|
168
|
+
easbot-skills store list
|
|
169
|
+
easbot-skills store list [keyword] # Filter by skill name
|
|
170
|
+
|
|
171
|
+
# Reset the store (default: wipe store dirs + index.json; --force additionally clears cache)
|
|
172
|
+
easbot-skills store clean
|
|
173
|
+
easbot-skills store clean --force
|
|
174
|
+
|
|
175
|
+
# Refresh store from source (does NOT touch agent distribution)
|
|
176
|
+
# No source-key → full store refresh
|
|
177
|
+
# With source-key (64-hex, copy from `store list`) → refresh only that source (entire source mirror)
|
|
178
|
+
easbot-skills store update
|
|
179
|
+
easbot-skills store update <full-source-key> # Decision 0049-yyy: [keyword] → [source-key]
|
|
180
|
+
|
|
181
|
+
# Remove a single store source (--force additionally clears cache; local source cache = user dir, NEVER deleted)
|
|
182
|
+
easbot-skills store remove <source-key>
|
|
183
|
+
easbot-skills store remove <source-key> --force
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Core semantics**:
|
|
187
|
+
- `store` operates on the **whole-source mirror** (not on individual skills) — the store is a
|
|
188
|
+
cp of the source; either refresh the entire source or do nothing; there is no "update
|
|
189
|
+
only one skill inside the store" semantic.
|
|
190
|
+
- To "trigger store refresh + agent distribution by skill name", use `skills update <name>`
|
|
191
|
+
— that path already does full-source pull + per-skill hash compare → agent distribution.
|
|
192
|
+
- `store list` prints the **full** sourceKey (Decision 0049-yyy: previously 8-char truncated → users
|
|
193
|
+
couldn't reuse it directly).
|
|
194
|
+
|
|
142
195
|
### Delegated from a host CLI
|
|
143
196
|
|
|
144
|
-
`@easbot/agent`'s `easbot skills ...` reuses
|
|
197
|
+
`@easbot/agent`'s `easbot skills ...` reuses every subcommand via `handleSkillsCli(args, deps)`:
|
|
145
198
|
|
|
146
199
|
```typescript
|
|
147
|
-
import { handleSkillsCli,
|
|
200
|
+
import { handleSkillsCli, setAgentAdapter } from '@easbot/skills';
|
|
148
201
|
|
|
149
|
-
|
|
150
|
-
|
|
202
|
+
setAgentAdapter({
|
|
203
|
+
global: Global, // IGlobal
|
|
204
|
+
instance: Instance, // IInstance
|
|
205
|
+
// subAgentRunner / localAgentRunner / triggerEvent are optional
|
|
206
|
+
});
|
|
151
207
|
|
|
152
208
|
const result = await handleSkillsCli(['add', 'houjallen/agent-skills', '-y'], {
|
|
153
209
|
version: ctx.programVersion,
|
|
@@ -156,105 +212,354 @@ const result = await handleSkillsCli(['add', 'houjallen/agent-skills', '-y'], {
|
|
|
156
212
|
// process.exit(result.code) if result.code !== 0
|
|
157
213
|
```
|
|
158
214
|
|
|
159
|
-
`easbot skills` is registered in `packages/agent/src/cli/commands/skills.ts` via `registerSkillsCommand()`. Commander.js `skills.<subcommand>` converts flags to argv and dispatches to `handleSkillsCli`. The `skills store` sub-family is
|
|
215
|
+
`easbot skills` is registered in `packages/agent/src/cli/commands/skills.ts` via `registerSkillsCommand()`. Commander.js `skills.<subcommand>` converts flags to argv and dispatches to `handleSkillsCli`. The `skills store` sub-family is registered in the same module.
|
|
160
216
|
|
|
161
|
-
## API
|
|
217
|
+
## API (by module)
|
|
162
218
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
201
|
-
|
|
219
|
+
> All exports flow from the top-level entry [`src/index.ts`](src/index.ts) and are grouped by theme below.
|
|
220
|
+
|
|
221
|
+
### 1. Core types
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import type { AgentType, Skill, AgentConfig, ParsedSource, RemoteSkill } from '@easbot/skills';
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
| Type | Description |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `AgentType` | 70+ Agent union (includes the `universal` virtual type) |
|
|
230
|
+
| `Skill` | Skill model (name / path / frontmatter / pluginName / subpath etc.) |
|
|
231
|
+
| `AgentConfig` | Agent configuration (name / displayName / skillsDir / globalSkillsDir / detectInstalled) |
|
|
232
|
+
| `ParsedSource` | Source descriptor (type / url / ref / subpath) |
|
|
233
|
+
| `RemoteSkill` | Remote-skill model |
|
|
234
|
+
|
|
235
|
+
### 2. Agent system
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import {
|
|
239
|
+
agents, // Record<AgentType, AgentConfig>
|
|
240
|
+
EVE_SUBAGENTS_DIR, // 'agent/subagents'
|
|
241
|
+
PROJECT_SKILLS_DIR_PATTERN, // /^\.[^/]+\/skills$/
|
|
242
|
+
detectInstalledAgents,
|
|
243
|
+
getAgentConfig,
|
|
244
|
+
getAgentGlobalSkillDirs, // List of project-level agent global skill dirs
|
|
245
|
+
getAgentProjectSkillDirs,
|
|
246
|
+
getAgentProjectSkillContainerPrefixes,
|
|
247
|
+
getAgentSkillDirs,
|
|
248
|
+
getEveSubagents,
|
|
249
|
+
getNonUniversalAgents, // Non-universal agents
|
|
250
|
+
getOpenClawGlobalSkillsDir,
|
|
251
|
+
getUniversalAgents,
|
|
252
|
+
isUniversalAgent,
|
|
253
|
+
matchesUniversalScope,
|
|
254
|
+
} from '@easbot/skills';
|
|
255
|
+
import type { AgentSkillDirsResult, UniversalScope } from '@easbot/skills';
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 3. Skill discovery / install
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import {
|
|
262
|
+
discoverSkills, filterSkills, getSkillDisplayName,
|
|
263
|
+
isSubpathSafe, parseSkillMd, shouldInstallInternalSkills,
|
|
264
|
+
installSkillForAgent, installRemoteSkillForAgent, installBlobSkillForAgent,
|
|
265
|
+
installWellKnownSkillForAgent,
|
|
266
|
+
linkSkillDir, copySkillDir,
|
|
267
|
+
getAgentBaseDir, getCanonicalPath, getCanonicalSkillsDir,
|
|
268
|
+
getEveSubagentSkillsDir, getInstallPath,
|
|
269
|
+
isSkillInstalled, listInstalledSkills, sanitizeName,
|
|
270
|
+
} from '@easbot/skills';
|
|
271
|
+
import type { DiscoverSkillsOptions, InstallMode, InstalledSkill } from '@easbot/skills';
|
|
272
|
+
|
|
273
|
+
// Post-install matrix
|
|
274
|
+
import { applyActions, buildMatrix, planActions, probeCell, runPostInstallReconcile } from '@easbot/skills';
|
|
275
|
+
import type { AgentInstallMatrix, CellAction, CellScope, InstallCell, InstallState,
|
|
276
|
+
PostInstallInput, PostInstallResult } from '@easbot/skills';
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 4. Source parsing
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { parseSource, parseOwnerRepo, getOwnerRepo, isRepoPrivate, sanitizeSubpath } from '@easbot/skills';
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 5. Command entry points (`run*` + `parse*`)
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { runAdd, parseAddOptions, initTelemetry } from '@easbot/skills';
|
|
289
|
+
import type { AddOptions } from '@easbot/skills';
|
|
290
|
+
|
|
291
|
+
import { runFind, parseFindOptions, searchSkillsAPI } from '@easbot/skills';
|
|
292
|
+
import type { FindOptions, ParseFindOptionsResult, SearchSkill } from '@easbot/skills';
|
|
293
|
+
|
|
294
|
+
import { runList, parseListOptions } from '@easbot/skills';
|
|
295
|
+
import { removeCommand, parseRemoveOptions } from '@easbot/skills';
|
|
296
|
+
import type { RemoveOptions } from '@easbot/skills';
|
|
297
|
+
|
|
298
|
+
import { runUpdate, parseUpdateOptions, hasProjectSkills, matchesSkillFilter, resolveUpdateScope } from '@easbot/skills';
|
|
299
|
+
import type { UpdateCheckOptions, UpdateScope } from '@easbot/skills';
|
|
300
|
+
|
|
301
|
+
import { runUse, parseUseOptions, buildUsePrompt, materializeUseSkill, launchAgentInteractively } from '@easbot/skills';
|
|
302
|
+
import type { AgentProcess, AgentSpawn, MaterializedUseSkill, ParseUseOptionsResult, UseOptions, UseSkill } from '@easbot/skills';
|
|
303
|
+
|
|
304
|
+
import { runDoctor } from '@easbot/skills';
|
|
305
|
+
|
|
306
|
+
import { runStore, parseStoreOptions, runStoreList, runStoreClean, runStoreUpdate, runStoreRemove } from '@easbot/skills';
|
|
307
|
+
import type { StoreOptions } from '@easbot/skills';
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### 6. Lockfile / hashing
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
import {
|
|
314
|
+
readSkillLock, writeSkillLock, addSkillToLock, removeSkillFromLock, getSkillFromLock,
|
|
315
|
+
getGitHubToken, getAllLockedSkills, getSkillsBySource,
|
|
316
|
+
getSkillLockPath, computeContentHash, storePathFromLockEntry,
|
|
317
|
+
dismissPrompt, isPromptDismissed, resetGhAuthWarning,
|
|
318
|
+
} from '@easbot/skills';
|
|
319
|
+
import type { DismissedPrompts, SkillLockEntry, SkillLockFile } from '@easbot/skills';
|
|
320
|
+
|
|
321
|
+
import {
|
|
322
|
+
readLocalLock, writeLocalLock, addSkillToLocalLock, removeSkillFromLocalLock,
|
|
323
|
+
getLocalLockPath, storePathFromLocalLockEntry,
|
|
324
|
+
} from '@easbot/skills';
|
|
325
|
+
import type { LocalSkillLockEntry, LocalSkillLockFile } from '@easbot/skills';
|
|
326
|
+
|
|
327
|
+
import { computeFromDir, computeSnapshotHash } from '@easbot/skills';
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### 7. Git / Blob integration
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import {
|
|
334
|
+
DEFAULT_CLONE_TIMEOUT, GitCloneError,
|
|
335
|
+
cloneRepo, cleanupTempDir, parseGitHubRepoUrl,
|
|
336
|
+
isGitHubHttpsCloneUrl, isGitHubSsoAuthError,
|
|
337
|
+
} from '@easbot/skills';
|
|
338
|
+
|
|
339
|
+
import {
|
|
340
|
+
BLOB_ALLOWED_REPOS, // Record<string, { downloadUrl }>
|
|
341
|
+
toSkillSlug,
|
|
342
|
+
fetchRepoTree, findSkillMdPaths, getSkillFolderHashFromTree,
|
|
343
|
+
resetRepoTreeAuthState, tryBlobInstall,
|
|
344
|
+
} from '@easbot/skills';
|
|
345
|
+
import type { BlobInstallResult, BlobSkill, RepoTree, SkillDownloadResponse, SkillSnapshotFile, TreeEntry } from '@easbot/skills';
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### 8. Installer support layer (three-layer source / cache / install)
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import {
|
|
352
|
+
acquireSourceClone, ensureCachedSource, installFromCache, cleanCache, cleanCachedRepo,
|
|
353
|
+
getCacheRepoDir, getCacheRoot, getSourceDir,
|
|
354
|
+
} from '@easbot/skills';
|
|
355
|
+
import type { InstallScope } from '@easbot/skills';
|
|
356
|
+
|
|
357
|
+
// store-types shared types
|
|
358
|
+
export type {
|
|
359
|
+
StoreSourceType, SkillScope,
|
|
360
|
+
SkillEntry, PluginDefinition, MarketDefinition, SkillLocation,
|
|
361
|
+
DefaultPluginConfig, StoreIndex,
|
|
362
|
+
STORE_INDEX_VERSION,
|
|
363
|
+
parsePluginId, pluginDirFromPluginId, storePathForSkillLock,
|
|
364
|
+
} from '@easbot/skills';
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### 9. Security / telemetry / Agent detection
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import {
|
|
371
|
+
track, flushTelemetry, fetchAuditData, setVersion, setDetectedAgent,
|
|
372
|
+
} from '@easbot/skills';
|
|
373
|
+
import type { AuditResponse, PartnerAudit, SkillAuditData } from '@easbot/skills';
|
|
374
|
+
|
|
375
|
+
import { sanitizeMetadata, stripTerminalEscapes } from '@easbot/skills';
|
|
376
|
+
|
|
377
|
+
import { detectAgent, getAgentName, getAgentType, isRunningInAgent } from '@easbot/skills';
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 10. Provider abstraction
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
import { wellKnownProvider, WellKnownProvider } from '@easbot/skills';
|
|
384
|
+
import type {
|
|
385
|
+
WellKnownIndex, WellKnownIndexV1, WellKnownIndexV2,
|
|
386
|
+
WellKnownSkill, WellKnownSkillEntry, WellKnownSkillEntryV1, WellKnownSkillEntryV2,
|
|
387
|
+
WellKnownFileContent,
|
|
388
|
+
} from '@easbot/skills';
|
|
389
|
+
|
|
390
|
+
import { findProvider, getProviders, registerProvider, registry } from '@easbot/skills';
|
|
391
|
+
import type { HostProvider, ProviderMatch, ProviderRegistry, RemoteSkill as ProviderRemoteSkill } from '@easbot/skills';
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 11. Constants & helpers
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
import { AGENTS_DIR, SKILLS_SUBDIR, UNIVERSAL_SKILLS_DIR, parseFrontmatter } from '@easbot/skills';
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 12. CLI bridge (reused by `@easbot/agent`)
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
import { handleSkillsCli, renderBanner, renderHelp } from '@easbot/skills';
|
|
404
|
+
import type { SkillsCliDeps, SkillsCliResult } from '@easbot/skills';
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### 13. Interface injection (host → skills)
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import {
|
|
411
|
+
setGlobalAdapter, setInstanceAdapter, setAgentAdapter,
|
|
412
|
+
resetGlobalAdapter, resetInstanceAdapter,
|
|
413
|
+
getGlobal, getInstance, getAgentAdapter, getHomeDir,
|
|
414
|
+
getXdgConfig, getXdgData, getXdgState, getXdgCache,
|
|
415
|
+
getProjectDirectory,
|
|
416
|
+
hasAgentAdapter, requireAgentAdapter,
|
|
417
|
+
} from '@easbot/skills';
|
|
418
|
+
import type { SkillsAgentAdapter } from '@easbot/skills';
|
|
419
|
+
import type { IGlobal, IInstance, ISubAgentRunner } from '@easbot/skills';
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### 14. Plugin Source registry (decision 0044)
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { registerSource, unregisterSource, listSources, findSource, findSourcesByCategory, listAllEntries,
|
|
426
|
+
createWellKnownSource, createLocalPluginSource } from '@easbot/skills';
|
|
427
|
+
import type {
|
|
428
|
+
PluginSource, PluginSourceCategory, PluginSourceEntry, PluginSourceLoadResult,
|
|
429
|
+
WellKnownSourceOptions, LocalPluginSourceOptions,
|
|
430
|
+
} from '@easbot/skills';
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import { registerSource, createWellKnownSource, createLocalPluginSource } from '@easbot/skills';
|
|
435
|
+
|
|
436
|
+
// 1) Register a well-known endpoint as a plugin source
|
|
437
|
+
registerSource(createWellKnownSource({
|
|
438
|
+
url: 'https://mintlify.com/docs',
|
|
439
|
+
}));
|
|
440
|
+
|
|
441
|
+
// 2) Register a local plugin.json as a plugin source
|
|
442
|
+
registerSource(createLocalPluginSource({
|
|
443
|
+
basePath: process.cwd(),
|
|
444
|
+
}));
|
|
445
|
+
|
|
446
|
+
// 3) At @easbot/agent bootstrap, pull every source
|
|
447
|
+
import { listSources } from '@easbot/skills';
|
|
448
|
+
for (const source of listSources()) {
|
|
449
|
+
const entries = await source.fetch();
|
|
450
|
+
for (const entry of entries) {
|
|
451
|
+
const { skills } = await source.load(entry);
|
|
452
|
+
// → inject into PluginDefinition.skills
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Supported Agent List (complete)
|
|
458
|
+
|
|
459
|
+
The `AgentType` union in `agents.ts` covers **72 agents** (plus the `universal` virtual type):
|
|
460
|
+
|
|
461
|
+
`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`, plus the virtual type `universal`.
|
|
462
|
+
|
|
463
|
+
**Universal shared `.agents/skills` directory** (16 agents): `eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code` etc.
|
|
464
|
+
|
|
465
|
+
All agent configuration (displayName / skillsDir / globalSkillsDir / universal flag / install detection / `detectInstalled`) lives in `src/agents.ts`.
|
|
202
466
|
|
|
203
467
|
## Global Path Dependency Injection
|
|
204
468
|
|
|
205
|
-
To avoid conflicting with the host (agent/gateway) over XDG / home, `@easbot/skills` resolves paths through dependency injection by default:
|
|
469
|
+
To avoid conflicting with the host (agent / gateway) over XDG / home, `@easbot/skills` resolves paths through dependency injection by default:
|
|
206
470
|
|
|
207
471
|
```typescript
|
|
208
472
|
import {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
473
|
+
setAgentAdapter, // Recommended: one-shot injection (global + instance + optional subAgentRunner etc.)
|
|
474
|
+
setGlobalAdapter, // Inject IGlobal.Path
|
|
475
|
+
setInstanceAdapter, // Inject IInstance.directory / worktree
|
|
212
476
|
getHomeDir,
|
|
213
477
|
getXdgConfig,
|
|
214
478
|
getXdgData,
|
|
215
479
|
getProjectDirectory,
|
|
216
480
|
} from '@easbot/skills';
|
|
217
481
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
482
|
+
setAgentAdapter({
|
|
483
|
+
global: {
|
|
484
|
+
Path: {
|
|
485
|
+
home: '/Users/me',
|
|
486
|
+
data: '/Users/me/.local/share/easbot',
|
|
487
|
+
config: '/Users/me/.config/easbot',
|
|
488
|
+
state: '/Users/me/.local/state/easbot',
|
|
489
|
+
cache: '/Users/me/.cache/easbot',
|
|
490
|
+
log: '/Users/me/.local/state/easbot/log',
|
|
491
|
+
bin: '/Users/me/.local/bin',
|
|
492
|
+
},
|
|
227
493
|
},
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
494
|
+
instance: {
|
|
495
|
+
directory: '/repo',
|
|
496
|
+
worktree: '/repo',
|
|
497
|
+
},
|
|
498
|
+
// Optional
|
|
499
|
+
subAgentRunner: ...,
|
|
500
|
+
triggerEvent: async (event, input, ctx) => ({ success: true, output: undefined, modified: false }),
|
|
233
501
|
});
|
|
234
502
|
```
|
|
235
503
|
|
|
236
|
-
When no adapter is set,
|
|
504
|
+
When no adapter is set, the skills package falls back to `xdg-basedir` + `homedir()`, keeping full backward compatibility with the v1 standalone CLI.
|
|
505
|
+
|
|
506
|
+
**`getHomeDir()` priority** (for test isolation):
|
|
507
|
+
1. `process.env.EASBOT_TEST_HOME` (**test-only**, highest priority)
|
|
508
|
+
2. Injected `Global.Path.home`
|
|
509
|
+
3. `os.homedir()` fallback
|
|
237
510
|
|
|
238
511
|
## Data Layout
|
|
239
512
|
|
|
240
|
-
|
|
241
|
-
|---|---|
|
|
242
|
-
| `${Global.Path.data}/skills/` | Skills dir loaded by the agent at runtime |
|
|
243
|
-
| `${Global.Path.data}/skills/.skill-lock.json` | Global install lockfile (same root as store) |
|
|
244
|
-
| `${Global.Path.data}/skills/store/<sourceKey>/` | **Store physical dir** (sourceKey-hashed normalized source; written once by `add`, reused by `update`) |
|
|
245
|
-
| `${Global.Path.data}/skills/store/index.json` | **Store defs index** (key = skillName; records registryKey / type / url / skillPath / computedHash) |
|
|
246
|
-
| `${Global.Path.cache}/skills/cache/<owner>/<repo>/` | **Cache physical** (remote source download/materialize cache; local source = same as user directory) |
|
|
247
|
-
| `<cwd>/.agents/skills/` or `<cwd>/skills/` | Project-level skill directories |
|
|
248
|
-
| `<cwd>/skills-lock.json` | Project-level lockfile |
|
|
249
|
-
| `<home>/.config/easbot/skills/` | XDG config fallback |
|
|
513
|
+
> When injected, every `getXdgData / getXdgCache / ...` resolves through `Global.Path.*`; the default path uses `xdg-basedir + easbot` segments.
|
|
250
514
|
|
|
251
|
-
|
|
515
|
+
| Path | Purpose | Implementation |
|
|
516
|
+
|---|---|---|
|
|
517
|
+
| `${getXdgData()}/skills/` | Skills directory loaded by the agent at runtime | `installer/store.ts` |
|
|
518
|
+
| `${getXdgData()}/skills/.skill-lock.json` | Global install lockfile (same root as store) | `skill-lock.ts` |
|
|
519
|
+
| `${getXdgData()}/skills/store/<sourceKey>/` | **Store physical dir** (sourceKey-hashed normalized source; written once by `add`, reused by `update`) | `installer/store.ts::getStoreDir` |
|
|
520
|
+
| `${getXdgData()}/skills/store/index.json` | **Store defs index** (per-skill registryKey / type / url / skillPath / computedHash) | `installer/store.ts::getStoreDefinitionsFile` |
|
|
521
|
+
| `${getXdgCache()}/skills/cache/<type>/<owner/repo>/` | **Cache physical** (remote source download/materialize cache; local source = same as user directory) | `installer/store.ts::getCacheRepoDir` |
|
|
522
|
+
| `<cwd>/.easbot/skills/<skill>/` | EASBot project-level (not hit by universal agents) | `agents.ts` |
|
|
523
|
+
| `<cwd>/.agents/skills/<skill>/` | Universal agents (claude-code / cursor / gemini-cli etc.) project-level | `agents.ts` |
|
|
524
|
+
| `<cwd>/<agent-glob>/skills/<skill>/` | Each agent's custom project-level (e.g. `~/.trae/skills/`) | `agents.ts` |
|
|
525
|
+
| `<cwd>/skills-lock.json` | Project-level lockfile | `local-lock.ts` |
|
|
526
|
+
| `${getXdgConfig()}/easbot/skills/` | EASBot global skill dir (injected scenario) | `agents.ts::easbot.globalSkillsDir` |
|
|
527
|
+
| `~/.config/easbot/skills/` | EASBot global skill dir (default fallback) | same |
|
|
528
|
+
|
|
529
|
+
> When delegated from `@easbot/agent`, everything lands under `{Global.Path.data}` — sibling to Gateway / MCP / Session / Contact modules.
|
|
252
530
|
|
|
253
531
|
## External Audit Hooks (skills.sh)
|
|
254
532
|
|
|
255
|
-
`telemetry.ts` sends telemetry/audit data back to skills.sh (configurable via `SKILLS_API_URL`) for:
|
|
533
|
+
`telemetry.ts` sends telemetry / audit data back to skills.sh (configurable via `SKILLS_API_URL`) for:
|
|
534
|
+
|
|
256
535
|
- Skill audit (`fetchAuditData` returns per-skill `PartnerAudit` information)
|
|
257
|
-
- Security gate check (skipped with `--dangerously-accept-openclaw-risks` flag)
|
|
536
|
+
- Security gate check (skipped with the `--dangerously-accept-openclaw-risks` flag)
|
|
537
|
+
|
|
538
|
+
## Interaction Conventions (Session 4 refactor)
|
|
539
|
+
|
|
540
|
+
Every interactive flow (select / confirm / multiselect / spinner / intro / outro / cancel / Log) goes through [`@easbot/terminal.Prompt`](../terminal/README.en.md):
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
import { Prompt, Symbol as Glyph } from '@easbot/terminal';
|
|
544
|
+
|
|
545
|
+
// Cancellation contract: Prompt.cancel returns `never` and exits internally
|
|
546
|
+
const v = await Prompt.select({ message: 'Choose scope', options: [...] });
|
|
547
|
+
if (Prompt.isCancel(v)) await cleanup();
|
|
548
|
+
Prompt.cancel('User cancelled');
|
|
549
|
+
|
|
550
|
+
// Icons centralized (writing ✓✗◆ literals is FORBIDDEN)
|
|
551
|
+
console.log(`${Glyph.statusIcon('success')} Operation succeeded`); // ✓ green
|
|
552
|
+
console.log(`${Glyph.colorize(Glyph.bar.bullet, 'error')} bullet`);
|
|
553
|
+
|
|
554
|
+
// Status logging (colors unified with terminal theme)
|
|
555
|
+
Prompt.Log.info('Installing...');
|
|
556
|
+
Prompt.Log.warn('Warning');
|
|
557
|
+
Prompt.Log.error('Failure');
|
|
558
|
+
Prompt.Log.step('Step');
|
|
559
|
+
Prompt.Log.message('Plain message');
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Business code **must not** call `pc.green('✓')` directly, **nor** `console.log(p.theme.error(...))`. Everything routes through `utils/color.ts` (the picocolors-shape **bridge**, kept as a transitional layer) and `Glyph.*` / `Prompt.Log.*`.
|
|
258
563
|
|
|
259
564
|
## Development
|
|
260
565
|
|
|
@@ -273,11 +578,12 @@ pnpm test
|
|
|
273
578
|
pnpm test:run
|
|
274
579
|
|
|
275
580
|
# Code quality
|
|
276
|
-
pnpm
|
|
277
|
-
pnpm
|
|
278
|
-
pnpm
|
|
581
|
+
pnpm lint # biome check .
|
|
582
|
+
pnpm lint:fix # biome check --write .
|
|
583
|
+
pnpm format # biome format .
|
|
584
|
+
pnpm format:fix # biome format --write .
|
|
279
585
|
|
|
280
|
-
# Type
|
|
586
|
+
# Type-check
|
|
281
587
|
pnpm type-check
|
|
282
588
|
|
|
283
589
|
# Clean
|
|
@@ -287,7 +593,7 @@ pnpm clean
|
|
|
287
593
|
## Publishing
|
|
288
594
|
|
|
289
595
|
```bash
|
|
290
|
-
# Linux /macOS
|
|
596
|
+
# Linux / macOS
|
|
291
597
|
bash scripts/publish.sh
|
|
292
598
|
|
|
293
599
|
# Windows PowerShell
|
|
@@ -300,10 +606,11 @@ pnpm publish --access public --git-checks false --registry https://registry.npmj
|
|
|
300
606
|
|
|
301
607
|
## Runtime Notes
|
|
302
608
|
|
|
303
|
-
- Uses Node built-ins (`fs/promises`, `
|
|
304
|
-
- Dependencies: `simple-git`, `@
|
|
609
|
+
- Uses Node built-ins (`fs/promises`, `node:os`, `node:path`, `node:child_process`); **not** browser-compatible.
|
|
610
|
+
- Dependencies: `simple-git`, `@easbot/terminal` (unified Prompt + theme + icons), `xdg-basedir`, `zod`, `yaml`.
|
|
611
|
+
- **No longer** depends on `@clack/prompts` or `picocolors` — everything converges to `@easbot/terminal` (see Session 4 decisions).
|
|
305
612
|
- `engines.node >= 22.22.3` — Node 22 LTS recommended.
|
|
306
613
|
|
|
307
614
|
## License
|
|
308
615
|
|
|
309
|
-
MIT
|
|
616
|
+
MIT
|