skills-manager-cli 2026.9.5 → 2026.9.10-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +54 -45
  2. package/README.zh-CN.md +53 -45
  3. package/dist/cli/bootstrap-prompt.js +80 -0
  4. package/dist/cli/bootstrap-prompt.js.map +1 -0
  5. package/dist/cli/bootstrap.js +82 -0
  6. package/dist/cli/bootstrap.js.map +1 -0
  7. package/dist/cli/main.js +155 -17
  8. package/dist/cli/main.js.map +1 -1
  9. package/dist/core/index.js +1 -0
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/ports/github-api.js +22 -0
  12. package/dist/core/ports/github-api.js.map +1 -0
  13. package/dist/core/services/detection-log.js +24 -0
  14. package/dist/core/services/detection-log.js.map +1 -0
  15. package/dist/core/services/detection-service.js +196 -0
  16. package/dist/core/services/detection-service.js.map +1 -0
  17. package/dist/core/services/distribute-service.js +0 -0
  18. package/dist/core/services/distribute-service.js.map +1 -1
  19. package/dist/core/services/index.js +11 -2
  20. package/dist/core/services/index.js.map +1 -1
  21. package/dist/core/services/init-service.js +58 -18
  22. package/dist/core/services/init-service.js.map +1 -1
  23. package/dist/core/services/install-service.js +7 -5
  24. package/dist/core/services/install-service.js.map +1 -1
  25. package/dist/core/services/manager-skill-service.js +102 -0
  26. package/dist/core/services/manager-skill-service.js.map +1 -0
  27. package/dist/core/services/provenance-service.js +61 -0
  28. package/dist/core/services/provenance-service.js.map +1 -0
  29. package/dist/core/services/registry-service.js +13 -5
  30. package/dist/core/services/registry-service.js.map +1 -1
  31. package/dist/core/services/skill-home-resolver.js +5 -2
  32. package/dist/core/services/skill-home-resolver.js.map +1 -1
  33. package/dist/core/services/skill-lock-service.js +98 -0
  34. package/dist/core/services/skill-lock-service.js.map +1 -0
  35. package/dist/core/services/source-service.js +154 -12
  36. package/dist/core/services/source-service.js.map +1 -1
  37. package/dist/core/services/update-service.js +14 -13
  38. package/dist/core/services/update-service.js.map +1 -1
  39. package/dist/dashboard/server/main.js +20 -80
  40. package/dist/dashboard/server/main.js.map +1 -1
  41. package/dist/dashboard-web/assets/{index-BtkWyamF.js → index-DSQV4D7B.js} +6 -6
  42. package/dist/dashboard-web/index.html +1 -1
  43. package/dist/infra/fs-skill-home.js +8 -0
  44. package/dist/infra/fs-skill-home.js.map +1 -1
  45. package/dist/infra/git-cli.js +101 -7
  46. package/dist/infra/git-cli.js.map +1 -1
  47. package/dist/infra/git-transport-retry.js +46 -0
  48. package/dist/infra/git-transport-retry.js.map +1 -0
  49. package/dist/infra/github-api-client.js +163 -0
  50. package/dist/infra/github-api-client.js.map +1 -0
  51. package/dist/infra/index.js +1 -0
  52. package/dist/infra/index.js.map +1 -1
  53. package/dist/infra/runtime.js +3 -2
  54. package/dist/infra/runtime.js.map +1 -1
  55. package/dist/infra/shell-runner.js +36 -3
  56. package/dist/infra/shell-runner.js.map +1 -1
  57. package/dist/shared/redact.js +15 -0
  58. package/dist/shared/redact.js.map +1 -0
  59. package/dist/shared/validation.js +8 -7
  60. package/dist/shared/validation.js.map +1 -1
  61. package/docs/CLI.md +21 -2
  62. package/package.json +4 -1
  63. package/skills/skills-manager/SKILL.md +201 -0
package/README.md CHANGED
@@ -2,80 +2,71 @@
2
2
 
3
3
  **English** | [简体中文](README.zh-CN.md)
4
4
 
5
- `skills-manager-cli` is a local-first CLI and dashboard for managing agent, Claude, and Codex skills from a registry-driven skill home.
5
+ Manage your agent skills **from the conversation**: one `npx` command installs the manager skill, and from then on you just ask your agent — install, import, distribute, update, backfill provenance. Works with any skill-loading agent (Claude Code, Codex, Cursor, …).
6
6
 
7
7
  ## Quick Start
8
8
 
9
- **No setup needed** — just run:
10
-
11
- ```sh
12
- npx skills-manager-cli web
13
- ```
14
-
15
- This automatically creates and initializes `~/.skills-manager/` on first run.
16
-
17
- **Already have skills in `~/.claude/skills` or other agent runtimes?** Fold them in with `skills-manager init` — content moves into the hub, originals become symlinks (backed up first):
18
-
19
9
  ```sh
20
- skills-manager init --dry-run # preview
21
- skills-manager init # import
10
+ npx skills-manager-cli
22
11
  ```
23
12
 
24
- Or install globally:
13
+ That is the whole setup. Bootstrap creates the skill hub (`~/.skills-manager`), installs the **manager skill** into it from the bundled copy, and mounts it (symlink) into the agents it detects on your machine — you confirm the list in the one prompt it shows.
25
14
 
26
- ```sh
27
- npm install -g skills-manager-cli
28
- # or
29
- pnpm add -g skills-manager-cli
30
- skills-manager web
31
- ```
15
+ Then go back to your agent and say:
32
16
 
33
- 👉 **[See Getting Started guide](docs/GETTING_STARTED.md)** for detailed instructions and common tasks.
17
+ > **帮我看看我的 skills:有哪些、装到哪些 agent 了、有没有能更新的**
18
+ > (“Take stock of my skills: what I have, which agents they are wired into, and what has updates”)
34
19
 
35
- ## Install and Run
20
+ **Already have skills in `~/.claude/skills` or other agent runtimes?** Don't migrate during setup — just ask your agent:
36
21
 
37
- Use without installing globally:
22
+ > 帮我把现有的 skills 导入 skills-manager 并整理好来源
38
23
 
39
- ```sh
40
- npx skills-manager-cli web
41
- ```
24
+ Content moves into the hub, originals become symlinks (backed up first). Prefer to preview it yourself first? `skills-manager init --dry-run`.
42
25
 
43
- Or install globally from a published package or packed tarball:
26
+ ## How it works
44
27
 
45
- ```sh
46
- npm install -g skills-manager-cli
47
- # or
48
- pnpm add -g skills-manager-cli
49
- skills-manager web
50
- skills-manager doctor
28
+ ```text
29
+ ~/.skills-manager ← hub: the only content authority
30
+ skills/<name>/ · registry.yaml
31
+ │
32
+ │ distribute (symlink / copy)
33
+ ▼
34
+ ~/.claude/skills ~/.cursor/skills … ← agent runtime dirs
35
+ ▲
36
+ │ drives, via `npx skills-manager-cli …`
37
+ your agent ⇄ the manager skill
51
38
  ```
52
39
 
53
- `web` opens a local Vue/Fastify dashboard by default. Use `--no-open` to keep the browser closed.
40
+ - The **manager skill** is the primary interface ([ADR-0014](docs/adr/0014-manager-skill-first-bootstrap.md)): the npx bootstrap installs it and nothing else; every management action afterwards happens through it, in agent conversation. No agent detected yet? Bootstrap still creates the hub and tells you how to mount later.
41
+ - It keeps itself current: every CLI run compares the bundled copy with the hub copy and silently refreshes it — unless you edited the hub copy yourself, in which case it is yours and stays untouched.
42
+ - The CLI underneath is a plain engine (JSON output, non-interactive flags) — see the [CLI reference](docs/CLI.md).
54
43
 
55
44
  ## Skill home layout
56
45
 
57
46
  A skill home contains:
58
47
 
59
48
  - `skills/`: canonical skill directories, kept flat as `skills/<skill-name>/SKILL.md`
60
- - `views/`: generated consumer symlink trees such as `views/agents/` and `views/claude/`
61
- - `collections/`: generated category symlink trees
62
- - `registry.yaml`: metadata, provenance, consumers, category, source, and update policy
63
- - `.skills/activity.jsonl`: operation records written by the dashboard/CLI
49
+ - `collections/`: generated category symlink trees (browse-only)
50
+ - `registry.yaml`: metadata — category, tags, consumers, source (repo, subpath, ref, baseline), update policy
51
+ - `.skills/`: distribution index (`distributions.jsonl`), activity log, optional agent-catalog override
52
+ - `.backups/`: pre-init originals, kept for 30 days
64
53
 
65
54
  Skill home resolution priority:
66
55
 
67
56
  1. `--home <path>`
68
57
  2. `SKILL_HOME`
69
58
  3. current working directory when it already looks like a skill home
70
- 4. `~/.skills-manager`, initialized automatically
59
+ 4. `~/.skills-manager` — created by bootstrap only; other commands point you at it instead of creating it
71
60
 
72
61
  ## Common commands
73
62
 
74
63
  ```sh
75
- skills-manager web --home ~/.skills-manager
76
- skills-manager doctor --home ~/.skills-manager
77
- skills-manager list --home ~/.skills-manager
78
- skills-manager add owner/repo --all --consumer agents --consumer claude --yes
64
+ npx skills-manager-cli # bootstrap (default when no subcommand)
65
+ skills-manager bootstrap --agent claude-code # scripted bootstrap / mount later
66
+ skills-manager doctor
67
+ skills-manager list
68
+ skills-manager add owner/repo --all --yes
69
+ skills-manager distribute --to user --skill my-skill --agent claude-code
79
70
  skills-manager update --plan
80
71
  skills-manager update --skill my-skill
81
72
  skills-manager init --dry-run # preview runtime-skill import
@@ -83,12 +74,30 @@ skills-manager init --prefer claude-code hub # this-run conflict priority
83
74
  skills-manager init --resolve my-skill=cursor # import with a conflict decision
84
75
  skills-manager backup list # inspect init backups
85
76
  skills-manager backup restore my-skill # roll one import back
86
- skills-manager edit my-skill --source-url https://github.com/owner/repo
77
+ skills-manager edit my-skill --source-git owner/repo --subpath skills/my-skill
78
+ skills-manager provenance list # skills still missing a source
79
+ skills-manager provenance adopt # backfill lockfile evidence
87
80
  skills-manager archive old-skill
88
81
  ```
89
82
 
90
83
  Sources can be GitHub shorthand (`owner/repo`), Git URLs, GitHub tree URLs, or local paths.
91
84
 
85
+ ## Optional: global install & dashboard
86
+
87
+ Prefer typing a bare command? Install globally:
88
+
89
+ ```sh
90
+ npm install -g skills-manager-cli # or pnpm add -g skills-manager-cli
91
+ ```
92
+
93
+ Prefer a visual interface? The local dashboard is an optional alternative to the conversation:
94
+
95
+ ```sh
96
+ skills-manager web # http://127.0.0.1:4777, --no-open to skip the browser
97
+ ```
98
+
99
+ It offers the same library on one page: browse, install, update, and distribute. It never creates the hub — run bootstrap first.
100
+
92
101
  ## Development
93
102
 
94
103
  ```sh
@@ -99,6 +108,6 @@ pnpm test
99
108
 
100
109
  ## Documentation
101
110
 
102
- - **[Getting Started](docs/GETTING_STARTED.md)** — Installation, first launch, common tasks
111
+ - **[Getting Started](docs/GETTING_STARTED.md)** — First run, importing existing skills, common tasks
103
112
  - **[CLI Reference](docs/CLI.md)** — Full command reference and advanced usage
104
113
  - **[Architecture](CONTEXT.md)** — Project structure and design decisions
package/README.zh-CN.md CHANGED
@@ -2,80 +2,70 @@
2
2
 
3
3
  [English](README.md) | **简体中文**
4
4
 
5
- `skills-manager-cli` 是一个本地优先的 CLI 与网页控制台,基于注册表驱动的技能库(skill home)管理 agent、Claude、Codex 的技能。
5
+ 在**对话里**管理你的 agent skills:一条 `npx` 命令装上 manager skill,之后一切都直接吩咐你的 agent——安装、导入、分发、更新、补齐来源。任何会加载 skills 的 agent 都能用(Claude Code、Codex、Cursor、…)。
6
6
 
7
7
  ## 快速开始
8
8
 
9
- **无需任何安装** —— 直接运行:
10
-
11
- ```sh
12
- npx skills-manager-cli web
13
- ```
14
-
15
- 首次运行时会自动创建并初始化 `~/.skills-manager/`。
16
-
17
- **已经在 `~/.claude/skills` 或其他 agent 运行时目录里有技能了?** 用 `skills-manager init` 一键收纳 —— 内容移入技能库,原位置变成软链接(会先备份):
18
-
19
9
  ```sh
20
- skills-manager init --dry-run # 预览
21
- skills-manager init # 导入
10
+ npx skills-manager-cli
22
11
  ```
23
12
 
24
- 或者全局安装:
13
+ 这就是全部的安装步骤。bootstrap 会创建技能库(`~/.skills-manager`),从包内副本把 **manager skill** 种进库,并(以软链接)挂载到它检测到的 agent——展示一次多选让你确认清单。
25
14
 
26
- ```sh
27
- npm install -g skills-manager-cli
28
- # 或
29
- pnpm add -g skills-manager-cli
30
- skills-manager web
31
- ```
15
+ 然后回到你的 agent,说:
32
16
 
33
- 👉 **[查看入门指南](docs/GETTING_STARTED.zh-CN.md)** 了解详细用法与常见任务。
17
+ > **帮我看看我的 skills:有哪些、装到哪些 agent 了、有没有能更新的**
34
18
 
35
- ## 安装与运行
19
+ **`~/.claude/skills` 等运行时目录里已经有 skills 了?** 不必在安装时迁移——直接吩咐:
36
20
 
37
- 免安装直接使用:
21
+ > 帮我把现有的 skills 导入 skills-manager 并整理好来源
38
22
 
39
- ```sh
40
- npx skills-manager-cli web
41
- ```
23
+ 内容会移入库中,原位置变成软链接(先备份)。想先自己预览?`skills-manager init --dry-run`。
42
24
 
43
- 或从已发布的包/本地打包的 tarball 全局安装:
25
+ ## 工作原理
44
26
 
45
- ```sh
46
- npm install -g skills-manager-cli
47
- # 或
48
- pnpm add -g skills-manager-cli
49
- skills-manager web
50
- skills-manager doctor
27
+ ```text
28
+ ~/.skills-manager ← 技能库:唯一的内容权威
29
+ skills/<name>/ · registry.yaml
30
+ │
31
+ │ 分发(软链接 / 拷贝)
32
+ ▼
33
+ ~/.claude/skills ~/.cursor/skills … ← agent 运行时目录
34
+ ▲
35
+ │ 通过 `npx skills-manager-cli …` 驱动
36
+ 你的 agent ⇄ manager skill
51
37
  ```
52
38
 
53
- `web` 默认自动打开本地 Vue/Fastify 控制台。加 `--no-open` 可保持浏览器关闭。
39
+ - **manager skill** 是主界面([ADR-0014](docs/adr/0014-manager-skill-first-bootstrap.md)):npx bootstrap 只装它、别的什么都不做;之后所有管理动作都通过它在 agent 对话里完成。还没装任何 agent?bootstrap 照样建好技能库,并告诉你之后怎么挂载。
40
+ - 它自己保持最新:CLI 每次运行都会对比包内副本与库内副本并静默刷新——除非你自己改过库内副本,那就是你的了,不再碰它。
41
+ - 底层的 CLI 是纯粹的引擎(JSON 输出、非交互 flag)——见 [CLI 参考](docs/CLI.zh-CN.md)。
54
42
 
55
43
  ## 技能库(skill home)结构
56
44
 
57
45
  一个技能库包含:
58
46
 
59
47
  - `skills/`:规范技能目录,扁平存放为 `skills/<skill-name>/SKILL.md`
60
- - `views/`:生成的消费方软链接树,如 `views/agents/` 和 `views/claude/`
61
- - `collections/`:生成的分类软链接树
62
- - `registry.yaml`:元数据、来源、消费方、分类、source 与更新策略
63
- - `.skills/activity.jsonl`:控制台/CLI 写入的操作记录
48
+ - `collections/`:生成的分类软链接树(仅供浏览)
49
+ - `registry.yaml`:元数据 —— 分类、标签、消费方、来源(仓库、子路径、ref、基线)、更新策略
50
+ - `.skills/`:分发索引(`distributions.jsonl`)、活动日志、可选的 agent 目录覆盖
51
+ - `.backups/`:init 前的原始内容,保留 30 天
64
52
 
65
53
  技能库解析优先级:
66
54
 
67
55
  1. `--home <path>`
68
56
  2. `SKILL_HOME`
69
57
  3. 当前目录(当它已经是一个技能库时)
70
- 4. `~/.skills-manager`(自动初始化)
58
+ 4. `~/.skills-manager` —— 仅由 bootstrap 创建;其他命令只会提示你先跑 bootstrap,不再隐式创建
71
59
 
72
60
  ## 常用命令
73
61
 
74
62
  ```sh
75
- skills-manager web --home ~/.skills-manager
76
- skills-manager doctor --home ~/.skills-manager
77
- skills-manager list --home ~/.skills-manager
78
- skills-manager add owner/repo --all --consumer agents --consumer claude --yes
63
+ npx skills-manager-cli # bootstrap(不带子命令时的默认行为)
64
+ skills-manager bootstrap --agent claude-code # 脚本化 bootstrap / 之后再挂载
65
+ skills-manager doctor
66
+ skills-manager list
67
+ skills-manager add owner/repo --all --yes
68
+ skills-manager distribute --to user --skill my-skill --agent claude-code
79
69
  skills-manager update --plan
80
70
  skills-manager update --skill my-skill
81
71
  skills-manager init --dry-run # 预览运行时技能导入
@@ -83,12 +73,30 @@ skills-manager init --prefer claude-code hub # 本次导入的冲突优先
83
73
  skills-manager init --resolve my-skill=cursor # 按冲突决策导入
84
74
  skills-manager backup list # 查看 init 备份
85
75
  skills-manager backup restore my-skill # 回滚某次导入
86
- skills-manager edit my-skill --source-url https://github.com/owner/repo
76
+ skills-manager edit my-skill --source-git owner/repo --subpath skills/my-skill
77
+ skills-manager provenance list # 仍缺来源的技能清单
78
+ skills-manager provenance adopt # 补采锁文件证据
87
79
  skills-manager archive old-skill
88
80
  ```
89
81
 
90
82
  来源(source)支持 GitHub 简写(`owner/repo`)、Git URL、GitHub tree URL 或本地路径。
91
83
 
84
+ ## 可选:全局安装与 dashboard
85
+
86
+ 想直接敲裸命令?全局安装:
87
+
88
+ ```sh
89
+ npm install -g skills-manager-cli # 或 pnpm add -g skills-manager-cli
90
+ ```
91
+
92
+ 想要可视化界面?本地 dashboard 是对话之外的可选替代:
93
+
94
+ ```sh
95
+ skills-manager web # http://127.0.0.1:4777,--no-open 不自动开浏览器
96
+ ```
97
+
98
+ 它在单页里提供同一个技能库:浏览、安装、更新、分发。它不会创建技能库——请先跑 bootstrap。
99
+
92
100
  ## 开发
93
101
 
94
102
  ```sh
@@ -99,6 +107,6 @@ pnpm test
99
107
 
100
108
  ## 文档
101
109
 
102
- - **[入门指南](docs/GETTING_STARTED.zh-CN.md)** —— 安装、首次启动、常见任务
110
+ - **[入门指南](docs/GETTING_STARTED.zh-CN.md)** —— 首次运行、导入现有技能、常见任务
103
111
  - **[CLI 参考](docs/CLI.zh-CN.md)** —— 完整命令参考与进阶用法
104
112
  - **[架构](CONTEXT.md)** —— 项目结构与设计决策(英文)
@@ -0,0 +1,80 @@
1
+ import readline from 'node:readline';
2
+ const DIM = '\x1b[2m';
3
+ const BOLD = '\x1b[1m';
4
+ const CYAN = '\x1b[36m';
5
+ const RESET = '\x1b[0m';
6
+ /**
7
+ * Minimal TTY multi-select (the CLI's only interactive moment — ADR-0014):
8
+ * ↑/↓ move, space toggles, `a` toggles all, enter confirms, ctrl-c aborts.
9
+ * Returns the selected ids; all options start checked unless `allByDefault` is false.
10
+ */
11
+ export async function multiSelect(title, options, config = {}) {
12
+ if (!process.stdin.isTTY || !process.stdout.isTTY)
13
+ throw new Error('multiSelect requires a TTY');
14
+ if (options.length === 0)
15
+ return [];
16
+ const checked = options.map(() => config.allByDefault !== false);
17
+ let cursor = 0;
18
+ const stdin = process.stdin;
19
+ readline.emitKeypressEvents(stdin);
20
+ const priorRaw = stdin.isRaw ?? false;
21
+ stdin.setRawMode(true);
22
+ stdin.resume();
23
+ process.stdout.write('\x1b[?25l');
24
+ const cleanup = () => {
25
+ process.stdout.write('\x1b[?25h\n');
26
+ stdin.setRawMode(priorRaw);
27
+ if (!priorRaw)
28
+ stdin.pause();
29
+ };
30
+ const render = () => {
31
+ const lines = [
32
+ `${BOLD}${title}${RESET}`,
33
+ ...options.map((option, index) => {
34
+ const marker = checked[index] ? '[x]' : '[ ]';
35
+ const pointer = index === cursor ? `${CYAN}❯${RESET} ` : ' ';
36
+ const detail = option.detail ? ` ${DIM}${option.detail}${RESET}` : '';
37
+ return `${pointer}${marker} ${option.label}${detail}`;
38
+ }),
39
+ `${DIM}↑/↓ move · space toggle · a all · enter confirm · ctrl-c abort${RESET}`,
40
+ ];
41
+ const total = lines.length + 1; // +1: the newline the previous render ended on
42
+ process.stdout.write(`\x1b[${total}A\x1b[0J`);
43
+ process.stdout.write(lines.join('\n') + '\n');
44
+ };
45
+ return new Promise((resolve) => {
46
+ const finish = (selection) => {
47
+ stdin.removeListener('keypress', onKey);
48
+ cleanup();
49
+ resolve(selection);
50
+ };
51
+ const onKey = (_chunk, key) => {
52
+ if (key.ctrl && key.name === 'c') {
53
+ finish([]);
54
+ process.exitCode = 130;
55
+ return;
56
+ }
57
+ if (key.name === 'up' || key.name === 'k')
58
+ cursor = (cursor - 1 + options.length) % options.length;
59
+ else if (key.name === 'down' || key.name === 'j')
60
+ cursor = (cursor + 1) % options.length;
61
+ else if (key.name === 'space')
62
+ checked[cursor] = !checked[cursor];
63
+ else if (key.name === 'a') {
64
+ const all = checked.every(Boolean);
65
+ for (let i = 0; i < checked.length; i += 1)
66
+ checked[i] = !all;
67
+ }
68
+ else if (key.name === 'return') {
69
+ finish(options.filter((_, index) => checked[index]).map((option) => option.id));
70
+ return;
71
+ }
72
+ else
73
+ return;
74
+ render();
75
+ };
76
+ stdin.on('keypress', onKey);
77
+ render();
78
+ });
79
+ }
80
+ //# sourceMappingURL=bootstrap-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap-prompt.js","sourceRoot":"","sources":["../../src/cli/bootstrap-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { createRequire } from 'node:module';
2
+ import { createRuntimeServices, projectRootFromImportMeta } from '../infra/runtime.js';
3
+ import { MANAGER_SKILL_NAME } from '../core/index.js';
4
+ import { normalizeGitSourceUrl } from '../core/services/source-service.js';
5
+ import { SkillsManagerError } from '../shared/errors.js';
6
+ import { multiSelect } from './bootstrap-prompt.js';
7
+ const pkg = createRequire(import.meta.url)('../../package.json');
8
+ const projectRoot = projectRootFromImportMeta(import.meta.url);
9
+ const STARTER_PROMPT_ZH = '帮我看看我的 skills:有哪些、装到哪些 agent 了、有没有能更新的';
10
+ const STARTER_PROMPT_EN = 'Take stock of my skills: what I have, which agents they are wired into, and what has updates';
11
+ const IMPORT_PROMPT_ZH = '帮我把现有的 skills 导入 skills-manager 并整理好来源';
12
+ export function managerSkillBundle() {
13
+ const raw = pkg.repository?.url || 'shenysun/skills-manager';
14
+ return { root: projectRoot, version: pkg.version, repoUrl: normalizeGitSourceUrl(raw.replace(/^git\+/, '')) };
15
+ }
16
+ /**
17
+ * The one-time setup, and the product's front door (ADR-0014): create the hub,
18
+ * seed the manager skill from the bundled copy, mount it to the chosen agents,
19
+ * print the starter prompt. It imports nothing — importing existing runtime
20
+ * skills is a conversational act for later, through the manager skill itself.
21
+ */
22
+ export async function runBootstrap(opts, cmd) {
23
+ const globalOpts = cmd.optsWithGlobals();
24
+ const s = createRuntimeServices({ home: globalOpts.home, ensureDefaultHub: true }, projectRoot);
25
+ const bundle = managerSkillBundle();
26
+ const seeded = s.managerSkill.seed(bundle);
27
+ const seedNotes = {
28
+ seeded: `installed the manager skill (skills-manager v${bundle.version})`,
29
+ refreshed: `updated the manager skill to v${bundle.version}`,
30
+ 'up-to-date': `manager skill already current (v${bundle.version})`,
31
+ 'user-managed': 'kept the existing skills-manager copy (installed or edited outside bootstrap)',
32
+ };
33
+ console.log(`• skill home: ${s.resolution.root}${s.resolution.created ? ' (created)' : ''}`);
34
+ console.log(`• ${seedNotes[seeded.status]}`);
35
+ const detected = s.catalog.detected();
36
+ const agents = await chooseAgents(opts, detected, s.catalog.resolveGlobalDir.bind(s.catalog));
37
+ if (agents.length > 0) {
38
+ try {
39
+ const applied = s.distribute.apply({ to: 'user', skills: [MANAGER_SKILL_NAME], agents, mode: 'symlink', force: Boolean(opts.force) });
40
+ const dirs = [...new Set(applied.entries.map((entry) => entry.runtimePath))];
41
+ console.log(`• mounted to: ${dirs.join(', ')}`);
42
+ }
43
+ catch (error) {
44
+ if (error instanceof SkillsManagerError && error.code === 'distribute_foreign_exists') {
45
+ throw new SkillsManagerError('bootstrap_foreign_runtime', `${error.message} Re-run with --force to replace it, or remove it first.`);
46
+ }
47
+ throw error;
48
+ }
49
+ }
50
+ else {
51
+ console.log('• manager skill mounted nowhere yet.');
52
+ console.log(' To mount later: npx skills-manager-cli bootstrap --agent <id>');
53
+ }
54
+ // Bootstrap never imports — it only reports what the user can bring in later (ADR-0014).
55
+ try {
56
+ const preview = s.init.run({ dryRun: true });
57
+ if (preview.imported.length > 0) {
58
+ const conflicts = preview.conflicts.length > 0 ? ` (+${preview.conflicts.length} needing decisions)` : '';
59
+ console.log(`• found ${preview.imported.length} existing skill(s) in your agent dirs${conflicts}.`);
60
+ console.log(` Import them later from your agent: “${IMPORT_PROMPT_ZH}”`);
61
+ }
62
+ }
63
+ catch {
64
+ /* zero detected agents — there is nothing to preview */
65
+ }
66
+ s.activity.record({ action: 'cli-bootstrap', summary: `Bootstrap: ${seeded.status}, mounted to ${agents.join(', ') || 'none'}`, details: { seeded: seeded.status, agents } });
67
+ console.log('\nAll set. Go back to your agent and say:');
68
+ console.log(` “${STARTER_PROMPT_ZH}”`);
69
+ console.log(` (“${STARTER_PROMPT_EN}”)`);
70
+ }
71
+ /** `--agent` wins; one detected agent needs no question; several get the picker in a TTY, all of them otherwise. */
72
+ async function chooseAgents(opts, detected, resolveGlobalDir) {
73
+ if (opts.agent && opts.agent.length > 0)
74
+ return opts.agent;
75
+ if (detected.length <= 1)
76
+ return detected;
77
+ if (!process.stdin.isTTY || !process.stdout.isTTY)
78
+ return detected;
79
+ const options = detected.map((id) => ({ id, label: id, detail: resolveGlobalDir(id) ?? undefined }));
80
+ return multiSelect('Install the manager skill into:', options);
81
+ }
82
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/cli/bootstrap.ts"],"names":[],"mappings":"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"}