@captain_z/zsk 0.1.0

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 (49) hide show
  1. package/README.md +147 -0
  2. package/dist/bin.d.ts +2 -0
  3. package/dist/bin.js +155 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/commands/add.d.ts +13 -0
  6. package/dist/commands/add.js +418 -0
  7. package/dist/commands/add.js.map +1 -0
  8. package/dist/commands/init.d.ts +1 -0
  9. package/dist/commands/init.js +127 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/install.d.ts +7 -0
  12. package/dist/commands/install.js +54 -0
  13. package/dist/commands/install.js.map +1 -0
  14. package/dist/commands/project-init.d.ts +6 -0
  15. package/dist/commands/project-init.js +63 -0
  16. package/dist/commands/project-init.js.map +1 -0
  17. package/dist/commands/remove.d.ts +11 -0
  18. package/dist/commands/remove.js +209 -0
  19. package/dist/commands/remove.js.map +1 -0
  20. package/dist/core/bundles.d.ts +7 -0
  21. package/dist/core/bundles.js +39 -0
  22. package/dist/core/bundles.js.map +1 -0
  23. package/dist/core/capabilities.d.ts +25 -0
  24. package/dist/core/capabilities.js +79 -0
  25. package/dist/core/capabilities.js.map +1 -0
  26. package/dist/core/installer.d.ts +18 -0
  27. package/dist/core/installer.js +114 -0
  28. package/dist/core/installer.js.map +1 -0
  29. package/dist/core/manifest.d.ts +39 -0
  30. package/dist/core/manifest.js +89 -0
  31. package/dist/core/manifest.js.map +1 -0
  32. package/dist/core/scaffolder.d.ts +14 -0
  33. package/dist/core/scaffolder.js +71 -0
  34. package/dist/core/scaffolder.js.map +1 -0
  35. package/dist/core/skills.d.ts +17 -0
  36. package/dist/core/skills.js +89 -0
  37. package/dist/core/skills.js.map +1 -0
  38. package/dist/core/targets.d.ts +9 -0
  39. package/dist/core/targets.js +50 -0
  40. package/dist/core/targets.js.map +1 -0
  41. package/dist/ui/prompts.d.ts +10 -0
  42. package/dist/ui/prompts.js +40 -0
  43. package/dist/ui/prompts.js.map +1 -0
  44. package/package.json +39 -0
  45. package/templates/project-init/.raws/FIGMA-INDEX.md +38 -0
  46. package/templates/project-init/.raws/README.md +37 -0
  47. package/templates/project-init/.raws/SRS.md +73 -0
  48. package/templates/project-init/CLAUDE.md +45 -0
  49. package/templates/project-init/project-config.md +296 -0
@@ -0,0 +1,6 @@
1
+ export type ProjectInitOptions = {
2
+ target?: string;
3
+ yes?: boolean;
4
+ overwrite?: boolean;
5
+ };
6
+ export declare function run(opts?: ProjectInitOptions): Promise<void>;
@@ -0,0 +1,63 @@
1
+ // `zsk project-init` — scaffold project-config.md + .raws/ + CLAUDE.md into
2
+ // the current (or given) project directory. Non-destructive by default:
3
+ // existing files are skipped.
4
+ //
5
+ // Similar to Claude Code's /init but project-level (creates project-config.md
6
+ // and .raws/ templates; optionally a CLAUDE.md pointer).
7
+ import pc from "picocolors";
8
+ import { intro, outro, confirm, log, spinner, note } from "../ui/prompts.js";
9
+ import { resolvePath } from "../core/targets.js";
10
+ import { scaffoldTemplate, fileExists } from "../core/scaffolder.js";
11
+ import { join } from "node:path";
12
+ export async function run(opts = {}) {
13
+ const target = opts.target ? resolvePath(opts.target) : process.cwd();
14
+ const interactive = !opts.yes;
15
+ if (interactive) {
16
+ intro(`${pc.bold("zsk")} · 项目 bootstrap`);
17
+ log.info(`目标:${pc.cyan(target)}`);
18
+ }
19
+ const existingConfig = await fileExists(join(target, "project-config.md"));
20
+ const existingRaws = await fileExists(join(target, ".raws"));
21
+ const existingClaude = await fileExists(join(target, "CLAUDE.md"));
22
+ const summaryPre = [
23
+ `project-config.md: ${existingConfig ? pc.yellow("已存在(跳过)") : pc.green("将创建")}`,
24
+ `.raws/: ${existingRaws ? pc.yellow("已存在(跳过内部文件)") : pc.green("将创建")}`,
25
+ `CLAUDE.md: ${existingClaude ? pc.yellow("已存在(跳过)") : pc.green("将创建")}`,
26
+ ].join("\n");
27
+ if (interactive) {
28
+ note(summaryPre, "计划");
29
+ const proceed = await confirm("继续?", true);
30
+ if (!proceed) {
31
+ outro("bye");
32
+ return;
33
+ }
34
+ }
35
+ const s = interactive ? spinner() : null;
36
+ s?.start("scaffold 项目文件");
37
+ const result = await scaffoldTemplate("project-init", target, {
38
+ overwrite: Boolean(opts.overwrite),
39
+ });
40
+ s?.stop("scaffold 完成");
41
+ const summary = [
42
+ `✓ 写入 ${result.written.length} 文件`,
43
+ result.skipped.length > 0 ? `○ 跳过 ${result.skipped.length} 既存` : "",
44
+ ]
45
+ .filter(Boolean)
46
+ .join("\n");
47
+ const nextSteps = [
48
+ "",
49
+ `${pc.bold("下一步:")}`,
50
+ `1. 编辑 ${pc.cyan("project-config.md")},把 frontmatter 中的 ${pc.yellow("<fill-me>")} 填完`,
51
+ `2. 填 ${pc.cyan(".raws/SRS.md")} 与 ${pc.cyan(".raws/FIGMA-INDEX.md")}(或按需删除)`,
52
+ `3. 跑 ${pc.cyan("npx @captain_z/zsk add")} 选 bundle 安装 skill`,
53
+ ].join("\n");
54
+ if (interactive) {
55
+ note(summary + nextSteps, "bootstrap 摘要");
56
+ outro("完成");
57
+ }
58
+ else {
59
+ console.log(`\n${summary}`);
60
+ console.log(nextSteps);
61
+ }
62
+ }
63
+ //# sourceMappingURL=project-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-init.js","sourceRoot":"","sources":["../../src/commands/project-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type RemoveOptions = {
2
+ target?: string;
3
+ yes?: boolean;
4
+ skill?: string[];
5
+ command?: string[];
6
+ agent?: string[];
7
+ hook?: string[];
8
+ mcpServer?: string[];
9
+ prompt?: string[];
10
+ };
11
+ export declare function run(positional: string[], opts: RemoveOptions, zskVersion: string): Promise<void>;
@@ -0,0 +1,209 @@
1
+ // `zsk remove` — multi-select removal of zsk-installed skills.
2
+ //
3
+ // ARCHITECTURE.md §6.4.2:
4
+ // - Target list filtered to directories with a manifest (avoids foot-guns).
5
+ // - Multi-select groupMultiselect by domain; hand-modified files marked `⚠️ 手改`.
6
+ // - Hand-modified files are backed up before deletion.
7
+ // - Hard confirm step (--yes required for CI; even then, flags must be complete).
8
+ import pc from "picocolors";
9
+ import { rm, mkdir, rename } from "node:fs/promises";
10
+ import { dirname, join } from "node:path";
11
+ import { intro, outro, select, groupMultiselect, confirm, log, spinner, note, } from "../ui/prompts.js";
12
+ import { TARGET_OPTIONS, resolvePath } from "../core/targets.js";
13
+ import { loadSkill, DOMAINS } from "../core/skills.js";
14
+ import { readManifest, writeManifest, buildManifest, detectDrift, } from "../core/manifest.js";
15
+ import { expandCapabilityFilters, } from "../core/capabilities.js";
16
+ export async function run(positional, opts, zskVersion) {
17
+ intro(`${pc.bold("zsk")} · remove`);
18
+ const isTTY = Boolean(process.stdout.isTTY);
19
+ const nonInteractive = Boolean(opts.yes) && Boolean(opts.target) && positional.length + (opts.skill?.length ?? 0) > 0;
20
+ if (!isTTY && !nonInteractive) {
21
+ log.error("非 TTY 环境需完整 flags:--target + 至少一个 pattern/--skill + --yes");
22
+ outro("bye");
23
+ process.exit(1);
24
+ }
25
+ // Step 1 — target (flag preloads)
26
+ const targetPath = await selectTarget(opts);
27
+ const manifest = await readManifest(targetPath);
28
+ if (!manifest) {
29
+ log.error(`${targetPath} 不是 zsk 管理目录(缺 zsk-manifest.json)`);
30
+ outro(`运行 ${pc.cyan("zsk list")} 查看已管理目录`);
31
+ process.exit(1);
32
+ }
33
+ const drift = await detectDrift(targetPath, manifest);
34
+ const installedNames = manifest.skills.map((s) => s.name);
35
+ // Step 2 — pick skills (patterns → skip multiselect; else interactive)
36
+ const patterns = [
37
+ ...positional,
38
+ ...(opts.skill ?? []),
39
+ ];
40
+ let toRemove;
41
+ if (patterns.length > 0) {
42
+ toRemove = expandCapabilityFilters(patterns, installedNames);
43
+ if (toRemove.length === 0) {
44
+ log.error(`未匹配到已装 skill:${patterns.join(", ")}`);
45
+ outro("bye");
46
+ process.exit(1);
47
+ }
48
+ }
49
+ else {
50
+ toRemove = await pickRemovals(manifest, drift);
51
+ }
52
+ if (toRemove.length === 0) {
53
+ log.warn("未选任何 skill,退出。");
54
+ outro("bye");
55
+ return;
56
+ }
57
+ // Step 3 — hard confirm (destructive)
58
+ const confirmed = await confirmRemoval(toRemove, drift, targetPath, opts);
59
+ if (!confirmed) {
60
+ outro("已取消");
61
+ return;
62
+ }
63
+ // Step 4 — execute (backup hand-modified, then delete)
64
+ const s = spinner();
65
+ s.start(`移除 ${toRemove.length} skill`);
66
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
67
+ const backupDir = join(targetPath, ".zsk-backup", timestamp);
68
+ const removed = [];
69
+ const backedUp = [];
70
+ const errors = [];
71
+ try {
72
+ const toRemoveSet = new Set(toRemove);
73
+ const modifiedSet = new Set(drift.filter((d) => d.kind === "modified").map((d) => d.name));
74
+ for (const name of toRemove) {
75
+ const record = manifest.skills.find((r) => r.name === name);
76
+ if (!record)
77
+ continue;
78
+ const abs = join(targetPath, record.relPath);
79
+ try {
80
+ if (modifiedSet.has(name)) {
81
+ const backupPath = join(backupDir, record.relPath);
82
+ await mkdir(dirname(backupPath), { recursive: true });
83
+ await rename(abs, backupPath);
84
+ backedUp.push(backupPath);
85
+ }
86
+ else {
87
+ await rm(abs, { force: true });
88
+ }
89
+ // clean up empty parent dir (zsk-<slug>/)
90
+ const parent = dirname(abs);
91
+ await rm(parent, { recursive: true, force: true }).catch(() => { });
92
+ removed.push(name);
93
+ }
94
+ catch (err) {
95
+ errors.push({
96
+ skill: name,
97
+ message: err instanceof Error ? err.message : String(err),
98
+ });
99
+ }
100
+ }
101
+ // Update manifest (remove entries) or delete it entirely if empty
102
+ const remaining = manifest.skills.filter((r) => !toRemoveSet.has(r.name));
103
+ if (remaining.length === 0) {
104
+ await rm(join(targetPath, "zsk-manifest.json"), { force: true });
105
+ }
106
+ else {
107
+ await writeManifest(targetPath, buildManifest({
108
+ zskVersion,
109
+ bundle: manifest.bundle,
110
+ skills: remaining,
111
+ }));
112
+ }
113
+ s.stop("移除完成");
114
+ }
115
+ catch (err) {
116
+ s.stop("移除失败");
117
+ throw err;
118
+ }
119
+ const summary = [
120
+ `✓ ${removed.length} skill 已删除`,
121
+ backedUp.length > 0 ? `↶ 备份 ${backedUp.length} 文件 → ${backupDir}` : "",
122
+ errors.length > 0 ? `✗ ${errors.length} 错误` : "",
123
+ `✓ manifest 已更新(${manifest.skills.length} → ${manifest.skills.length - removed.length})`,
124
+ ]
125
+ .filter(Boolean)
126
+ .join("\n");
127
+ note(summary, "移除摘要");
128
+ if (errors.length > 0) {
129
+ for (const err of errors)
130
+ log.error(`${err.skill}: ${err.message}`);
131
+ }
132
+ outro("完成");
133
+ }
134
+ // ---- helpers ----------------------------------------------------------------
135
+ async function selectTarget(opts) {
136
+ if (opts.target)
137
+ return resolvePath(opts.target);
138
+ const candidates = await Promise.all(TARGET_OPTIONS.filter((t) => t.kind !== "custom").map(async (t) => {
139
+ const path = t.resolve();
140
+ const manifest = await readManifest(path).catch(() => null);
141
+ if (!manifest)
142
+ return null;
143
+ const drift = await detectDrift(path, manifest);
144
+ const modified = drift.filter((d) => d.kind === "modified").length;
145
+ const hint = [
146
+ manifest.bundle ?? "custom",
147
+ `${manifest.skills.length} 颗`,
148
+ modified > 0 ? pc.yellow(`${modified} 手改`) : "",
149
+ ]
150
+ .filter(Boolean)
151
+ .join(" · ");
152
+ return {
153
+ kind: t.kind,
154
+ label: t.label,
155
+ hint,
156
+ path,
157
+ };
158
+ }));
159
+ const managed = candidates.filter((c) => c !== null);
160
+ if (managed.length === 0) {
161
+ log.error("没有 zsk 管理的目录(未找到 zsk-manifest.json)");
162
+ outro(`先跑 ${pc.cyan("zsk add")} 或 ${pc.cyan("zsk list")}`);
163
+ process.exit(1);
164
+ }
165
+ const kind = await select("从哪里移除?", managed.map((c) => ({
166
+ value: c.kind,
167
+ label: `${c.label.padEnd(24)} ${pc.dim(c.hint)}`,
168
+ })));
169
+ return managed.find((c) => c.kind === kind).path;
170
+ }
171
+ async function pickRemovals(manifest, drift) {
172
+ const modifiedSet = new Set(drift.filter((d) => d.kind === "modified").map((d) => d.name));
173
+ const grouped = {};
174
+ for (const d of DOMAINS)
175
+ grouped[d] = [];
176
+ for (const s of manifest.skills) {
177
+ const marker = modifiedSet.has(s.name) ? pc.yellow(" ⚠️ 手改") : "";
178
+ try {
179
+ const meta = await loadSkill(s.name);
180
+ grouped[meta.domain].push({
181
+ value: s.name,
182
+ label: `${s.name}${marker}`,
183
+ });
184
+ }
185
+ catch {
186
+ (grouped.unknown ??= []).push({
187
+ value: s.name,
188
+ label: `${s.name}${marker} (unknown domain)`,
189
+ });
190
+ }
191
+ }
192
+ for (const k of Object.keys(grouped)) {
193
+ if (grouped[k].length === 0)
194
+ delete grouped[k];
195
+ }
196
+ return groupMultiselect("选择要移除的 skill(Space 切换 · a 全选 · A 全不选 · Enter 确认)", grouped, []);
197
+ }
198
+ async function confirmRemoval(names, drift, targetPath, opts) {
199
+ const modifiedSet = new Set(drift.filter((d) => d.kind === "modified").map((d) => d.name));
200
+ const lines = names.map((n) => {
201
+ const mark = modifiedSet.has(n) ? pc.yellow(" · 手改 → 备份") : "";
202
+ return `· ${n}${mark}`;
203
+ });
204
+ note(lines.join("\n"), `将从 ${targetPath} 移除 ${names.length} 颗`);
205
+ if (opts.yes)
206
+ return true;
207
+ return confirm("确认移除?", false);
208
+ }
209
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,0BAA0B;AAC1B,8EAA8E;AAC9E,mFAAmF;AACnF,yDAAyD;AACzD,oFAAoF;AAEpF,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,KAAK,EACL,KAAK,EACL,MAAM,EACN,gBAAgB,EAChB,OAAO,EACP,GAAG,EACH,OAAO,EACP,IAAI,GACL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,GAGZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,GAExB,MAAM,yBAAyB,CAAC;AAajC,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,UAAoB,EACpB,IAAmB,EACnB,UAAkB;IAElB,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAEjG,IAAI,CAAC,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CACP,2DAA2D,CAC5D,CAAC;QACF,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kCAAkC;IAClC,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,GAAG,CAAC,KAAK,CAAC,GAAG,UAAU,mCAAmC,CAAC,CAAC;QAC5D,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE1D,uEAAuE;IACvE,MAAM,QAAQ,GAAG;QACf,GAAG,UAAU;QACb,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;KACtB,CAAC;IACF,IAAI,QAAkB,CAAC;IAEvB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjD,KAAK,CAAC,KAAK,CAAC,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3B,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,sCAAsC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAC1E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,uDAAuD;IACvD,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC;IAEvC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAA8C,EAAE,CAAC;IAE7D,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC9D,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC5D,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;oBACnD,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACtD,MAAM,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;oBAC9B,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACjC,CAAC;gBACD,0CAA0C;gBAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,IAAI;oBACX,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1E,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,aAAa,CACjB,UAAU,EACV,aAAa,CAAC;gBACZ,UAAU;gBACV,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,MAAM,EAAE,SAAS;aAClB,CAAC,CACH,CAAC;QACJ,CAAC;QAED,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG;QACd,KAAK,OAAO,CAAC,MAAM,YAAY;QAC/B,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,MAAM,SAAS,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;QACtE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE;QAChD,kBAAkB,QAAQ,CAAC,MAAM,CAAC,MAAM,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG;KACzF;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEtB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,MAAM;YAAE,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,gFAAgF;AAEhF,KAAK,UAAU,YAAY,CAAC,IAAmB;IAC7C,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAChE,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,IAAI,GAAG;YACX,QAAQ,CAAC,MAAM,IAAI,QAAQ;YAC3B,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI;YAC7B,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SAChD;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI;YACJ,IAAI;SACL,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAC/B,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,IAAI,CAC9C,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACjD,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,MAAM,CACvB,QAAQ,EACR,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClB,KAAK,EAAE,CAAC,CAAC,IAAI;QACb,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;KACjD,CAAC,CAAC,CACJ,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAE,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,QAAkB,EAClB,KAAmB;IAEnB,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC9D,CAAC;IACF,MAAM,OAAO,GAA4D,EAAE,CAAC;IAC5E,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAEzC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAE,CAAC,IAAI,CAAC;gBACzB,KAAK,EAAE,CAAC,CAAC,IAAI;gBACb,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,MAAM,EAAE;aAC5B,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,CAAC,OAAO,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;gBAC5B,KAAK,EAAE,CAAC,CAAC,IAAI;gBACb,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,MAAM,mBAAmB;aAC7C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,CAAC,CAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,gBAAgB,CACrB,kDAAkD,EAClD,OAAO,EACP,EAAE,CACH,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,KAAe,EACf,KAAmB,EACnB,UAAkB,EAClB,IAAmB;IAEnB,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC9D,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,OAAO,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,UAAU,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAEhE,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type Bundle = {
2
+ label: string;
3
+ hint: string;
4
+ skills: string[];
5
+ };
6
+ export type Bundles = Record<string, Bundle>;
7
+ export declare function loadBundles(): Promise<Bundles>;
@@ -0,0 +1,39 @@
1
+ // Load bundles.yaml from @captain_z/zsk-skills.
2
+ //
3
+ // Dev (monorepo via tsx/pnpm workspace): resolves sibling packages/skills/bundles.yaml.
4
+ // Production (installed from npm): resolves via the package's "exports" map.
5
+ import { readFile } from "node:fs/promises";
6
+ import { dirname, resolve } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { createRequire } from "node:module";
9
+ import { parse as parseYaml } from "yaml";
10
+ export async function loadBundles() {
11
+ const path = await resolveBundlesPath();
12
+ const raw = await readFile(path, "utf8");
13
+ const parsed = parseYaml(raw);
14
+ if (!parsed?.bundles) {
15
+ throw new Error(`bundles.yaml is missing the "bundles" root key: ${path}`);
16
+ }
17
+ return parsed.bundles;
18
+ }
19
+ async function resolveBundlesPath() {
20
+ // Dev (monorepo): packages/cli/src/core/bundles.ts → packages/skills/bundles.yaml
21
+ const thisDir = dirname(fileURLToPath(import.meta.url));
22
+ const devPath = resolve(thisDir, "../../../skills/bundles.yaml");
23
+ try {
24
+ await readFile(devPath);
25
+ return devPath;
26
+ }
27
+ catch {
28
+ // fall through
29
+ }
30
+ // Production: resolve via the skills package export
31
+ const require = createRequire(import.meta.url);
32
+ try {
33
+ return require.resolve("@captain_z/zsk-skills/bundles.yaml");
34
+ }
35
+ catch {
36
+ throw new Error("Could not locate bundles.yaml in @captain_z/zsk-skills (is it installed?)");
37
+ }
38
+ }
39
+ //# sourceMappingURL=bundles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundles.js","sourceRoot":"","sources":["../../src/core/bundles.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,wFAAwF;AACxF,6EAA6E;AAE7E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAU1C,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,IAAI,GAAG,MAAM,kBAAkB,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAA0B,CAAC;IACvD,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,kFAAkF;IAClF,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,oDAAoD;IACpD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ export type CapabilityType = "skill" | "command" | "agent" | "hook" | "mcp-server" | "prompt";
2
+ export declare const CAPABILITY_TYPES: readonly CapabilityType[];
3
+ export type CapabilityFilters = Partial<Record<CapabilityType, string[]>>;
4
+ export declare function hasCapabilityFilter(filters: CapabilityFilters): boolean;
5
+ /**
6
+ * Collect commander-style repeated option values into string[].
7
+ * Commander passes `string | string[] | undefined` depending on how many times
8
+ * a flag is seen; normalize to always-an-array.
9
+ */
10
+ export declare function collectValues(v: string | string[] | undefined): string[];
11
+ /**
12
+ * Expand capability filters against a candidate pool.
13
+ * `'*'` matches all; exact names (e.g. `zsk:spec`) match by equality;
14
+ * globs (e.g. `zsk:a11y-*`) convert to regex.
15
+ *
16
+ * Returns a de-duplicated, sorted list of names that matched at least one
17
+ * filter pattern.
18
+ */
19
+ export declare function expandCapabilityFilters(patterns: string[], pool: string[]): string[];
20
+ /**
21
+ * Decide whether a positional `<pattern>` arg is a bundle name, a skill
22
+ * identifier (`zsk:xxx`), or a glob. Used by `add` to route straight to the
23
+ * groupMultiselect step (bundle) or skip both pick screens (skill/glob).
24
+ */
25
+ export declare function classifyPattern(pattern: string, bundleNames: string[]): "bundle" | "skill" | "glob" | "unknown";
@@ -0,0 +1,79 @@
1
+ // Capability-type flags: --skill / --command / --agent / --hook / --mcp-server / --prompt.
2
+ // Each value may be `'*'` (all of that type), an exact name, or a glob.
3
+ // MVP: only `skill` resolves to real content; other capability types are
4
+ // grammar-complete but currently expand to an empty set (see ARCHITECTURE §3).
5
+ export const CAPABILITY_TYPES = [
6
+ "skill",
7
+ "command",
8
+ "agent",
9
+ "hook",
10
+ "mcp-server",
11
+ "prompt",
12
+ ];
13
+ export function hasCapabilityFilter(filters) {
14
+ return CAPABILITY_TYPES.some((t) => (filters[t]?.length ?? 0) > 0);
15
+ }
16
+ /**
17
+ * Collect commander-style repeated option values into string[].
18
+ * Commander passes `string | string[] | undefined` depending on how many times
19
+ * a flag is seen; normalize to always-an-array.
20
+ */
21
+ export function collectValues(v) {
22
+ if (v === undefined)
23
+ return [];
24
+ return Array.isArray(v) ? v : [v];
25
+ }
26
+ /**
27
+ * Expand capability filters against a candidate pool.
28
+ * `'*'` matches all; exact names (e.g. `zsk:spec`) match by equality;
29
+ * globs (e.g. `zsk:a11y-*`) convert to regex.
30
+ *
31
+ * Returns a de-duplicated, sorted list of names that matched at least one
32
+ * filter pattern.
33
+ */
34
+ export function expandCapabilityFilters(patterns, pool) {
35
+ if (patterns.length === 0)
36
+ return [];
37
+ const hit = new Set();
38
+ for (const pat of patterns) {
39
+ if (pat === "*") {
40
+ for (const p of pool)
41
+ hit.add(p);
42
+ continue;
43
+ }
44
+ if (hasGlobChar(pat)) {
45
+ const re = globToRegex(pat);
46
+ for (const p of pool)
47
+ if (re.test(p))
48
+ hit.add(p);
49
+ continue;
50
+ }
51
+ if (pool.includes(pat))
52
+ hit.add(pat);
53
+ }
54
+ return [...hit].sort();
55
+ }
56
+ function hasGlobChar(s) {
57
+ return s.includes("*") || s.includes("?");
58
+ }
59
+ function globToRegex(glob) {
60
+ // Minimal glob: `*` → `.*`, `?` → `.`, other regex metachars escaped.
61
+ const escaped = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&");
62
+ const pattern = escaped.replace(/\*/g, ".*").replace(/\?/g, ".");
63
+ return new RegExp(`^${pattern}$`);
64
+ }
65
+ /**
66
+ * Decide whether a positional `<pattern>` arg is a bundle name, a skill
67
+ * identifier (`zsk:xxx`), or a glob. Used by `add` to route straight to the
68
+ * groupMultiselect step (bundle) or skip both pick screens (skill/glob).
69
+ */
70
+ export function classifyPattern(pattern, bundleNames) {
71
+ if (hasGlobChar(pattern))
72
+ return "glob";
73
+ if (bundleNames.includes(pattern))
74
+ return "bundle";
75
+ if (pattern.startsWith("zsk:"))
76
+ return "skill";
77
+ return "unknown";
78
+ }
79
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/core/capabilities.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,wEAAwE;AACxE,yEAAyE;AACzE,+EAA+E;AAU/E,MAAM,CAAC,MAAM,gBAAgB,GAA8B;IACzD,OAAO;IACP,SAAS;IACT,OAAO;IACP,MAAM;IACN,YAAY;IACZ,QAAQ;CACA,CAAC;AAIX,MAAM,UAAU,mBAAmB,CAAC,OAA0B;IAC5D,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,CAAgC;IAC5D,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAkB,EAClB,IAAc;IAEd,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YAChB,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC5B,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;oBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjD,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,sEAAsE;IACtE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjE,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,WAAqB;IAErB,IAAI,WAAW,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IACxC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAC;IACnD,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/C,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type ConflictMode = "skip" | "overwrite" | "backup";
2
+ export type InstallPlan = {
3
+ skills: string[];
4
+ target: string;
5
+ onConflict: ConflictMode;
6
+ dryRun: boolean;
7
+ };
8
+ export type InstallResult = {
9
+ written: string[];
10
+ skipped: string[];
11
+ backedUp: string[];
12
+ errors: Array<{
13
+ skill: string;
14
+ message: string;
15
+ }>;
16
+ backupDir: string | null;
17
+ };
18
+ export declare function install(plan: InstallPlan): Promise<InstallResult>;
@@ -0,0 +1,114 @@
1
+ // Install engine: staging → rename + conflict resolution + backup.
2
+ import { mkdir, copyFile, rm, rename, readdir, access, } from "node:fs/promises";
3
+ import { dirname, join, relative } from "node:path";
4
+ import { loadSkill } from "./skills.js";
5
+ export async function install(plan) {
6
+ const result = {
7
+ written: [],
8
+ skipped: [],
9
+ backedUp: [],
10
+ errors: [],
11
+ backupDir: null,
12
+ };
13
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
14
+ const stagingDir = join(plan.target, `.zsk-staging-${timestamp}`);
15
+ const backupDir = join(plan.target, ".zsk-backup", timestamp);
16
+ // Dry-run: enumerate target paths and return without touching disk
17
+ if (plan.dryRun) {
18
+ for (const skillName of plan.skills) {
19
+ try {
20
+ const skill = await loadSkill(skillName);
21
+ const dst = skillTargetPath(plan.target, skill);
22
+ result.written.push(dst);
23
+ }
24
+ catch (err) {
25
+ result.errors.push({
26
+ skill: skillName,
27
+ message: err instanceof Error ? err.message : String(err),
28
+ });
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ try {
34
+ await mkdir(plan.target, { recursive: true });
35
+ await mkdir(stagingDir, { recursive: true });
36
+ // Stage all skills
37
+ for (const skillName of plan.skills) {
38
+ try {
39
+ const skill = await loadSkill(skillName);
40
+ const stagingDst = skillTargetPath(stagingDir, skill);
41
+ await mkdir(dirname(stagingDst), { recursive: true });
42
+ await copyFile(skill.file, stagingDst);
43
+ }
44
+ catch (err) {
45
+ result.errors.push({
46
+ skill: skillName,
47
+ message: err instanceof Error ? err.message : String(err),
48
+ });
49
+ }
50
+ }
51
+ // Commit staging → target, handling conflicts per skill file
52
+ await commitStaging(stagingDir, plan.target, plan.onConflict, backupDir, result);
53
+ }
54
+ finally {
55
+ await rm(stagingDir, { recursive: true, force: true });
56
+ }
57
+ return result;
58
+ }
59
+ function skillTargetPath(root, skill) {
60
+ // Flat layout: <target>/zsk-<slug>/SKILL.md
61
+ // Claude / Codex scan `<root>/<dir>/SKILL.md` one level deep; nested
62
+ // <domain>/<slug>/ would be skipped. `zsk-` prefix namespaces against
63
+ // existing flat skills (archive / coding / design / reviewing etc).
64
+ return join(root, `zsk-${skill.slug}`, "SKILL.md");
65
+ }
66
+ async function commitStaging(stagingDir, target, onConflict, backupDir, result) {
67
+ const files = await walk(stagingDir);
68
+ for (const src of files) {
69
+ const rel = relative(stagingDir, src);
70
+ const dst = join(target, rel);
71
+ const exists = await fileExists(dst);
72
+ if (exists) {
73
+ if (onConflict === "skip") {
74
+ result.skipped.push(dst);
75
+ continue;
76
+ }
77
+ if (onConflict === "backup") {
78
+ const backupPath = join(backupDir, rel);
79
+ await mkdir(dirname(backupPath), { recursive: true });
80
+ await rename(dst, backupPath);
81
+ result.backedUp.push(backupPath);
82
+ result.backupDir = backupDir;
83
+ }
84
+ // overwrite: fall through
85
+ }
86
+ await mkdir(dirname(dst), { recursive: true });
87
+ await copyFile(src, dst);
88
+ result.written.push(dst);
89
+ }
90
+ }
91
+ async function fileExists(p) {
92
+ try {
93
+ await access(p);
94
+ return true;
95
+ }
96
+ catch {
97
+ return false;
98
+ }
99
+ }
100
+ async function walk(dir) {
101
+ const out = [];
102
+ const entries = await readdir(dir, { withFileTypes: true });
103
+ for (const e of entries) {
104
+ const p = join(dir, e.name);
105
+ if (e.isDirectory()) {
106
+ out.push(...(await walk(p)));
107
+ }
108
+ else {
109
+ out.push(p);
110
+ }
111
+ }
112
+ return out;
113
+ }
114
+ //# sourceMappingURL=installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"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"}