@skill-map/cli 0.70.0 → 0.71.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // kernel/i18n/registry.texts.ts
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9e0186ab-b10f-5a49-8eef-f0668584ed01")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="44976d76-8c48-5b39-862d-641f0e3be027")}catch(e){}}();
4
4
  var REGISTRY_TEXTS = {
5
5
  duplicateExtension: "Extension already registered: {{kind}}:{{qualifiedId}}",
6
6
  unknownKind: "Unknown extension kind: {{kind}}",
@@ -102,7 +102,7 @@ import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
102
102
  // package.json
103
103
  var package_default = {
104
104
  name: "@skill-map/cli",
105
- version: "0.70.0",
105
+ version: "0.71.0",
106
106
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
107
107
  license: "MIT",
108
108
  type: "module",
@@ -789,6 +789,8 @@ var ORCHESTRATOR_TEXTS = {
789
789
  frontmatterMalformedPasteWithIndent: "Frontmatter fence in {{path}} appears indented; YAML frontmatter MUST start with `---` at column 0. The file was scanned as body-only; the metadata block was silently lost. Move the `---` lines to the start of the line.",
790
790
  frontmatterMalformedByteOrderMark: "Frontmatter fence in {{path}} is preceded by a UTF-8 byte-order mark (BOM); the file was scanned as body-only. Re-save the file as UTF-8 without BOM. The metadata block was silently lost.",
791
791
  frontmatterMalformedMissingClose: "Frontmatter in {{path}} opens with `---` but never closes (no matching `---` line at column 0 was found). The file was scanned as body-only and every metadata field was silently lost. Add a closing `---` line below the metadata block.",
792
+ bodyBacktickUnclosedFence: "Body of {{path}} has an unclosed fenced code block opened at body line {{line}} (no matching closing ``` or ~~~). The code-strip policy then reads the rest of the file as code, so prose extractors stop emitting edges past it. Close the fence.",
793
+ bodyBacktickUnclosedInline: "Body of {{path}} has an unclosed inline backtick at body line {{line}} (the backtick run has no equal-length closer). Close the inline span with a matching backtick run, or escape a literal backtick with a backslash.",
792
794
  extensionErrorLinkKindNotDeclared: 'Extractor "{{extractorId}}" emitted a link of kind "{{linkKind}}" outside its declared `emitsLinkKinds` set [{{declaredKinds}}]. Link dropped.',
793
795
  extensionErrorIssueInvalidSeverity: `Rule "{{analyzerId}}" emitted an issue with invalid severity {{severity}} (allowed: 'error' | 'warn' | 'info'). Issue dropped.`,
794
796
  extensionErrorContributionUndeclaredRef: 'Extension "{{extractorId}}" emitted a view contribution on {{nodePath}} whose object is not one declared in its `ui` map (pass the declared const by reference, do not spread or inline it). Contribution dropped.',
@@ -1508,6 +1510,11 @@ var FRONTMATTER_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
1508
1510
  "frontmatter-malformed",
1509
1511
  "frontmatter-parse-error"
1510
1512
  ]);
1513
+ var BACKTICK_ISSUE_ID = "backtick-unbalanced";
1514
+ var CACHED_KERNEL_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
1515
+ ...FRONTMATTER_ISSUE_ANALYZERS,
1516
+ BACKTICK_ISSUE_ID
1517
+ ]);
1511
1518
 
1512
1519
  // kernel/orchestrator/cache.ts
1513
1520
  function indexPriorSnapshot(prior) {
@@ -1537,7 +1544,7 @@ function indexPriorLinks(links, byOriginating) {
1537
1544
  }
1538
1545
  function indexPriorFrontmatterIssues(issues, byNode) {
1539
1546
  for (const issue of issues) {
1540
- if (!FRONTMATTER_ISSUE_ANALYZERS.has(issue.analyzerId)) continue;
1547
+ if (!CACHED_KERNEL_ISSUE_ANALYZERS.has(issue.analyzerId)) continue;
1541
1548
  if (issue.nodeIds.length !== 1) continue;
1542
1549
  const path = issue.nodeIds[0];
1543
1550
  const list = byNode.get(path);
@@ -2803,6 +2810,83 @@ function malformedMessage(hint, path) {
2803
2810
  }
2804
2811
  }
2805
2812
 
2813
+ // kernel/util/strip-code-blocks.ts
2814
+ var FENCE_RE = /^(?<indent> {0,3})(?<fence>`{3,}|~{3,})/;
2815
+ function findBacktickImbalance(body) {
2816
+ if (!body) return null;
2817
+ const { stripped, openFenceLine } = scanFences(body);
2818
+ if (openFenceLine > 0) {
2819
+ return { kind: "fence", line: openFenceLine, sourceLine: sourceLineAt(body, openFenceLine) };
2820
+ }
2821
+ const survivor = stripInline(maskEscapes(stripped)).indexOf("`");
2822
+ if (survivor < 0) return null;
2823
+ const line = lineOfIndex(stripped, survivor);
2824
+ return { kind: "inline", line, sourceLine: sourceLineAt(body, line) };
2825
+ }
2826
+ function maskEscapes(text) {
2827
+ return text.replace(/\\[^\n]/g, " ");
2828
+ }
2829
+ function lineOfIndex(text, idx) {
2830
+ let line = 1;
2831
+ for (let i = 0; i < idx; i++) if (text[i] === "\n") line++;
2832
+ return line;
2833
+ }
2834
+ function sourceLineAt(text, line) {
2835
+ return text.split("\n")[line - 1]?.trim() ?? "";
2836
+ }
2837
+ function scanFences(input) {
2838
+ const out = [];
2839
+ const lines = input.split("\n");
2840
+ let openFence = null;
2841
+ let openFenceLine = 0;
2842
+ for (let i = 0; i < lines.length; i++) {
2843
+ const line = lines[i];
2844
+ if (openFence) {
2845
+ if (matchClosingFence(line, openFence)) openFence = null;
2846
+ out.push(blank(line));
2847
+ continue;
2848
+ }
2849
+ const open = FENCE_RE.exec(line);
2850
+ if (open?.groups) {
2851
+ openFence = open.groups["fence"];
2852
+ openFenceLine = i + 1;
2853
+ out.push(blank(line));
2854
+ continue;
2855
+ }
2856
+ out.push(line);
2857
+ }
2858
+ return { stripped: out.join("\n"), openFenceLine: openFence ? openFenceLine : 0 };
2859
+ }
2860
+ function matchClosingFence(line, openFence) {
2861
+ const m = FENCE_RE.exec(line);
2862
+ if (!m?.groups) return false;
2863
+ const fence = m.groups["fence"];
2864
+ return fence[0] === openFence[0] && fence.length >= openFence.length;
2865
+ }
2866
+ function stripInline(input) {
2867
+ return input.replace(/(`+)([\s\S]*?)\1/g, (_full, ticks, body) => {
2868
+ return ticks.replace(/`/g, " ") + blank(body) + ticks.replace(/`/g, " ");
2869
+ });
2870
+ }
2871
+ function blank(s) {
2872
+ return s.replace(/[^\s]/g, " ");
2873
+ }
2874
+
2875
+ // kernel/orchestrator/body-syntax.ts
2876
+ function detectUnclosedBacktick(body, path, strict) {
2877
+ const imbalance = findBacktickImbalance(body);
2878
+ if (!imbalance) return null;
2879
+ const template = imbalance.kind === "fence" ? ORCHESTRATOR_TEXTS.bodyBacktickUnclosedFence : ORCHESTRATOR_TEXTS.bodyBacktickUnclosedInline;
2880
+ return {
2881
+ analyzerId: BACKTICK_ISSUE_ID,
2882
+ severity: strict ? "error" : "warn",
2883
+ nodeIds: [path],
2884
+ message: tx(template, { path, line: imbalance.line }),
2885
+ detail: imbalance.sourceLine,
2886
+ data: { kind: imbalance.kind, line: imbalance.line }
2887
+ };
2888
+ }
2889
+
2806
2890
  // kernel/orchestrator/node-build.ts
2807
2891
  function buildNode(args) {
2808
2892
  const bytesFrontmatter = Buffer.byteLength(args.frontmatterRaw, "utf8");
@@ -2929,6 +3013,9 @@ function relativePathFromRoots(absolutePath, roots) {
2929
3013
  }
2930
3014
  return absolutePath;
2931
3015
  }
3016
+ function pushIssue(list, issue) {
3017
+ if (issue) list.push(issue);
3018
+ }
2932
3019
  function buildFreshNodeAndValidateFrontmatter(opts) {
2933
3020
  const node = buildNode({
2934
3021
  path: opts.raw.path,
@@ -2956,19 +3043,27 @@ function buildFreshNodeAndValidateFrontmatter(opts) {
2956
3043
  }
2957
3044
  }
2958
3045
  if (opts.raw.frontmatterRaw.length > 0) {
2959
- const fmIssue = validateFrontmatter(
2960
- opts.providerFrontmatter,
2961
- opts.provider,
2962
- opts.kind,
2963
- opts.raw.frontmatter,
2964
- opts.raw.path,
2965
- opts.strict
3046
+ pushIssue(
3047
+ frontmatterIssues,
3048
+ validateFrontmatter(
3049
+ opts.providerFrontmatter,
3050
+ opts.provider,
3051
+ opts.kind,
3052
+ opts.raw.frontmatter,
3053
+ opts.raw.path,
3054
+ opts.strict
3055
+ )
2966
3056
  );
2967
- if (fmIssue) frontmatterIssues.push(fmIssue);
2968
3057
  } else {
2969
- const malformed = detectMalformedFrontmatter(opts.raw.body, opts.raw.path, opts.strict);
2970
- if (malformed) frontmatterIssues.push(malformed);
3058
+ pushIssue(
3059
+ frontmatterIssues,
3060
+ detectMalformedFrontmatter(opts.raw.body, opts.raw.path, opts.strict)
3061
+ );
2971
3062
  }
3063
+ pushIssue(
3064
+ frontmatterIssues,
3065
+ detectUnclosedBacktick(opts.raw.body, opts.raw.path, opts.strict)
3066
+ );
2972
3067
  return { node, frontmatterIssues };
2973
3068
  }
2974
3069
  function mergeNodeWithEnrichments(node, enrichments, opts = {}) {
@@ -4166,4 +4261,4 @@ export {
4166
4261
  runScanWithRenames
4167
4262
  };
4168
4263
  //# sourceMappingURL=index.js.map
4169
- //# debugId=9e0186ab-b10f-5a49-8eef-f0668584ed01
4264
+ //# debugId=44976d76-8c48-5b39-862d-641f0e3be027
@@ -1,6 +1,6 @@
1
1
  // kernel/i18n/registry.texts.ts
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="37ae34a6-8712-5003-b7e6-767b1b040298")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7667ff07-bdd8-541a-b813-e01e201964f0")}catch(e){}}();
4
4
  var REGISTRY_TEXTS = {
5
5
  duplicateExtension: "Extension already registered: {{kind}}:{{qualifiedId}}",
6
6
  unknownKind: "Unknown extension kind: {{kind}}",
@@ -102,7 +102,7 @@ import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
102
102
  // package.json
103
103
  var package_default = {
104
104
  name: "@skill-map/cli",
105
- version: "0.70.0",
105
+ version: "0.71.0",
106
106
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
107
107
  license: "MIT",
108
108
  type: "module",
@@ -789,6 +789,8 @@ var ORCHESTRATOR_TEXTS = {
789
789
  frontmatterMalformedPasteWithIndent: "Frontmatter fence in {{path}} appears indented; YAML frontmatter MUST start with `---` at column 0. The file was scanned as body-only; the metadata block was silently lost. Move the `---` lines to the start of the line.",
790
790
  frontmatterMalformedByteOrderMark: "Frontmatter fence in {{path}} is preceded by a UTF-8 byte-order mark (BOM); the file was scanned as body-only. Re-save the file as UTF-8 without BOM. The metadata block was silently lost.",
791
791
  frontmatterMalformedMissingClose: "Frontmatter in {{path}} opens with `---` but never closes (no matching `---` line at column 0 was found). The file was scanned as body-only and every metadata field was silently lost. Add a closing `---` line below the metadata block.",
792
+ bodyBacktickUnclosedFence: "Body of {{path}} has an unclosed fenced code block opened at body line {{line}} (no matching closing ``` or ~~~). The code-strip policy then reads the rest of the file as code, so prose extractors stop emitting edges past it. Close the fence.",
793
+ bodyBacktickUnclosedInline: "Body of {{path}} has an unclosed inline backtick at body line {{line}} (the backtick run has no equal-length closer). Close the inline span with a matching backtick run, or escape a literal backtick with a backslash.",
792
794
  extensionErrorLinkKindNotDeclared: 'Extractor "{{extractorId}}" emitted a link of kind "{{linkKind}}" outside its declared `emitsLinkKinds` set [{{declaredKinds}}]. Link dropped.',
793
795
  extensionErrorIssueInvalidSeverity: `Rule "{{analyzerId}}" emitted an issue with invalid severity {{severity}} (allowed: 'error' | 'warn' | 'info'). Issue dropped.`,
794
796
  extensionErrorContributionUndeclaredRef: 'Extension "{{extractorId}}" emitted a view contribution on {{nodePath}} whose object is not one declared in its `ui` map (pass the declared const by reference, do not spread or inline it). Contribution dropped.',
@@ -1508,6 +1510,11 @@ var FRONTMATTER_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
1508
1510
  "frontmatter-malformed",
1509
1511
  "frontmatter-parse-error"
1510
1512
  ]);
1513
+ var BACKTICK_ISSUE_ID = "backtick-unbalanced";
1514
+ var CACHED_KERNEL_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
1515
+ ...FRONTMATTER_ISSUE_ANALYZERS,
1516
+ BACKTICK_ISSUE_ID
1517
+ ]);
1511
1518
 
1512
1519
  // kernel/orchestrator/cache.ts
1513
1520
  function indexPriorSnapshot(prior) {
@@ -1537,7 +1544,7 @@ function indexPriorLinks(links, byOriginating) {
1537
1544
  }
1538
1545
  function indexPriorFrontmatterIssues(issues, byNode) {
1539
1546
  for (const issue of issues) {
1540
- if (!FRONTMATTER_ISSUE_ANALYZERS.has(issue.analyzerId)) continue;
1547
+ if (!CACHED_KERNEL_ISSUE_ANALYZERS.has(issue.analyzerId)) continue;
1541
1548
  if (issue.nodeIds.length !== 1) continue;
1542
1549
  const path = issue.nodeIds[0];
1543
1550
  const list = byNode.get(path);
@@ -2803,6 +2810,83 @@ function malformedMessage(hint, path) {
2803
2810
  }
2804
2811
  }
2805
2812
 
2813
+ // kernel/util/strip-code-blocks.ts
2814
+ var FENCE_RE = /^(?<indent> {0,3})(?<fence>`{3,}|~{3,})/;
2815
+ function findBacktickImbalance(body) {
2816
+ if (!body) return null;
2817
+ const { stripped, openFenceLine } = scanFences(body);
2818
+ if (openFenceLine > 0) {
2819
+ return { kind: "fence", line: openFenceLine, sourceLine: sourceLineAt(body, openFenceLine) };
2820
+ }
2821
+ const survivor = stripInline(maskEscapes(stripped)).indexOf("`");
2822
+ if (survivor < 0) return null;
2823
+ const line = lineOfIndex(stripped, survivor);
2824
+ return { kind: "inline", line, sourceLine: sourceLineAt(body, line) };
2825
+ }
2826
+ function maskEscapes(text) {
2827
+ return text.replace(/\\[^\n]/g, " ");
2828
+ }
2829
+ function lineOfIndex(text, idx) {
2830
+ let line = 1;
2831
+ for (let i = 0; i < idx; i++) if (text[i] === "\n") line++;
2832
+ return line;
2833
+ }
2834
+ function sourceLineAt(text, line) {
2835
+ return text.split("\n")[line - 1]?.trim() ?? "";
2836
+ }
2837
+ function scanFences(input) {
2838
+ const out = [];
2839
+ const lines = input.split("\n");
2840
+ let openFence = null;
2841
+ let openFenceLine = 0;
2842
+ for (let i = 0; i < lines.length; i++) {
2843
+ const line = lines[i];
2844
+ if (openFence) {
2845
+ if (matchClosingFence(line, openFence)) openFence = null;
2846
+ out.push(blank(line));
2847
+ continue;
2848
+ }
2849
+ const open = FENCE_RE.exec(line);
2850
+ if (open?.groups) {
2851
+ openFence = open.groups["fence"];
2852
+ openFenceLine = i + 1;
2853
+ out.push(blank(line));
2854
+ continue;
2855
+ }
2856
+ out.push(line);
2857
+ }
2858
+ return { stripped: out.join("\n"), openFenceLine: openFence ? openFenceLine : 0 };
2859
+ }
2860
+ function matchClosingFence(line, openFence) {
2861
+ const m = FENCE_RE.exec(line);
2862
+ if (!m?.groups) return false;
2863
+ const fence = m.groups["fence"];
2864
+ return fence[0] === openFence[0] && fence.length >= openFence.length;
2865
+ }
2866
+ function stripInline(input) {
2867
+ return input.replace(/(`+)([\s\S]*?)\1/g, (_full, ticks, body) => {
2868
+ return ticks.replace(/`/g, " ") + blank(body) + ticks.replace(/`/g, " ");
2869
+ });
2870
+ }
2871
+ function blank(s) {
2872
+ return s.replace(/[^\s]/g, " ");
2873
+ }
2874
+
2875
+ // kernel/orchestrator/body-syntax.ts
2876
+ function detectUnclosedBacktick(body, path, strict) {
2877
+ const imbalance = findBacktickImbalance(body);
2878
+ if (!imbalance) return null;
2879
+ const template = imbalance.kind === "fence" ? ORCHESTRATOR_TEXTS.bodyBacktickUnclosedFence : ORCHESTRATOR_TEXTS.bodyBacktickUnclosedInline;
2880
+ return {
2881
+ analyzerId: BACKTICK_ISSUE_ID,
2882
+ severity: strict ? "error" : "warn",
2883
+ nodeIds: [path],
2884
+ message: tx(template, { path, line: imbalance.line }),
2885
+ detail: imbalance.sourceLine,
2886
+ data: { kind: imbalance.kind, line: imbalance.line }
2887
+ };
2888
+ }
2889
+
2806
2890
  // kernel/orchestrator/node-build.ts
2807
2891
  function buildNode(args) {
2808
2892
  const bytesFrontmatter = Buffer.byteLength(args.frontmatterRaw, "utf8");
@@ -2929,6 +3013,9 @@ function relativePathFromRoots(absolutePath, roots) {
2929
3013
  }
2930
3014
  return absolutePath;
2931
3015
  }
3016
+ function pushIssue(list, issue) {
3017
+ if (issue) list.push(issue);
3018
+ }
2932
3019
  function buildFreshNodeAndValidateFrontmatter(opts) {
2933
3020
  const node = buildNode({
2934
3021
  path: opts.raw.path,
@@ -2956,19 +3043,27 @@ function buildFreshNodeAndValidateFrontmatter(opts) {
2956
3043
  }
2957
3044
  }
2958
3045
  if (opts.raw.frontmatterRaw.length > 0) {
2959
- const fmIssue = validateFrontmatter(
2960
- opts.providerFrontmatter,
2961
- opts.provider,
2962
- opts.kind,
2963
- opts.raw.frontmatter,
2964
- opts.raw.path,
2965
- opts.strict
3046
+ pushIssue(
3047
+ frontmatterIssues,
3048
+ validateFrontmatter(
3049
+ opts.providerFrontmatter,
3050
+ opts.provider,
3051
+ opts.kind,
3052
+ opts.raw.frontmatter,
3053
+ opts.raw.path,
3054
+ opts.strict
3055
+ )
2966
3056
  );
2967
- if (fmIssue) frontmatterIssues.push(fmIssue);
2968
3057
  } else {
2969
- const malformed = detectMalformedFrontmatter(opts.raw.body, opts.raw.path, opts.strict);
2970
- if (malformed) frontmatterIssues.push(malformed);
3058
+ pushIssue(
3059
+ frontmatterIssues,
3060
+ detectMalformedFrontmatter(opts.raw.body, opts.raw.path, opts.strict)
3061
+ );
2971
3062
  }
3063
+ pushIssue(
3064
+ frontmatterIssues,
3065
+ detectUnclosedBacktick(opts.raw.body, opts.raw.path, opts.strict)
3066
+ );
2972
3067
  return { node, frontmatterIssues };
2973
3068
  }
2974
3069
  function mergeNodeWithEnrichments(node, enrichments, opts = {}) {
@@ -4166,4 +4261,4 @@ export {
4166
4261
  runScanWithRenames
4167
4262
  };
4168
4263
  //# sourceMappingURL=index.js.map
4169
- //# debugId=37ae34a6-8712-5003-b7e6-767b1b040298
4264
+ //# debugId=7667ff07-bdd8-541a-b813-e01e201964f0