@shortwind/cli 0.1.0-beta.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/dist/bench-a_9WmuOE.js +1836 -0
- package/dist/bench-a_9WmuOE.js.map +1 -0
- package/dist/bin.js +267 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +374 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/package.json +41 -0
package/dist/bin.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { _ as add, a as formatFindingsText, b as init, c as UpgradeError, d as BuildError, f as build, g as remove, h as preset, l as upgrade, m as ls, n as formatBenchTable, o as lint, p as formatLsText, r as ALL_RULES, s as verify, t as bench, u as dev, y as DEFAULT_REGISTRY } from "./bench-a_9WmuOE.js";
|
|
3
|
+
import * as p from "@clack/prompts";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import { cac } from "cac";
|
|
6
|
+
//#region src/cli.ts
|
|
7
|
+
const KNOWN_PRESETS = [
|
|
8
|
+
"starter",
|
|
9
|
+
"app",
|
|
10
|
+
"content",
|
|
11
|
+
"all",
|
|
12
|
+
"none"
|
|
13
|
+
];
|
|
14
|
+
async function run(argv = process.argv) {
|
|
15
|
+
const cli = cac("shortwind");
|
|
16
|
+
cli.command("init", "Bootstrap Shortwind in this project").option("--preset <name>", "Preset to install (starter|app|content|all|none)").option("--registry <url>", "Registry origin", { default: DEFAULT_REGISTRY }).option("--cwd <dir>", "Working directory", { default: process.cwd() }).action(async (opts) => {
|
|
17
|
+
const preset = opts.preset ?? await promptForPreset();
|
|
18
|
+
const options = {
|
|
19
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
20
|
+
preset
|
|
21
|
+
};
|
|
22
|
+
if (opts.registry !== void 0) options.registry = opts.registry;
|
|
23
|
+
printInitSummary(await init(options));
|
|
24
|
+
});
|
|
25
|
+
cli.command("add <...families>", "Install one or more families").option("--as <name>", "Rename the family on install (requires a single family)").option("--all", "Install every family in the registry").option("--force", "Overwrite existing files").option("--registry <url>", "Registry origin").option("--cwd <dir>", "Working directory").action(async (families, opts) => {
|
|
26
|
+
const addOptions = {
|
|
27
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
28
|
+
families
|
|
29
|
+
};
|
|
30
|
+
if (opts.as !== void 0) addOptions.as = opts.as;
|
|
31
|
+
if (opts.all) addOptions.all = true;
|
|
32
|
+
if (opts.force) addOptions.force = true;
|
|
33
|
+
if (opts.registry !== void 0) addOptions.registry = opts.registry;
|
|
34
|
+
const result = await add(addOptions);
|
|
35
|
+
for (const fam of result.added) p.log.success(`added ${fam}`);
|
|
36
|
+
for (const fam of result.overwritten) p.log.success(`overwrote ${fam}`);
|
|
37
|
+
for (const fam of result.skipped) p.log.warn(`${fam} already exists (use --force)`);
|
|
38
|
+
for (const missing of result.missingDependencies) p.log.warn(`${missing.family} references unknown recipes: ${missing.references.join(", ")}`);
|
|
39
|
+
});
|
|
40
|
+
cli.command("remove <...families>", "Remove installed families").option("--cwd <dir>", "Working directory").action(async (families, opts) => {
|
|
41
|
+
const result = await remove({
|
|
42
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
43
|
+
families
|
|
44
|
+
});
|
|
45
|
+
for (const fam of result.removed) p.log.success(`removed ${fam}`);
|
|
46
|
+
for (const fam of result.notFound) p.log.warn(`${fam} is not installed`);
|
|
47
|
+
for (const broken of result.brokenDependents) p.log.warn(`${broken.dependent} references removed recipes: ${broken.references.join(", ")}`);
|
|
48
|
+
});
|
|
49
|
+
cli.command("preset <name>", "Install every family in the named preset (additive)").option("--registry <url>", "Registry origin").option("--cwd <dir>", "Working directory").action(async (name, opts) => {
|
|
50
|
+
const presetOptions = {
|
|
51
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
52
|
+
name
|
|
53
|
+
};
|
|
54
|
+
if (opts.registry !== void 0) presetOptions.registry = opts.registry;
|
|
55
|
+
const result = await preset(presetOptions);
|
|
56
|
+
p.log.info(`preset ${name}: ${result.added.length} added, ${result.skipped.length} already present`);
|
|
57
|
+
});
|
|
58
|
+
cli.command("ls", "List installed and available families").option("--installed", "Only installed").option("--available", "Only available").option("--json", "Emit JSON").option("--registry <url>", "Registry origin").option("--cwd <dir>", "Working directory").action(async (opts) => {
|
|
59
|
+
const lsOptions = { cwd: opts.cwd ?? process.cwd() };
|
|
60
|
+
if (opts.installed) lsOptions.installedOnly = true;
|
|
61
|
+
if (opts.available) lsOptions.availableOnly = true;
|
|
62
|
+
if (opts.registry !== void 0) lsOptions.registry = opts.registry;
|
|
63
|
+
const result = await ls(lsOptions);
|
|
64
|
+
if (opts.json) process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
65
|
+
else process.stdout.write(formatLsText(result) + "\n");
|
|
66
|
+
});
|
|
67
|
+
cli.command("build", "Regenerate SKILL.md from ./recipes/").option("--cwd <dir>", "Working directory").action(async (opts) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = await build({ cwd: opts.cwd ?? process.cwd() });
|
|
70
|
+
if (result.changed) p.log.success(`regenerated ${result.families.length} families`);
|
|
71
|
+
else p.log.info(`up to date (${result.families.length} families)`);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
if (err instanceof BuildError) {
|
|
74
|
+
process.stderr.write(err.message + "\n");
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
cli.command("dev", "Watch ./recipes/ and regenerate SKILL.md on change").option("--cwd <dir>", "Working directory").option("--once", "Run build once and exit").action(async (opts) => {
|
|
81
|
+
if (opts.once) {
|
|
82
|
+
try {
|
|
83
|
+
await build({ cwd: opts.cwd ?? process.cwd() });
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (err instanceof BuildError) {
|
|
86
|
+
process.stderr.write(err.message + "\n");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const controller = new AbortController();
|
|
94
|
+
const onSigint = () => controller.abort();
|
|
95
|
+
process.on("SIGINT", onSigint);
|
|
96
|
+
try {
|
|
97
|
+
const { stop } = await dev({
|
|
98
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
99
|
+
signal: controller.signal,
|
|
100
|
+
onStatus: (status) => {
|
|
101
|
+
if (status.kind === "rebuilt") {
|
|
102
|
+
const msg = `✓ regenerated ${status.families.length} families${status.changed ? "" : " (no changes)"}`;
|
|
103
|
+
process.stdout.write(msg + "\n");
|
|
104
|
+
} else if (status.kind === "ready") process.stdout.write(`watching ${status.recipesDir}\n`);
|
|
105
|
+
else process.stderr.write(status.message + "\n");
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
await new Promise((resolve) => {
|
|
109
|
+
if (controller.signal.aborted) resolve();
|
|
110
|
+
else controller.signal.addEventListener("abort", () => resolve(), { once: true });
|
|
111
|
+
});
|
|
112
|
+
await stop();
|
|
113
|
+
} finally {
|
|
114
|
+
process.off("SIGINT", onSigint);
|
|
115
|
+
}
|
|
116
|
+
process.exit(0);
|
|
117
|
+
});
|
|
118
|
+
cli.command("upgrade [...families]", "Pull registry updates into ./recipes").option("--check", "Read-only — print drift summary and exit nonzero on updates").option("--force", "Skip touched-detection; overwrite local edits").option("--registry <url>", "Registry origin").option("--cwd <dir>", "Working directory").action(async (families, opts) => {
|
|
119
|
+
try {
|
|
120
|
+
const upgradeOptions = {
|
|
121
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
122
|
+
families
|
|
123
|
+
};
|
|
124
|
+
if (opts.check) upgradeOptions.check = true;
|
|
125
|
+
if (opts.force) upgradeOptions.force = true;
|
|
126
|
+
if (opts.registry !== void 0) upgradeOptions.registry = opts.registry;
|
|
127
|
+
if (!opts.check && !opts.force) upgradeOptions.resolver = makeInteractiveResolver();
|
|
128
|
+
const result = await upgrade(upgradeOptions);
|
|
129
|
+
printUpgradeSummary(result.outcomes);
|
|
130
|
+
if (opts.check) {
|
|
131
|
+
if (result.hasUpdates || result.hasTouched) process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err instanceof UpgradeError) {
|
|
135
|
+
process.stderr.write(err.message + "\n");
|
|
136
|
+
process.exit(2);
|
|
137
|
+
}
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
cli.command("verify", "Check installed recipes against fingerprint headers and lockfile").option("--cwd <dir>", "Working directory").action(async (opts) => {
|
|
142
|
+
const result = await verify({ cwd: opts.cwd ?? process.cwd() });
|
|
143
|
+
if (result.ok) {
|
|
144
|
+
p.log.success(`verified ${result.checked.length} families`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const issue of result.issues) {
|
|
148
|
+
const desc = describeVerifyIssue(issue);
|
|
149
|
+
process.stderr.write(`${issue.family}: ${desc}\n`);
|
|
150
|
+
}
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
153
|
+
cli.command("lint", "Static analysis over source files and recipes").option("--fix", "Apply auto-fixes where supported").option("--rule <rule>", "Only run the named rule (repeatable)").option("--json", "Emit machine-readable JSON").option("--cwd <dir>", "Working directory").action(async (opts) => {
|
|
154
|
+
const requested = opts.rule === void 0 ? [] : Array.isArray(opts.rule) ? opts.rule : [opts.rule];
|
|
155
|
+
for (const r of requested) if (!ALL_RULES.includes(r)) {
|
|
156
|
+
process.stderr.write(`unknown rule: ${r}\n`);
|
|
157
|
+
process.stderr.write(`available: ${ALL_RULES.join(", ")}\n`);
|
|
158
|
+
process.exit(2);
|
|
159
|
+
}
|
|
160
|
+
const lintOptions = { cwd: opts.cwd ?? process.cwd() };
|
|
161
|
+
if (opts.fix) lintOptions.fix = true;
|
|
162
|
+
if (requested.length > 0) lintOptions.rules = requested;
|
|
163
|
+
const result = await lint(lintOptions);
|
|
164
|
+
if (opts.json) process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
165
|
+
else {
|
|
166
|
+
const text = formatFindingsText(result.findings);
|
|
167
|
+
if (text) process.stdout.write(text + "\n");
|
|
168
|
+
for (const f of result.filesFixed) p.log.success(`fixed ${f}`);
|
|
169
|
+
if (result.findings.length === 0) p.log.success("no findings");
|
|
170
|
+
}
|
|
171
|
+
if (!result.ok) process.exit(1);
|
|
172
|
+
});
|
|
173
|
+
cli.command("bench [path]", "Benchmark token savings in a corpus or target directory").option("--corpus", "Run benchmark on the built-in corpus").option("--json", "Emit machine-readable JSON").option("--cwd <dir>", "Working directory").action(async (pathArg, opts) => {
|
|
174
|
+
const benchOptions = { cwd: opts.cwd ?? process.cwd() };
|
|
175
|
+
if (opts.corpus) benchOptions.corpus = true;
|
|
176
|
+
if (opts.json) benchOptions.json = true;
|
|
177
|
+
if (pathArg !== void 0) benchOptions.path = pathArg;
|
|
178
|
+
const result = await bench(benchOptions);
|
|
179
|
+
if (opts.json) process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
180
|
+
else {
|
|
181
|
+
const text = formatBenchTable(result);
|
|
182
|
+
process.stdout.write(text + "\n");
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
cli.help();
|
|
186
|
+
cli.version("0.0.0");
|
|
187
|
+
cli.parse(argv);
|
|
188
|
+
}
|
|
189
|
+
function makeInteractiveResolver() {
|
|
190
|
+
return async (ctx) => {
|
|
191
|
+
process.stdout.write(pc.yellow(`\n${ctx.family}: locally modified — incoming ${ctx.incoming.version}\n`));
|
|
192
|
+
const choice = await p.select({
|
|
193
|
+
message: `Resolve ${ctx.family}`,
|
|
194
|
+
options: [
|
|
195
|
+
{
|
|
196
|
+
value: "accept",
|
|
197
|
+
label: "Accept new (discard local edits)"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
value: "keep",
|
|
201
|
+
label: "Keep yours"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
value: "skip",
|
|
205
|
+
label: "Skip for now"
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
});
|
|
209
|
+
if (p.isCancel(choice)) return "skip";
|
|
210
|
+
return choice;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function printUpgradeSummary(outcomes) {
|
|
214
|
+
for (const o of outcomes) if (o.action === "updated") process.stdout.write(pc.green(`✓ ${o.family} ${o.from} → ${o.to}\n`));
|
|
215
|
+
else if (o.action === "would-update") process.stdout.write(pc.cyan(`→ ${o.family} ${o.from} → ${o.to} (available)\n`));
|
|
216
|
+
else if (o.action === "would-review") process.stdout.write(pc.yellow(`! ${o.family} ${o.from} → ${o.to} (touched; needs review)\n`));
|
|
217
|
+
else if (o.action === "kept" && o.reason === "user-chose-keep") process.stdout.write(pc.dim(` ${o.family} kept local\n`));
|
|
218
|
+
else if (o.action === "skipped") process.stdout.write(pc.dim(` ${o.family} skipped (${o.reason})\n`));
|
|
219
|
+
}
|
|
220
|
+
function describeVerifyIssue(issue) {
|
|
221
|
+
switch (issue.kind) {
|
|
222
|
+
case "missing-header": return "no fingerprint header — recipe was hand-stripped";
|
|
223
|
+
case "header-tampered": return `header sha ${issue.recorded} but body hashes to ${issue.actual}`;
|
|
224
|
+
case "lockfile-mismatch": return `lockfile expects ${issue.locked} but body hashes to ${issue.actual}`;
|
|
225
|
+
case "missing-lock-entry": return "installed but not recorded in lockfile";
|
|
226
|
+
case "missing-file": return "in lockfile but file is missing";
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function promptForPreset() {
|
|
230
|
+
const choice = await p.select({
|
|
231
|
+
message: "Pick a preset",
|
|
232
|
+
options: KNOWN_PRESETS.map((name) => ({
|
|
233
|
+
value: name,
|
|
234
|
+
label: name
|
|
235
|
+
}))
|
|
236
|
+
});
|
|
237
|
+
if (p.isCancel(choice)) {
|
|
238
|
+
p.cancel("Cancelled.");
|
|
239
|
+
process.exit(0);
|
|
240
|
+
}
|
|
241
|
+
return choice;
|
|
242
|
+
}
|
|
243
|
+
function printInitSummary(result) {
|
|
244
|
+
p.note([
|
|
245
|
+
`preset: ${result.preset}`,
|
|
246
|
+
`registry: ${result.registry}`,
|
|
247
|
+
`package manager: ${result.packageManager}`,
|
|
248
|
+
`families copied: ${result.installedFamilies.length}`,
|
|
249
|
+
`families skipped: ${result.skippedFamilies.length}`,
|
|
250
|
+
``,
|
|
251
|
+
`config: ${result.configPath}`,
|
|
252
|
+
`vscode settings: ${result.vscodePath}`,
|
|
253
|
+
`pre-commit: ${result.huskyPath}`,
|
|
254
|
+
`SKILL.md: ${result.skillPath}`
|
|
255
|
+
].join("\n"), "shortwind init");
|
|
256
|
+
p.outro(`Next: run \`${result.packageManager} dev\` to start watching.`);
|
|
257
|
+
}
|
|
258
|
+
//#endregion
|
|
259
|
+
//#region src/bin.ts
|
|
260
|
+
run().catch((err) => {
|
|
261
|
+
console.error(err instanceof Error ? err.stack ?? err.message : err);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
});
|
|
264
|
+
//#endregion
|
|
265
|
+
export {};
|
|
266
|
+
|
|
267
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","names":["runPreset"],"sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { cac } from \"cac\";\nimport { add } from \"./commands/add.js\";\nimport { build, BuildError } from \"./commands/build.js\";\nimport { dev } from \"./commands/dev.js\";\nimport { remove } from \"./commands/remove.js\";\nimport { preset as runPreset } from \"./commands/preset.js\";\nimport { ls, formatLsText } from \"./commands/ls.js\";\nimport {\n upgrade,\n UpgradeError,\n type TouchedContext,\n type UpgradeChoice,\n} from \"./commands/upgrade.js\";\nimport { verify } from \"./commands/verify.js\";\nimport { lint, formatFindingsText, ALL_RULES, type Rule } from \"./commands/lint.js\";\nimport { init, type InitOptions, DEFAULT_REGISTRY } from \"./init.js\";\nimport { bench, formatBenchTable } from \"./commands/bench.js\";\n\nconst KNOWN_PRESETS = [\"starter\", \"app\", \"content\", \"all\", \"none\"];\n\nexport async function run(argv: string[] = process.argv): Promise<void> {\n const cli = cac(\"shortwind\");\n\n cli\n .command(\"init\", \"Bootstrap Shortwind in this project\")\n .option(\"--preset <name>\", \"Preset to install (starter|app|content|all|none)\")\n .option(\"--registry <url>\", \"Registry origin\", { default: DEFAULT_REGISTRY })\n .option(\"--cwd <dir>\", \"Working directory\", { default: process.cwd() })\n .action(async (opts: { preset?: string; registry?: string; cwd?: string }) => {\n const preset = opts.preset ?? (await promptForPreset());\n const options: InitOptions = {\n cwd: opts.cwd ?? process.cwd(),\n preset,\n };\n if (opts.registry !== undefined) options.registry = opts.registry;\n const result = await init(options);\n printInitSummary(result);\n });\n\n cli\n .command(\"add <...families>\", \"Install one or more families\")\n .option(\"--as <name>\", \"Rename the family on install (requires a single family)\")\n .option(\"--all\", \"Install every family in the registry\")\n .option(\"--force\", \"Overwrite existing files\")\n .option(\"--registry <url>\", \"Registry origin\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(\n async (\n families: string[],\n opts: { as?: string; all?: boolean; force?: boolean; registry?: string; cwd?: string },\n ) => {\n const addOptions: Parameters<typeof add>[0] = {\n cwd: opts.cwd ?? process.cwd(),\n families,\n };\n if (opts.as !== undefined) addOptions.as = opts.as;\n if (opts.all) addOptions.all = true;\n if (opts.force) addOptions.force = true;\n if (opts.registry !== undefined) addOptions.registry = opts.registry;\n const result = await add(addOptions);\n for (const fam of result.added) p.log.success(`added ${fam}`);\n for (const fam of result.overwritten) p.log.success(`overwrote ${fam}`);\n for (const fam of result.skipped) p.log.warn(`${fam} already exists (use --force)`);\n for (const missing of result.missingDependencies) {\n p.log.warn(\n `${missing.family} references unknown recipes: ${missing.references.join(\", \")}`,\n );\n }\n },\n );\n\n cli\n .command(\"remove <...families>\", \"Remove installed families\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(async (families: string[], opts: { cwd?: string }) => {\n const result = await remove({ cwd: opts.cwd ?? process.cwd(), families });\n for (const fam of result.removed) p.log.success(`removed ${fam}`);\n for (const fam of result.notFound) p.log.warn(`${fam} is not installed`);\n for (const broken of result.brokenDependents) {\n p.log.warn(\n `${broken.dependent} references removed recipes: ${broken.references.join(\", \")}`,\n );\n }\n });\n\n cli\n .command(\"preset <name>\", \"Install every family in the named preset (additive)\")\n .option(\"--registry <url>\", \"Registry origin\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(async (name: string, opts: { registry?: string; cwd?: string }) => {\n const presetOptions: Parameters<typeof runPreset>[0] = {\n cwd: opts.cwd ?? process.cwd(),\n name,\n };\n if (opts.registry !== undefined) presetOptions.registry = opts.registry;\n const result = await runPreset(presetOptions);\n p.log.info(`preset ${name}: ${result.added.length} added, ${result.skipped.length} already present`);\n });\n\n cli\n .command(\"ls\", \"List installed and available families\")\n .option(\"--installed\", \"Only installed\")\n .option(\"--available\", \"Only available\")\n .option(\"--json\", \"Emit JSON\")\n .option(\"--registry <url>\", \"Registry origin\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(\n async (opts: {\n installed?: boolean;\n available?: boolean;\n json?: boolean;\n registry?: string;\n cwd?: string;\n }) => {\n const lsOptions: Parameters<typeof ls>[0] = {\n cwd: opts.cwd ?? process.cwd(),\n };\n if (opts.installed) lsOptions.installedOnly = true;\n if (opts.available) lsOptions.availableOnly = true;\n if (opts.registry !== undefined) lsOptions.registry = opts.registry;\n const result = await ls(lsOptions);\n if (opts.json) {\n process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n process.stdout.write(formatLsText(result) + \"\\n\");\n }\n },\n );\n\n cli\n .command(\"build\", \"Regenerate SKILL.md from ./recipes/\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(async (opts: { cwd?: string }) => {\n try {\n const result = await build({ cwd: opts.cwd ?? process.cwd() });\n if (result.changed) p.log.success(`regenerated ${result.families.length} families`);\n else p.log.info(`up to date (${result.families.length} families)`);\n } catch (err) {\n if (err instanceof BuildError) {\n process.stderr.write(err.message + \"\\n\");\n process.exit(1);\n }\n throw err;\n }\n });\n\n cli\n .command(\"dev\", \"Watch ./recipes/ and regenerate SKILL.md on change\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .option(\"--once\", \"Run build once and exit\")\n .action(async (opts: { cwd?: string; once?: boolean }) => {\n if (opts.once) {\n try {\n await build({ cwd: opts.cwd ?? process.cwd() });\n } catch (err) {\n if (err instanceof BuildError) {\n process.stderr.write(err.message + \"\\n\");\n process.exit(1);\n }\n throw err;\n }\n return;\n }\n const controller = new AbortController();\n const onSigint = (): void => controller.abort();\n process.on(\"SIGINT\", onSigint);\n try {\n const { stop } = await dev({\n cwd: opts.cwd ?? process.cwd(),\n signal: controller.signal,\n onStatus: (status) => {\n if (status.kind === \"rebuilt\") {\n const msg = `✓ regenerated ${status.families.length} families${status.changed ? \"\" : \" (no changes)\"}`;\n process.stdout.write(msg + \"\\n\");\n } else if (status.kind === \"ready\") {\n process.stdout.write(`watching ${status.recipesDir}\\n`);\n } else {\n process.stderr.write(status.message + \"\\n\");\n }\n },\n });\n // Block until SIGINT (or otherwise aborted), then close the watcher\n // and exit cleanly — without this the listener stays attached and\n // controller.abort() never returns control to the CLI.\n await new Promise<void>((resolve) => {\n if (controller.signal.aborted) resolve();\n else controller.signal.addEventListener(\"abort\", () => resolve(), { once: true });\n });\n await stop();\n } finally {\n process.off(\"SIGINT\", onSigint);\n }\n process.exit(0);\n });\n\n cli\n .command(\"upgrade [...families]\", \"Pull registry updates into ./recipes\")\n .option(\"--check\", \"Read-only — print drift summary and exit nonzero on updates\")\n .option(\"--force\", \"Skip touched-detection; overwrite local edits\")\n .option(\"--registry <url>\", \"Registry origin\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(\n async (\n families: string[],\n opts: { check?: boolean; force?: boolean; registry?: string; cwd?: string },\n ) => {\n try {\n const upgradeOptions: Parameters<typeof upgrade>[0] = {\n cwd: opts.cwd ?? process.cwd(),\n families,\n };\n if (opts.check) upgradeOptions.check = true;\n if (opts.force) upgradeOptions.force = true;\n if (opts.registry !== undefined) upgradeOptions.registry = opts.registry;\n if (!opts.check && !opts.force) {\n upgradeOptions.resolver = makeInteractiveResolver();\n }\n const result = await upgrade(upgradeOptions);\n printUpgradeSummary(result.outcomes);\n if (opts.check) {\n if (result.hasUpdates || result.hasTouched) process.exit(1);\n }\n } catch (err) {\n if (err instanceof UpgradeError) {\n process.stderr.write(err.message + \"\\n\");\n process.exit(2);\n }\n throw err;\n }\n },\n );\n\n cli\n .command(\"verify\", \"Check installed recipes against fingerprint headers and lockfile\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(async (opts: { cwd?: string }) => {\n const result = await verify({ cwd: opts.cwd ?? process.cwd() });\n if (result.ok) {\n p.log.success(`verified ${result.checked.length} families`);\n return;\n }\n for (const issue of result.issues) {\n const desc = describeVerifyIssue(issue);\n process.stderr.write(`${issue.family}: ${desc}\\n`);\n }\n process.exit(1);\n });\n\n cli\n .command(\"lint\", \"Static analysis over source files and recipes\")\n .option(\"--fix\", \"Apply auto-fixes where supported\")\n .option(\"--rule <rule>\", \"Only run the named rule (repeatable)\")\n .option(\"--json\", \"Emit machine-readable JSON\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(\n async (opts: { fix?: boolean; rule?: string | string[]; json?: boolean; cwd?: string }) => {\n const requested = opts.rule === undefined ? [] : Array.isArray(opts.rule) ? opts.rule : [opts.rule];\n for (const r of requested) {\n if (!ALL_RULES.includes(r as Rule)) {\n process.stderr.write(`unknown rule: ${r}\\n`);\n process.stderr.write(`available: ${ALL_RULES.join(\", \")}\\n`);\n process.exit(2);\n }\n }\n const lintOptions: Parameters<typeof lint>[0] = { cwd: opts.cwd ?? process.cwd() };\n if (opts.fix) lintOptions.fix = true;\n if (requested.length > 0) lintOptions.rules = requested as Rule[];\n const result = await lint(lintOptions);\n if (opts.json) {\n process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n const text = formatFindingsText(result.findings);\n if (text) process.stdout.write(text + \"\\n\");\n for (const f of result.filesFixed) p.log.success(`fixed ${f}`);\n if (result.findings.length === 0) p.log.success(\"no findings\");\n }\n if (!result.ok) process.exit(1);\n },\n );\n\n cli\n .command(\"bench [path]\", \"Benchmark token savings in a corpus or target directory\")\n .option(\"--corpus\", \"Run benchmark on the built-in corpus\")\n .option(\"--json\", \"Emit machine-readable JSON\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .action(async (pathArg: string | undefined, opts: { corpus?: boolean; json?: boolean; cwd?: string }) => {\n const benchOptions: Parameters<typeof bench>[0] = { cwd: opts.cwd ?? process.cwd() };\n if (opts.corpus) benchOptions.corpus = true;\n if (opts.json) benchOptions.json = true;\n if (pathArg !== undefined) benchOptions.path = pathArg;\n const result = await bench(benchOptions);\n if (opts.json) {\n process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n const text = formatBenchTable(result);\n process.stdout.write(text + \"\\n\");\n }\n });\n\n cli.help();\n cli.version(\"0.0.0\");\n cli.parse(argv);\n}\n\nfunction makeInteractiveResolver() {\n return async (ctx: TouchedContext): Promise<UpgradeChoice> => {\n process.stdout.write(\n pc.yellow(`\\n${ctx.family}: locally modified — incoming ${ctx.incoming.version}\\n`),\n );\n const choice = await p.select({\n message: `Resolve ${ctx.family}`,\n options: [\n { value: \"accept\", label: \"Accept new (discard local edits)\" },\n { value: \"keep\", label: \"Keep yours\" },\n { value: \"skip\", label: \"Skip for now\" },\n ],\n });\n if (p.isCancel(choice)) return \"skip\";\n return choice as UpgradeChoice;\n };\n}\n\nfunction printUpgradeSummary(outcomes: Awaited<ReturnType<typeof upgrade>>[\"outcomes\"]): void {\n for (const o of outcomes) {\n if (o.action === \"updated\") {\n process.stdout.write(pc.green(`✓ ${o.family} ${o.from} → ${o.to}\\n`));\n } else if (o.action === \"would-update\") {\n process.stdout.write(pc.cyan(`→ ${o.family} ${o.from} → ${o.to} (available)\\n`));\n } else if (o.action === \"would-review\") {\n process.stdout.write(pc.yellow(`! ${o.family} ${o.from} → ${o.to} (touched; needs review)\\n`));\n } else if (o.action === \"kept\" && o.reason === \"user-chose-keep\") {\n process.stdout.write(pc.dim(` ${o.family} kept local\\n`));\n } else if (o.action === \"skipped\") {\n process.stdout.write(pc.dim(` ${o.family} skipped (${o.reason})\\n`));\n }\n }\n}\n\nfunction describeVerifyIssue(issue: import(\"./commands/verify.js\").VerifyIssue): string {\n switch (issue.kind) {\n case \"missing-header\":\n return \"no fingerprint header — recipe was hand-stripped\";\n case \"header-tampered\":\n return `header sha ${issue.recorded} but body hashes to ${issue.actual}`;\n case \"lockfile-mismatch\":\n return `lockfile expects ${issue.locked} but body hashes to ${issue.actual}`;\n case \"missing-lock-entry\":\n return \"installed but not recorded in lockfile\";\n case \"missing-file\":\n return \"in lockfile but file is missing\";\n }\n}\n\nasync function promptForPreset(): Promise<string> {\n const choice = await p.select({\n message: \"Pick a preset\",\n options: KNOWN_PRESETS.map((name) => ({ value: name, label: name })),\n });\n if (p.isCancel(choice)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n return choice;\n}\n\nfunction printInitSummary(result: Awaited<ReturnType<typeof init>>): void {\n p.note(\n [\n `preset: ${result.preset}`,\n `registry: ${result.registry}`,\n `package manager: ${result.packageManager}`,\n `families copied: ${result.installedFamilies.length}`,\n `families skipped: ${result.skippedFamilies.length}`,\n ``,\n `config: ${result.configPath}`,\n `vscode settings: ${result.vscodePath}`,\n `pre-commit: ${result.huskyPath}`,\n `SKILL.md: ${result.skillPath}`,\n ].join(\"\\n\"),\n \"shortwind init\",\n );\n p.outro(`Next: run \\`${result.packageManager} dev\\` to start watching.`);\n}\n","#!/usr/bin/env node\nimport { run } from \"./cli.js\";\n\nrun().catch((err) => {\n console.error(err instanceof Error ? err.stack ?? err.message : err);\n process.exit(1);\n});\n"],"mappings":"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"}
|