@skill-map/cli 0.14.1 → 0.15.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/cli/tutorial/sm-tutorial.md +876 -0
- package/dist/cli.js +339 -333
- package/dist/cli.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.js +2 -2
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/chunk-7PFTODKS.js +1031 -0
- package/dist/ui/{chunk-WFJRSBK6.js → chunk-A4RBO3TD.js} +1 -1
- package/dist/ui/{chunk-VJAWM5V3.js → chunk-E2ZFWQW6.js} +1 -1
- package/dist/ui/{chunk-TEPC3SFH.js → chunk-KPEISNOV.js} +1 -1
- package/dist/ui/{chunk-T5SUVDLE.js → chunk-S5C4U3I3.js} +1 -1
- package/dist/ui/chunk-TG6IWVEC.js +54 -0
- package/dist/ui/{chunk-DOJURY6T.js → chunk-TGJQE3TH.js} +1 -1
- package/dist/ui/{chunk-G6SL4UFD.js → chunk-UGEECDPV.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/ui/main-JI2DDER5.js +1 -0
- package/package.json +2 -2
- package/dist/cli/guide/sm-guide.md +0 -798
- package/dist/ui/chunk-AVRC55YV.js +0 -971
- package/dist/ui/chunk-ZF7H74JY.js +0 -114
- package/dist/ui/main-TG4BEOVI.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -7353,109 +7353,16 @@ var GraphCommand = class extends SmCommand {
|
|
|
7353
7353
|
}
|
|
7354
7354
|
};
|
|
7355
7355
|
|
|
7356
|
-
// cli/commands/guide.ts
|
|
7357
|
-
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
|
|
7358
|
-
import { writeFile } from "fs/promises";
|
|
7359
|
-
import { dirname as dirname9, join as join10, resolve as resolve13 } from "path";
|
|
7360
|
-
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
7361
|
-
import { Command as Command8, Option as Option8 } from "clipanion";
|
|
7362
|
-
|
|
7363
|
-
// cli/i18n/guide.texts.ts
|
|
7364
|
-
var GUIDE_TEXTS = {
|
|
7365
|
-
// Success — written to stdout after `<cwd>/sm-guide.md` is created.
|
|
7366
|
-
written: 'Listo. sm-guide.md creado en {{cwd}}. Abr\xED Claude Code ac\xE1 y decile "ejecut\xE1 @sm-guide.md" para arrancar la gu\xEDa interactiva.\n',
|
|
7367
|
-
// Refusal — `sm-guide.md` already exists and `--force` was not set.
|
|
7368
|
-
// Goes to stderr, exit code 2 (operational error per spec § Exit codes).
|
|
7369
|
-
alreadyExists: "sm guide: sm-guide.md ya existe en {{cwd}}. Us\xE1 `--force` para sobrescribir.\n",
|
|
7370
|
-
// I/O failure on write or on reading the bundled SKILL source.
|
|
7371
|
-
writeFailed: "sm guide: no se pudo escribir sm-guide.md: {{message}}\n",
|
|
7372
|
-
sourceMissing: "sm guide: no se pudo leer la gu\xEDa empaquetada (SKILL.md) desde la instalaci\xF3n. Reinstal\xE1 @skill-map/cli o report\xE1 el bug.\n"
|
|
7373
|
-
};
|
|
7374
|
-
|
|
7375
|
-
// cli/commands/guide.ts
|
|
7376
|
-
var SM_GUIDE_FILENAME = "sm-guide.md";
|
|
7377
|
-
var GuideCommand = class extends SmCommand {
|
|
7378
|
-
static paths = [["guide"]];
|
|
7379
|
-
static usage = Command8.Usage({
|
|
7380
|
-
category: "Setup",
|
|
7381
|
-
description: "Materialize the interactive tester guide (sm-guide.md) in the current directory.",
|
|
7382
|
-
details: `
|
|
7383
|
-
Drops the canonical SKILL.md content as ./sm-guide.md so a tester
|
|
7384
|
-
can open Claude Code in the cwd and load the file as a skill by
|
|
7385
|
-
typing "ejecut\xE1 @sm-guide.md". Top-level only \u2014 no subdirectory
|
|
7386
|
-
is created.
|
|
7387
|
-
|
|
7388
|
-
Does NOT require an initialized .skill-map/ project. Refuses to
|
|
7389
|
-
overwrite an existing sm-guide.md unless --force is passed.
|
|
7390
|
-
`,
|
|
7391
|
-
examples: [
|
|
7392
|
-
["Materialize the guide in the cwd", "$0 guide"],
|
|
7393
|
-
["Overwrite an existing sm-guide.md", "$0 guide --force"]
|
|
7394
|
-
]
|
|
7395
|
-
});
|
|
7396
|
-
force = Option8.Boolean("--force", false, {
|
|
7397
|
-
description: "Overwrite an existing sm-guide.md without prompting."
|
|
7398
|
-
});
|
|
7399
|
-
async run() {
|
|
7400
|
-
const ctx = defaultRuntimeContext();
|
|
7401
|
-
const target = join10(ctx.cwd, SM_GUIDE_FILENAME);
|
|
7402
|
-
if (await pathExists(target) && !this.force) {
|
|
7403
|
-
this.context.stderr.write(tx(GUIDE_TEXTS.alreadyExists, { cwd: ctx.cwd }));
|
|
7404
|
-
return ExitCode.Error;
|
|
7405
|
-
}
|
|
7406
|
-
let body;
|
|
7407
|
-
try {
|
|
7408
|
-
body = loadBundledGuideText();
|
|
7409
|
-
} catch {
|
|
7410
|
-
this.context.stderr.write(GUIDE_TEXTS.sourceMissing);
|
|
7411
|
-
return ExitCode.Error;
|
|
7412
|
-
}
|
|
7413
|
-
try {
|
|
7414
|
-
await writeFile(target, body);
|
|
7415
|
-
} catch (err) {
|
|
7416
|
-
this.context.stderr.write(
|
|
7417
|
-
tx(GUIDE_TEXTS.writeFailed, { message: formatErrorMessage(err) })
|
|
7418
|
-
);
|
|
7419
|
-
return ExitCode.Error;
|
|
7420
|
-
}
|
|
7421
|
-
this.context.stdout.write(tx(GUIDE_TEXTS.written, { cwd: ctx.cwd }));
|
|
7422
|
-
return ExitCode.Ok;
|
|
7423
|
-
}
|
|
7424
|
-
};
|
|
7425
|
-
var cachedGuide = null;
|
|
7426
|
-
function loadBundledGuideText() {
|
|
7427
|
-
if (cachedGuide !== null) return cachedGuide;
|
|
7428
|
-
cachedGuide = readGuideFromDisk();
|
|
7429
|
-
return cachedGuide;
|
|
7430
|
-
}
|
|
7431
|
-
function readGuideFromDisk() {
|
|
7432
|
-
const here = dirname9(fileURLToPath5(import.meta.url));
|
|
7433
|
-
const candidates = [
|
|
7434
|
-
// dev: src/cli/commands/ → repo-root .claude/skills/sm-guide/SKILL.md
|
|
7435
|
-
resolve13(here, "../../../.claude/skills/sm-guide/SKILL.md"),
|
|
7436
|
-
// bundled: dist/cli.js → dist/cli/guide/sm-guide.md (sibling)
|
|
7437
|
-
resolve13(here, "cli/guide/sm-guide.md"),
|
|
7438
|
-
// bundled fallback: any-depth → cli/guide/sm-guide.md
|
|
7439
|
-
resolve13(here, "../cli/guide/sm-guide.md")
|
|
7440
|
-
];
|
|
7441
|
-
for (const candidate of candidates) {
|
|
7442
|
-
if (existsSync12(candidate)) {
|
|
7443
|
-
return readFileSync10(candidate, "utf8");
|
|
7444
|
-
}
|
|
7445
|
-
}
|
|
7446
|
-
throw new Error(`SKILL.md not found in any candidate location (last tried: ${candidates[candidates.length - 1]})`);
|
|
7447
|
-
}
|
|
7448
|
-
|
|
7449
7356
|
// cli/commands/help.ts
|
|
7450
|
-
import { readFileSync as
|
|
7357
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
7451
7358
|
import { createRequire as createRequire4 } from "module";
|
|
7452
|
-
import { resolve as
|
|
7453
|
-
import { Command as
|
|
7359
|
+
import { resolve as resolve13 } from "path";
|
|
7360
|
+
import { Command as Command8, Option as Option8 } from "clipanion";
|
|
7454
7361
|
|
|
7455
7362
|
// package.json
|
|
7456
7363
|
var package_default = {
|
|
7457
7364
|
name: "@skill-map/cli",
|
|
7458
|
-
version: "0.
|
|
7365
|
+
version: "0.15.0",
|
|
7459
7366
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
7460
7367
|
license: "MIT",
|
|
7461
7368
|
type: "module",
|
|
@@ -7514,7 +7421,7 @@ var package_default = {
|
|
|
7514
7421
|
},
|
|
7515
7422
|
dependencies: {
|
|
7516
7423
|
"@hono/node-server": "2.0.1",
|
|
7517
|
-
"@skill-map/spec": "0.
|
|
7424
|
+
"@skill-map/spec": "0.15.0",
|
|
7518
7425
|
ajv: "8.18.0",
|
|
7519
7426
|
"ajv-formats": "3.0.1",
|
|
7520
7427
|
chokidar: "5.0.0",
|
|
@@ -7631,9 +7538,9 @@ var HELP_TEXTS = {
|
|
|
7631
7538
|
};
|
|
7632
7539
|
|
|
7633
7540
|
// cli/commands/help.ts
|
|
7634
|
-
var HelpCommand = class extends
|
|
7541
|
+
var HelpCommand = class extends Command8 {
|
|
7635
7542
|
static paths = [["help"]];
|
|
7636
|
-
static usage =
|
|
7543
|
+
static usage = Command8.Usage({
|
|
7637
7544
|
category: "Introspection",
|
|
7638
7545
|
description: "Self-describing introspection. --format human|md|json.",
|
|
7639
7546
|
details: `
|
|
@@ -7647,8 +7554,8 @@ var HelpCommand = class extends Command9 {
|
|
|
7647
7554
|
json \u2014 structured surface dump per spec/cli-contract.md.
|
|
7648
7555
|
`
|
|
7649
7556
|
});
|
|
7650
|
-
verbParts =
|
|
7651
|
-
format =
|
|
7557
|
+
verbParts = Option8.Rest({ required: 0 });
|
|
7558
|
+
format = Option8.String("--format", "human");
|
|
7652
7559
|
async execute() {
|
|
7653
7560
|
const format = normalizeFormat(this.format);
|
|
7654
7561
|
if (!format) {
|
|
@@ -7770,8 +7677,8 @@ function resolveSpecVersion() {
|
|
|
7770
7677
|
try {
|
|
7771
7678
|
const req = createRequire4(import.meta.url);
|
|
7772
7679
|
const indexPath = req.resolve("@skill-map/spec/index.json");
|
|
7773
|
-
const pkgPath =
|
|
7774
|
-
const pkg = JSON.parse(
|
|
7680
|
+
const pkgPath = resolve13(indexPath, "..", "package.json");
|
|
7681
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf8"));
|
|
7775
7682
|
return pkg.version;
|
|
7776
7683
|
} catch {
|
|
7777
7684
|
return "unknown";
|
|
@@ -7966,7 +7873,7 @@ function renderCompactOverview(verbs) {
|
|
|
7966
7873
|
lines.push(HELP_TEXTS.compactFooter);
|
|
7967
7874
|
return lines.join("\n") + "\n";
|
|
7968
7875
|
}
|
|
7969
|
-
var RootHelpCommand = class extends
|
|
7876
|
+
var RootHelpCommand = class extends Command8 {
|
|
7970
7877
|
static paths = [["-h"], ["--help"]];
|
|
7971
7878
|
async execute() {
|
|
7972
7879
|
const rawDefs = this.cli.definitions();
|
|
@@ -8022,13 +7929,13 @@ function registeredVerbPaths(cli2) {
|
|
|
8022
7929
|
}
|
|
8023
7930
|
|
|
8024
7931
|
// cli/commands/init.ts
|
|
8025
|
-
import { mkdir as mkdir2, readFile as readFile2, writeFile
|
|
8026
|
-
import { join as
|
|
8027
|
-
import { Command as
|
|
7932
|
+
import { mkdir as mkdir2, readFile as readFile2, writeFile } from "fs/promises";
|
|
7933
|
+
import { join as join10 } from "path";
|
|
7934
|
+
import { Command as Command9, Option as Option9 } from "clipanion";
|
|
8028
7935
|
|
|
8029
7936
|
// kernel/orchestrator.ts
|
|
8030
7937
|
import { createHash } from "crypto";
|
|
8031
|
-
import { existsSync as
|
|
7938
|
+
import { existsSync as existsSync12, statSync as statSync3 } from "fs";
|
|
8032
7939
|
import { Tiktoken } from "js-tiktoken/lite";
|
|
8033
7940
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
8034
7941
|
import yaml2 from "js-yaml";
|
|
@@ -8163,7 +8070,7 @@ function validateRoots(roots) {
|
|
|
8163
8070
|
throw new Error(ORCHESTRATOR_TEXTS.runScanRootEmptyArray);
|
|
8164
8071
|
}
|
|
8165
8072
|
for (const root of roots) {
|
|
8166
|
-
if (!
|
|
8073
|
+
if (!existsSync12(root) || !statSync3(root).isDirectory()) {
|
|
8167
8074
|
throw new Error(tx(ORCHESTRATOR_TEXTS.runScanRootMissing, { root }));
|
|
8168
8075
|
}
|
|
8169
8076
|
}
|
|
@@ -8939,10 +8846,10 @@ function recomputeExternalRefsCount(nodes, externalLinks, cachedPaths) {
|
|
|
8939
8846
|
}
|
|
8940
8847
|
|
|
8941
8848
|
// kernel/scan/watcher.ts
|
|
8942
|
-
import { resolve as
|
|
8849
|
+
import { resolve as resolve14, relative as relative4, sep as sep2 } from "path";
|
|
8943
8850
|
import chokidar from "chokidar";
|
|
8944
8851
|
function createChokidarWatcher(opts) {
|
|
8945
|
-
const absRoots = opts.roots.map((r) =>
|
|
8852
|
+
const absRoots = opts.roots.map((r) => resolve14(opts.cwd, r));
|
|
8946
8853
|
const ignoreFilter = opts.ignoreFilter;
|
|
8947
8854
|
const ignored = ignoreFilter ? (path) => {
|
|
8948
8855
|
const rel = relativePathFromRoots(path, absRoots);
|
|
@@ -9188,7 +9095,7 @@ function createCliProgressEmitter(stderr) {
|
|
|
9188
9095
|
// cli/commands/init.ts
|
|
9189
9096
|
var InitCommand = class extends SmCommand {
|
|
9190
9097
|
static paths = [["init"]];
|
|
9191
|
-
static usage =
|
|
9098
|
+
static usage = Command9.Usage({
|
|
9192
9099
|
category: "Setup",
|
|
9193
9100
|
description: "Bootstrap the current scope: scaffold .skill-map/, provision DB, run first scan.",
|
|
9194
9101
|
details: `
|
|
@@ -9212,16 +9119,16 @@ var InitCommand = class extends SmCommand {
|
|
|
9212
9119
|
["Preview what would be created", "$0 init --dry-run"]
|
|
9213
9120
|
]
|
|
9214
9121
|
});
|
|
9215
|
-
noScan =
|
|
9122
|
+
noScan = Option9.Boolean("--no-scan", false, {
|
|
9216
9123
|
description: "Skip the first scan after scaffolding."
|
|
9217
9124
|
});
|
|
9218
|
-
force =
|
|
9125
|
+
force = Option9.Boolean("--force", false, {
|
|
9219
9126
|
description: "Overwrite an existing settings.json / settings.local.json / .skill-mapignore."
|
|
9220
9127
|
});
|
|
9221
|
-
strict =
|
|
9128
|
+
strict = Option9.Boolean("--strict", false, {
|
|
9222
9129
|
description: "Strict mode: fail on any layered-loader warning AND promote frontmatter warnings to errors during the first scan. Same flag as sm scan / sm config."
|
|
9223
9130
|
});
|
|
9224
|
-
dryRun =
|
|
9131
|
+
dryRun = Option9.Boolean("-n,--dry-run", false, {
|
|
9225
9132
|
description: "Preview the scope provisioning without touching the filesystem or the DB. Honours --force for the would-overwrite preview. Skips the first scan unconditionally \u2014 dry-run never persists."
|
|
9226
9133
|
});
|
|
9227
9134
|
// CLI orchestrator: paths setup + dry-run branch (delegated to
|
|
@@ -9232,7 +9139,7 @@ var InitCommand = class extends SmCommand {
|
|
|
9232
9139
|
async run() {
|
|
9233
9140
|
const ctx = defaultRuntimeContext();
|
|
9234
9141
|
const scopeRoot = this.global ? ctx.homedir : ctx.cwd;
|
|
9235
|
-
const skillMapDir =
|
|
9142
|
+
const skillMapDir = join10(scopeRoot, SKILL_MAP_DIR);
|
|
9236
9143
|
const settingsPath = defaultSettingsPath(scopeRoot);
|
|
9237
9144
|
const localPath = defaultLocalSettingsPath(scopeRoot);
|
|
9238
9145
|
const ignorePath = defaultIgnoreFilePath(scopeRoot);
|
|
@@ -9256,17 +9163,17 @@ var InitCommand = class extends SmCommand {
|
|
|
9256
9163
|
return ExitCode.Ok;
|
|
9257
9164
|
}
|
|
9258
9165
|
await mkdir2(skillMapDir, { recursive: true });
|
|
9259
|
-
await
|
|
9166
|
+
await writeFile(settingsPath, JSON.stringify({ schemaVersion: 1 }, null, 2) + "\n");
|
|
9260
9167
|
if (!await pathExists(localPath) || this.force) {
|
|
9261
|
-
await
|
|
9168
|
+
await writeFile(localPath, "{}\n");
|
|
9262
9169
|
}
|
|
9263
9170
|
if (!await pathExists(ignorePath) || this.force) {
|
|
9264
|
-
await
|
|
9171
|
+
await writeFile(ignorePath, loadBundledIgnoreText());
|
|
9265
9172
|
}
|
|
9266
9173
|
if (!this.global) {
|
|
9267
9174
|
const updated = await ensureGitignoreEntries(scopeRoot, GITIGNORE_ENTRIES);
|
|
9268
9175
|
if (updated) {
|
|
9269
|
-
const gitignorePath =
|
|
9176
|
+
const gitignorePath = join10(scopeRoot, ".gitignore");
|
|
9270
9177
|
this.context.stdout.write(
|
|
9271
9178
|
GITIGNORE_ENTRIES.length === 1 ? tx(INIT_TEXTS.gitignoreUpdatedSingular, { path: gitignorePath }) : tx(INIT_TEXTS.gitignoreUpdatedPlural, {
|
|
9272
9179
|
path: gitignorePath,
|
|
@@ -9305,7 +9212,7 @@ async function dryRunFileMessage(path) {
|
|
|
9305
9212
|
}
|
|
9306
9213
|
async function writeDryRunGitignorePlan(stdout, scopeRoot) {
|
|
9307
9214
|
const wouldAdd = await previewGitignoreEntries(scopeRoot, GITIGNORE_ENTRIES);
|
|
9308
|
-
const gitignorePath =
|
|
9215
|
+
const gitignorePath = join10(scopeRoot, ".gitignore");
|
|
9309
9216
|
if (wouldAdd.length === 0) {
|
|
9310
9217
|
stdout.write(tx(INIT_TEXTS.dryRunWouldLeaveGitignoreUnchanged, { path: gitignorePath }));
|
|
9311
9218
|
} else if (wouldAdd.length === 1) {
|
|
@@ -9380,7 +9287,7 @@ async function runFirstScan(scopeRoot, homedir3, dbPath, strict, stdout, stderr)
|
|
|
9380
9287
|
return hasErrors ? ExitCode.Issues : ExitCode.Ok;
|
|
9381
9288
|
}
|
|
9382
9289
|
async function previewGitignoreEntries(scopeRoot, entries) {
|
|
9383
|
-
const path =
|
|
9290
|
+
const path = join10(scopeRoot, ".gitignore");
|
|
9384
9291
|
const body = await pathExists(path) ? await readFile2(path, "utf8") : "";
|
|
9385
9292
|
const present = new Set(
|
|
9386
9293
|
body.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"))
|
|
@@ -9388,7 +9295,7 @@ async function previewGitignoreEntries(scopeRoot, entries) {
|
|
|
9388
9295
|
return entries.filter((entry) => !present.has(entry));
|
|
9389
9296
|
}
|
|
9390
9297
|
async function ensureGitignoreEntries(scopeRoot, entries) {
|
|
9391
|
-
const path =
|
|
9298
|
+
const path = join10(scopeRoot, ".gitignore");
|
|
9392
9299
|
let body = "";
|
|
9393
9300
|
if (await pathExists(path)) {
|
|
9394
9301
|
body = await readFile2(path, "utf8");
|
|
@@ -9405,12 +9312,12 @@ async function ensureGitignoreEntries(scopeRoot, entries) {
|
|
|
9405
9312
|
present.add(entry);
|
|
9406
9313
|
changed = true;
|
|
9407
9314
|
}
|
|
9408
|
-
if (changed) await
|
|
9315
|
+
if (changed) await writeFile(path, body);
|
|
9409
9316
|
return changed;
|
|
9410
9317
|
}
|
|
9411
9318
|
|
|
9412
9319
|
// cli/commands/history.ts
|
|
9413
|
-
import { Command as
|
|
9320
|
+
import { Command as Command10, Option as Option10 } from "clipanion";
|
|
9414
9321
|
|
|
9415
9322
|
// cli/i18n/option-validators.texts.ts
|
|
9416
9323
|
var OPTION_VALIDATORS_TEXTS = {
|
|
@@ -9499,7 +9406,7 @@ function parseStatuses(input, stderr) {
|
|
|
9499
9406
|
}
|
|
9500
9407
|
var HistoryCommand = class extends SmCommand {
|
|
9501
9408
|
static paths = [["history"]];
|
|
9502
|
-
static usage =
|
|
9409
|
+
static usage = Command10.Usage({
|
|
9503
9410
|
category: "History",
|
|
9504
9411
|
description: "Filter execution records. --json emits an array conforming to execution-record.schema.json.",
|
|
9505
9412
|
details: `
|
|
@@ -9519,12 +9426,12 @@ var HistoryCommand = class extends SmCommand {
|
|
|
9519
9426
|
["Machine-readable, scoped to one node", "$0 history -n skills/foo.md --json"]
|
|
9520
9427
|
]
|
|
9521
9428
|
});
|
|
9522
|
-
node =
|
|
9523
|
-
action =
|
|
9524
|
-
status =
|
|
9525
|
-
since =
|
|
9526
|
-
until =
|
|
9527
|
-
limit =
|
|
9429
|
+
node = Option10.String("-n", { required: false });
|
|
9430
|
+
action = Option10.String("--action", { required: false });
|
|
9431
|
+
status = Option10.String("--status", { required: false });
|
|
9432
|
+
since = Option10.String("--since", { required: false });
|
|
9433
|
+
until = Option10.String("--until", { required: false });
|
|
9434
|
+
limit = Option10.String("--limit", { required: false });
|
|
9528
9435
|
// CLI list verb: many optional filter flags (`--node`, `--action`,
|
|
9529
9436
|
// `--status`, `--since`, `--until`, `--limit`, `--json`, `--quiet`)
|
|
9530
9437
|
// each adding a guarded mutation to the filter or render path. Each
|
|
@@ -9572,7 +9479,7 @@ var HistoryCommand = class extends SmCommand {
|
|
|
9572
9479
|
};
|
|
9573
9480
|
var HistoryStatsCommand = class extends SmCommand {
|
|
9574
9481
|
static paths = [["history", "stats"]];
|
|
9575
|
-
static usage =
|
|
9482
|
+
static usage = Command10.Usage({
|
|
9576
9483
|
category: "History",
|
|
9577
9484
|
description: "Aggregate counts, tokens, periods, top nodes, and error rates over state_executions. --json conforms to history-stats.schema.json.",
|
|
9578
9485
|
details: `
|
|
@@ -9590,10 +9497,10 @@ var HistoryStatsCommand = class extends SmCommand {
|
|
|
9590
9497
|
["Top 5 nodes, JSON", "$0 history stats --top 5 --json"]
|
|
9591
9498
|
]
|
|
9592
9499
|
});
|
|
9593
|
-
since =
|
|
9594
|
-
until =
|
|
9595
|
-
period =
|
|
9596
|
-
top =
|
|
9500
|
+
since = Option10.String("--since", { required: false });
|
|
9501
|
+
until = Option10.String("--until", { required: false });
|
|
9502
|
+
period = Option10.String("--period", { required: false });
|
|
9503
|
+
top = Option10.String("--top", { required: false });
|
|
9597
9504
|
// CLI stats verb: range parsing + window flags + period flag + JSON
|
|
9598
9505
|
// branch + per-period iteration. Each branch is a single-purpose
|
|
9599
9506
|
// gate; the data work lives in `aggregateHistoryStats`.
|
|
@@ -9774,11 +9681,11 @@ function formatRow(...cols) {
|
|
|
9774
9681
|
|
|
9775
9682
|
// cli/commands/jobs.ts
|
|
9776
9683
|
import { unlink } from "fs/promises";
|
|
9777
|
-
import { Command as
|
|
9684
|
+
import { Command as Command11, Option as Option11 } from "clipanion";
|
|
9778
9685
|
|
|
9779
9686
|
// kernel/jobs/orphan-files.ts
|
|
9780
9687
|
import { readdirSync as readdirSync6, statSync as statSync4 } from "fs";
|
|
9781
|
-
import { join as
|
|
9688
|
+
import { join as join11, resolve as resolve15 } from "path";
|
|
9782
9689
|
function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
9783
9690
|
let entries;
|
|
9784
9691
|
try {
|
|
@@ -9793,7 +9700,7 @@ function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
|
9793
9700
|
const orphans = [];
|
|
9794
9701
|
for (const name of entries) {
|
|
9795
9702
|
if (!name.endsWith(".md")) continue;
|
|
9796
|
-
const abs =
|
|
9703
|
+
const abs = resolve15(join11(jobsDir, name));
|
|
9797
9704
|
if (!referencedPaths.has(abs)) orphans.push(abs);
|
|
9798
9705
|
}
|
|
9799
9706
|
orphans.sort();
|
|
@@ -9822,7 +9729,7 @@ var JOBS_TEXTS = {
|
|
|
9822
9729
|
// cli/commands/jobs.ts
|
|
9823
9730
|
var JobPruneCommand = class extends SmCommand {
|
|
9824
9731
|
static paths = [["job", "prune"]];
|
|
9825
|
-
static usage =
|
|
9732
|
+
static usage = Command11.Usage({
|
|
9826
9733
|
category: "Jobs",
|
|
9827
9734
|
description: "Retention GC for completed / failed jobs (per config policy). --orphan-files removes MD files with no DB row.",
|
|
9828
9735
|
details: `
|
|
@@ -9849,10 +9756,10 @@ var JobPruneCommand = class extends SmCommand {
|
|
|
9849
9756
|
["Preview without touching the DB", "$0 job prune --dry-run --json"]
|
|
9850
9757
|
]
|
|
9851
9758
|
});
|
|
9852
|
-
orphanFiles =
|
|
9759
|
+
orphanFiles = Option11.Boolean("--orphan-files", false, {
|
|
9853
9760
|
description: "Also remove MD files in .skill-map/jobs/ that have no matching state_jobs row."
|
|
9854
9761
|
});
|
|
9855
|
-
dryRun =
|
|
9762
|
+
dryRun = Option11.Boolean("-n,--dry-run", false, {
|
|
9856
9763
|
description: "Report what would be pruned without touching the DB or filesystem."
|
|
9857
9764
|
});
|
|
9858
9765
|
async run() {
|
|
@@ -9969,7 +9876,7 @@ function formatPolicy(seconds) {
|
|
|
9969
9876
|
}
|
|
9970
9877
|
|
|
9971
9878
|
// cli/commands/list.ts
|
|
9972
|
-
import { Command as
|
|
9879
|
+
import { Command as Command12, Option as Option12 } from "clipanion";
|
|
9973
9880
|
|
|
9974
9881
|
// cli/i18n/list.texts.ts
|
|
9975
9882
|
var LIST_TEXTS = {
|
|
@@ -9997,7 +9904,7 @@ var SORT_BY = {
|
|
|
9997
9904
|
var PATH_COL_WIDTH = 50;
|
|
9998
9905
|
var ListCommand = class extends SmCommand {
|
|
9999
9906
|
static paths = [["list"]];
|
|
10000
|
-
static usage =
|
|
9907
|
+
static usage = Command12.Usage({
|
|
10001
9908
|
category: "Browse",
|
|
10002
9909
|
description: "Tabular listing of nodes. --json emits an array conforming to node.schema.json.",
|
|
10003
9910
|
details: `
|
|
@@ -10018,10 +9925,10 @@ var ListCommand = class extends SmCommand {
|
|
|
10018
9925
|
["Only nodes with issues, machine-readable", "$0 list --issue --json"]
|
|
10019
9926
|
]
|
|
10020
9927
|
});
|
|
10021
|
-
kind =
|
|
10022
|
-
issue =
|
|
10023
|
-
sortBy =
|
|
10024
|
-
limit =
|
|
9928
|
+
kind = Option12.String("--kind", { required: false });
|
|
9929
|
+
issue = Option12.Boolean("--issue", false);
|
|
9930
|
+
sortBy = Option12.String("--sort-by", { required: false });
|
|
9931
|
+
limit = Option12.String("--limit", { required: false });
|
|
10025
9932
|
async run() {
|
|
10026
9933
|
let sortColumn = "path";
|
|
10027
9934
|
let sortDirection = "asc";
|
|
@@ -10123,7 +10030,7 @@ function formatRow2(path, kind, out, inCount, ext, issues, bytes) {
|
|
|
10123
10030
|
}
|
|
10124
10031
|
|
|
10125
10032
|
// cli/commands/orphans.ts
|
|
10126
|
-
import { Command as
|
|
10033
|
+
import { Command as Command13, Option as Option13 } from "clipanion";
|
|
10127
10034
|
|
|
10128
10035
|
// cli/i18n/orphans.texts.ts
|
|
10129
10036
|
var ORPHANS_TEXTS = {
|
|
@@ -10178,7 +10085,7 @@ function isStringArray(v) {
|
|
|
10178
10085
|
}
|
|
10179
10086
|
var OrphansCommand = class extends SmCommand {
|
|
10180
10087
|
static paths = [["orphans"]];
|
|
10181
|
-
static usage =
|
|
10088
|
+
static usage = Command13.Usage({
|
|
10182
10089
|
category: "Browse",
|
|
10183
10090
|
description: "List orphan / auto-rename issues from the last scan. --json emits an array conforming to issue.schema.json.",
|
|
10184
10091
|
details: `
|
|
@@ -10193,7 +10100,7 @@ var OrphansCommand = class extends SmCommand {
|
|
|
10193
10100
|
["Just the ambiguous ones, JSON", "$0 orphans --kind ambiguous --json"]
|
|
10194
10101
|
]
|
|
10195
10102
|
});
|
|
10196
|
-
kind =
|
|
10103
|
+
kind = Option13.String("--kind", { required: false });
|
|
10197
10104
|
async run() {
|
|
10198
10105
|
let ruleFilter = null;
|
|
10199
10106
|
if (this.kind !== void 0) {
|
|
@@ -10231,7 +10138,7 @@ var OrphansCommand = class extends SmCommand {
|
|
|
10231
10138
|
};
|
|
10232
10139
|
var OrphansReconcileCommand = class extends SmCommand {
|
|
10233
10140
|
static paths = [["orphans", "reconcile"]];
|
|
10234
|
-
static usage =
|
|
10141
|
+
static usage = Command13.Usage({
|
|
10235
10142
|
category: "Browse",
|
|
10236
10143
|
description: "Migrate state_* FKs from an orphan path to a live node, resolving the orphan issue.",
|
|
10237
10144
|
details: `
|
|
@@ -10247,9 +10154,9 @@ var OrphansReconcileCommand = class extends SmCommand {
|
|
|
10247
10154
|
["Reattach orphan history", "$0 orphans reconcile skills/old.md --to skills/new.md"]
|
|
10248
10155
|
]
|
|
10249
10156
|
});
|
|
10250
|
-
orphanPath =
|
|
10251
|
-
to =
|
|
10252
|
-
dryRun =
|
|
10157
|
+
orphanPath = Option13.String({ required: true });
|
|
10158
|
+
to = Option13.String("--to", { required: true });
|
|
10159
|
+
dryRun = Option13.Boolean("-n,--dry-run", false);
|
|
10253
10160
|
async run() {
|
|
10254
10161
|
const dbPath = resolveDbPath({ global: this.global, db: this.db, ...defaultRuntimeContext() });
|
|
10255
10162
|
if (!assertDbExists(dbPath, this.context.stderr)) return ExitCode.NotFound;
|
|
@@ -10319,7 +10226,7 @@ var OrphansReconcileCommand = class extends SmCommand {
|
|
|
10319
10226
|
};
|
|
10320
10227
|
var OrphansUndoRenameCommand = class extends SmCommand {
|
|
10321
10228
|
static paths = [["orphans", "undo-rename"]];
|
|
10322
|
-
static usage =
|
|
10229
|
+
static usage = Command13.Usage({
|
|
10323
10230
|
category: "Browse",
|
|
10324
10231
|
description: "Reverse a medium- or ambiguous-confidence auto-rename. Migrates state_* FKs back, emits a new orphan on the prior path.",
|
|
10325
10232
|
details: `
|
|
@@ -10339,10 +10246,10 @@ var OrphansUndoRenameCommand = class extends SmCommand {
|
|
|
10339
10246
|
["Undo an ambiguous, picking a candidate", "$0 orphans undo-rename skills/new.md --from skills/old-a.md"]
|
|
10340
10247
|
]
|
|
10341
10248
|
});
|
|
10342
|
-
newPath =
|
|
10343
|
-
from =
|
|
10344
|
-
force =
|
|
10345
|
-
dryRun =
|
|
10249
|
+
newPath = Option13.String({ required: true });
|
|
10250
|
+
from = Option13.String("--from", { required: false });
|
|
10251
|
+
force = Option13.Boolean("--force", false);
|
|
10252
|
+
dryRun = Option13.Boolean("-n,--dry-run", false);
|
|
10346
10253
|
async run() {
|
|
10347
10254
|
const dbPath = resolveDbPath({ global: this.global, db: this.db, ...defaultRuntimeContext() });
|
|
10348
10255
|
if (!assertDbExists(dbPath, this.context.stderr)) return ExitCode.NotFound;
|
|
@@ -10506,9 +10413,9 @@ var ORPHANS_COMMANDS = [
|
|
|
10506
10413
|
];
|
|
10507
10414
|
|
|
10508
10415
|
// cli/commands/plugins.ts
|
|
10509
|
-
import { existsSync as
|
|
10510
|
-
import { join as
|
|
10511
|
-
import { Command as
|
|
10416
|
+
import { existsSync as existsSync13 } from "fs";
|
|
10417
|
+
import { join as join12, resolve as resolve16 } from "path";
|
|
10418
|
+
import { Command as Command14, Option as Option14 } from "clipanion";
|
|
10512
10419
|
|
|
10513
10420
|
// cli/i18n/plugins.texts.ts
|
|
10514
10421
|
var PLUGINS_TEXTS = {
|
|
@@ -10555,8 +10462,8 @@ var PLUGINS_TEXTS = {
|
|
|
10555
10462
|
rowStatusOkPad: "ok ",
|
|
10556
10463
|
rowStatusOffPad: "off ",
|
|
10557
10464
|
builtInBundleHeader: "{{status}} {{id}}@built-in (granularity={{granularity}})",
|
|
10558
|
-
builtInBundleKindsLine: "
|
|
10559
|
-
builtInExtensionRow: "
|
|
10465
|
+
builtInBundleKindsLine: " {{kinds}}",
|
|
10466
|
+
builtInExtensionRow: "{{stat}} {{kind}}:{{qualifiedId}}@{{version}}",
|
|
10560
10467
|
pluginRow: "{{statusIcon}} {{id}}@{{version}}{{granularitySuffix}}{{tail}}",
|
|
10561
10468
|
pluginRowGranularitySuffix: " (granularity={{granularity}})",
|
|
10562
10469
|
pluginRowTailEnabled: " \xB7 {{kinds}}",
|
|
@@ -10584,7 +10491,7 @@ var PLUGINS_TEXTS = {
|
|
|
10584
10491
|
|
|
10585
10492
|
// cli/commands/plugins.ts
|
|
10586
10493
|
function resolveSearchPaths2(opts, cwd, homedir3) {
|
|
10587
|
-
if (opts.pluginDir) return [
|
|
10494
|
+
if (opts.pluginDir) return [resolve16(opts.pluginDir)];
|
|
10588
10495
|
const ctx = { cwd, homedir: homedir3 };
|
|
10589
10496
|
const project = defaultProjectPluginsDir(ctx);
|
|
10590
10497
|
const user = defaultUserPluginsDir(ctx);
|
|
@@ -10653,12 +10560,12 @@ function builtInRows(resolveEnabled) {
|
|
|
10653
10560
|
}
|
|
10654
10561
|
var PluginsListCommand = class extends SmCommand {
|
|
10655
10562
|
static paths = [["plugins", "list"]];
|
|
10656
|
-
static usage =
|
|
10563
|
+
static usage = Command14.Usage({
|
|
10657
10564
|
category: "Plugins",
|
|
10658
10565
|
description: "List discovered plugins and their load status.",
|
|
10659
10566
|
details: "Scans <scope>/.skill-map/plugins and ~/.skill-map/plugins (or --plugin-dir <path>). Built-in bundles (claude, core) are listed alongside user plugins."
|
|
10660
10567
|
});
|
|
10661
|
-
pluginDir =
|
|
10568
|
+
pluginDir = Option14.String("--plugin-dir", { required: false });
|
|
10662
10569
|
async run() {
|
|
10663
10570
|
const plugins = await loadAll({ global: this.global, pluginDir: this.pluginDir });
|
|
10664
10571
|
const resolveEnabled = await buildResolver(this.global);
|
|
@@ -10688,13 +10595,15 @@ function renderBuiltInBundleRow(bundle) {
|
|
|
10688
10595
|
})
|
|
10689
10596
|
);
|
|
10690
10597
|
if (bundle.granularity === "bundle") {
|
|
10691
|
-
const
|
|
10692
|
-
|
|
10598
|
+
for (const ext of bundle.extensions) {
|
|
10599
|
+
const line = `${ext.kind}:${qualifiedExtensionId(bundle.id, ext.id)}@${ext.version}`;
|
|
10600
|
+
lines.push(tx(PLUGINS_TEXTS.builtInBundleKindsLine, { kinds: line }));
|
|
10601
|
+
}
|
|
10693
10602
|
} else {
|
|
10694
10603
|
for (const ext of bundle.extensions) {
|
|
10695
10604
|
lines.push(
|
|
10696
10605
|
tx(PLUGINS_TEXTS.builtInExtensionRow, {
|
|
10697
|
-
stat: ext.enabled ? PLUGINS_TEXTS.
|
|
10606
|
+
stat: ext.enabled ? PLUGINS_TEXTS.rowStatusOk : PLUGINS_TEXTS.rowStatusOff,
|
|
10698
10607
|
kind: ext.kind,
|
|
10699
10608
|
qualifiedId: qualifiedExtensionId(bundle.id, ext.id),
|
|
10700
10609
|
version: ext.version
|
|
@@ -10720,12 +10629,12 @@ function renderPluginRow(p) {
|
|
|
10720
10629
|
}
|
|
10721
10630
|
var PluginsShowCommand = class extends SmCommand {
|
|
10722
10631
|
static paths = [["plugins", "show"]];
|
|
10723
|
-
static usage =
|
|
10632
|
+
static usage = Command14.Usage({
|
|
10724
10633
|
category: "Plugins",
|
|
10725
10634
|
description: "Show a single plugin's manifest + loaded extensions."
|
|
10726
10635
|
});
|
|
10727
|
-
id =
|
|
10728
|
-
pluginDir =
|
|
10636
|
+
id = Option14.String({ required: true });
|
|
10637
|
+
pluginDir = Option14.String("--plugin-dir", { required: false });
|
|
10729
10638
|
async run() {
|
|
10730
10639
|
const plugins = await loadAll({ global: this.global, pluginDir: this.pluginDir });
|
|
10731
10640
|
const resolveEnabled = await buildResolver(this.global);
|
|
@@ -10902,7 +10811,7 @@ function appendUnknownKindWarnings(out, extractorQualifiedId, applicableKinds, k
|
|
|
10902
10811
|
}
|
|
10903
10812
|
function expandHome(p, homedir3) {
|
|
10904
10813
|
if (p === "~") return homedir3;
|
|
10905
|
-
if (p.startsWith("~/")) return
|
|
10814
|
+
if (p.startsWith("~/")) return join12(homedir3, p.slice(2));
|
|
10906
10815
|
return p;
|
|
10907
10816
|
}
|
|
10908
10817
|
function collectExplorationDirWarnings(plugins, homedir3) {
|
|
@@ -10911,7 +10820,7 @@ function collectExplorationDirWarnings(plugins, homedir3) {
|
|
|
10911
10820
|
const dir = instance["explorationDir"];
|
|
10912
10821
|
if (typeof dir !== "string" || dir.length === 0) return;
|
|
10913
10822
|
const resolved = expandHome(dir, homedir3);
|
|
10914
|
-
if (!
|
|
10823
|
+
if (!existsSync13(resolved)) {
|
|
10915
10824
|
out.push({
|
|
10916
10825
|
providerQualifiedId: qualifiedExtensionId(pluginId, id),
|
|
10917
10826
|
explorationDir: dir,
|
|
@@ -10923,12 +10832,12 @@ function collectExplorationDirWarnings(plugins, homedir3) {
|
|
|
10923
10832
|
}
|
|
10924
10833
|
var PluginsDoctorCommand = class extends SmCommand {
|
|
10925
10834
|
static paths = [["plugins", "doctor"]];
|
|
10926
|
-
static usage =
|
|
10835
|
+
static usage = Command14.Usage({
|
|
10927
10836
|
category: "Plugins",
|
|
10928
10837
|
description: "Run the full load pass and summarise by failure mode.",
|
|
10929
10838
|
details: "Exit code 0 when every plugin loads or is intentionally disabled; 1 when any plugin is in an error / incompat state."
|
|
10930
10839
|
});
|
|
10931
|
-
pluginDir =
|
|
10840
|
+
pluginDir = Option14.String("--plugin-dir", { required: false });
|
|
10932
10841
|
// Doctor verb: counts by status + applicableKinds warnings +
|
|
10933
10842
|
// explorationDir warnings + bad-plugins issues, each with its own
|
|
10934
10843
|
// gated render. Branching is intrinsic to the multi-section diagnostic
|
|
@@ -11094,8 +11003,8 @@ function resolveToggleTarget(id, catalogue, verb) {
|
|
|
11094
11003
|
return { key: bundle.id };
|
|
11095
11004
|
}
|
|
11096
11005
|
var TogglePluginsBase = class extends SmCommand {
|
|
11097
|
-
all =
|
|
11098
|
-
id =
|
|
11006
|
+
all = Option14.Boolean("--all", false);
|
|
11007
|
+
id = Option14.String({ required: false });
|
|
11099
11008
|
// eslint-disable-next-line complexity
|
|
11100
11009
|
async toggle(enabled) {
|
|
11101
11010
|
const verb = enabled ? "enable" : "disable";
|
|
@@ -11146,7 +11055,7 @@ var TogglePluginsBase = class extends SmCommand {
|
|
|
11146
11055
|
};
|
|
11147
11056
|
var PluginsEnableCommand = class extends TogglePluginsBase {
|
|
11148
11057
|
static paths = [["plugins", "enable"]];
|
|
11149
|
-
static usage =
|
|
11058
|
+
static usage = Command14.Usage({
|
|
11150
11059
|
category: "Plugins",
|
|
11151
11060
|
description: "Enable a plugin (or --all). Persists in config_plugins.",
|
|
11152
11061
|
details: `
|
|
@@ -11168,7 +11077,7 @@ var PluginsEnableCommand = class extends TogglePluginsBase {
|
|
|
11168
11077
|
};
|
|
11169
11078
|
var PluginsDisableCommand = class extends TogglePluginsBase {
|
|
11170
11079
|
static paths = [["plugins", "disable"]];
|
|
11171
|
-
static usage =
|
|
11080
|
+
static usage = Command14.Usage({
|
|
11172
11081
|
category: "Plugins",
|
|
11173
11082
|
description: "Disable a plugin (or --all). Persists in config_plugins; does not delete files.",
|
|
11174
11083
|
details: `
|
|
@@ -11204,8 +11113,8 @@ var PLUGIN_COMMANDS = [
|
|
|
11204
11113
|
|
|
11205
11114
|
// cli/commands/refresh.ts
|
|
11206
11115
|
import { readFile as readFile3 } from "fs/promises";
|
|
11207
|
-
import { resolve as
|
|
11208
|
-
import { Command as
|
|
11116
|
+
import { resolve as resolve18 } from "path";
|
|
11117
|
+
import { Command as Command15, Option as Option15 } from "clipanion";
|
|
11209
11118
|
|
|
11210
11119
|
// cli/i18n/refresh.texts.ts
|
|
11211
11120
|
var REFRESH_TEXTS = {
|
|
@@ -11234,12 +11143,12 @@ var REFRESH_TEXTS = {
|
|
|
11234
11143
|
};
|
|
11235
11144
|
|
|
11236
11145
|
// cli/util/path-guard.ts
|
|
11237
|
-
import { isAbsolute as isAbsolute3, resolve as
|
|
11146
|
+
import { isAbsolute as isAbsolute3, resolve as resolve17, sep as sep3 } from "path";
|
|
11238
11147
|
function assertContained2(cwd, rel) {
|
|
11239
11148
|
if (isAbsolute3(rel)) {
|
|
11240
11149
|
throw new Error(`node path is absolute, refusing to read: ${rel}`);
|
|
11241
11150
|
}
|
|
11242
|
-
const abs =
|
|
11151
|
+
const abs = resolve17(cwd, rel);
|
|
11243
11152
|
if (abs !== cwd && !abs.startsWith(cwd + sep3)) {
|
|
11244
11153
|
throw new Error(`node path escapes repo root: ${rel}`);
|
|
11245
11154
|
}
|
|
@@ -11248,7 +11157,7 @@ function assertContained2(cwd, rel) {
|
|
|
11248
11157
|
// cli/commands/refresh.ts
|
|
11249
11158
|
var RefreshCommand = class extends SmCommand {
|
|
11250
11159
|
static paths = [["refresh"]];
|
|
11251
|
-
static usage =
|
|
11160
|
+
static usage = Command15.Usage({
|
|
11252
11161
|
category: "Scan",
|
|
11253
11162
|
description: "Refresh enrichment rows: granular (single node) or batch (every stale row).",
|
|
11254
11163
|
details: `
|
|
@@ -11273,11 +11182,11 @@ var RefreshCommand = class extends SmCommand {
|
|
|
11273
11182
|
["Refresh every node with stale enrichments", "$0 refresh --stale"]
|
|
11274
11183
|
]
|
|
11275
11184
|
});
|
|
11276
|
-
nodePath =
|
|
11277
|
-
stale =
|
|
11185
|
+
nodePath = Option15.String({ name: "node", required: false });
|
|
11186
|
+
stale = Option15.Boolean("--stale", false, {
|
|
11278
11187
|
description: "Refresh every node whose probabilistic enrichment row is flagged stale=1."
|
|
11279
11188
|
});
|
|
11280
|
-
noPlugins =
|
|
11189
|
+
noPlugins = Option15.Boolean("--no-plugins", false, {
|
|
11281
11190
|
description: "Skip drop-in plugin discovery; use only the built-in extractor set."
|
|
11282
11191
|
});
|
|
11283
11192
|
// The remaining cyclomatic count comes from CLI ergonomics that don't
|
|
@@ -11413,7 +11322,7 @@ var RefreshCommand = class extends SmCommand {
|
|
|
11413
11322
|
let body;
|
|
11414
11323
|
try {
|
|
11415
11324
|
assertContained2(cwd, node.path);
|
|
11416
|
-
const raw = await readFile3(
|
|
11325
|
+
const raw = await readFile3(resolve18(cwd, node.path), "utf8");
|
|
11417
11326
|
body = stripFrontmatterFence(raw);
|
|
11418
11327
|
} catch (err) {
|
|
11419
11328
|
this.context.stderr.write(
|
|
@@ -11462,7 +11371,7 @@ function stripFrontmatterFence(text) {
|
|
|
11462
11371
|
var REFRESH_COMMANDS = [RefreshCommand];
|
|
11463
11372
|
|
|
11464
11373
|
// cli/commands/scan.ts
|
|
11465
|
-
import { Command as
|
|
11374
|
+
import { Command as Command17, Option as Option17 } from "clipanion";
|
|
11466
11375
|
|
|
11467
11376
|
// cli/i18n/scan.texts.ts
|
|
11468
11377
|
var SCAN_TEXTS = {
|
|
@@ -11654,7 +11563,7 @@ async function runEphemeralPath(opts, dbPath, strict, loadPrior, runScanWith) {
|
|
|
11654
11563
|
}
|
|
11655
11564
|
|
|
11656
11565
|
// cli/commands/watch.ts
|
|
11657
|
-
import { Command as
|
|
11566
|
+
import { Command as Command16, Option as Option16 } from "clipanion";
|
|
11658
11567
|
|
|
11659
11568
|
// cli/i18n/watch.texts.ts
|
|
11660
11569
|
var WATCH_TEXTS = {
|
|
@@ -11833,7 +11742,7 @@ async function runWatchLoop(opts) {
|
|
|
11833
11742
|
}
|
|
11834
11743
|
var WatchCommand = class extends SmCommand {
|
|
11835
11744
|
static paths = [["watch"]];
|
|
11836
|
-
static usage =
|
|
11745
|
+
static usage = Command16.Usage({
|
|
11837
11746
|
category: "Scan",
|
|
11838
11747
|
description: "Watch roots and run an incremental scan after each debounced batch of filesystem events.",
|
|
11839
11748
|
details: `
|
|
@@ -11857,17 +11766,17 @@ var WatchCommand = class extends SmCommand {
|
|
|
11857
11766
|
["Stream ScanResult per batch as ndjson", "$0 watch --json"]
|
|
11858
11767
|
]
|
|
11859
11768
|
});
|
|
11860
|
-
roots =
|
|
11861
|
-
noTokens =
|
|
11769
|
+
roots = Option16.Rest({ name: "roots" });
|
|
11770
|
+
noTokens = Option16.Boolean("--no-tokens", false, {
|
|
11862
11771
|
description: "Skip per-node token counts (cl100k_base BPE)."
|
|
11863
11772
|
});
|
|
11864
|
-
strict =
|
|
11773
|
+
strict = Option16.Boolean("--strict", false, {
|
|
11865
11774
|
description: "Promote frontmatter-validation findings from warn to error inside each batch. Does not change the watcher exit code."
|
|
11866
11775
|
});
|
|
11867
|
-
noPlugins =
|
|
11776
|
+
noPlugins = Option16.Boolean("--no-plugins", false, {
|
|
11868
11777
|
description: "Skip drop-in plugin discovery for the watcher session."
|
|
11869
11778
|
});
|
|
11870
|
-
maxConsecutiveFailures =
|
|
11779
|
+
maxConsecutiveFailures = Option16.String("--max-consecutive-failures", {
|
|
11871
11780
|
required: false,
|
|
11872
11781
|
description: "Shut down with exit 2 after N consecutive batch failures (default 5; 0 disables the breaker)."
|
|
11873
11782
|
});
|
|
@@ -11905,7 +11814,7 @@ function parseBreakerLimit(raw, stderr) {
|
|
|
11905
11814
|
// cli/commands/scan.ts
|
|
11906
11815
|
var ScanCommand = class extends SmCommand {
|
|
11907
11816
|
static paths = [["scan"]];
|
|
11908
|
-
static usage =
|
|
11817
|
+
static usage = Command17.Usage({
|
|
11909
11818
|
category: "Scan",
|
|
11910
11819
|
description: "Scan roots for markdown nodes, run extractors and rules.",
|
|
11911
11820
|
details: `
|
|
@@ -11934,29 +11843,29 @@ var ScanCommand = class extends SmCommand {
|
|
|
11934
11843
|
["What would the next incremental scan persist?", "$0 scan --changed -n --json"]
|
|
11935
11844
|
]
|
|
11936
11845
|
});
|
|
11937
|
-
roots =
|
|
11938
|
-
noBuiltIns =
|
|
11846
|
+
roots = Option17.Rest({ name: "roots" });
|
|
11847
|
+
noBuiltIns = Option17.Boolean("--no-built-ins", false, {
|
|
11939
11848
|
description: "Skip the built-in extension set. Yields a zero-filled ScanResult (kernel-empty-boot parity); skips DB persistence."
|
|
11940
11849
|
});
|
|
11941
|
-
noPlugins =
|
|
11850
|
+
noPlugins = Option17.Boolean("--no-plugins", false, {
|
|
11942
11851
|
description: "Skip drop-in plugin discovery. Only the built-in set runs. Combine with --no-built-ins for a fully empty pipeline."
|
|
11943
11852
|
});
|
|
11944
|
-
noTokens =
|
|
11853
|
+
noTokens = Option17.Boolean("--no-tokens", false, {
|
|
11945
11854
|
description: "Skip per-node token counts (cl100k_base BPE). Leaves node.tokens undefined; spec-valid since the field is optional."
|
|
11946
11855
|
});
|
|
11947
|
-
dryRun =
|
|
11856
|
+
dryRun = Option17.Boolean("-n,--dry-run", false, {
|
|
11948
11857
|
description: "Run the scan in memory and skip every DB write. Combined with --changed, still opens the DB read-side to load the prior snapshot."
|
|
11949
11858
|
});
|
|
11950
|
-
changed =
|
|
11859
|
+
changed = Option17.Boolean("--changed", false, {
|
|
11951
11860
|
description: "Incremental scan: reuse unchanged nodes from the persisted prior snapshot. Degrades to a full scan if no prior snapshot exists."
|
|
11952
11861
|
});
|
|
11953
|
-
allowEmpty =
|
|
11862
|
+
allowEmpty = Option17.Boolean("--allow-empty", false, {
|
|
11954
11863
|
description: "Allow a zero-result scan to wipe an already-populated DB (replace-all replace by zero rows). Off by default to avoid the typo-trap where an invalid root silently clears your data."
|
|
11955
11864
|
});
|
|
11956
|
-
strict =
|
|
11865
|
+
strict = Option17.Boolean("--strict", false, {
|
|
11957
11866
|
description: "Promote frontmatter-validation findings from warn to error (exit code 1 on any violation). Overrides scan.strict from config when both are set."
|
|
11958
11867
|
});
|
|
11959
|
-
watch =
|
|
11868
|
+
watch = Option17.Boolean("--watch", false, {
|
|
11960
11869
|
description: "Long-running mode: watch the roots and trigger an incremental scan after each debounced batch of filesystem events. Alias of `sm watch`."
|
|
11961
11870
|
});
|
|
11962
11871
|
async run() {
|
|
@@ -12054,11 +11963,11 @@ var ScanCommand = class extends SmCommand {
|
|
|
12054
11963
|
};
|
|
12055
11964
|
|
|
12056
11965
|
// cli/commands/scan-compare.ts
|
|
12057
|
-
import { existsSync as
|
|
12058
|
-
import { Command as
|
|
11966
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
11967
|
+
import { Command as Command18, Option as Option18 } from "clipanion";
|
|
12059
11968
|
var ScanCompareCommand = class extends SmCommand {
|
|
12060
11969
|
static paths = [["scan", "compare-with"]];
|
|
12061
|
-
static usage =
|
|
11970
|
+
static usage = Command18.Usage({
|
|
12062
11971
|
category: "Scan",
|
|
12063
11972
|
description: "Run a fresh scan in memory and emit a delta against the saved ScanResult dump at <dump>. Read-only.",
|
|
12064
11973
|
details: `
|
|
@@ -12086,15 +11995,15 @@ var ScanCompareCommand = class extends SmCommand {
|
|
|
12086
11995
|
["JSON output for tooling", "$0 scan compare-with baseline.json --json"]
|
|
12087
11996
|
]
|
|
12088
11997
|
});
|
|
12089
|
-
dump =
|
|
12090
|
-
roots =
|
|
12091
|
-
noTokens =
|
|
11998
|
+
dump = Option18.String({ required: true });
|
|
11999
|
+
roots = Option18.Rest({ name: "roots" });
|
|
12000
|
+
noTokens = Option18.Boolean("--no-tokens", false, {
|
|
12092
12001
|
description: "Skip per-node token counts during the fresh scan."
|
|
12093
12002
|
});
|
|
12094
|
-
strict =
|
|
12003
|
+
strict = Option18.Boolean("--strict", false, {
|
|
12095
12004
|
description: "Promote layered-config warnings and frontmatter-validation findings from warn to error."
|
|
12096
12005
|
});
|
|
12097
|
-
noPlugins =
|
|
12006
|
+
noPlugins = Option18.Boolean("--no-plugins", false, {
|
|
12098
12007
|
description: "Skip drop-in plugin discovery."
|
|
12099
12008
|
});
|
|
12100
12009
|
// Cyclomatic count comes from CLI ergonomics: 3 distinct try/catch
|
|
@@ -12165,12 +12074,12 @@ var ScanCompareCommand = class extends SmCommand {
|
|
|
12165
12074
|
}
|
|
12166
12075
|
};
|
|
12167
12076
|
function loadAndValidateDump(path) {
|
|
12168
|
-
if (!
|
|
12077
|
+
if (!existsSync14(path)) {
|
|
12169
12078
|
throw new Error(tx(SCAN_TEXTS.compareDumpNotFound, { path }));
|
|
12170
12079
|
}
|
|
12171
12080
|
let raw;
|
|
12172
12081
|
try {
|
|
12173
|
-
raw =
|
|
12082
|
+
raw = readFileSync11(path, "utf8");
|
|
12174
12083
|
} catch (err) {
|
|
12175
12084
|
const message = formatErrorMessage(err);
|
|
12176
12085
|
throw new Error(tx(SCAN_TEXTS.compareDumpReadFailed, { path, message }), { cause: err });
|
|
@@ -12279,8 +12188,8 @@ function renderDeltaIssues(issues) {
|
|
|
12279
12188
|
|
|
12280
12189
|
// cli/commands/serve.ts
|
|
12281
12190
|
import { spawn } from "child_process";
|
|
12282
|
-
import { existsSync as
|
|
12283
|
-
import { Command as
|
|
12191
|
+
import { existsSync as existsSync18 } from "fs";
|
|
12192
|
+
import { Command as Command19, Option as Option19 } from "clipanion";
|
|
12284
12193
|
|
|
12285
12194
|
// server/index.ts
|
|
12286
12195
|
import { serve } from "@hono/node-server";
|
|
@@ -12461,7 +12370,7 @@ function contentTypeFor(format) {
|
|
|
12461
12370
|
}
|
|
12462
12371
|
|
|
12463
12372
|
// server/health.ts
|
|
12464
|
-
import { existsSync as
|
|
12373
|
+
import { existsSync as existsSync15 } from "fs";
|
|
12465
12374
|
var FALLBACK_SCHEMA_VERSION = "1";
|
|
12466
12375
|
function buildHealth(deps) {
|
|
12467
12376
|
return {
|
|
@@ -12470,7 +12379,7 @@ function buildHealth(deps) {
|
|
|
12470
12379
|
specVersion: deps.specVersion,
|
|
12471
12380
|
implVersion: VERSION,
|
|
12472
12381
|
scope: deps.scope,
|
|
12473
|
-
db:
|
|
12382
|
+
db: existsSync15(deps.dbPath) ? "present" : "missing"
|
|
12474
12383
|
};
|
|
12475
12384
|
}
|
|
12476
12385
|
async function resolveSpecVersion2() {
|
|
@@ -12910,9 +12819,9 @@ function emptyScanResult() {
|
|
|
12910
12819
|
}
|
|
12911
12820
|
|
|
12912
12821
|
// server/static.ts
|
|
12913
|
-
import { existsSync as
|
|
12822
|
+
import { existsSync as existsSync16 } from "fs";
|
|
12914
12823
|
import { readFile as readFile5 } from "fs/promises";
|
|
12915
|
-
import { extname, join as
|
|
12824
|
+
import { extname, join as join13 } from "path";
|
|
12916
12825
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
12917
12826
|
var INDEX_HTML = "index.html";
|
|
12918
12827
|
var PLACEHOLDER_HTML = `<!doctype html>
|
|
@@ -12943,8 +12852,8 @@ function createSpaFallback(uiDist) {
|
|
|
12943
12852
|
return async (c, _next) => {
|
|
12944
12853
|
if (c.req.method !== "GET" && c.req.method !== "HEAD") return c.notFound();
|
|
12945
12854
|
if (uiDist === null) return htmlResponse(c, PLACEHOLDER_HTML);
|
|
12946
|
-
const indexPath =
|
|
12947
|
-
if (!
|
|
12855
|
+
const indexPath = join13(uiDist, INDEX_HTML);
|
|
12856
|
+
if (!existsSync16(indexPath)) return htmlResponse(c, PLACEHOLDER_HTML);
|
|
12948
12857
|
return fileResponse(c, indexPath);
|
|
12949
12858
|
};
|
|
12950
12859
|
}
|
|
@@ -13348,6 +13257,7 @@ function createWatcherService(opts) {
|
|
|
13348
13257
|
if ("ready" in chokidarHandle && chokidarHandle.ready instanceof Promise) {
|
|
13349
13258
|
await chokidarHandle.ready;
|
|
13350
13259
|
}
|
|
13260
|
+
await runInitialBatch({ isStopped: () => stopped, runOneBatch });
|
|
13351
13261
|
opts.broadcaster.broadcast(
|
|
13352
13262
|
buildWatcherStartedEvent({ roots: [WATCH_ROOT], debounceMs })
|
|
13353
13263
|
);
|
|
@@ -13430,6 +13340,19 @@ async function persistOutcome(dbPath, ran) {
|
|
|
13430
13340
|
(writer) => writer.scans.persist(result, { renameOps, extractorRuns, enrichments })
|
|
13431
13341
|
);
|
|
13432
13342
|
}
|
|
13343
|
+
async function runInitialBatch(deps) {
|
|
13344
|
+
if (deps.isStopped()) return;
|
|
13345
|
+
try {
|
|
13346
|
+
await deps.runOneBatch();
|
|
13347
|
+
} catch (err) {
|
|
13348
|
+
const message = formatErrorMessage(err);
|
|
13349
|
+
log.warn(
|
|
13350
|
+
tx(SERVER_TEXTS.watcherBatchFailed, {
|
|
13351
|
+
message: sanitizeForTerminal(message)
|
|
13352
|
+
})
|
|
13353
|
+
);
|
|
13354
|
+
}
|
|
13355
|
+
}
|
|
13433
13356
|
|
|
13434
13357
|
// server/options.ts
|
|
13435
13358
|
var DEFAULT_PORT = 4242;
|
|
@@ -13534,10 +13457,10 @@ function validateWatcherDebounce(value) {
|
|
|
13534
13457
|
}
|
|
13535
13458
|
|
|
13536
13459
|
// server/paths.ts
|
|
13537
|
-
import { existsSync as
|
|
13538
|
-
import { dirname as
|
|
13539
|
-
import { fileURLToPath as
|
|
13540
|
-
var DEFAULT_UI_REL =
|
|
13460
|
+
import { existsSync as existsSync17, statSync as statSync5 } from "fs";
|
|
13461
|
+
import { dirname as dirname9, isAbsolute as isAbsolute5, join as join14, resolve as resolve19 } from "path";
|
|
13462
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
13463
|
+
var DEFAULT_UI_REL = join14("ui", "dist", "ui", "browser");
|
|
13541
13464
|
var PACKAGE_UI_REL = "ui";
|
|
13542
13465
|
var INDEX_HTML2 = "index.html";
|
|
13543
13466
|
function resolveDefaultUiDist(ctx) {
|
|
@@ -13546,13 +13469,13 @@ function resolveDefaultUiDist(ctx) {
|
|
|
13546
13469
|
return walkUpForUi(ctx.cwd);
|
|
13547
13470
|
}
|
|
13548
13471
|
function resolveExplicitUiDist(ctx, raw) {
|
|
13549
|
-
return isAbsolute5(raw) ? raw :
|
|
13472
|
+
return isAbsolute5(raw) ? raw : resolve19(ctx.cwd, raw);
|
|
13550
13473
|
}
|
|
13551
13474
|
function isUiBundleDir(path) {
|
|
13552
|
-
if (!
|
|
13475
|
+
if (!existsSync17(path)) return false;
|
|
13553
13476
|
try {
|
|
13554
13477
|
if (!statSync5(path).isDirectory()) return false;
|
|
13555
|
-
return
|
|
13478
|
+
return existsSync17(join14(path, INDEX_HTML2));
|
|
13556
13479
|
} catch {
|
|
13557
13480
|
return false;
|
|
13558
13481
|
}
|
|
@@ -13560,7 +13483,7 @@ function isUiBundleDir(path) {
|
|
|
13560
13483
|
function resolvePackageBundledUi() {
|
|
13561
13484
|
let here;
|
|
13562
13485
|
try {
|
|
13563
|
-
here =
|
|
13486
|
+
here = dirname9(fileURLToPath5(import.meta.url));
|
|
13564
13487
|
} catch {
|
|
13565
13488
|
return null;
|
|
13566
13489
|
}
|
|
@@ -13569,22 +13492,22 @@ function resolvePackageBundledUi() {
|
|
|
13569
13492
|
function resolvePackageBundledUiFrom(here) {
|
|
13570
13493
|
let current = here;
|
|
13571
13494
|
for (let i = 0; i < 8; i++) {
|
|
13572
|
-
const candidate =
|
|
13495
|
+
const candidate = join14(current, PACKAGE_UI_REL);
|
|
13573
13496
|
if (isUiBundleDir(candidate)) return candidate;
|
|
13574
|
-
const distHere =
|
|
13497
|
+
const distHere = join14(current, "dist", PACKAGE_UI_REL);
|
|
13575
13498
|
if (isUiBundleDir(distHere)) return distHere;
|
|
13576
|
-
const parent =
|
|
13499
|
+
const parent = dirname9(current);
|
|
13577
13500
|
if (parent === current) return null;
|
|
13578
13501
|
current = parent;
|
|
13579
13502
|
}
|
|
13580
13503
|
return null;
|
|
13581
13504
|
}
|
|
13582
13505
|
function walkUpForUi(startDir) {
|
|
13583
|
-
let current =
|
|
13506
|
+
let current = resolve19(startDir);
|
|
13584
13507
|
for (let i = 0; i < 64; i++) {
|
|
13585
|
-
const candidate =
|
|
13508
|
+
const candidate = join14(current, DEFAULT_UI_REL);
|
|
13586
13509
|
if (isUiBundleDir(candidate)) return candidate;
|
|
13587
|
-
const parent =
|
|
13510
|
+
const parent = dirname9(current);
|
|
13588
13511
|
if (parent === current) return null;
|
|
13589
13512
|
current = parent;
|
|
13590
13513
|
}
|
|
@@ -13810,15 +13733,9 @@ function renderFiglet(input) {
|
|
|
13810
13733
|
greenUnderline,
|
|
13811
13734
|
greenUnderlineClose,
|
|
13812
13735
|
violetOpen,
|
|
13813
|
-
violetClose
|
|
13814
|
-
greenOpen,
|
|
13815
|
-
greenClose
|
|
13736
|
+
violetClose
|
|
13816
13737
|
} = resolveAnsi(input.colorEnabled);
|
|
13817
|
-
const logoLines = LOGO_LINES.map((line
|
|
13818
|
-
const open = i < 3 ? violetOpen : greenOpen;
|
|
13819
|
-
const close = i < 3 ? violetClose : greenClose;
|
|
13820
|
-
return `${open}${line}${close}`;
|
|
13821
|
-
});
|
|
13738
|
+
const logoLines = LOGO_LINES.map((line) => `${violetOpen}${line}${violetClose}`);
|
|
13822
13739
|
const versionText = `v${input.version}`;
|
|
13823
13740
|
const versionPad = Math.max(0, LOGO_WIDTH - versionText.length);
|
|
13824
13741
|
const versionLine = `${" ".repeat(versionPad)}${dimOpen}${versionText}${dimClose}`;
|
|
@@ -13842,9 +13759,7 @@ var EMPTY_ANSI = {
|
|
|
13842
13759
|
greenUnderline: "",
|
|
13843
13760
|
greenUnderlineClose: "",
|
|
13844
13761
|
violetOpen: "",
|
|
13845
|
-
violetClose: ""
|
|
13846
|
-
greenOpen: "",
|
|
13847
|
-
greenClose: ""
|
|
13762
|
+
violetClose: ""
|
|
13848
13763
|
};
|
|
13849
13764
|
var ENABLED_ANSI = {
|
|
13850
13765
|
dimOpen: ESC.dim,
|
|
@@ -13852,9 +13767,7 @@ var ENABLED_ANSI = {
|
|
|
13852
13767
|
greenUnderline: `${ESC.green}${ESC.underline}`,
|
|
13853
13768
|
greenUnderlineClose: ESC.reset,
|
|
13854
13769
|
violetOpen: ESC.violet,
|
|
13855
|
-
violetClose: ESC.reset
|
|
13856
|
-
greenOpen: ESC.green,
|
|
13857
|
-
greenClose: ESC.reset
|
|
13770
|
+
violetClose: ESC.reset
|
|
13858
13771
|
};
|
|
13859
13772
|
function resolveAnsi(colorEnabled) {
|
|
13860
13773
|
return colorEnabled ? ENABLED_ANSI : EMPTY_ANSI;
|
|
@@ -13880,7 +13793,7 @@ function formatCwdPath(cwd) {
|
|
|
13880
13793
|
// cli/commands/serve.ts
|
|
13881
13794
|
var ServeCommand = class extends SmCommand {
|
|
13882
13795
|
static paths = [["serve"]];
|
|
13883
|
-
static usage =
|
|
13796
|
+
static usage = Command19.Usage({
|
|
13884
13797
|
category: "Setup",
|
|
13885
13798
|
description: "Start the Hono BFF (single-port: REST + WebSocket + SPA bundle).",
|
|
13886
13799
|
details: `
|
|
@@ -13905,22 +13818,22 @@ var ServeCommand = class extends SmCommand {
|
|
|
13905
13818
|
["Point at a pre-built UI bundle", "$0 serve --ui-dist ./ui/dist/browser"]
|
|
13906
13819
|
]
|
|
13907
13820
|
});
|
|
13908
|
-
port =
|
|
13821
|
+
port = Option19.String("--port", {
|
|
13909
13822
|
required: false,
|
|
13910
13823
|
description: "Listening port (default 4242). 0 = OS-assigned."
|
|
13911
13824
|
});
|
|
13912
|
-
host =
|
|
13825
|
+
host = Option19.String("--host", {
|
|
13913
13826
|
required: false,
|
|
13914
13827
|
description: "Listening host (default 127.0.0.1). Loopback-only enforced when --dev-cors is set."
|
|
13915
13828
|
});
|
|
13916
|
-
scope =
|
|
13829
|
+
scope = Option19.String("--scope", {
|
|
13917
13830
|
required: false,
|
|
13918
13831
|
description: "project | global. Alias for -g/--global. Default: project."
|
|
13919
13832
|
});
|
|
13920
|
-
noBuiltIns =
|
|
13833
|
+
noBuiltIns = Option19.Boolean("--no-built-ins", false, {
|
|
13921
13834
|
description: "Skip built-in plugin registration (parity with sm scan --no-built-ins)."
|
|
13922
13835
|
});
|
|
13923
|
-
noPlugins =
|
|
13836
|
+
noPlugins = Option19.Boolean("--no-plugins", false, {
|
|
13924
13837
|
description: "Skip drop-in plugin discovery."
|
|
13925
13838
|
});
|
|
13926
13839
|
// `Option.Boolean('--open', true)` — Clipanion's parser auto-derives
|
|
@@ -13930,24 +13843,24 @@ var ServeCommand = class extends SmCommand {
|
|
|
13930
13843
|
// two registrations for the same flag and rejects the invocation
|
|
13931
13844
|
// with "Ambiguous Syntax Error". Same convention shipped by every
|
|
13932
13845
|
// other `--no-...` flag in the CLI tree.
|
|
13933
|
-
open =
|
|
13846
|
+
open = Option19.Boolean("--open", true, {
|
|
13934
13847
|
description: "Auto-open the SPA in the user's default browser after listen. --no-open opts out."
|
|
13935
13848
|
});
|
|
13936
|
-
devCors =
|
|
13849
|
+
devCors = Option19.Boolean("--dev-cors", false, {
|
|
13937
13850
|
description: "Enable permissive CORS for the Angular dev-server proxy workflow."
|
|
13938
13851
|
});
|
|
13939
13852
|
// `--ui-dist` is intentionally undocumented in the Usage block above
|
|
13940
13853
|
// (the demo build pipeline + tests rely on it; everyday users never
|
|
13941
13854
|
// need it). Clipanion still exposes it on the parser; the Usage
|
|
13942
13855
|
// omission is the "hidden" contract per the 14.1 brief.
|
|
13943
|
-
uiDist =
|
|
13944
|
-
noWatcher =
|
|
13856
|
+
uiDist = Option19.String("--ui-dist", { required: false, hidden: true });
|
|
13857
|
+
noWatcher = Option19.Boolean("--no-watcher", false, {
|
|
13945
13858
|
description: "Disable the chokidar-fed scan-and-broadcast loop. Use only for CI / read-only deployments."
|
|
13946
13859
|
});
|
|
13947
13860
|
// `--watcher-debounce-ms` is undocumented sugar for advanced users
|
|
13948
13861
|
// who want to tighten / relax the watcher's batching window without
|
|
13949
13862
|
// editing settings.json. Hidden flag — the Usage block omits it.
|
|
13950
|
-
watcherDebounceMs =
|
|
13863
|
+
watcherDebounceMs = Option19.String("--watcher-debounce-ms", { required: false, hidden: true });
|
|
13951
13864
|
// Long-running daemon — `done in <…>` after a graceful shutdown is
|
|
13952
13865
|
// noise. Mirrors `sm watch`'s opt-out.
|
|
13953
13866
|
emitElapsed = false;
|
|
@@ -13975,7 +13888,7 @@ var ServeCommand = class extends SmCommand {
|
|
|
13975
13888
|
return ExitCode.Error;
|
|
13976
13889
|
}
|
|
13977
13890
|
const dbPath = resolveDbPath({ global: this.global, db: this.db, ...runtimeCtx });
|
|
13978
|
-
if (this.db !== void 0 && !
|
|
13891
|
+
if (this.db !== void 0 && !existsSync18(dbPath)) {
|
|
13979
13892
|
this.context.stderr.write(
|
|
13980
13893
|
tx(SERVE_TEXTS.dbNotFound, { path: sanitizeForTerminal(dbPath) })
|
|
13981
13894
|
);
|
|
@@ -14162,7 +14075,7 @@ function tryOpenBrowser(url, stderr) {
|
|
|
14162
14075
|
}
|
|
14163
14076
|
|
|
14164
14077
|
// cli/commands/show.ts
|
|
14165
|
-
import { Command as
|
|
14078
|
+
import { Command as Command20, Option as Option20 } from "clipanion";
|
|
14166
14079
|
|
|
14167
14080
|
// cli/i18n/show.texts.ts
|
|
14168
14081
|
var SHOW_TEXTS = {
|
|
@@ -14202,7 +14115,7 @@ var SHOW_TEXTS = {
|
|
|
14202
14115
|
// cli/commands/show.ts
|
|
14203
14116
|
var ShowCommand = class extends SmCommand {
|
|
14204
14117
|
static paths = [["show"]];
|
|
14205
|
-
static usage =
|
|
14118
|
+
static usage = Command20.Usage({
|
|
14206
14119
|
category: "Browse",
|
|
14207
14120
|
description: "Node detail: weight, frontmatter, links, issues.",
|
|
14208
14121
|
details: `
|
|
@@ -14218,7 +14131,7 @@ var ShowCommand = class extends SmCommand {
|
|
|
14218
14131
|
["Machine-readable detail", "$0 show .claude/agents/architect.md --json"]
|
|
14219
14132
|
]
|
|
14220
14133
|
});
|
|
14221
|
-
nodePath =
|
|
14134
|
+
nodePath = Option20.String({ required: true });
|
|
14222
14135
|
async run() {
|
|
14223
14136
|
const dbPath = resolveDbPath({ global: this.global, db: this.db, ...defaultRuntimeContext() });
|
|
14224
14137
|
if (!assertDbExists(dbPath, this.context.stderr)) return ExitCode.NotFound;
|
|
@@ -14367,7 +14280,7 @@ function rankConfidenceForGrouping(c) {
|
|
|
14367
14280
|
}
|
|
14368
14281
|
|
|
14369
14282
|
// cli/commands/stubs.ts
|
|
14370
|
-
import { Command as
|
|
14283
|
+
import { Command as Command21, Option as Option21 } from "clipanion";
|
|
14371
14284
|
|
|
14372
14285
|
// cli/i18n/stubs.texts.ts
|
|
14373
14286
|
var STUBS_TEXTS = {
|
|
@@ -14382,9 +14295,9 @@ function notImplemented(cmd, verb) {
|
|
|
14382
14295
|
cmd.context.stderr.write(tx(STUBS_TEXTS.notImplemented, { verb }));
|
|
14383
14296
|
return ExitCode.Error;
|
|
14384
14297
|
}
|
|
14385
|
-
var DoctorCommand = class extends
|
|
14298
|
+
var DoctorCommand = class extends Command21 {
|
|
14386
14299
|
static paths = [["doctor"]];
|
|
14387
|
-
static usage =
|
|
14300
|
+
static usage = Command21.Usage({
|
|
14388
14301
|
category: "Setup",
|
|
14389
14302
|
description: planned("Diagnostic report: DB integrity, pending migrations, orphan rows, plugin status, runner availability.")
|
|
14390
14303
|
});
|
|
@@ -14392,23 +14305,23 @@ var DoctorCommand = class extends Command22 {
|
|
|
14392
14305
|
return notImplemented(this, "doctor");
|
|
14393
14306
|
}
|
|
14394
14307
|
};
|
|
14395
|
-
var FindingsCommand = class extends
|
|
14308
|
+
var FindingsCommand = class extends Command21 {
|
|
14396
14309
|
static paths = [["findings"]];
|
|
14397
|
-
static usage =
|
|
14310
|
+
static usage = Command21.Usage({
|
|
14398
14311
|
category: "Browse",
|
|
14399
14312
|
description: planned("Probabilistic findings: injection, stale summaries, low confidence.")
|
|
14400
14313
|
});
|
|
14401
|
-
kind =
|
|
14402
|
-
since =
|
|
14403
|
-
threshold =
|
|
14404
|
-
json =
|
|
14314
|
+
kind = Option21.String("--kind", { required: false });
|
|
14315
|
+
since = Option21.String("--since", { required: false });
|
|
14316
|
+
threshold = Option21.String("--threshold", { required: false });
|
|
14317
|
+
json = Option21.Boolean("--json", false);
|
|
14405
14318
|
async execute() {
|
|
14406
14319
|
return notImplemented(this, "findings");
|
|
14407
14320
|
}
|
|
14408
14321
|
};
|
|
14409
|
-
var ActionsListCommand = class extends
|
|
14322
|
+
var ActionsListCommand = class extends Command21 {
|
|
14410
14323
|
static paths = [["actions", "list"]];
|
|
14411
|
-
static usage =
|
|
14324
|
+
static usage = Command21.Usage({
|
|
14412
14325
|
category: "Jobs",
|
|
14413
14326
|
description: planned("Registered action types (manifest view).")
|
|
14414
14327
|
});
|
|
@@ -14416,121 +14329,121 @@ var ActionsListCommand = class extends Command22 {
|
|
|
14416
14329
|
return notImplemented(this, "actions list");
|
|
14417
14330
|
}
|
|
14418
14331
|
};
|
|
14419
|
-
var ActionsShowCommand = class extends
|
|
14332
|
+
var ActionsShowCommand = class extends Command21 {
|
|
14420
14333
|
static paths = [["actions", "show"]];
|
|
14421
|
-
static usage =
|
|
14334
|
+
static usage = Command21.Usage({
|
|
14422
14335
|
category: "Jobs",
|
|
14423
14336
|
description: planned("Full action manifest, including preconditions and expected duration.")
|
|
14424
14337
|
});
|
|
14425
|
-
id =
|
|
14338
|
+
id = Option21.String({ required: true });
|
|
14426
14339
|
async execute() {
|
|
14427
14340
|
return notImplemented(this, "actions show");
|
|
14428
14341
|
}
|
|
14429
14342
|
};
|
|
14430
|
-
var JobSubmitCommand = class extends
|
|
14343
|
+
var JobSubmitCommand = class extends Command21 {
|
|
14431
14344
|
static paths = [["job", "submit"]];
|
|
14432
|
-
static usage =
|
|
14345
|
+
static usage = Command21.Usage({
|
|
14433
14346
|
category: "Jobs",
|
|
14434
14347
|
description: planned("Enqueue a single job or fan out to every matching node (--all).")
|
|
14435
14348
|
});
|
|
14436
|
-
action =
|
|
14437
|
-
node =
|
|
14438
|
-
all =
|
|
14439
|
-
run =
|
|
14440
|
-
force =
|
|
14441
|
-
ttl =
|
|
14442
|
-
priority =
|
|
14349
|
+
action = Option21.String({ required: true });
|
|
14350
|
+
node = Option21.String("-n", { required: false });
|
|
14351
|
+
all = Option21.Boolean("--all", false);
|
|
14352
|
+
run = Option21.Boolean("--run", false);
|
|
14353
|
+
force = Option21.Boolean("--force", false);
|
|
14354
|
+
ttl = Option21.String("--ttl", { required: false });
|
|
14355
|
+
priority = Option21.String("--priority", { required: false });
|
|
14443
14356
|
async execute() {
|
|
14444
14357
|
return notImplemented(this, "job submit");
|
|
14445
14358
|
}
|
|
14446
14359
|
};
|
|
14447
|
-
var JobListCommand = class extends
|
|
14360
|
+
var JobListCommand = class extends Command21 {
|
|
14448
14361
|
static paths = [["job", "list"]];
|
|
14449
|
-
static usage =
|
|
14450
|
-
status =
|
|
14451
|
-
action =
|
|
14452
|
-
node =
|
|
14362
|
+
static usage = Command21.Usage({ category: "Jobs", description: planned("List jobs.") });
|
|
14363
|
+
status = Option21.String("--status", { required: false });
|
|
14364
|
+
action = Option21.String("--action", { required: false });
|
|
14365
|
+
node = Option21.String("--node", { required: false });
|
|
14453
14366
|
async execute() {
|
|
14454
14367
|
return notImplemented(this, "job list");
|
|
14455
14368
|
}
|
|
14456
14369
|
};
|
|
14457
|
-
var JobShowCommand = class extends
|
|
14370
|
+
var JobShowCommand = class extends Command21 {
|
|
14458
14371
|
static paths = [["job", "show"]];
|
|
14459
|
-
static usage =
|
|
14460
|
-
id =
|
|
14372
|
+
static usage = Command21.Usage({ category: "Jobs", description: planned("Job detail: state, claim time, TTL, runner, content hash.") });
|
|
14373
|
+
id = Option21.String({ required: true });
|
|
14461
14374
|
async execute() {
|
|
14462
14375
|
return notImplemented(this, "job show");
|
|
14463
14376
|
}
|
|
14464
14377
|
};
|
|
14465
|
-
var JobPreviewCommand = class extends
|
|
14378
|
+
var JobPreviewCommand = class extends Command21 {
|
|
14466
14379
|
static paths = [["job", "preview"]];
|
|
14467
|
-
static usage =
|
|
14468
|
-
id =
|
|
14380
|
+
static usage = Command21.Usage({ category: "Jobs", description: planned("Render the job MD file without executing.") });
|
|
14381
|
+
id = Option21.String({ required: true });
|
|
14469
14382
|
async execute() {
|
|
14470
14383
|
return notImplemented(this, "job preview");
|
|
14471
14384
|
}
|
|
14472
14385
|
};
|
|
14473
|
-
var JobClaimCommand = class extends
|
|
14386
|
+
var JobClaimCommand = class extends Command21 {
|
|
14474
14387
|
static paths = [["job", "claim"]];
|
|
14475
|
-
static usage =
|
|
14388
|
+
static usage = Command21.Usage({
|
|
14476
14389
|
category: "Jobs",
|
|
14477
14390
|
description: planned("Atomic primitive: return next queued job id, mark it running.")
|
|
14478
14391
|
});
|
|
14479
|
-
filter =
|
|
14392
|
+
filter = Option21.String("--filter", { required: false });
|
|
14480
14393
|
async execute() {
|
|
14481
14394
|
return notImplemented(this, "job claim");
|
|
14482
14395
|
}
|
|
14483
14396
|
};
|
|
14484
|
-
var JobRunCommand = class extends
|
|
14397
|
+
var JobRunCommand = class extends Command21 {
|
|
14485
14398
|
static paths = [["job", "run"]];
|
|
14486
|
-
static usage =
|
|
14399
|
+
static usage = Command21.Usage({
|
|
14487
14400
|
category: "Jobs",
|
|
14488
14401
|
description: planned("Full CLI-runner loop: claim + spawn + record.")
|
|
14489
14402
|
});
|
|
14490
|
-
all =
|
|
14491
|
-
max =
|
|
14403
|
+
all = Option21.Boolean("--all", false);
|
|
14404
|
+
max = Option21.String("--max", { required: false });
|
|
14492
14405
|
async execute() {
|
|
14493
14406
|
return notImplemented(this, "job run");
|
|
14494
14407
|
}
|
|
14495
14408
|
};
|
|
14496
|
-
var JobStatusCommand = class extends
|
|
14409
|
+
var JobStatusCommand = class extends Command21 {
|
|
14497
14410
|
static paths = [["job", "status"]];
|
|
14498
|
-
static usage =
|
|
14411
|
+
static usage = Command21.Usage({
|
|
14499
14412
|
category: "Jobs",
|
|
14500
14413
|
description: planned("Counts (per status) or single-job status.")
|
|
14501
14414
|
});
|
|
14502
|
-
id =
|
|
14415
|
+
id = Option21.String({ required: false });
|
|
14503
14416
|
async execute() {
|
|
14504
14417
|
return notImplemented(this, "job status");
|
|
14505
14418
|
}
|
|
14506
14419
|
};
|
|
14507
|
-
var JobCancelCommand = class extends
|
|
14420
|
+
var JobCancelCommand = class extends Command21 {
|
|
14508
14421
|
static paths = [["job", "cancel"]];
|
|
14509
|
-
static usage =
|
|
14422
|
+
static usage = Command21.Usage({
|
|
14510
14423
|
category: "Jobs",
|
|
14511
14424
|
description: planned("Force a running job to failed with reason user-cancelled.")
|
|
14512
14425
|
});
|
|
14513
|
-
id =
|
|
14514
|
-
all =
|
|
14426
|
+
id = Option21.String({ required: false });
|
|
14427
|
+
all = Option21.Boolean("--all", false);
|
|
14515
14428
|
async execute() {
|
|
14516
14429
|
return notImplemented(this, "job cancel");
|
|
14517
14430
|
}
|
|
14518
14431
|
};
|
|
14519
|
-
var RecordCommand = class extends
|
|
14432
|
+
var RecordCommand = class extends Command21 {
|
|
14520
14433
|
static paths = [["record"]];
|
|
14521
|
-
static usage =
|
|
14434
|
+
static usage = Command21.Usage({
|
|
14522
14435
|
category: "Jobs",
|
|
14523
14436
|
description: planned("Close a running job with success or failure. Nonce is the sole credential.")
|
|
14524
14437
|
});
|
|
14525
|
-
id =
|
|
14526
|
-
nonce =
|
|
14527
|
-
status =
|
|
14528
|
-
report =
|
|
14529
|
-
tokensIn =
|
|
14530
|
-
tokensOut =
|
|
14531
|
-
durationMs =
|
|
14532
|
-
model =
|
|
14533
|
-
error =
|
|
14438
|
+
id = Option21.String("--id", { required: true });
|
|
14439
|
+
nonce = Option21.String("--nonce", { required: true });
|
|
14440
|
+
status = Option21.String("--status", { required: true });
|
|
14441
|
+
report = Option21.String("--report", { required: false });
|
|
14442
|
+
tokensIn = Option21.String("--tokens-in", { required: false });
|
|
14443
|
+
tokensOut = Option21.String("--tokens-out", { required: false });
|
|
14444
|
+
durationMs = Option21.String("--duration-ms", { required: false });
|
|
14445
|
+
model = Option21.String("--model", { required: false });
|
|
14446
|
+
error = Option21.String("--error", { required: false });
|
|
14534
14447
|
async execute() {
|
|
14535
14448
|
return notImplemented(this, "record");
|
|
14536
14449
|
}
|
|
@@ -14551,6 +14464,99 @@ var STUB_COMMANDS = [
|
|
|
14551
14464
|
RecordCommand
|
|
14552
14465
|
];
|
|
14553
14466
|
|
|
14467
|
+
// cli/commands/tutorial.ts
|
|
14468
|
+
import { existsSync as existsSync19, readFileSync as readFileSync12 } from "fs";
|
|
14469
|
+
import { writeFile as writeFile2 } from "fs/promises";
|
|
14470
|
+
import { dirname as dirname10, join as join15, resolve as resolve20 } from "path";
|
|
14471
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
14472
|
+
import { Command as Command22, Option as Option22 } from "clipanion";
|
|
14473
|
+
|
|
14474
|
+
// cli/i18n/tutorial.texts.ts
|
|
14475
|
+
var TUTORIAL_TEXTS = {
|
|
14476
|
+
// Success — written to stdout after `<cwd>/sm-tutorial.md` is created.
|
|
14477
|
+
written: 'Done. sm-tutorial.md created at {{cwd}}. Open Claude Code here and tell it "run @sm-tutorial.md" to start the interactive tutorial.\n',
|
|
14478
|
+
// Refusal — `sm-tutorial.md` already exists and `--force` was not set.
|
|
14479
|
+
// Goes to stderr, exit code 2 (operational error per spec § Exit codes).
|
|
14480
|
+
alreadyExists: "sm tutorial: sm-tutorial.md already exists at {{cwd}}. Pass `--force` to overwrite.\n",
|
|
14481
|
+
// I/O failure on write or on reading the bundled SKILL source.
|
|
14482
|
+
writeFailed: "sm tutorial: failed to write sm-tutorial.md: {{message}}\n",
|
|
14483
|
+
sourceMissing: "sm tutorial: could not read the bundled tutorial (SKILL.md) from the install. Reinstall @skill-map/cli or report the bug.\n"
|
|
14484
|
+
};
|
|
14485
|
+
|
|
14486
|
+
// cli/commands/tutorial.ts
|
|
14487
|
+
var SM_TUTORIAL_FILENAME = "sm-tutorial.md";
|
|
14488
|
+
var TutorialCommand = class extends SmCommand {
|
|
14489
|
+
static paths = [["tutorial"]];
|
|
14490
|
+
static usage = Command22.Usage({
|
|
14491
|
+
category: "Setup",
|
|
14492
|
+
description: "Materialize the interactive tester tutorial (sm-tutorial.md) in the current directory.",
|
|
14493
|
+
details: `
|
|
14494
|
+
Drops the canonical SKILL.md content as ./sm-tutorial.md so a tester
|
|
14495
|
+
can open Claude Code in the cwd and load the file as a skill by
|
|
14496
|
+
typing "ejecut\xE1 @sm-tutorial.md". Top-level only \u2014 no subdirectory
|
|
14497
|
+
is created.
|
|
14498
|
+
|
|
14499
|
+
Does NOT require an initialized .skill-map/ project. Refuses to
|
|
14500
|
+
overwrite an existing sm-tutorial.md unless --force is passed.
|
|
14501
|
+
`,
|
|
14502
|
+
examples: [
|
|
14503
|
+
["Materialize the tutorial in the cwd", "$0 tutorial"],
|
|
14504
|
+
["Overwrite an existing sm-tutorial.md", "$0 tutorial --force"]
|
|
14505
|
+
]
|
|
14506
|
+
});
|
|
14507
|
+
force = Option22.Boolean("--force", false, {
|
|
14508
|
+
description: "Overwrite an existing sm-tutorial.md without prompting."
|
|
14509
|
+
});
|
|
14510
|
+
async run() {
|
|
14511
|
+
const ctx = defaultRuntimeContext();
|
|
14512
|
+
const target = join15(ctx.cwd, SM_TUTORIAL_FILENAME);
|
|
14513
|
+
if (await pathExists(target) && !this.force) {
|
|
14514
|
+
this.context.stderr.write(tx(TUTORIAL_TEXTS.alreadyExists, { cwd: ctx.cwd }));
|
|
14515
|
+
return ExitCode.Error;
|
|
14516
|
+
}
|
|
14517
|
+
let body;
|
|
14518
|
+
try {
|
|
14519
|
+
body = loadBundledTutorialText();
|
|
14520
|
+
} catch {
|
|
14521
|
+
this.context.stderr.write(TUTORIAL_TEXTS.sourceMissing);
|
|
14522
|
+
return ExitCode.Error;
|
|
14523
|
+
}
|
|
14524
|
+
try {
|
|
14525
|
+
await writeFile2(target, body);
|
|
14526
|
+
} catch (err) {
|
|
14527
|
+
this.context.stderr.write(
|
|
14528
|
+
tx(TUTORIAL_TEXTS.writeFailed, { message: formatErrorMessage(err) })
|
|
14529
|
+
);
|
|
14530
|
+
return ExitCode.Error;
|
|
14531
|
+
}
|
|
14532
|
+
this.context.stdout.write(tx(TUTORIAL_TEXTS.written, { cwd: ctx.cwd }));
|
|
14533
|
+
return ExitCode.Ok;
|
|
14534
|
+
}
|
|
14535
|
+
};
|
|
14536
|
+
var cachedTutorial = null;
|
|
14537
|
+
function loadBundledTutorialText() {
|
|
14538
|
+
if (cachedTutorial !== null) return cachedTutorial;
|
|
14539
|
+
cachedTutorial = readTutorialFromDisk();
|
|
14540
|
+
return cachedTutorial;
|
|
14541
|
+
}
|
|
14542
|
+
function readTutorialFromDisk() {
|
|
14543
|
+
const here = dirname10(fileURLToPath6(import.meta.url));
|
|
14544
|
+
const candidates = [
|
|
14545
|
+
// dev: src/cli/commands/ → repo-root .claude/skills/sm-tutorial/SKILL.md
|
|
14546
|
+
resolve20(here, "../../../.claude/skills/sm-tutorial/SKILL.md"),
|
|
14547
|
+
// bundled: dist/cli.js → dist/cli/tutorial/sm-tutorial.md (sibling)
|
|
14548
|
+
resolve20(here, "cli/tutorial/sm-tutorial.md"),
|
|
14549
|
+
// bundled fallback: any-depth → cli/tutorial/sm-tutorial.md
|
|
14550
|
+
resolve20(here, "../cli/tutorial/sm-tutorial.md")
|
|
14551
|
+
];
|
|
14552
|
+
for (const candidate of candidates) {
|
|
14553
|
+
if (existsSync19(candidate)) {
|
|
14554
|
+
return readFileSync12(candidate, "utf8");
|
|
14555
|
+
}
|
|
14556
|
+
}
|
|
14557
|
+
throw new Error(`SKILL.md not found in any candidate location (last tried: ${candidates[candidates.length - 1]})`);
|
|
14558
|
+
}
|
|
14559
|
+
|
|
14554
14560
|
// cli/commands/version.ts
|
|
14555
14561
|
import { Command as Command23 } from "clipanion";
|
|
14556
14562
|
|
|
@@ -14634,7 +14640,7 @@ cli.register(Builtins.VersionCommand);
|
|
|
14634
14640
|
cli.register(RootHelpCommand);
|
|
14635
14641
|
cli.register(HelpCommand);
|
|
14636
14642
|
cli.register(InitCommand);
|
|
14637
|
-
cli.register(
|
|
14643
|
+
cli.register(TutorialCommand);
|
|
14638
14644
|
cli.register(ScanCommand);
|
|
14639
14645
|
cli.register(ScanCompareCommand);
|
|
14640
14646
|
cli.register(ServeCommand);
|