@hagicode/skillsbase 0.1.0-dev.20260406025440.0.0.local → 0.1.0-dev.6.1.7f41ada

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 CHANGED
@@ -1,78 +1,116 @@
1
- # skillsbase
1
+ # @hagicode/skillsbase
2
2
 
3
- `skillsbase` 是一个独立 Node CLI,用于初始化和维护“别的 skills 仓库”。
4
- 重点是:本仓库只放 CLI 代码与模板,不提交受管 `skills/` 内容。
5
- 当前源码使用 `TypeScript + Vite 8`。
3
+ [中文文档](./README.zh-CN.md)
6
4
 
7
- ## Commands
5
+ [![npm version](https://img.shields.io/npm/v/%40hagicode%2Fskillsbase?logo=npm&color=cb3837)](https://www.npmjs.com/package/@hagicode/skillsbase)
6
+ [![npm downloads](https://img.shields.io/npm/dm/%40hagicode%2Fskillsbase?logo=npm&color=2d8cf0)](https://www.npmjs.com/package/@hagicode/skillsbase)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22.12.0-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
8
+
9
+ `skillsbase` is a standalone Node.js CLI for bootstrapping and maintaining managed skills repositories.
10
+ It ships the CLI and templates only. The generated `skills/` content belongs in the target repository, not in this package repository.
11
+
12
+ ## Install
13
+
14
+ Requirements:
15
+
16
+ - Node.js `>= 22.12.0`
17
+ - npm `>= 10.9.2`
18
+
19
+ Install globally:
8
20
 
9
21
  ```bash
10
- node ./bin/skillsbase.mjs init
11
- node ./bin/skillsbase.mjs sync
12
- node ./bin/skillsbase.mjs sync --check
13
- node ./bin/skillsbase.mjs add <skill-name>
14
- node ./bin/skillsbase.mjs github_action --kind all
22
+ npm install --global @hagicode/skillsbase
15
23
  ```
16
24
 
17
- 开发期常用:
25
+ Then run:
18
26
 
19
27
  ```bash
20
- npm run build
21
- npm run cli -- --help
22
- npm test
23
- npm run smoke
24
- node ./bin/skillsbase.mjs <command> --repo /path/to/target-repo
28
+ skillsbase --help
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ Initialize a managed repository:
34
+
35
+ ```bash
36
+ skillsbase init --repo /path/to/target-repo
37
+ ```
38
+
39
+ Sync managed skills from `sources.yaml`:
40
+
41
+ ```bash
42
+ skillsbase sync --repo /path/to/target-repo
43
+ ```
44
+
45
+ Add one skill and sync immediately:
46
+
47
+ ```bash
48
+ skillsbase add documentation-writer --repo /path/to/target-repo
49
+ ```
50
+
51
+ Generate managed GitHub Actions assets:
52
+
53
+ ```bash
54
+ skillsbase github_action --repo /path/to/target-repo --kind all
25
55
  ```
26
56
 
27
- 打包产物仍为 `dist/cli.mjs`,`bin/skillsbase.mjs` 只负责发布态加载与开发态回退。
57
+ ## Commands
28
58
 
29
- ## npm Publish
59
+ | Command | Purpose | Example |
60
+ | --- | --- | --- |
61
+ | `init` | Create the managed repository baseline. | `skillsbase init --repo ./my-skills-repo` |
62
+ | `sync` | Reconcile managed skills from `sources.yaml`. | `skillsbase sync --repo ./my-skills-repo` |
63
+ | `sync --check` | Validate drift without writing files. | `skillsbase sync --check --repo ./my-skills-repo` |
64
+ | `add <skill-name>` | Add a skill to a source block, then run sync. | `skillsbase add documentation-writer --repo ./my-skills-repo` |
65
+ | `github_action` | Generate managed GitHub Actions workflow or action files. | `skillsbase github_action --repo ./my-skills-repo --kind workflow` |
30
66
 
31
- - workflow: `.github/workflows/npm-publish-dev.yml`
32
- - `push` 到 `main` 时发布 `dev` dist-tag
33
- - GitHub Release `published` 且非 draft / prerelease 时发布 `latest`
34
- - 发布前会执行:
35
- - `npm test`
36
- - `npm run pack:check`
37
- - 当前包名:`@hagicode/skillsbase`
67
+ Global options:
38
68
 
39
- 发布依赖 npm Trusted Publishing;仓库侧需要在 npm 绑定此 GitHub repository。
69
+ - `--repo <path>`: target repository path, defaults to the current directory
70
+ - `--help`, `-h`: show help
71
+ - `--version`, `-v`: show version
40
72
 
41
- ## Managed Repo Contract
73
+ ## Managed Repository Contract
42
74
 
43
- - `sources.yaml`
44
- 清单单一真相源,声明来源根目录、命名规则、包含列表与非交互默认值。
45
- - `skills/<name>/SKILL.md`
46
- 受管输出。内容来自当前仓库内临时 `npx skills add` 安装结果,再转换为最终形态。
47
- - `skills/<name>/.skill-source.json`
48
- 来源、转换、目标路径与安装元数据。
49
- - `.github/workflows/skills-sync.yml`
50
- 受管 workflow,执行 `npm test` 与 `skillsbase sync --check`。
51
- - `.github/actions/skillsbase-sync/action.yml`
52
- 可复用 composite action。
75
+ `skillsbase` manages files in the target repository, including:
53
76
 
54
- 以上文件属于 **目标 skills 仓库**,不属于本 CLI 仓库本身。
77
+ - `sources.yaml`: the single source of truth for source roots, naming rules, include lists, and defaults
78
+ - `skills/<name>/SKILL.md`: managed skill output converted from installed source content
79
+ - `skills/<name>/.skill-source.json`: source, conversion, target-path, and install metadata
80
+ - `docs/maintainer-workflow.md`: maintainer guidance generated from the bundled templates
81
+ - `.github/workflows/skills-sync.yml`: reusable workflow for validation and sync checks
82
+ - `.github/actions/skillsbase-sync/action.yml`: reusable composite action
55
83
 
56
84
  ## Non-Interactive Defaults
57
85
 
58
- - 目标仓库默认为当前工作目录。
59
- - `init` 默认来源根目录:
86
+ - The target repository defaults to the current working directory.
87
+ - `init` defaults the source roots to:
60
88
  - first-party: `$HOME/.agents/skills`
61
89
  - system: `$HOME/.codex/skills/.system`
62
- - `add` 默认写入第一个已声明 source block
63
- - `github_action` 默认 `--kind workflow`。
64
- - 若上下文不足以安全写入,命令直接失败并给出诊断;不会进入交互提问。
90
+ - `add` writes to the first declared source block unless `--source <key>` is provided.
91
+ - `github_action` defaults to `--kind workflow`.
92
+ - When the CLI does not have enough context to write safely, it fails with diagnostics instead of prompting interactively.
65
93
 
66
- ## Usage Notes
94
+ ## Development
67
95
 
68
- - `sync` 会执行“安装到当前仓库 -> 转换 -> 卸载临时产物 -> 对账写盘”闭环。
69
- - `sync --check` 不修改最终仓库状态;若发现漂移则返回非零退出码。
70
- - `sync --allow-missing-sources` 可在来源根目录暂缺时跳过该来源。
71
- - `github_action` 仅覆盖带 `Managed by skillsbase CLI` 标记的文件;冲突文件需显式 `--force`。
96
+ Common commands for working on this package:
72
97
 
73
- ## Development
98
+ ```bash
99
+ npm run build
100
+ npm run cli -- --help
101
+ npm test
102
+ npm run smoke
103
+ npm run pack:check
104
+ ```
105
+
106
+ The published entry point is `bin/skillsbase.mjs`. In development, `npm run cli -- <args>` runs the TypeScript entry directly.
107
+
108
+ ## Publishing Notes
109
+
110
+ The GitHub Actions workflow supports two npm authentication modes:
111
+
112
+ - Preferred: npm trusted publishing via GitHub Actions OIDC
113
+ - Fallback: `NPM_TOKEN` repository secret mapped to `NODE_AUTH_TOKEN`
74
114
 
75
- - `npm test`
76
- CLI 单测。
77
- - `npm run smoke`
78
- 在临时目录创建一个示例 managed repo,验证 `init -> sync -> sync --check -> github_action`。
115
+ Before relying on trusted publishing, make sure the npm package settings for `@hagicode/skillsbase` trust the `HagiCode-org/skillsbase` repository.
116
+ The npm docs currently require Node.js `>= 22.14.0` and npm `>= 11.5.1` for trusted publishing.
@@ -0,0 +1,116 @@
1
+ # @hagicode/skillsbase
2
+
3
+ [English README](./README.md)
4
+
5
+ [![npm version](https://img.shields.io/npm/v/%40hagicode%2Fskillsbase?logo=npm&color=cb3837)](https://www.npmjs.com/package/@hagicode/skillsbase)
6
+ [![npm downloads](https://img.shields.io/npm/dm/%40hagicode%2Fskillsbase?logo=npm&color=2d8cf0)](https://www.npmjs.com/package/@hagicode/skillsbase)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22.12.0-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
8
+
9
+ `skillsbase` 是一个独立的 Node.js CLI,用于初始化并维护受管 skills 仓库。
10
+ 本仓库只提供 CLI 与模板,不提交目标仓库中的 `skills/` 产物。
11
+
12
+ ## 安装
13
+
14
+ 要求:
15
+
16
+ - Node.js `>= 22.12.0`
17
+ - npm `>= 10.9.2`
18
+
19
+ 全局安装:
20
+
21
+ ```bash
22
+ npm install --global @hagicode/skillsbase
23
+ ```
24
+
25
+ 安装后可直接执行:
26
+
27
+ ```bash
28
+ skillsbase --help
29
+ ```
30
+
31
+ ## 快速开始
32
+
33
+ 初始化受管仓库:
34
+
35
+ ```bash
36
+ skillsbase init --repo /path/to/target-repo
37
+ ```
38
+
39
+ 按 `sources.yaml` 同步技能:
40
+
41
+ ```bash
42
+ skillsbase sync --repo /path/to/target-repo
43
+ ```
44
+
45
+ 添加单个技能并立即同步:
46
+
47
+ ```bash
48
+ skillsbase add documentation-writer --repo /path/to/target-repo
49
+ ```
50
+
51
+ 生成受管 GitHub Actions 资产:
52
+
53
+ ```bash
54
+ skillsbase github_action --repo /path/to/target-repo --kind all
55
+ ```
56
+
57
+ ## 命令
58
+
59
+ | 命令 | 用途 | 示例 |
60
+ | --- | --- | --- |
61
+ | `init` | 创建受管仓库基础结构 | `skillsbase init --repo ./my-skills-repo` |
62
+ | `sync` | 按 `sources.yaml` 对账并同步技能 | `skillsbase sync --repo ./my-skills-repo` |
63
+ | `sync --check` | 只校验漂移,不写文件 | `skillsbase sync --check --repo ./my-skills-repo` |
64
+ | `add <skill-name>` | 将技能写入 source block 后执行同步 | `skillsbase add documentation-writer --repo ./my-skills-repo` |
65
+ | `github_action` | 生成受管 GitHub Actions 工作流或 action 文件 | `skillsbase github_action --repo ./my-skills-repo --kind workflow` |
66
+
67
+ 全局选项:
68
+
69
+ - `--repo <path>`:目标仓库路径,默认当前目录
70
+ - `--help`、`-h`:显示帮助
71
+ - `--version`、`-v`:显示版本
72
+
73
+ ## 受管仓库约定
74
+
75
+ `skillsbase` 会在目标仓库中管理以下文件:
76
+
77
+ - `sources.yaml`:来源根目录、命名规则、包含列表与默认值的单一真相源
78
+ - `skills/<name>/SKILL.md`:由安装源内容转换得到的受管技能输出
79
+ - `skills/<name>/.skill-source.json`:来源、转换、目标路径与安装元数据
80
+ - `docs/maintainer-workflow.md`:由模板生成的维护说明
81
+ - `.github/workflows/skills-sync.yml`:用于校验与同步检查的工作流
82
+ - `.github/actions/skillsbase-sync/action.yml`:可复用 composite action
83
+
84
+ ## 非交互默认行为
85
+
86
+ - 目标仓库默认是当前工作目录。
87
+ - `init` 默认来源根目录为:
88
+ - first-party:`$HOME/.agents/skills`
89
+ - system:`$HOME/.codex/skills/.system`
90
+ - `add` 默认写入第一个已声明的 source block;如需指定,传 `--source <key>`。
91
+ - `github_action` 默认使用 `--kind workflow`。
92
+ - 若上下文不足以安全写入,CLI 会直接失败并输出诊断,不会进入交互提问。
93
+
94
+ ## 开发
95
+
96
+ 常用命令:
97
+
98
+ ```bash
99
+ npm run build
100
+ npm run cli -- --help
101
+ npm test
102
+ npm run smoke
103
+ npm run pack:check
104
+ ```
105
+
106
+ 发布入口为 `bin/skillsbase.mjs`。开发期可用 `npm run cli -- <args>` 直接运行 TypeScript 入口。
107
+
108
+ ## 发布说明
109
+
110
+ GitHub Actions 发布流支持两种 npm 认证模式:
111
+
112
+ - 推荐:GitHub Actions OIDC 的 npm trusted publishing
113
+ - 兜底:仓库 `NPM_TOKEN` secret,经 `NODE_AUTH_TOKEN` 注入
114
+
115
+ 若使用 trusted publishing,需先在 npm 的 `@hagicode/skillsbase` 包设置中,将 `HagiCode-org/skillsbase` 配置为 trusted publisher。
116
+ npm 官方当前要求 Node.js `>= 22.14.0` 且 npm `>= 11.5.1`。
package/dist/cli.mjs CHANGED
@@ -168,6 +168,21 @@ function validateSource(source) {
168
168
  include: [...source.include]
169
169
  };
170
170
  }
171
+ function isRemoteRepositorySource(source) {
172
+ return source.kind === "github-repository";
173
+ }
174
+ function buildSourcePath(source, originalName) {
175
+ if (isRemoteRepositorySource(source)) return `${source.root}@${originalName}`;
176
+ return path.join(source.root, originalName);
177
+ }
178
+ function resolveSourceRoot(repoPath, source) {
179
+ if (isRemoteRepositorySource(source) || path.isAbsolute(source.root)) return source.root;
180
+ return path.resolve(repoPath, source.root);
181
+ }
182
+ function resolveSourcePath(repoPath, source, originalName) {
183
+ if (isRemoteRepositorySource(source)) return buildSourcePath(source, originalName);
184
+ return path.join(resolveSourceRoot(repoPath, source), originalName);
185
+ }
171
186
  function createManifest(repoPath, options = {}) {
172
187
  return {
173
188
  version: 1,
@@ -258,7 +273,7 @@ async function loadManifest(repoPath) {
258
273
  const sourceStartMatch = /^ - key:\s*(.+)$/.exec(line);
259
274
  if (sourceStartMatch) {
260
275
  currentSource = {
261
- key: parseScalar(sourceStartMatch[1]),
276
+ key: String(parseScalar(sourceStartMatch[1])),
262
277
  include: []
263
278
  };
264
279
  manifest.sources.push(currentSource);
@@ -300,19 +315,25 @@ async function saveManifest(manifest) {
300
315
  }
301
316
  function buildManifestEntries(manifest, repoPath = manifest.repoPath) {
302
317
  const entries = [];
303
- for (const source of manifest.sources) for (const originalName of source.include ?? []) {
304
- const targetName = `${source.targetPrefix ?? ""}${originalName}`;
305
- entries.push({
306
- sourceKey: source.key,
307
- sourceLabel: source.label,
308
- sourceKind: source.kind,
309
- sourceRoot: source.root,
310
- sourcePath: path.join(source.root, originalName),
311
- originalName,
312
- targetName,
313
- targetPath: path.join(repoPath, manifest.skillsRoot, targetName),
314
- targetPathRelative: toPosix(path.join(manifest.skillsRoot, targetName))
315
- });
318
+ for (const source of manifest.sources) {
319
+ const resolvedSourceRoot = resolveSourceRoot(repoPath, source);
320
+ for (const originalName of source.include ?? []) {
321
+ const targetName = `${source.targetPrefix ?? ""}${originalName}`;
322
+ entries.push({
323
+ sourceKey: source.key,
324
+ sourceLabel: source.label,
325
+ sourceKind: source.kind,
326
+ remoteSource: isRemoteRepositorySource(source),
327
+ sourceRoot: source.root,
328
+ sourcePath: buildSourcePath(source, originalName),
329
+ resolvedSourceRoot,
330
+ resolvedSourcePath: resolveSourcePath(repoPath, source, originalName),
331
+ originalName,
332
+ targetName,
333
+ targetPath: path.join(repoPath, manifest.skillsRoot, targetName),
334
+ targetPathRelative: toPosix(path.join(manifest.skillsRoot, targetName))
335
+ });
336
+ }
316
337
  }
317
338
  const collisions = /* @__PURE__ */ new Map();
318
339
  for (const entry of entries) {
@@ -362,6 +383,11 @@ function buildMetadata(manifest, entry, installRecord) {
362
383
  //#endregion
363
384
  //#region src/lib/installer.ts
364
385
  var execFile$1 = promisify(execFile);
386
+ function toInstallReference(entry) {
387
+ if (entry.remoteSource) return entry.sourcePath;
388
+ if (path.isAbsolute(entry.sourcePath) || entry.sourcePath.startsWith(`.${path.sep}`) || entry.sourcePath === ".") return entry.sourcePath;
389
+ return `.${path.sep}${entry.sourcePath}`;
390
+ }
365
391
  function buildNpxArgs(manifest, subcommand, extraArgs) {
366
392
  return [
367
393
  "--yes",
@@ -378,6 +404,7 @@ function renderExecFailure(error) {
378
404
  return String(error);
379
405
  }
380
406
  async function installIntoCurrentRepository(repoPath, manifest, entry, options = {}) {
407
+ const installReference = toInstallReference(entry);
381
408
  const installPath = path.join(repoPath, ".agents", "skills", entry.originalName);
382
409
  const lockPath = path.join(repoPath, "skills-lock.json");
383
410
  const snapshot = {
@@ -385,11 +412,11 @@ async function installIntoCurrentRepository(repoPath, manifest, entry, options =
385
412
  lockPath,
386
413
  installTree: await snapshotTree(installPath),
387
414
  lockText: await readFileIfExists(lockPath),
388
- installReference: entry.sourcePath
415
+ installReference
389
416
  };
390
417
  try {
391
418
  await execFile$1("npx", buildNpxArgs(manifest, "add", [
392
- entry.sourcePath,
419
+ installReference,
393
420
  "--agent",
394
421
  manifest.installAgent,
395
422
  "--copy",
@@ -407,7 +434,7 @@ async function installIntoCurrentRepository(repoPath, manifest, entry, options =
407
434
  return {
408
435
  installPath,
409
436
  lockPath,
410
- installReference: entry.sourcePath,
437
+ installReference,
411
438
  snapshot
412
439
  };
413
440
  }
@@ -524,14 +551,15 @@ async function convertInstalledSkill(_manifest, entry, installState) {
524
551
  //#endregion
525
552
  //#region src/lib/sync-engine.ts
526
553
  async function assertSourceState(entry, allowMissingSources) {
527
- if (!await pathExists(entry.sourceRoot)) {
554
+ if (entry.remoteSource) return { skip: false };
555
+ if (!await pathExists(entry.resolvedSourceRoot)) {
528
556
  if (allowMissingSources) return {
529
557
  skip: true,
530
- reason: `missing source root: ${entry.sourceRoot}`
558
+ reason: `missing source root: ${entry.resolvedSourceRoot}`
531
559
  };
532
- throw new CliError(`Managed source root does not exist: ${entry.sourceRoot}`, { details: ["Use `skillsbase sync --allow-missing-sources` to skip missing roots."] });
560
+ throw new CliError(`Managed source root does not exist: ${entry.resolvedSourceRoot}`, { details: ["Use `skillsbase sync --allow-missing-sources` to skip missing roots."] });
533
561
  }
534
- if (!await pathExists(entry.sourcePath)) throw new CliError(`Managed skill is missing from source root: ${entry.sourcePath}`, { details: [`source: ${entry.sourceKey}`, `skill: ${entry.originalName}`] });
562
+ if (!await pathExists(entry.resolvedSourcePath)) throw new CliError(`Managed skill is missing from source root: ${entry.resolvedSourcePath}`, { details: [`source: ${entry.sourceKey}`, `skill: ${entry.originalName}`] });
535
563
  return { skip: false };
536
564
  }
537
565
  async function assertManagedTargetWritable(manifest, entry) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hagicode/skillsbase",
3
- "version": "0.1.0-dev.20260406025440.0.0.local",
3
+ "version": "0.1.0-dev.6.1.7f41ada",
4
4
  "description": "Managed skills repository CLI",
5
5
  "homepage": "https://github.com/HagiCode-org/skillsbase#readme",
6
6
  "bugs": {
@@ -19,17 +19,20 @@
19
19
  "bin",
20
20
  "dist",
21
21
  "templates",
22
- "README.md"
22
+ "README.md",
23
+ "README.zh-CN.md"
23
24
  ],
24
25
  "scripts": {
25
26
  "build": "vite build",
26
27
  "clean": "rm -rf dist",
27
28
  "cli": "node --import tsx ./src/cli-entry.ts",
28
29
  "pack:check": "node ./scripts/verify-package.mjs",
29
- "publish:prepare-dev-version": "node ./scripts/prepare-dev-version.mjs",
30
+ "publish:resolve-dev-version": "node ./scripts/resolve-dev-version.mjs",
31
+ "publish:verify-readiness": "node ./scripts/verify-publish-readiness.mjs",
30
32
  "publish:verify-release": "node ./scripts/verify-release-version.mjs",
31
33
  "test": "node --import tsx --test ./tests/*.test.ts",
32
- "smoke": "node --import tsx ./scripts/smoke.mjs"
34
+ "smoke": "node --import tsx ./scripts/smoke.mjs",
35
+ "typecheck": "tsc --noEmit -p tsconfig.json"
33
36
  },
34
37
  "engines": {
35
38
  "node": ">=22.12.0",
@@ -26,6 +26,10 @@ runs:
26
26
  shell: bash
27
27
  run: npm ci
28
28
 
29
+ - name: Install skillsbase
30
+ shell: bash
31
+ run: npm install --global @hagicode/skillsbase
32
+
29
33
  - name: Run tests
30
34
  if: ${{ inputs.run-tests == 'true' }}
31
35
  shell: bash
@@ -33,4 +37,4 @@ runs:
33
37
 
34
38
  - name: Run sync check
35
39
  shell: bash
36
- run: node ./bin/skillsbase.mjs sync --check
40
+ run: skillsbase sync --check --repo .
@@ -32,8 +32,11 @@ jobs:
32
32
  - name: Install dependencies
33
33
  run: npm ci
34
34
 
35
+ - name: Install skillsbase
36
+ run: npm install --global @hagicode/skillsbase
37
+
35
38
  - name: Run tests
36
39
  run: npm test
37
40
 
38
41
  - name: Validate managed repository state
39
- run: node ./bin/skillsbase.mjs sync --check
42
+ run: skillsbase sync --check --repo .