@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.
- package/README.md +147 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +155 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/add.d.ts +13 -0
- package/dist/commands/add.js +418 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +127 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.d.ts +7 -0
- package/dist/commands/install.js +54 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/project-init.d.ts +6 -0
- package/dist/commands/project-init.js +63 -0
- package/dist/commands/project-init.js.map +1 -0
- package/dist/commands/remove.d.ts +11 -0
- package/dist/commands/remove.js +209 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/core/bundles.d.ts +7 -0
- package/dist/core/bundles.js +39 -0
- package/dist/core/bundles.js.map +1 -0
- package/dist/core/capabilities.d.ts +25 -0
- package/dist/core/capabilities.js +79 -0
- package/dist/core/capabilities.js.map +1 -0
- package/dist/core/installer.d.ts +18 -0
- package/dist/core/installer.js +114 -0
- package/dist/core/installer.js.map +1 -0
- package/dist/core/manifest.d.ts +39 -0
- package/dist/core/manifest.js +89 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/scaffolder.d.ts +14 -0
- package/dist/core/scaffolder.js +71 -0
- package/dist/core/scaffolder.js.map +1 -0
- package/dist/core/skills.d.ts +17 -0
- package/dist/core/skills.js +89 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/targets.d.ts +9 -0
- package/dist/core/targets.js +50 -0
- package/dist/core/targets.js.map +1 -0
- package/dist/ui/prompts.d.ts +10 -0
- package/dist/ui/prompts.js +40 -0
- package/dist/ui/prompts.js.map +1 -0
- package/package.json +39 -0
- package/templates/project-init/.raws/FIGMA-INDEX.md +38 -0
- package/templates/project-init/.raws/README.md +37 -0
- package/templates/project-init/.raws/SRS.md +73 -0
- package/templates/project-init/CLAUDE.md +45 -0
- package/templates/project-init/project-config.md +296 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
// `zsk add` — adaptive install wizard.
|
|
2
|
+
//
|
|
3
|
+
// ARCHITECTURE.md §6.4:
|
|
4
|
+
// - Target-first; pre-check manifest to label each target in the prompt.
|
|
5
|
+
// - Branch A (installed): refresh / append / exit + refresh scope.
|
|
6
|
+
// - Branch B (empty): preset bundle vs cherry-pick → groupMultiselect by domain.
|
|
7
|
+
// - Flag preloading skips the corresponding clack step.
|
|
8
|
+
// - Writes zsk-manifest.json on success so future runs can branch correctly.
|
|
9
|
+
import pc from "picocolors";
|
|
10
|
+
import { readFile, access } from "node:fs/promises";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { intro, outro, select, groupMultiselect, text, confirm, log, spinner, note, } from "../ui/prompts.js";
|
|
13
|
+
import { loadBundles } from "../core/bundles.js";
|
|
14
|
+
import { enumerateSkills, loadSkill, DOMAINS, } from "../core/skills.js";
|
|
15
|
+
import { TARGET_OPTIONS, resolvePath, } from "../core/targets.js";
|
|
16
|
+
import { install } from "../core/installer.js";
|
|
17
|
+
import { fileExists } from "../core/scaffolder.js";
|
|
18
|
+
import { readManifest, writeManifest, buildManifest, detectDrift, sha256File, } from "../core/manifest.js";
|
|
19
|
+
import { expandCapabilityFilters, classifyPattern, hasCapabilityFilter, } from "../core/capabilities.js";
|
|
20
|
+
export async function run(positional, opts, zskVersion) {
|
|
21
|
+
intro(`${pc.bold("zsk")} · add`);
|
|
22
|
+
const isTTY = Boolean(process.stdout.isTTY);
|
|
23
|
+
// Non-TTY gate: `--yes` + `--target` mandatory. Source (positional / capability
|
|
24
|
+
// flag) only required when the target is empty; refresh path infers sources
|
|
25
|
+
// from the existing manifest.
|
|
26
|
+
if (!isTTY) {
|
|
27
|
+
if (!opts.yes) {
|
|
28
|
+
log.error("非 TTY 环境必须加 --yes");
|
|
29
|
+
outro("bye");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
if (!opts.target) {
|
|
33
|
+
log.error("非 TTY 环境必须加 --target");
|
|
34
|
+
outro("bye");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const probeTarget = resolvePath(opts.target);
|
|
38
|
+
const probeManifest = await readManifest(probeTarget).catch(() => null);
|
|
39
|
+
const hasSource = hasAnySource(positional, opts);
|
|
40
|
+
if (!probeManifest && !hasSource) {
|
|
41
|
+
log.error("非 TTY 环境 · 新装 target 需要 pattern(bundle 名 / zsk:<slug> / glob)或能力 flag(如 --skill='*')");
|
|
42
|
+
outro("bye");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Step 0 — offer project-init when project-config.md missing (interactive only)
|
|
47
|
+
if (isTTY && !opts.yes) {
|
|
48
|
+
await maybeOfferProjectInit();
|
|
49
|
+
}
|
|
50
|
+
// Step 1 — target (flag preloads)
|
|
51
|
+
const bundles = await loadBundles();
|
|
52
|
+
const targetPath = await selectTarget(opts, bundles);
|
|
53
|
+
// Step 2 — read manifest → branch A vs B
|
|
54
|
+
const manifest = await readManifest(targetPath);
|
|
55
|
+
const drift = manifest ? await detectDrift(targetPath, manifest) : [];
|
|
56
|
+
const filters = capabilityFiltersFromOptions(opts);
|
|
57
|
+
const allSkills = await enumerateSkills();
|
|
58
|
+
const allSkillNames = allSkills.map((s) => s.name);
|
|
59
|
+
// Resolve positional into bundle or skill pattern (if any)
|
|
60
|
+
const bundleFromArg = positional.find((p) => classifyPattern(p, Object.keys(bundles)) === "bundle");
|
|
61
|
+
const skillPatternsFromArgs = positional.filter((p) => classifyPattern(p, Object.keys(bundles)) !== "bundle");
|
|
62
|
+
let pickedSkills = [];
|
|
63
|
+
let chosenBundle = null;
|
|
64
|
+
let mode = "new";
|
|
65
|
+
const hasExplicitPicks = positional.length > 0 || hasCapabilityFilter(filters);
|
|
66
|
+
if (manifest) {
|
|
67
|
+
// Explicit pattern/filter → user wants to install/reinstall those specific
|
|
68
|
+
// skills, not a blanket refresh. Treat as append against the full pool
|
|
69
|
+
// (existing entries merge + conflict policy takes over per-file).
|
|
70
|
+
const action = hasExplicitPicks
|
|
71
|
+
? "append"
|
|
72
|
+
: await askExistingAction(manifest, drift, opts);
|
|
73
|
+
if (action === "exit") {
|
|
74
|
+
outro("取消");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (action === "refresh") {
|
|
78
|
+
mode = "refresh";
|
|
79
|
+
pickedSkills = await askRefreshScope(manifest, drift, opts);
|
|
80
|
+
chosenBundle = manifest.bundle;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
mode = "append";
|
|
84
|
+
const picked = await pickSkills({
|
|
85
|
+
bundles,
|
|
86
|
+
availableSkills: allSkillNames,
|
|
87
|
+
allSkills,
|
|
88
|
+
bundleFromArg,
|
|
89
|
+
skillPatternsFromArgs,
|
|
90
|
+
filters,
|
|
91
|
+
opts,
|
|
92
|
+
});
|
|
93
|
+
pickedSkills = picked.skills;
|
|
94
|
+
chosenBundle = picked.bundle ?? manifest.bundle;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
mode = "new";
|
|
99
|
+
const picked = await pickSkills({
|
|
100
|
+
bundles,
|
|
101
|
+
availableSkills: allSkillNames,
|
|
102
|
+
allSkills,
|
|
103
|
+
bundleFromArg,
|
|
104
|
+
skillPatternsFromArgs,
|
|
105
|
+
filters,
|
|
106
|
+
opts,
|
|
107
|
+
});
|
|
108
|
+
pickedSkills = picked.skills;
|
|
109
|
+
chosenBundle = picked.bundle;
|
|
110
|
+
}
|
|
111
|
+
if (pickedSkills.length === 0) {
|
|
112
|
+
log.warn("未选任何 skill,退出。");
|
|
113
|
+
outro("bye");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Step 3 — conflict policy (flag preloads; refresh + drift defaults to backup)
|
|
117
|
+
const onConflict = await askConflict(opts, mode);
|
|
118
|
+
const dryRun = Boolean(opts.dryRun);
|
|
119
|
+
// Step 4 — dry-run preview short-circuit
|
|
120
|
+
if (dryRun) {
|
|
121
|
+
const lines = pickedSkills.map((n) => ` + ${n}`).join("\n");
|
|
122
|
+
note(`[dry-run] 将写入 ${pickedSkills.length} 个 skill → ${pc.cyan(targetPath)}\n${lines}`, "预览");
|
|
123
|
+
outro("完成 (dry-run)");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Step 5 — execute install
|
|
127
|
+
const s = spinner();
|
|
128
|
+
s.start(`${mode === "refresh" ? "刷新" : "安装"} ${pickedSkills.length} skill → ${targetPath}`);
|
|
129
|
+
let result;
|
|
130
|
+
try {
|
|
131
|
+
result = await install({
|
|
132
|
+
skills: pickedSkills,
|
|
133
|
+
target: targetPath,
|
|
134
|
+
onConflict,
|
|
135
|
+
dryRun: false,
|
|
136
|
+
});
|
|
137
|
+
s.stop(mode === "refresh" ? "刷新完成" : "安装完成");
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
s.stop("失败");
|
|
141
|
+
throw err;
|
|
142
|
+
}
|
|
143
|
+
// Step 6 — update manifest (merge with existing for append mode)
|
|
144
|
+
const records = await buildRecords(pickedSkills, targetPath, zskVersion);
|
|
145
|
+
const mergedSkills = mergeSkillRecords(mode === "append" ? manifest?.skills ?? [] : [], records);
|
|
146
|
+
await writeManifest(targetPath, buildManifest({
|
|
147
|
+
zskVersion,
|
|
148
|
+
bundle: chosenBundle,
|
|
149
|
+
skills: mergedSkills,
|
|
150
|
+
}));
|
|
151
|
+
// Step 7 — summary
|
|
152
|
+
const summary = [
|
|
153
|
+
`✓ 写入 ${result.written.length} 文件`,
|
|
154
|
+
result.skipped.length > 0 ? `○ 跳过 ${result.skipped.length} 既存` : "",
|
|
155
|
+
result.backedUp.length > 0
|
|
156
|
+
? `↶ 备份 ${result.backedUp.length} 文件 → ${result.backupDir}`
|
|
157
|
+
: "",
|
|
158
|
+
result.errors.length > 0 ? `✗ ${result.errors.length} 错误` : "",
|
|
159
|
+
`✓ zsk-manifest.json 已更新(${mergedSkills.length} skill)`,
|
|
160
|
+
]
|
|
161
|
+
.filter(Boolean)
|
|
162
|
+
.join("\n");
|
|
163
|
+
note(summary, mode === "refresh" ? "刷新摘要" : "安装摘要");
|
|
164
|
+
if (result.errors.length > 0) {
|
|
165
|
+
for (const err of result.errors)
|
|
166
|
+
log.error(`${err.skill}: ${err.message}`);
|
|
167
|
+
}
|
|
168
|
+
outro(`完成 · 运行 ${pc.cyan("zsk doctor")} 校验`);
|
|
169
|
+
}
|
|
170
|
+
// ---- helpers ----------------------------------------------------------------
|
|
171
|
+
function hasAnySource(positional, opts) {
|
|
172
|
+
return (positional.length > 0 ||
|
|
173
|
+
Boolean(opts.skill?.length) ||
|
|
174
|
+
Boolean(opts.command?.length) ||
|
|
175
|
+
Boolean(opts.agent?.length) ||
|
|
176
|
+
Boolean(opts.hook?.length) ||
|
|
177
|
+
Boolean(opts.mcpServer?.length) ||
|
|
178
|
+
Boolean(opts.prompt?.length));
|
|
179
|
+
}
|
|
180
|
+
function capabilityFiltersFromOptions(opts) {
|
|
181
|
+
return {
|
|
182
|
+
skill: opts.skill ?? [],
|
|
183
|
+
command: opts.command ?? [],
|
|
184
|
+
agent: opts.agent ?? [],
|
|
185
|
+
hook: opts.hook ?? [],
|
|
186
|
+
"mcp-server": opts.mcpServer ?? [],
|
|
187
|
+
prompt: opts.prompt ?? [],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async function maybeOfferProjectInit() {
|
|
191
|
+
const cwd = process.cwd();
|
|
192
|
+
const has = await fileExists(join(cwd, "project-config.md"));
|
|
193
|
+
if (has)
|
|
194
|
+
return;
|
|
195
|
+
log.warn(`当前目录缺 ${pc.cyan("project-config.md")}(skill 的 ${pc.yellow("{{config.*}}")} 解析源)`);
|
|
196
|
+
const wantsBootstrap = await confirm("先跑 zsk project-init 创建 project-config.md + .raws/ + CLAUDE.md?", true);
|
|
197
|
+
if (wantsBootstrap) {
|
|
198
|
+
const { run: runProjectInit } = await import("./project-init.js");
|
|
199
|
+
await runProjectInit({ target: cwd, yes: true });
|
|
200
|
+
log.step("项目 bootstrap 完成,继续 skill 安装…");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function selectTarget(opts, bundles) {
|
|
204
|
+
if (opts.target)
|
|
205
|
+
return resolvePath(opts.target);
|
|
206
|
+
// pre-check each preset for manifest status to show in the label
|
|
207
|
+
const precheck = await Promise.all(TARGET_OPTIONS.map(async (t) => {
|
|
208
|
+
if (t.kind === "custom")
|
|
209
|
+
return { kind: t.kind, hint: t.hint };
|
|
210
|
+
const path = t.resolve();
|
|
211
|
+
const manifest = await readManifest(path).catch(() => null);
|
|
212
|
+
if (manifest) {
|
|
213
|
+
const bLabel = manifest.bundle
|
|
214
|
+
? `${manifest.bundle} v${manifest.zskVersion}`
|
|
215
|
+
: `custom v${manifest.zskVersion}`;
|
|
216
|
+
return {
|
|
217
|
+
kind: t.kind,
|
|
218
|
+
hint: `${t.hint} · 已装 ${manifest.skills.length} 颗 ${bLabel}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const exists = await directoryNonEmpty(path);
|
|
222
|
+
return {
|
|
223
|
+
kind: t.kind,
|
|
224
|
+
hint: exists ? `${t.hint} · 目录存在(非 zsk 管理)` : `${t.hint} · 空`,
|
|
225
|
+
};
|
|
226
|
+
}));
|
|
227
|
+
const targetKind = await select("装到哪里?", TARGET_OPTIONS.map((t, i) => ({
|
|
228
|
+
value: t.kind,
|
|
229
|
+
label: `${t.label.padEnd(24)} ${pc.dim(precheck[i]?.hint ?? t.hint)}`,
|
|
230
|
+
})));
|
|
231
|
+
if (targetKind === "custom") {
|
|
232
|
+
const input = await text("自定义路径(支持 ~ / 相对 / 绝对)", {
|
|
233
|
+
placeholder: "./zsk-skills",
|
|
234
|
+
validate: (v) => (v.trim().length === 0 ? "路径不能为空" : undefined),
|
|
235
|
+
});
|
|
236
|
+
return resolvePath(input);
|
|
237
|
+
}
|
|
238
|
+
const opt = TARGET_OPTIONS.find((t) => t.kind === targetKind);
|
|
239
|
+
if (!opt)
|
|
240
|
+
throw new Error(`unknown target kind: ${targetKind}`);
|
|
241
|
+
return opt.resolve();
|
|
242
|
+
}
|
|
243
|
+
async function askExistingAction(manifest, drift, opts) {
|
|
244
|
+
const modifiedCount = drift.filter((d) => d.kind === "modified").length;
|
|
245
|
+
const missingCount = drift.filter((d) => d.kind === "missing").length;
|
|
246
|
+
if (opts.yes)
|
|
247
|
+
return "refresh"; // --yes defaults to refresh per §6.4.3
|
|
248
|
+
const label = [
|
|
249
|
+
`${pc.cyan(manifest.bundle ?? "custom")} v${manifest.zskVersion}`,
|
|
250
|
+
`· 已装 ${manifest.skills.length}`,
|
|
251
|
+
modifiedCount > 0 ? pc.yellow(`· 手改 ${modifiedCount}`) : "",
|
|
252
|
+
missingCount > 0 ? pc.yellow(`· 缺失 ${missingCount}`) : "",
|
|
253
|
+
]
|
|
254
|
+
.filter(Boolean)
|
|
255
|
+
.join(" ");
|
|
256
|
+
log.info(`当前状态:${label}`);
|
|
257
|
+
return select("接下来?", [
|
|
258
|
+
{ value: "refresh", label: "刷新到最新(按 manifest 重装)" },
|
|
259
|
+
{ value: "append", label: "追加其他 skill" },
|
|
260
|
+
{ value: "exit", label: "退出" },
|
|
261
|
+
], "refresh");
|
|
262
|
+
}
|
|
263
|
+
async function askRefreshScope(manifest, drift, opts) {
|
|
264
|
+
const modifiedNames = new Set(drift.filter((d) => d.kind === "modified").map((d) => d.name));
|
|
265
|
+
if (opts.yes) {
|
|
266
|
+
// --yes → skip hand-modified files by default
|
|
267
|
+
return manifest.skills.map((s) => s.name).filter((n) => !modifiedNames.has(n));
|
|
268
|
+
}
|
|
269
|
+
if (modifiedNames.size === 0) {
|
|
270
|
+
return manifest.skills.map((s) => s.name);
|
|
271
|
+
}
|
|
272
|
+
const scope = await select(`更新范围(${modifiedNames.size} 个手改文件)`, [
|
|
273
|
+
{
|
|
274
|
+
value: "all-official",
|
|
275
|
+
label: `全部官方变更(跳过 ${modifiedNames.size} 手改)`,
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
value: "force",
|
|
279
|
+
label: `含手改的强刷(先备份)`,
|
|
280
|
+
},
|
|
281
|
+
], "all-official");
|
|
282
|
+
if (scope === "force")
|
|
283
|
+
return manifest.skills.map((s) => s.name);
|
|
284
|
+
return manifest.skills.map((s) => s.name).filter((n) => !modifiedNames.has(n));
|
|
285
|
+
}
|
|
286
|
+
async function pickSkills(args) {
|
|
287
|
+
const { bundles, availableSkills, allSkills, bundleFromArg, skillPatternsFromArgs, filters, opts } = args;
|
|
288
|
+
// Priority 1 — capability filters (--skill='*' / --skill='zsk:spec' / glob)
|
|
289
|
+
const filterMatched = expandCapabilityFilters(filters.skill ?? [], availableSkills);
|
|
290
|
+
if (filterMatched.length > 0 || Object.values(filters).some((v) => v?.length)) {
|
|
291
|
+
// if any capability filter is present, pattern-only (no clack step).
|
|
292
|
+
// Non-skill filters currently resolve to empty sets (see §3).
|
|
293
|
+
return { skills: filterMatched, bundle: null };
|
|
294
|
+
}
|
|
295
|
+
// Priority 2 — positional skill/glob patterns
|
|
296
|
+
if (skillPatternsFromArgs.length > 0) {
|
|
297
|
+
const matched = expandCapabilityFilters(skillPatternsFromArgs, availableSkills);
|
|
298
|
+
if (matched.length === 0) {
|
|
299
|
+
log.error(`未匹配到任何 skill:${skillPatternsFromArgs.join(", ")}`);
|
|
300
|
+
return { skills: [], bundle: null };
|
|
301
|
+
}
|
|
302
|
+
return { skills: matched, bundle: null };
|
|
303
|
+
}
|
|
304
|
+
// Priority 3 — positional bundle
|
|
305
|
+
if (bundleFromArg) {
|
|
306
|
+
const bundle = bundles[bundleFromArg];
|
|
307
|
+
if (!bundle)
|
|
308
|
+
return { skills: [], bundle: null };
|
|
309
|
+
const pool = bundleToAvailable(bundle, availableSkills);
|
|
310
|
+
const selected = opts.yes
|
|
311
|
+
? pool
|
|
312
|
+
: await groupMultiselect(`本次要装的 skill(${pool.length}/${bundle.skills.length})`, await groupByDomain(pool), pool);
|
|
313
|
+
return { skills: selected, bundle: bundleFromArg };
|
|
314
|
+
}
|
|
315
|
+
// Priority 4 — interactive two-level pick
|
|
316
|
+
return interactiveTwoLevelPick(bundles, availableSkills, allSkills);
|
|
317
|
+
}
|
|
318
|
+
function bundleToAvailable(bundle, available) {
|
|
319
|
+
const set = new Set(available);
|
|
320
|
+
return bundle.skills.filter((s) => set.has(s));
|
|
321
|
+
}
|
|
322
|
+
async function interactiveTwoLevelPick(bundles, availableSkills, allSkills) {
|
|
323
|
+
// Level 1 — preset bundle vs cherry-pick
|
|
324
|
+
const presetEntries = Object.entries(bundles).filter(([, b]) => b.skills.length > 0);
|
|
325
|
+
const level1 = await select("装什么?", [
|
|
326
|
+
...presetEntries.map(([name, b]) => ({
|
|
327
|
+
value: name,
|
|
328
|
+
label: `${pc.cyan(name.padEnd(32))} ${pc.dim(`${b.skills.length} · ${b.hint}`)}`,
|
|
329
|
+
})),
|
|
330
|
+
{
|
|
331
|
+
value: "__cherry__",
|
|
332
|
+
label: `${pc.cyan("挑单颗 / 几颗 skill".padEnd(32))} ${pc.dim(`按领域分组浏览 ${availableSkills.length} 颗`)}`,
|
|
333
|
+
},
|
|
334
|
+
], presetEntries.find(([n]) => n === "frontend-project")?.[0] ?? presetEntries[0]?.[0]);
|
|
335
|
+
if (level1 === "__cherry__") {
|
|
336
|
+
const selected = await groupMultiselect("本次要装的 skill(Space 切换 · a 全选 · A 全不选 · Enter 确认)", await groupByDomain(availableSkills), []);
|
|
337
|
+
return { skills: selected, bundle: null };
|
|
338
|
+
}
|
|
339
|
+
// preset bundle chosen → defaults prefilled
|
|
340
|
+
const bundle = bundles[level1];
|
|
341
|
+
if (!bundle)
|
|
342
|
+
return { skills: [], bundle: null };
|
|
343
|
+
const pool = bundleToAvailable(bundle, availableSkills);
|
|
344
|
+
const selected = await groupMultiselect(`本次要装的 skill(默认全选;可取消个别)`, await groupByDomain(pool), pool);
|
|
345
|
+
return { skills: selected, bundle: level1 };
|
|
346
|
+
}
|
|
347
|
+
async function groupByDomain(skillNames) {
|
|
348
|
+
const groups = {};
|
|
349
|
+
for (const domain of DOMAINS)
|
|
350
|
+
groups[domain] = [];
|
|
351
|
+
for (const name of skillNames) {
|
|
352
|
+
try {
|
|
353
|
+
const s = await loadSkill(name);
|
|
354
|
+
groups[s.domain].push({ value: name, label: name });
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
(groups.missing ??= []).push({ value: name, label: `${name} (missing)` });
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// drop empty domains so the prompt isn't cluttered
|
|
361
|
+
for (const k of Object.keys(groups)) {
|
|
362
|
+
if (groups[k].length === 0)
|
|
363
|
+
delete groups[k];
|
|
364
|
+
}
|
|
365
|
+
return groups;
|
|
366
|
+
}
|
|
367
|
+
async function askConflict(opts, mode) {
|
|
368
|
+
if (isConflictMode(opts.onConflict))
|
|
369
|
+
return opts.onConflict;
|
|
370
|
+
if (opts.yes)
|
|
371
|
+
return mode === "refresh" ? "backup" : "backup";
|
|
372
|
+
return select("冲突策略(默认备份后覆盖)", [
|
|
373
|
+
{ value: "backup", label: "备份后覆盖(推荐)" },
|
|
374
|
+
{ value: "skip", label: "跳过冲突" },
|
|
375
|
+
{ value: "overwrite", label: "直接覆盖(危险)" },
|
|
376
|
+
], "backup");
|
|
377
|
+
}
|
|
378
|
+
function isConflictMode(v) {
|
|
379
|
+
return v === "skip" || v === "overwrite" || v === "backup";
|
|
380
|
+
}
|
|
381
|
+
async function buildRecords(skillNames, targetPath, zskVersion) {
|
|
382
|
+
const out = [];
|
|
383
|
+
for (const name of skillNames) {
|
|
384
|
+
try {
|
|
385
|
+
const skill = await loadSkill(name);
|
|
386
|
+
const relPath = `zsk-${skill.slug}/SKILL.md`;
|
|
387
|
+
const buf = await readFile(join(targetPath, relPath));
|
|
388
|
+
out.push({
|
|
389
|
+
name,
|
|
390
|
+
version: zskVersion,
|
|
391
|
+
sha256: sha256File(buf),
|
|
392
|
+
relPath,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
// file wasn't actually written (conflict=skip); omit from manifest
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return out;
|
|
400
|
+
}
|
|
401
|
+
function mergeSkillRecords(existing, fresh) {
|
|
402
|
+
const map = new Map();
|
|
403
|
+
for (const e of existing)
|
|
404
|
+
map.set(e.name, e);
|
|
405
|
+
for (const f of fresh)
|
|
406
|
+
map.set(f.name, f); // fresh wins
|
|
407
|
+
return [...map.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
408
|
+
}
|
|
409
|
+
async function directoryNonEmpty(p) {
|
|
410
|
+
try {
|
|
411
|
+
await access(p);
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(): Promise<void>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Interactive install wizard · ARCHITECTURE.md §6.4 Steps 0-5.
|
|
2
|
+
// If project-config.md is missing in cwd, offer `zsk project-init` first.
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { intro, outro, select, groupMultiselect, text, confirm, log, spinner, note, } from "../ui/prompts.js";
|
|
6
|
+
import { loadBundles } from "../core/bundles.js";
|
|
7
|
+
import { loadSkill } from "../core/skills.js";
|
|
8
|
+
import { TARGET_OPTIONS, resolvePath } from "../core/targets.js";
|
|
9
|
+
import { install } from "../core/installer.js";
|
|
10
|
+
import { fileExists } from "../core/scaffolder.js";
|
|
11
|
+
export async function run() {
|
|
12
|
+
intro(`${pc.bold("zsk")} · ZNorth Standard Kit`);
|
|
13
|
+
// Step 0 — detect project-config; offer bootstrap if missing
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
const hasProjectConfig = await fileExists(join(cwd, "project-config.md"));
|
|
16
|
+
if (!hasProjectConfig) {
|
|
17
|
+
log.warn(`当前目录缺 ${pc.cyan("project-config.md")}(skill 的 ${pc.yellow("{{config.*}}")} 解析源)`);
|
|
18
|
+
const wantsBootstrap = await confirm("先跑 zsk:project-init 创建 project-config.md + .raws/ + CLAUDE.md?", true);
|
|
19
|
+
if (wantsBootstrap) {
|
|
20
|
+
const { run: runProjectInit } = await import("./project-init.js");
|
|
21
|
+
await runProjectInit({ target: cwd, yes: true });
|
|
22
|
+
log.step(`项目 bootstrap 完成,继续 skill 安装…`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Step 1 — bundle
|
|
26
|
+
const bundles = await loadBundles();
|
|
27
|
+
const bundleName = await select("你在建什么?", Object.entries(bundles).map(([name, b]) => {
|
|
28
|
+
const count = b.skills.length === 0 ? "交互自选" : `${b.skills.length} skills`;
|
|
29
|
+
return {
|
|
30
|
+
value: name,
|
|
31
|
+
label: `${pc.cyan(name.padEnd(32))} ${pc.dim(count.padEnd(14))} ${b.hint}`,
|
|
32
|
+
};
|
|
33
|
+
}));
|
|
34
|
+
// Step 2 — skills (trim from bundle; or pick from all if custom)
|
|
35
|
+
const bundle = bundles[bundleName];
|
|
36
|
+
if (!bundle) {
|
|
37
|
+
log.error(`Unknown bundle: ${bundleName}`);
|
|
38
|
+
outro("bye");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const picksPool = bundle.skills.length > 0
|
|
42
|
+
? bundle.skills
|
|
43
|
+
: Array.from(new Set(Object.values(bundles).flatMap((b) => b.skills)));
|
|
44
|
+
const grouped = await groupByDomain(picksPool);
|
|
45
|
+
const selectedSkills = await groupMultiselect("本次要装的 skill(Space 切换,Enter 确认)", grouped, bundle.skills);
|
|
46
|
+
if (selectedSkills.length === 0) {
|
|
47
|
+
log.warn("未选任何 skill,退出。");
|
|
48
|
+
outro("bye");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Step 3 — target
|
|
52
|
+
const targetKind = await select("写到哪里?", TARGET_OPTIONS.map((t) => ({
|
|
53
|
+
value: t.kind,
|
|
54
|
+
label: `${t.label.padEnd(32)} ${pc.dim(t.hint)}`,
|
|
55
|
+
})));
|
|
56
|
+
let targetPath;
|
|
57
|
+
if (targetKind === "custom") {
|
|
58
|
+
const input = await text("自定义路径(支持 ~ / 相对 / 绝对)", {
|
|
59
|
+
placeholder: "./zsk-skills",
|
|
60
|
+
validate: (v) => (v.trim().length === 0 ? "路径不能为空" : undefined),
|
|
61
|
+
});
|
|
62
|
+
targetPath = resolvePath(input);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const opt = TARGET_OPTIONS.find((t) => t.kind === targetKind);
|
|
66
|
+
if (!opt)
|
|
67
|
+
throw new Error(`unknown target kind: ${targetKind}`);
|
|
68
|
+
targetPath = opt.resolve();
|
|
69
|
+
}
|
|
70
|
+
// Step 4 — conflict policy (bulk for MVP; per-file future)
|
|
71
|
+
const onConflict = await select("遇到同名文件如何处理?", [
|
|
72
|
+
{ value: "backup", label: "备份后覆盖(推荐)" },
|
|
73
|
+
{ value: "skip", label: "跳过冲突" },
|
|
74
|
+
{ value: "overwrite", label: "直接覆盖" },
|
|
75
|
+
], "backup");
|
|
76
|
+
// Step 5 — execute
|
|
77
|
+
const s = spinner();
|
|
78
|
+
s.start(`安装 ${selectedSkills.length} skill → ${targetPath}`);
|
|
79
|
+
try {
|
|
80
|
+
const result = await install({
|
|
81
|
+
skills: selectedSkills,
|
|
82
|
+
target: targetPath,
|
|
83
|
+
onConflict,
|
|
84
|
+
dryRun: false,
|
|
85
|
+
});
|
|
86
|
+
s.stop("安装完成");
|
|
87
|
+
const summary = [
|
|
88
|
+
`✓ 写入 ${result.written.length} 文件`,
|
|
89
|
+
result.skipped.length > 0 ? `○ 跳过 ${result.skipped.length} 既存` : "",
|
|
90
|
+
result.backedUp.length > 0
|
|
91
|
+
? `↶ 备份 ${result.backedUp.length} 文件 → ${result.backupDir}`
|
|
92
|
+
: "",
|
|
93
|
+
result.errors.length > 0 ? `✗ ${result.errors.length} 错误` : "",
|
|
94
|
+
]
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.join("\n");
|
|
97
|
+
note(summary, "装机摘要");
|
|
98
|
+
if (result.errors.length > 0) {
|
|
99
|
+
for (const err of result.errors) {
|
|
100
|
+
log.error(`${err.skill}: ${err.message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
s.stop("安装失败");
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
outro(`完成 · 运行 ${pc.cyan("zsk doctor")} 校验`);
|
|
109
|
+
}
|
|
110
|
+
async function groupByDomain(skillNames) {
|
|
111
|
+
const groups = {};
|
|
112
|
+
for (const name of skillNames) {
|
|
113
|
+
try {
|
|
114
|
+
const skill = await loadSkill(name);
|
|
115
|
+
const existing = groups[skill.domain] ?? [];
|
|
116
|
+
existing.push({ value: name, label: name });
|
|
117
|
+
groups[skill.domain] = existing;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
const existing = groups.missing ?? [];
|
|
121
|
+
existing.push({ value: name, label: `${name} (missing)` });
|
|
122
|
+
groups.missing = existing;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return groups;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Non-interactive install · flags-only, CI friendly.
|
|
2
|
+
import { loadBundles } from "../core/bundles.js";
|
|
3
|
+
import { resolvePath } from "../core/targets.js";
|
|
4
|
+
import { install } from "../core/installer.js";
|
|
5
|
+
export async function run(opts) {
|
|
6
|
+
if (!opts.bundle) {
|
|
7
|
+
console.error("Error: --bundle is required for non-interactive install");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
if (!opts.target) {
|
|
11
|
+
console.error("Error: --target is required for non-interactive install");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const bundles = await loadBundles();
|
|
15
|
+
const bundle = bundles[opts.bundle];
|
|
16
|
+
if (!bundle) {
|
|
17
|
+
console.error(`Error: unknown bundle "${opts.bundle}"`);
|
|
18
|
+
console.error(`Available: ${Object.keys(bundles).join(", ")}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const onConflict = isConflictMode(opts.onConflict)
|
|
22
|
+
? opts.onConflict
|
|
23
|
+
: "skip";
|
|
24
|
+
const target = resolvePath(opts.target);
|
|
25
|
+
const dryRun = Boolean(opts.dryRun);
|
|
26
|
+
if (dryRun) {
|
|
27
|
+
console.log(`[dry-run] would install ${bundle.skills.length} skill(s) to ${target}`);
|
|
28
|
+
}
|
|
29
|
+
const result = await install({
|
|
30
|
+
skills: bundle.skills,
|
|
31
|
+
target,
|
|
32
|
+
onConflict,
|
|
33
|
+
dryRun,
|
|
34
|
+
});
|
|
35
|
+
if (dryRun) {
|
|
36
|
+
for (const w of result.written)
|
|
37
|
+
console.log(` + ${w}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(`\n✓ wrote ${result.written.length}, skipped ${result.skipped.length}, backed up ${result.backedUp.length}, errors ${result.errors.length}`);
|
|
41
|
+
if (result.backupDir) {
|
|
42
|
+
console.log(` backup directory: ${result.backupDir}`);
|
|
43
|
+
}
|
|
44
|
+
if (result.errors.length > 0) {
|
|
45
|
+
for (const err of result.errors) {
|
|
46
|
+
console.error(` ✗ ${err.skill}: ${err.message}`);
|
|
47
|
+
}
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function isConflictMode(v) {
|
|
52
|
+
return v === "skip" || v === "overwrite" || v === "backup";
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|