@wangkh/skill-sync-cli 0.2.1 → 0.2.2
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.md +20 -0
- package/README.zh-CN.md +16 -0
- package/package.json +2 -1
- package/skills/skill-sync/SKILL.md +91 -0
- package/src/commands.mjs +18 -5
- package/src/runner.mjs +8 -1
package/README.md
CHANGED
|
@@ -262,6 +262,11 @@ working include `https://gh-proxy.com/`, `https://ghproxy.net/`, and
|
|
|
262
262
|
`https://ghfast.top/`. To speed up the `skills` CLI download itself on a fresh
|
|
263
263
|
machine, configure an npm registry mirror such as `https://registry.npmmirror.com`.
|
|
264
264
|
|
|
265
|
+
Child `skills` commands run with `DO_NOT_TRACK=1`, so telemetry stays off. A
|
|
266
|
+
known Windows exit crash in the `skills` CLI after a completed install is
|
|
267
|
+
tolerated: when the files are in place, `sync` treats the group as installed
|
|
268
|
+
instead of failing.
|
|
269
|
+
|
|
265
270
|
For project-scoped skills, set:
|
|
266
271
|
|
|
267
272
|
```json
|
|
@@ -279,6 +284,21 @@ location. From the target application project, run:
|
|
|
279
284
|
npx @wangkh/skill-sync-cli sync --config /path/to/my-skills/skills.json
|
|
280
285
|
```
|
|
281
286
|
|
|
287
|
+
## Agent Skill
|
|
288
|
+
|
|
289
|
+
The repository ships an agent skill (`skills/skill-sync/SKILL.md`) that teaches
|
|
290
|
+
an agent how to use this CLI. Install it from the repository:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npx skills add yudaiyan/skill-sync-cli
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Or declare it in the manifest and let `sync` install it:
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{ "name": "skill-sync", "source": "yudaiyan/skill-sync-cli" }
|
|
300
|
+
```
|
|
301
|
+
|
|
282
302
|
## Run Before the First Release
|
|
283
303
|
|
|
284
304
|
From a source checkout, the following commands work without installing project
|
package/README.zh-CN.md
CHANGED
|
@@ -132,6 +132,8 @@ npx @wangkh/skill-sync-cli sync --github-mirror https://gh-proxy.com/
|
|
|
132
132
|
|
|
133
133
|
镜像通过 git 的 `insteadOf` 重写注入,只对本次命令生效,不会修改全局 git 配置。实测可用的免费公益镜像包括 `https://gh-proxy.com/`、`https://ghproxy.net/`、`https://ghfast.top/`。新机器上如果 `skills` CLI 下载慢,可以配置 npm 镜像源 `https://registry.npmmirror.com`。
|
|
134
134
|
|
|
135
|
+
wrapper 会以 `DO_NOT_TRACK=1` 运行 `skills` CLI(关闭遥测)。它在 Windows 上安装完成后偶发退出崩溃(0xC0000409);只要文件已就位,`sync` 会把该组视为安装成功,不再误判失败。
|
|
136
|
+
|
|
135
137
|
只预览,或者在单个 Skill 失败后继续处理其他条目:
|
|
136
138
|
|
|
137
139
|
```bash
|
|
@@ -186,6 +188,20 @@ Git 负责在机器之间传递清单,`sync` 根据本地清单安装 Skills
|
|
|
186
188
|
|
|
187
189
|
清单是这个脚本定义的格式;脚本读取后逐项调用官方 `skills` CLI。上游的 `.skill-lock.json` 继续由官方 CLI 维护。
|
|
188
190
|
|
|
191
|
+
## 给 agent 用的 skill
|
|
192
|
+
|
|
193
|
+
仓库自带一个 agent skill(`skills/skill-sync/SKILL.md`),用来告诉 agent 如何使用本 CLI。可以直接安装:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx skills add yudaiyan/skill-sync-cli
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
也可以加进清单,交给 `sync` 安装:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{ "name": "skill-sync", "source": "yudaiyan/skill-sync-cli" }
|
|
203
|
+
```
|
|
204
|
+
|
|
189
205
|
## 发布前使用
|
|
190
206
|
|
|
191
207
|
获取项目源码后,可以在源码目录直接运行,无需安装项目依赖:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wangkh/skill-sync-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Sync declared agent skills across machines through the skills CLI",
|
|
5
5
|
"author": "wkh",
|
|
6
6
|
"repository": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"bin",
|
|
28
28
|
"src",
|
|
29
29
|
"schemas",
|
|
30
|
+
"skills",
|
|
30
31
|
"README.md",
|
|
31
32
|
"README.zh-CN.md",
|
|
32
33
|
"RELEASING.md",
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-sync
|
|
3
|
+
description: >-
|
|
4
|
+
Manage the user's portable agent-skill manifest with the skill-sync CLI
|
|
5
|
+
(@wangkh/skill-sync-cli). Use when the user wants to sync, back up, or
|
|
6
|
+
restore agent skills across machines ("同步我的 skills", "恢复 skill 环境",
|
|
7
|
+
"新电脑安装 skills"), add or remove a skill in their manifest
|
|
8
|
+
("把 skill 加到清单"), preview or validate the manifest, or install skills
|
|
9
|
+
when GitHub is unreachable. Also use when a skill installation fails and the
|
|
10
|
+
user asks why or how to retry.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# skill-sync
|
|
14
|
+
|
|
15
|
+
`@wangkh/skill-sync-cli` keeps a portable JSON manifest of third-party agent
|
|
16
|
+
skills and installs them through the official `skills` CLI. The manifest is the
|
|
17
|
+
single source of truth; the tool only writes it during `init`.
|
|
18
|
+
|
|
19
|
+
## When to use
|
|
20
|
+
|
|
21
|
+
- Sync or restore skills on a machine: `sync`
|
|
22
|
+
- Add a skill to the manifest after finding it: edit the manifest, then `sync`
|
|
23
|
+
- Preview or validate before installing: `plan`, `validate`
|
|
24
|
+
- GitHub is blocked or slow: run `sync --github-mirror https://gh-proxy.com/`
|
|
25
|
+
- An install failed: check retries, the mirror, or `--continue-on-error`
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
Run through npx so no global install is needed:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx @wangkh/skill-sync-cli init # create the manifest (keeps an existing one)
|
|
33
|
+
npx @wangkh/skill-sync-cli path # print the manifest path in use
|
|
34
|
+
npx @wangkh/skill-sync-cli validate # parse and validate without network
|
|
35
|
+
npx @wangkh/skill-sync-cli plan # print the exact skills commands
|
|
36
|
+
npx @wangkh/skill-sync-cli sync # install or update declared skills
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Useful options:
|
|
40
|
+
|
|
41
|
+
| Option | Meaning |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `-c, --config <file>` | Use another manifest file (all commands) |
|
|
44
|
+
| `--from <url>` | `init` from a published manifest URL |
|
|
45
|
+
| `--dry-run` | Preview without installing |
|
|
46
|
+
| `--continue-on-error` | Keep going after a failure; exit code stays non-zero |
|
|
47
|
+
| `--retries <n>` | Retry failed installs (default 2) |
|
|
48
|
+
| `--github-mirror <url>` | Route GitHub clones and update checks through a mirror |
|
|
49
|
+
| `--force` | `init`: replace the file; `sync`: reinstall even if unchanged |
|
|
50
|
+
|
|
51
|
+
## Manifest
|
|
52
|
+
|
|
53
|
+
Default location:
|
|
54
|
+
|
|
55
|
+
- Windows: `%USERPROFILE%\.config\skill-sync\skills.json`
|
|
56
|
+
- macOS/Linux: `~/.config/skill-sync/skills.json`
|
|
57
|
+
|
|
58
|
+
Skill entries require `name` (the upstream skill name) and `source`
|
|
59
|
+
(`owner/repo`, Git URL, skill URL, or archive). Optional fields are
|
|
60
|
+
`description`, `ref`, `enabled`, `agents`, `scope`, and `copy`; shared
|
|
61
|
+
defaults live under `defaults`, and the `skills` CLI version is pinned under
|
|
62
|
+
`cli`.
|
|
63
|
+
|
|
64
|
+
To add a skill, append an entry and run `sync`. Confirm the upstream name
|
|
65
|
+
first:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx --yes skills@1.5.22 add <owner>/<repo> --list
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Behavior worth knowing
|
|
72
|
+
|
|
73
|
+
- Entries sharing `source`, `ref`, `agents`, `scope`, and `copy` install with
|
|
74
|
+
one `skills add` call; a failed batch falls back to installing each skill.
|
|
75
|
+
- `sync` records revisions in `~/.config/skill-sync/state.json` and skips
|
|
76
|
+
groups whose revision and installed files are unchanged. `--force`
|
|
77
|
+
overrides the skip.
|
|
78
|
+
- When the update check cannot reach the remote but the installed copy still
|
|
79
|
+
exists, `sync` keeps it instead of failing.
|
|
80
|
+
- GitHub unreachable: `--github-mirror https://gh-proxy.com/` (alternatives:
|
|
81
|
+
`https://ghproxy.net/`, `https://ghfast.top/`). For the `skills` CLI
|
|
82
|
+
download itself, configure an npm registry mirror such as
|
|
83
|
+
`https://registry.npmmirror.com`.
|
|
84
|
+
|
|
85
|
+
## Security
|
|
86
|
+
|
|
87
|
+
A skill is agent instructions and may run scripts; review third-party skills
|
|
88
|
+
before adding them. Prefer trusted repositories and immutable commit refs.
|
|
89
|
+
|
|
90
|
+
Full documentation lives in the project README and
|
|
91
|
+
`schemas/skills-sync.schema.json`.
|
package/src/commands.mjs
CHANGED
|
@@ -30,6 +30,9 @@ import { downloadManifest } from "./remote.mjs"
|
|
|
30
30
|
|
|
31
31
|
export const DEFAULT_RETRIES = 2
|
|
32
32
|
const DEFAULT_RETRY_DELAY_MS = 2000
|
|
33
|
+
// The skills CLI occasionally aborts on exit after a completed install on
|
|
34
|
+
// Windows (libuv teardown assertion). These are the observed exit codes.
|
|
35
|
+
const POST_INSTALL_CRASH_CODES = new Set([3221226505, -1073740791])
|
|
33
36
|
|
|
34
37
|
const SAMPLE_MANIFEST = {
|
|
35
38
|
version: 1,
|
|
@@ -171,11 +174,21 @@ export async function syncCommand(manifestFilename, options = {}) {
|
|
|
171
174
|
|
|
172
175
|
const key = stateKey(group.skills)
|
|
173
176
|
const entry = stateEntry(state, filename, key)
|
|
174
|
-
const
|
|
177
|
+
const installScope = {
|
|
175
178
|
global: group.skills[0].scope === "global",
|
|
176
179
|
cwd,
|
|
177
180
|
home,
|
|
178
|
-
}
|
|
181
|
+
}
|
|
182
|
+
const installedHere = allInstalled(group.skills, installScope)
|
|
183
|
+
// A completed install followed by the known exit crash counts as success.
|
|
184
|
+
const executeTolerant = (command, runOptions) => {
|
|
185
|
+
const result = execute(command, runOptions)
|
|
186
|
+
if (POST_INSTALL_CRASH_CODES.has(statusCode(result)) && allInstalled(group.skills, installScope)) {
|
|
187
|
+
console.error(`[${sourceLabel(group.skills)}] the skills CLI crashed after installing (known Windows bug); treating the install as complete`)
|
|
188
|
+
return { status: 0 }
|
|
189
|
+
}
|
|
190
|
+
return result
|
|
191
|
+
}
|
|
179
192
|
// Only a previous install can be skipped, so check the remote before
|
|
180
193
|
// installing only when there is a record and the files are still present.
|
|
181
194
|
// A first install records the revision afterwards.
|
|
@@ -202,7 +215,7 @@ export async function syncCommand(manifestFilename, options = {}) {
|
|
|
202
215
|
if (group.skills.length === 1) {
|
|
203
216
|
const skill = group.skills[0]
|
|
204
217
|
printDescriptions(group.skills)
|
|
205
|
-
const result = await runWithRetries(
|
|
218
|
+
const result = await runWithRetries(executeTolerant, group.command, {
|
|
206
219
|
cwd: options.cwd,
|
|
207
220
|
env: gitEnv,
|
|
208
221
|
retries,
|
|
@@ -219,7 +232,7 @@ export async function syncCommand(manifestFilename, options = {}) {
|
|
|
219
232
|
// A batched command shares one fetch. Since a failure could come from a
|
|
220
233
|
// single bad name or a transient error, retry each entry individually
|
|
221
234
|
// when the batch does not succeed.
|
|
222
|
-
const batch =
|
|
235
|
+
const batch = executeTolerant(group.command, { cwd: options.cwd, env: gitEnv })
|
|
223
236
|
if (statusCode(batch) !== 0) {
|
|
224
237
|
if (batch.signal) {
|
|
225
238
|
failures += group.skills.length
|
|
@@ -229,7 +242,7 @@ export async function syncCommand(manifestFilename, options = {}) {
|
|
|
229
242
|
} else {
|
|
230
243
|
console.error(`[${sourceLabel(group.skills)}] batch install failed; retrying each skill individually`)
|
|
231
244
|
for (const skill of group.skills) {
|
|
232
|
-
const result = await runWithRetries(
|
|
245
|
+
const result = await runWithRetries(executeTolerant, commandFor(skill, manifest.cli), {
|
|
233
246
|
cwd: options.cwd,
|
|
234
247
|
env: gitEnv,
|
|
235
248
|
retries,
|
package/src/runner.mjs
CHANGED
|
@@ -89,6 +89,13 @@ function windowsNpxCli(env) {
|
|
|
89
89
|
return filename
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// The skills CLI can crash on exit on some Windows setups (a libuv teardown
|
|
93
|
+
// assertion) while its telemetry flush is pending. DO_NOT_TRACK disables that
|
|
94
|
+
// flush so the process exits cleanly; it is also a privacy default.
|
|
95
|
+
export function childEnv(env = process.env) {
|
|
96
|
+
return { ...env, DO_NOT_TRACK: "1" }
|
|
97
|
+
}
|
|
98
|
+
|
|
92
99
|
export function runCommand(command, { cwd, env = process.env, timeout } = {}) {
|
|
93
100
|
try {
|
|
94
101
|
// Windows cannot spawn .cmd files directly. Run npx's JS entry point so
|
|
@@ -97,7 +104,7 @@ export function runCommand(command, { cwd, env = process.env, timeout } = {}) {
|
|
|
97
104
|
return spawnSync(useNode ? process.execPath : command.executable,
|
|
98
105
|
useNode ? [windowsNpxCli(env), ...command.args] : command.args, {
|
|
99
106
|
cwd,
|
|
100
|
-
env,
|
|
107
|
+
env: childEnv(env),
|
|
101
108
|
timeout,
|
|
102
109
|
stdio: "inherit",
|
|
103
110
|
windowsHide: true,
|