@skill-map/cli 0.24.4 → 0.25.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.js CHANGED
@@ -4614,8 +4614,8 @@ async function saveUpdateCheckCache(db, cache) {
4614
4614
  var SORT_BY_COLUMNS = /* @__PURE__ */ new Set([
4615
4615
  "path",
4616
4616
  "kind",
4617
- "bytes_total",
4618
- "bytesTotal",
4617
+ "tokens_total",
4618
+ "tokensTotal",
4619
4619
  "links_out_count",
4620
4620
  "linksOutCount",
4621
4621
  "links_in_count",
@@ -4626,7 +4626,7 @@ var SORT_BY_COLUMNS = /* @__PURE__ */ new Set([
4626
4626
  var SORT_BY_DEFAULT_DIRECTION = {
4627
4627
  path: "asc",
4628
4628
  kind: "asc",
4629
- bytesTotal: "desc",
4629
+ tokensTotal: "desc",
4630
4630
  linksOutCount: "desc",
4631
4631
  linksInCount: "desc",
4632
4632
  externalRefsCount: "desc"
@@ -5747,7 +5747,7 @@ var UPDATE_CHECK_TEXTS = {
5747
5747
  // package.json
5748
5748
  var package_default = {
5749
5749
  name: "@skill-map/cli",
5750
- version: "0.24.4",
5750
+ version: "0.25.0",
5751
5751
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
5752
5752
  license: "MIT",
5753
5753
  type: "module",
@@ -15209,7 +15209,7 @@ var LIST_TEXTS = {
15209
15209
  tableHeaderIn: "IN",
15210
15210
  tableHeaderExt: "EXT",
15211
15211
  tableHeaderIssues: "ISSUES",
15212
- tableHeaderBytes: "BYTES",
15212
+ tableHeaderTokens: "TOKENS",
15213
15213
  /** Footer line: count of rendered nodes (`3 nodes` / `1 node`). */
15214
15214
  tableFooterCount: "{{count}} {{noun}}\n",
15215
15215
  tableFooterNounSingular: "node",
@@ -15222,7 +15222,7 @@ var LIST_TEXTS = {
15222
15222
  var SORT_BY = {
15223
15223
  path: { column: "path", direction: "asc" },
15224
15224
  kind: { column: "kind", direction: "asc" },
15225
- bytes_total: { column: "bytesTotal", direction: "desc" },
15225
+ tokens_total: { column: "tokensTotal", direction: "desc" },
15226
15226
  links_out_count: { column: "linksOutCount", direction: "desc" },
15227
15227
  links_in_count: { column: "linksInCount", direction: "desc" },
15228
15228
  external_refs_count: { column: "externalRefsCount", direction: "desc" }
@@ -15241,7 +15241,7 @@ var ListCommand = class extends SmCommand {
15241
15241
  and sidecar.annotations.tags by default; --tag-source author|user
15242
15242
  narrows to one side).
15243
15243
 
15244
- --sort-by accepts: path, kind, bytes_total, links_out_count,
15244
+ --sort-by accepts: path, kind, tokens_total, links_out_count,
15245
15245
  links_in_count, external_refs_count. Default: path. --limit N caps
15246
15246
  the result; default is no limit.
15247
15247
 
@@ -15250,7 +15250,7 @@ var ListCommand = class extends SmCommand {
15250
15250
  examples: [
15251
15251
  ["List every node", "$0 list"],
15252
15252
  ["List only agents", "$0 list --kind agent"],
15253
- ["Top 5 by total bytes", "$0 list --sort-by bytes_total --limit 5"],
15253
+ ["Top 5 by total tokens", "$0 list --sort-by tokens_total --limit 5"],
15254
15254
  ["Only nodes with issues, machine-readable", "$0 list --issue --json"],
15255
15255
  ["Filter by tag (author or user surfaces)", "$0 list --tag urgent"],
15256
15256
  ["Filter by user-only tag", "$0 list --tag wip --tag-source user"]
@@ -15393,7 +15393,7 @@ function renderTable2(nodes, issuesByNode, ansi) {
15393
15393
  in: n.linksInCount,
15394
15394
  ext: n.externalRefsCount,
15395
15395
  issues: issuesByNode.get(n.path) ?? 0,
15396
- bytes: n.bytes.total
15396
+ tokens: n.tokens?.total ?? null
15397
15397
  }));
15398
15398
  const widths = computeWidths(rows);
15399
15399
  const lines = [];
@@ -15421,9 +15421,12 @@ function computeWidths(rows) {
15421
15421
  in: Math.max(headerLen(LIST_TEXTS.tableHeaderIn), ...rows.map((r) => String(r.in).length)),
15422
15422
  ext: Math.max(headerLen(LIST_TEXTS.tableHeaderExt), ...rows.map((r) => String(r.ext).length)),
15423
15423
  issues: Math.max(headerLen(LIST_TEXTS.tableHeaderIssues), ...rows.map((r) => String(r.issues).length)),
15424
- bytes: Math.max(headerLen(LIST_TEXTS.tableHeaderBytes), ...rows.map((r) => String(r.bytes).length))
15424
+ tokens: Math.max(headerLen(LIST_TEXTS.tableHeaderTokens), ...rows.map((r) => formatTokens(r.tokens).length))
15425
15425
  };
15426
15426
  }
15427
+ function formatTokens(value) {
15428
+ return value === null ? "-" : String(value);
15429
+ }
15427
15430
  function clampMax(value, max) {
15428
15431
  return value > max ? max : value;
15429
15432
  }
@@ -15436,7 +15439,7 @@ function formatHeaderRow(w, ansi) {
15436
15439
  ansi.dim(LIST_TEXTS.tableHeaderIn.padStart(w.in)),
15437
15440
  ansi.dim(LIST_TEXTS.tableHeaderExt.padStart(w.ext)),
15438
15441
  ansi.dim(LIST_TEXTS.tableHeaderIssues.padStart(w.issues)),
15439
- ansi.dim(LIST_TEXTS.tableHeaderBytes.padStart(w.bytes))
15442
+ ansi.dim(LIST_TEXTS.tableHeaderTokens.padStart(w.tokens))
15440
15443
  ].join(" ");
15441
15444
  }
15442
15445
  function formatDataRow(r, w, ansi) {
@@ -15449,7 +15452,7 @@ function formatDataRow(r, w, ansi) {
15449
15452
  String(r.in).padStart(w.in),
15450
15453
  String(r.ext).padStart(w.ext),
15451
15454
  issuesCol,
15452
- String(r.bytes).padStart(w.bytes)
15455
+ formatTokens(r.tokens).padStart(w.tokens)
15453
15456
  ].join(" ");
15454
15457
  }
15455
15458
 
@@ -22308,7 +22311,7 @@ var SHOW_TEXTS = {
22308
22311
  /** Tail appended to `nodeHeader` when provider differs from kind. */
22309
22312
  providerSuffix: " {{label}}",
22310
22313
  providerSuffixLabel: "provider: {{provider}}",
22311
- // --- field block (Title / Description / Bytes / Tokens / …) ---------
22314
+ // --- field block (Title / Description / Tokens / …) -----------------
22312
22315
  /** Field row, label padded by the renderer to align values. */
22313
22316
  fieldRow: " {{label}} {{value}}\n",
22314
22317
  /** Continuation indent for multi-line values (description, etc.). */
@@ -22317,7 +22320,6 @@ var SHOW_TEXTS = {
22317
22320
  fieldLabelDescription: "Description",
22318
22321
  fieldLabelStability: "Stability",
22319
22322
  fieldLabelVersion: "Version",
22320
- fieldLabelBytes: "Bytes",
22321
22323
  fieldLabelTokens: "Tokens",
22322
22324
  fieldLabelExternalRefs: "External refs",
22323
22325
  /** `{{total}} total · {{frontmatter}} frontmatter · {{body}} body`. */
@@ -22431,23 +22433,13 @@ function collectNodeFields(node) {
22431
22433
  fields.push({ label: SHOW_TEXTS.fieldLabelVersion, value: sanitizeForTerminal(String(projected.version)) });
22432
22434
  }
22433
22435
  fields.push({
22434
- label: SHOW_TEXTS.fieldLabelBytes,
22435
- value: tx(SHOW_TEXTS.weightSplit, {
22436
- total: node.bytes.total,
22437
- frontmatter: node.bytes.frontmatter,
22438
- body: node.bytes.body
22439
- })
22436
+ label: SHOW_TEXTS.fieldLabelTokens,
22437
+ value: node.tokens ? tx(SHOW_TEXTS.weightSplit, {
22438
+ total: node.tokens.total,
22439
+ frontmatter: node.tokens.frontmatter,
22440
+ body: node.tokens.body
22441
+ }) : "-"
22440
22442
  });
22441
- if (node.tokens) {
22442
- fields.push({
22443
- label: SHOW_TEXTS.fieldLabelTokens,
22444
- value: tx(SHOW_TEXTS.weightSplit, {
22445
- total: node.tokens.total,
22446
- frontmatter: node.tokens.frontmatter,
22447
- body: node.tokens.body
22448
- })
22449
- });
22450
- }
22451
22443
  fields.push({ label: SHOW_TEXTS.fieldLabelExternalRefs, value: String(node.externalRefsCount) });
22452
22444
  return fields;
22453
22445
  }
@@ -23291,7 +23283,7 @@ import { Command as Command37, Option as Option35 } from "clipanion";
23291
23283
 
23292
23284
  // cli/i18n/tutorial.texts.ts
23293
23285
  var TUTORIAL_TEXTS = {
23294
- // Success, written to stdout after `<cwd>/sm-tutorial.md` is created.
23286
+ // Success, written to stdout after `<cwd>/{{filename}}` is created.
23295
23287
  // Multi-line layout: the two trigger phrases (English / Spanish) are
23296
23288
  // indented and labelled so they're the most visible part of the
23297
23289
  // output. The reminder above them surfaces the SKILL's language
@@ -23303,55 +23295,91 @@ var TUTORIAL_TEXTS = {
23303
23295
  * `English` / `Español` labels print dim, the eye lands on the
23304
23296
  * trigger phrases the user is going to copy / paste.
23305
23297
  */
23306
- written: " {{glyph}} sm-tutorial.md created at {{cwd}}\n\n Open Claude Code in this directory. Your first message sets\n the tutorial language for the rest of the session:\n\n {{enLabel}} run @sm-tutorial.md\n {{esLabel}} ejecut\xE1 @sm-tutorial.md\n",
23298
+ written: " {{glyph}} {{filename}} created at {{cwd}}\n\n Open Claude Code in this directory. Your first message sets\n the tutorial language for the rest of the session:\n\n {{enLabel}} run @{{filename}}\n {{esLabel}} ejecut\xE1 @{{filename}}\n",
23307
23299
  writtenLabelEn: "English",
23308
23300
  writtenLabelEs: "Espa\xF1ol",
23309
- // Refusal, `sm-tutorial.md` already exists and `--force` was not set.
23301
+ // Refusal, `{{filename}}` already exists and `--force` was not set.
23310
23302
  // Goes to stderr, exit code 2 (operational error per spec § Exit codes).
23311
23303
  // Mirrors the success body shape: glyph + headline, then a dim hint
23312
23304
  // line spelling the fix.
23313
- alreadyExists: "{{glyph}} sm-tutorial.md already exists at {{cwd}}\n {{hint}}\n",
23305
+ alreadyExists: "{{glyph}} {{filename}} already exists at {{cwd}}\n {{hint}}\n",
23314
23306
  alreadyExistsHint: "Pass `--force` to overwrite.",
23307
+ // Invalid `variant` positional argument. Goes to stderr, exit code 2.
23308
+ // Mirrors `alreadyExists`: glyph + headline + dim hint enumerating the
23309
+ // valid values.
23310
+ invalidVariant: "{{glyph}} sm tutorial: unknown variant '{{variant}}'\n {{hint}}\n",
23311
+ invalidVariantHint: "Valid values: tutorial (default), master.",
23315
23312
  // I/O failure on write or on reading the bundled SKILL source.
23316
- writeFailed: "{{glyph}} sm tutorial: failed to write sm-tutorial.md: {{message}}\n",
23317
- sourceMissing: "{{glyph}} sm tutorial: could not read the bundled tutorial (SKILL.md) from the install.\n {{hint}}\n",
23313
+ writeFailed: "{{glyph}} sm tutorial: failed to write {{filename}}: {{message}}\n",
23314
+ sourceMissing: "{{glyph}} sm tutorial: could not read the bundled tutorial ({{filename}}) from the install.\n {{hint}}\n",
23318
23315
  sourceMissingHint: "Reinstall @skill-map/cli or report the bug."
23319
23316
  };
23320
23317
 
23321
23318
  // cli/commands/tutorial.ts
23322
- var SM_TUTORIAL_FILENAME = "sm-tutorial.md";
23319
+ var VALID_VARIANTS = ["tutorial", "master"];
23320
+ var DEFAULT_VARIANT = "tutorial";
23321
+ var VARIANT_SPECS = {
23322
+ tutorial: {
23323
+ filename: "sm-tutorial.md",
23324
+ sourcePath: ".claude/skills/sm-tutorial/SKILL.md",
23325
+ bundledName: "sm-tutorial.md"
23326
+ },
23327
+ master: {
23328
+ filename: "sm-master.md",
23329
+ sourcePath: ".claude/skills/sm-master/SKILL.md",
23330
+ bundledName: "sm-master.md"
23331
+ }
23332
+ };
23323
23333
  var TutorialCommand = class extends SmCommand {
23324
23334
  static paths = [["tutorial"]];
23325
23335
  static usage = Command37.Usage({
23326
23336
  category: "Setup",
23327
- description: "Materialize the interactive tester tutorial (sm-tutorial.md) in the current directory.",
23337
+ description: "Materialize an interactive tester tutorial (sm-tutorial.md or sm-master.md) in the current directory.",
23328
23338
  details: `
23329
- Drops the canonical SKILL.md content as ./sm-tutorial.md so a tester
23330
- can open Claude Code in the cwd and load the file as a skill by
23331
- typing "ejecut\xE1 @sm-tutorial.md". Top-level only; no subdirectory
23332
- is created.
23339
+ Drops the canonical SKILL.md content as ./sm-tutorial.md (default)
23340
+ or ./sm-master.md (when invoked as \`sm tutorial master\`) so a
23341
+ tester can open Claude Code in the cwd and load the file as a
23342
+ skill by typing "ejecut\xE1 @sm-tutorial.md" (or "@sm-master.md").
23343
+ Top-level only; no subdirectory is created.
23333
23344
 
23334
23345
  Does NOT require an initialized .skill-map/ project. Refuses to
23335
- overwrite an existing sm-tutorial.md unless --force is passed.
23346
+ overwrite the target file unless --force is passed. Valid values
23347
+ for the positional argument are: tutorial (default), master.
23336
23348
  `,
23337
23349
  examples: [
23338
- ["Materialize the tutorial in the cwd", "$0 tutorial"],
23339
- ["Overwrite an existing sm-tutorial.md", "$0 tutorial --force"]
23350
+ ["Materialize the basic tutorial in the cwd", "$0 tutorial"],
23351
+ ["Materialize the advanced tutorial in the cwd", "$0 tutorial master"],
23352
+ ["Overwrite an existing target file", "$0 tutorial --force"]
23340
23353
  ]
23341
23354
  });
23355
+ variant = Option35.String({ required: false });
23342
23356
  force = Option35.Boolean("--force", false, {
23343
- description: "Overwrite an existing sm-tutorial.md without prompting."
23357
+ description: "Overwrite an existing target file without prompting."
23344
23358
  });
23345
23359
  async run() {
23346
23360
  const ctx = defaultRuntimeContext();
23347
- const target = join17(ctx.cwd, SM_TUTORIAL_FILENAME);
23348
23361
  const stderr = this.context.stderr;
23349
23362
  const stderrAnsi = this.ansiFor("stderr");
23350
23363
  const errGlyph = stderrAnsi.red("\u2715");
23364
+ const rawVariant = this.variant;
23365
+ if (rawVariant !== void 0 && !isTutorialVariant(rawVariant)) {
23366
+ this.printer.error(
23367
+ tx(TUTORIAL_TEXTS.invalidVariant, {
23368
+ glyph: errGlyph,
23369
+ variant: rawVariant,
23370
+ hint: stderrAnsi.dim(TUTORIAL_TEXTS.invalidVariantHint)
23371
+ })
23372
+ );
23373
+ return ExitCode.Error;
23374
+ }
23375
+ const variant = rawVariant ?? DEFAULT_VARIANT;
23376
+ const spec = VARIANT_SPECS[variant];
23377
+ const target = join17(ctx.cwd, spec.filename);
23351
23378
  if (await pathExists(target) && !this.force) {
23352
23379
  this.printer.error(
23353
23380
  tx(TUTORIAL_TEXTS.alreadyExists, {
23354
23381
  glyph: errGlyph,
23382
+ filename: spec.filename,
23355
23383
  cwd: stderrAnsi.dim(displayCwd(ctx.cwd)),
23356
23384
  hint: stderrAnsi.dim(TUTORIAL_TEXTS.alreadyExistsHint)
23357
23385
  })
@@ -23360,11 +23388,12 @@ var TutorialCommand = class extends SmCommand {
23360
23388
  }
23361
23389
  let body;
23362
23390
  try {
23363
- body = loadBundledTutorialText();
23391
+ body = loadBundledTutorialText(variant);
23364
23392
  } catch {
23365
23393
  this.printer.error(
23366
23394
  tx(TUTORIAL_TEXTS.sourceMissing, {
23367
23395
  glyph: errGlyph,
23396
+ filename: spec.filename,
23368
23397
  hint: stderrAnsi.dim(TUTORIAL_TEXTS.sourceMissingHint)
23369
23398
  })
23370
23399
  );
@@ -23376,6 +23405,7 @@ var TutorialCommand = class extends SmCommand {
23376
23405
  this.printer.error(
23377
23406
  tx(TUTORIAL_TEXTS.writeFailed, {
23378
23407
  glyph: errGlyph,
23408
+ filename: spec.filename,
23379
23409
  message: formatErrorMessage(err)
23380
23410
  })
23381
23411
  );
@@ -23391,6 +23421,7 @@ var TutorialCommand = class extends SmCommand {
23391
23421
  this.printer.data(
23392
23422
  tx(TUTORIAL_TEXTS.written, {
23393
23423
  glyph: ansi.green("\u2713"),
23424
+ filename: spec.filename,
23394
23425
  cwd: ansi.dim(displayCwd(ctx.cwd)),
23395
23426
  enLabel: ansi.dim(TUTORIAL_TEXTS.writtenLabelEn),
23396
23427
  esLabel: ansi.dim(TUTORIAL_TEXTS.writtenLabelEs)
@@ -23399,26 +23430,32 @@ var TutorialCommand = class extends SmCommand {
23399
23430
  return ExitCode.Ok;
23400
23431
  }
23401
23432
  };
23433
+ function isTutorialVariant(value) {
23434
+ return VALID_VARIANTS.includes(value);
23435
+ }
23402
23436
  function displayCwd(cwd) {
23403
23437
  const segments = cwd.split("/").filter((s) => s.length > 0);
23404
23438
  if (segments.length === 0) return "./";
23405
23439
  return `./${segments[segments.length - 1]}/`;
23406
23440
  }
23407
- var cachedTutorial = null;
23408
- function loadBundledTutorialText() {
23409
- if (cachedTutorial !== null) return cachedTutorial;
23410
- cachedTutorial = readTutorialFromDisk();
23411
- return cachedTutorial;
23441
+ var cachedTutorials = /* @__PURE__ */ new Map();
23442
+ function loadBundledTutorialText(variant) {
23443
+ const cached = cachedTutorials.get(variant);
23444
+ if (cached !== void 0) return cached;
23445
+ const body = readTutorialFromDisk(variant);
23446
+ cachedTutorials.set(variant, body);
23447
+ return body;
23412
23448
  }
23413
- function readTutorialFromDisk() {
23449
+ function readTutorialFromDisk(variant) {
23450
+ const spec = VARIANT_SPECS[variant];
23414
23451
  const here = dirname18(fileURLToPath6(import.meta.url));
23415
23452
  const candidates = [
23416
- // dev: src/cli/commands/ → repo-root .claude/skills/sm-tutorial/SKILL.md
23417
- resolve36(here, "../../../.claude/skills/sm-tutorial/SKILL.md"),
23418
- // bundled: dist/cli.js → dist/cli/tutorial/sm-tutorial.md (sibling)
23419
- resolve36(here, "cli/tutorial/sm-tutorial.md"),
23420
- // bundled fallback: any-depth → cli/tutorial/sm-tutorial.md
23421
- resolve36(here, "../cli/tutorial/sm-tutorial.md")
23453
+ // dev: src/cli/commands/ → repo-root .claude/skills/<slug>/SKILL.md
23454
+ resolve36(here, "../../..", spec.sourcePath),
23455
+ // bundled: dist/cli.js → dist/cli/tutorial/<filename> (sibling)
23456
+ resolve36(here, "cli/tutorial", spec.bundledName),
23457
+ // bundled fallback: any-depth → cli/tutorial/<filename>
23458
+ resolve36(here, "../cli/tutorial", spec.bundledName)
23422
23459
  ];
23423
23460
  for (const candidate of candidates) {
23424
23461
  if (existsSync28(candidate)) {