@skill-map/cli 0.57.0 → 0.58.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
@@ -1,6 +1,6 @@
1
1
  // cli/entry.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]="e6038423-ea97-5e66-b371-0916d382d819")}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]="7e4fdbab-f037-5030-b67a-732bb7ee46fd")}catch(e){}}();
4
4
  import { existsSync as existsSync33 } from "fs";
5
5
  import { Builtins, Cli as Cli2 } from "clipanion";
6
6
 
@@ -250,7 +250,7 @@ function bucketByKind(kind, instance, bag) {
250
250
  // package.json
251
251
  var package_default = {
252
252
  name: "@skill-map/cli",
253
- version: "0.57.0",
253
+ version: "0.58.0",
254
254
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
255
255
  license: "MIT",
256
256
  type: "module",
@@ -1442,71 +1442,12 @@ var coreMarkdownProvider = {
1442
1442
  }
1443
1443
  };
1444
1444
 
1445
- // plugins/core/extractors/annotations/index.ts
1446
- var ID4 = "annotations";
1447
- var annotationsExtractor = {
1448
- id: ID4,
1449
- pluginId: CORE_PLUGIN_ID,
1450
- kind: "extractor",
1451
- description: "Turns the `supersedes` and `supersededBy` entries from a node's `.sm` sidecar into arrows between nodes in the graph. Example: `supersededBy: v1-skill.md` in a `.sm` sidecar draws an arrow to `v1-skill.md`.",
1452
- scope: "frontmatter",
1453
- extract(ctx) {
1454
- const sourcePath = ctx.node.path;
1455
- const seen = /* @__PURE__ */ new Set();
1456
- function emit(source, target, fieldPath) {
1457
- const key = `${source} ${target}`;
1458
- if (seen.has(key)) return;
1459
- seen.add(key);
1460
- ctx.emitSignal({
1461
- source,
1462
- scope: "sidecar",
1463
- fieldPath,
1464
- raw: target,
1465
- candidates: [
1466
- {
1467
- extractorId: ID4,
1468
- kind: "supersedes",
1469
- target,
1470
- confidence: 1,
1471
- rationale: "structured sidecar annotation"
1472
- }
1473
- ]
1474
- });
1475
- }
1476
- const ann = pickAnnotations(ctx.node);
1477
- if (ann) processBlock(ann, sourcePath, emit);
1478
- }
1479
- };
1480
- function processBlock(block, sourcePath, emit) {
1481
- const supersedes = stringArray(block["supersedes"]);
1482
- for (let i = 0; i < supersedes.length; i += 1) {
1483
- emit(sourcePath, supersedes[i], ["annotations", "supersedes", String(i)]);
1484
- }
1485
- const supersededBy = block["supersededBy"];
1486
- if (typeof supersededBy === "string" && supersededBy.length > 0) {
1487
- emit(supersededBy, sourcePath, ["annotations", "supersededBy"]);
1488
- }
1489
- }
1490
- function pickAnnotations(node) {
1491
- const sidecar = node.sidecar;
1492
- if (!sidecar || sidecar.present !== true) return null;
1493
- const ann = sidecar.annotations;
1494
- if (ann && typeof ann === "object" && !Array.isArray(ann)) {
1495
- return ann;
1496
- }
1497
- return null;
1498
- }
1499
- function stringArray(value) {
1500
- if (!Array.isArray(value)) return [];
1501
- return value.filter((v) => typeof v === "string" && v.length > 0);
1502
- }
1503
-
1504
1445
  // plugins/core/extractors/backtick-path/index.ts
1505
1446
  import { posix as pathPosix2 } from "path";
1506
- var ID5 = "backtick-path";
1447
+ var ID4 = "backtick-path";
1507
1448
  var PATH_RE = /(?<![\w/:.-])(?:\.{1,2}\/)?[\w][\w.-]*(?:\/[\w.-]+)*\.md\b(?![\w/])/g;
1508
1449
  var backtickPathExtractor = {
1509
- id: ID5,
1450
+ id: ID4,
1510
1451
  pluginId: CORE_PLUGIN_ID,
1511
1452
  kind: "extractor",
1512
1453
  description: "Turns relative .md paths written inside code spans and fenced blocks into arrows between nodes in the graph. Example: a backticked `references/rules.md` path draws an arrow to that file.",
@@ -1531,7 +1472,7 @@ var backtickPathExtractor = {
1531
1472
  raw: original,
1532
1473
  candidates: [
1533
1474
  {
1534
- extractorId: ID5,
1475
+ extractorId: ID4,
1535
1476
  kind: "points",
1536
1477
  target: resolved,
1537
1478
  // 0.85: a strong file signal with one degree of inference,
@@ -1560,7 +1501,7 @@ function resolveTarget(sourceDir, raw) {
1560
1501
  }
1561
1502
 
1562
1503
  // plugins/core/extractors/external-url-counter/index.ts
1563
- var ID6 = "external-url-counter";
1504
+ var ID5 = "external-url-counter";
1564
1505
  var count2 = {
1565
1506
  slot: "card.footer.left",
1566
1507
  icon: "pi-link",
@@ -1580,7 +1521,7 @@ var settings = {
1580
1521
  var URL_RE = /https?:\/\/[^\s<>"'`)\]]+/g;
1581
1522
  var TRAILING_PUNCT = /[.,;:!?]+$/;
1582
1523
  var externalUrlCounterExtractor = {
1583
- id: ID6,
1524
+ id: ID5,
1584
1525
  pluginId: CORE_PLUGIN_ID,
1585
1526
  kind: "extractor",
1586
1527
  description: "Counts the distinct external URLs in a node's body and shows the count on the card. Example: a body linking `https://example.com` and `https://docs.rs` shows a count of 2.",
@@ -1632,7 +1573,7 @@ var externalUrlCounterExtractor = {
1632
1573
  raw: original,
1633
1574
  candidates: [
1634
1575
  {
1635
- extractorId: ID6,
1576
+ extractorId: ID5,
1636
1577
  kind: "references",
1637
1578
  target: normalized.href,
1638
1579
  confidence: 0.3,
@@ -1674,11 +1615,11 @@ function normalizeUrl(raw) {
1674
1615
 
1675
1616
  // plugins/core/extractors/markdown-link/index.ts
1676
1617
  import { posix as pathPosix3 } from "path";
1677
- var ID7 = "markdown-link";
1618
+ var ID6 = "markdown-link";
1678
1619
  var LINK_RE = /(?<!!)\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
1679
1620
  var URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
1680
1621
  var markdownLinkExtractor = {
1681
- id: ID7,
1622
+ id: ID6,
1682
1623
  pluginId: CORE_PLUGIN_ID,
1683
1624
  kind: "extractor",
1684
1625
  description: "Turns markdown links (`[text](path)`) in a node's body into arrows between nodes in the graph. Example: `[the guide](docs/guide.md)` draws an arrow to `docs/guide.md`.",
@@ -1703,7 +1644,7 @@ var markdownLinkExtractor = {
1703
1644
  raw: match[0],
1704
1645
  candidates: [
1705
1646
  {
1706
- extractorId: ID7,
1647
+ extractorId: ID6,
1707
1648
  kind: "references",
1708
1649
  target: resolved,
1709
1650
  // 0.95: the `[text](path)` syntax is unambiguous (the spec's
@@ -1738,10 +1679,10 @@ function resolveTarget2(sourceDir, raw) {
1738
1679
  }
1739
1680
 
1740
1681
  // plugins/core/extractors/mcp-tools/index.ts
1741
- var ID8 = "mcp-tools";
1682
+ var ID7 = "mcp-tools";
1742
1683
  var MCP_PATTERN = /^mcp__([a-z0-9][a-z0-9_-]*)__[a-z0-9_-]+$/i;
1743
1684
  var mcpToolsExtractor = {
1744
- id: ID8,
1685
+ id: ID7,
1745
1686
  pluginId: CORE_PLUGIN_ID,
1746
1687
  kind: "extractor",
1747
1688
  description: "Turns `tools: [mcp__<server>__<tool>]` entries in a node's frontmatter into an MCP node per unique server and an arrow from the source to each one. Example: `tools: [mcp__github__create_pr]` adds an `mcp://github` node and an arrow to it.",
@@ -1772,7 +1713,7 @@ var mcpToolsExtractor = {
1772
1713
  raw: `mcp__${server}__*`,
1773
1714
  candidates: [
1774
1715
  {
1775
- extractorId: ID8,
1716
+ extractorId: ID7,
1776
1717
  kind: "references",
1777
1718
  target: mcpPath,
1778
1719
  confidence: 0.85,
@@ -1841,10 +1782,10 @@ var ANNOTATION_FIELD_UNKNOWN_TEXTS = {
1841
1782
  };
1842
1783
 
1843
1784
  // plugins/core/analyzers/annotation-field-unknown/index.ts
1844
- var ID9 = "annotation-field-unknown";
1785
+ var ID8 = "annotation-field-unknown";
1845
1786
  var RESERVED_ROOT_BLOCKS = /* @__PURE__ */ new Set(["identity", "annotations", "settings", "audit"]);
1846
1787
  var annotationFieldUnknownAnalyzer = {
1847
- id: ID9,
1788
+ id: ID8,
1848
1789
  pluginId: CORE_PLUGIN_ID,
1849
1790
  kind: "analyzer",
1850
1791
  description: "Flags typos or unrecognized keys in sidecars (`.sm`).",
@@ -1883,7 +1824,7 @@ var annotationFieldUnknownAnalyzer = {
1883
1824
  for (const key of Object.keys(annotations)) {
1884
1825
  if (!knownAnnotationKeys.has(key)) {
1885
1826
  issues.push({
1886
- analyzerId: ID9,
1827
+ analyzerId: ID8,
1887
1828
  severity: "warn",
1888
1829
  nodeIds: [node.path],
1889
1830
  message: formatFinding({
@@ -1910,7 +1851,7 @@ var annotationFieldUnknownAnalyzer = {
1910
1851
  if (validator(value)) continue;
1911
1852
  const errors = (validator.errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message ?? e.keyword}`).join("; ");
1912
1853
  issues.push({
1913
- analyzerId: ID9,
1854
+ analyzerId: ID8,
1914
1855
  severity: "warn",
1915
1856
  nodeIds: [node.path],
1916
1857
  message: formatFinding({
@@ -1926,7 +1867,7 @@ var annotationFieldUnknownAnalyzer = {
1926
1867
  continue;
1927
1868
  }
1928
1869
  issues.push({
1929
- analyzerId: ID9,
1870
+ analyzerId: ID8,
1930
1871
  severity: "warn",
1931
1872
  nodeIds: [node.path],
1932
1873
  message: formatFinding({
@@ -2000,9 +1941,9 @@ var ANNOTATION_ORPHAN_TEXTS = {
2000
1941
  };
2001
1942
 
2002
1943
  // plugins/core/analyzers/annotation-orphan/index.ts
2003
- var ID10 = "annotation-orphan";
1944
+ var ID9 = "annotation-orphan";
2004
1945
  var annotationOrphanAnalyzer = {
2005
- id: ID10,
1946
+ id: ID9,
2006
1947
  pluginId: CORE_PLUGIN_ID,
2007
1948
  kind: "analyzer",
2008
1949
  description: "Flags sidecars (`.sm`) whose `.md` file no longer exists.",
@@ -2014,7 +1955,7 @@ var annotationOrphanAnalyzer = {
2014
1955
  for (const orphan of orphans) {
2015
1956
  const expectedMdRelative = orphan.relativePath.endsWith(".sm") ? `${orphan.relativePath.slice(0, -".sm".length)}.md` : `${orphan.relativePath}.md`;
2016
1957
  issues.push({
2017
- analyzerId: ID10,
1958
+ analyzerId: ID9,
2018
1959
  severity: "warn",
2019
1960
  nodeIds: [expectedMdRelative],
2020
1961
  message: formatFinding({
@@ -2057,7 +1998,7 @@ var ANNOTATION_STALE_TEXTS = {
2057
1998
  };
2058
1999
 
2059
2000
  // plugins/core/analyzers/annotation-stale/index.ts
2060
- var ID11 = "annotation-stale";
2001
+ var ID10 = "annotation-stale";
2061
2002
  var staleIcon = {
2062
2003
  slot: "card.footer.right",
2063
2004
  icon: "pi-clock",
@@ -2070,7 +2011,7 @@ var staleBadge = {
2070
2011
  priority: 20
2071
2012
  };
2072
2013
  var annotationStaleAnalyzer = {
2073
- id: ID11,
2014
+ id: ID10,
2074
2015
  pluginId: CORE_PLUGIN_ID,
2075
2016
  kind: "analyzer",
2076
2017
  description: "Marks sidecars (`.sm`) that are out of date with their `.md`.",
@@ -2086,7 +2027,7 @@ var annotationStaleAnalyzer = {
2086
2027
  const status = staleStatus(node.sidecar);
2087
2028
  if (status === null) continue;
2088
2029
  issues.push({
2089
- analyzerId: ID11,
2030
+ analyzerId: ID10,
2090
2031
  severity: "info",
2091
2032
  nodeIds: [node.path],
2092
2033
  message: formatFinding({ body: messageFor(status) }),
@@ -2132,9 +2073,9 @@ function tooltipFor(status) {
2132
2073
  }
2133
2074
 
2134
2075
  // plugins/core/analyzers/contribution-orphan/index.ts
2135
- var ID12 = "contribution-orphan";
2076
+ var ID11 = "contribution-orphan";
2136
2077
  var contributionOrphanAnalyzer = {
2137
- id: ID12,
2078
+ id: ID11,
2138
2079
  pluginId: CORE_PLUGIN_ID,
2139
2080
  kind: "analyzer",
2140
2081
  description: "Warns about plugin data referencing nodes renamed or deleted in the latest scan.",
@@ -2166,12 +2107,12 @@ var EXTRACTOR_COLLISION_TEXTS = {
2166
2107
  };
2167
2108
 
2168
2109
  // plugins/core/analyzers/extractor-collision/index.ts
2169
- var ID13 = "extractor-collision";
2110
+ var ID12 = "extractor-collision";
2170
2111
  function signalLines(signal) {
2171
2112
  return signal.range && typeof signal.range.line === "number" ? [signal.range.line] : void 0;
2172
2113
  }
2173
2114
  var extractorCollisionAnalyzer = {
2174
- id: ID13,
2115
+ id: ID12,
2175
2116
  pluginId: CORE_PLUGIN_ID,
2176
2117
  kind: "analyzer",
2177
2118
  description: "Reports when two extractors detect something at the same span of body text and the resolver drops one.",
@@ -2195,7 +2136,7 @@ function makeIssue(signal) {
2195
2136
  const loserRange = signal.range ? `${signal.range.start}-${signal.range.end}` : "unknown";
2196
2137
  const winnerRange = `${winner.range.start}-${winner.range.end}`;
2197
2138
  return {
2198
- analyzerId: ID13,
2139
+ analyzerId: ID12,
2199
2140
  severity: "warn",
2200
2141
  nodeIds: [signal.source],
2201
2142
  message: formatFinding({
@@ -2239,7 +2180,7 @@ var ISSUE_COUNTER_TEXTS = {
2239
2180
  };
2240
2181
 
2241
2182
  // plugins/core/analyzers/issue-counter/index.ts
2242
- var ID14 = "issue-counter";
2183
+ var ID13 = "issue-counter";
2243
2184
  var warnCount = {
2244
2185
  slot: "card.footer.right",
2245
2186
  icon: "pi-exclamation-triangle",
@@ -2275,7 +2216,7 @@ function emitTierChips(ctx, ref, severity, counts, singleTooltip, manyTooltip) {
2275
2216
  }
2276
2217
  }
2277
2218
  var issueCounterAnalyzer = {
2278
- id: ID14,
2219
+ id: ID13,
2279
2220
  pluginId: CORE_PLUGIN_ID,
2280
2221
  kind: "analyzer",
2281
2222
  description: "Emits one aggregate severity chip per node (error + warn counts) from the live issue accumulator.",
@@ -2338,7 +2279,7 @@ var LINK_COUNTER_TEXTS = {
2338
2279
  };
2339
2280
 
2340
2281
  // plugins/core/analyzers/link-counter/index.ts
2341
- var ID15 = "link-counter";
2282
+ var ID14 = "link-counter";
2342
2283
  var linksIn = {
2343
2284
  slot: "card.footer.left",
2344
2285
  icon: "pi-download",
@@ -2354,7 +2295,7 @@ var linksOut = {
2354
2295
  priority: 20
2355
2296
  };
2356
2297
  var linkCounterAnalyzer = {
2357
- id: ID15,
2298
+ id: ID14,
2358
2299
  pluginId: CORE_PLUGIN_ID,
2359
2300
  kind: "analyzer",
2360
2301
  description: "Counts incoming and outgoing links per node.",
@@ -2419,10 +2360,10 @@ var LINK_KIND_CONFLICT_TEXTS = {
2419
2360
  };
2420
2361
 
2421
2362
  // plugins/core/analyzers/link-kind-conflict/index.ts
2422
- var ID16 = "link-kind-conflict";
2363
+ var ID15 = "link-kind-conflict";
2423
2364
  var NON_CONFLICTING_KINDS = /* @__PURE__ */ new Set(["points"]);
2424
2365
  var linkKindConflictAnalyzer = {
2425
- id: ID16,
2366
+ id: ID15,
2426
2367
  pluginId: CORE_PLUGIN_ID,
2427
2368
  kind: "analyzer",
2428
2369
  description: "Flags conflicting arrow meanings between extractors (e.g. `references` vs `invokes`).",
@@ -2470,7 +2411,7 @@ var linkKindConflictAnalyzer = {
2470
2411
  const [source, target] = key.split("\0");
2471
2412
  const kindList = variants.map((v) => v.kind).join(" / ");
2472
2413
  issues.push({
2473
- analyzerId: ID16,
2414
+ analyzerId: ID15,
2474
2415
  severity: "warn",
2475
2416
  nodeIds: [source, target],
2476
2417
  message: formatFinding({
@@ -2509,9 +2450,9 @@ var LINK_SELF_LOOP_TEXTS = {
2509
2450
  };
2510
2451
 
2511
2452
  // plugins/core/analyzers/link-self-loop/index.ts
2512
- var ID17 = "link-self-loop";
2453
+ var ID16 = "link-self-loop";
2513
2454
  var linkSelfLoopAnalyzer = {
2514
- id: ID17,
2455
+ id: ID16,
2515
2456
  pluginId: CORE_PLUGIN_ID,
2516
2457
  kind: "analyzer",
2517
2458
  description: "Flags links whose source is also their own resolved target (e.g. a body heading like `# /deploy` inside the file that defines `/deploy`).",
@@ -2521,7 +2462,7 @@ var linkSelfLoopAnalyzer = {
2521
2462
  for (const link of ctx.links) {
2522
2463
  if (!isSelfLoop(link)) continue;
2523
2464
  issues.push({
2524
- analyzerId: ID17,
2465
+ analyzerId: ID16,
2525
2466
  severity: "warn",
2526
2467
  nodeIds: [link.source],
2527
2468
  message: formatFinding({
@@ -2553,9 +2494,9 @@ var NAME_COLLISION_TEXTS = {
2553
2494
  };
2554
2495
 
2555
2496
  // plugins/core/analyzers/name-collision/index.ts
2556
- var ID18 = "name-collision";
2497
+ var ID17 = "name-collision";
2557
2498
  var nameCollisionAnalyzer = {
2558
- id: ID18,
2499
+ id: ID17,
2559
2500
  pluginId: CORE_PLUGIN_ID,
2560
2501
  kind: "analyzer",
2561
2502
  mode: "deterministic",
@@ -2569,7 +2510,7 @@ var nameCollisionAnalyzer = {
2569
2510
  for (const [name, claims] of collisions) {
2570
2511
  const paths = claims.map((c) => c.path);
2571
2512
  issues.push({
2572
- analyzerId: ID18,
2513
+ analyzerId: ID17,
2573
2514
  severity: "error",
2574
2515
  nodeIds: paths,
2575
2516
  message: formatFinding({
@@ -2619,9 +2560,9 @@ var NAME_RESERVED_TEXTS = {
2619
2560
  };
2620
2561
 
2621
2562
  // plugins/core/analyzers/name-reserved/index.ts
2622
- var ID19 = "name-reserved";
2563
+ var ID18 = "name-reserved";
2623
2564
  var nameReservedAnalyzer = {
2624
- id: ID19,
2565
+ id: ID18,
2625
2566
  pluginId: CORE_PLUGIN_ID,
2626
2567
  kind: "analyzer",
2627
2568
  description: "Flags two kinds of reserved-name collision: a file whose name shadows a built-in command of the active runtime, and a link that resolves to one of those reserved names.",
@@ -2639,7 +2580,7 @@ var nameReservedAnalyzer = {
2639
2580
  const node = byPath3.get(path);
2640
2581
  if (!node) continue;
2641
2582
  issues.push({
2642
- analyzerId: ID19,
2583
+ analyzerId: ID18,
2643
2584
  severity: "warn",
2644
2585
  nodeIds: [node.path],
2645
2586
  message: formatFinding({
@@ -2661,7 +2602,7 @@ var nameReservedAnalyzer = {
2661
2602
  adjust(link, { kind: "delta", value: -RESERVED_PENALTY });
2662
2603
  }
2663
2604
  issues.push({
2664
- analyzerId: ID19,
2605
+ analyzerId: ID18,
2665
2606
  severity: "warn",
2666
2607
  nodeIds: [link.source],
2667
2608
  message: formatFinding({
@@ -2688,26 +2629,32 @@ var nameReservedAnalyzer = {
2688
2629
  }
2689
2630
  };
2690
2631
 
2632
+ // plugins/core/stability.ts
2633
+ var STABILITY_VALUES = ["experimental", "stable", "deprecated"];
2634
+ function isStability(value) {
2635
+ return value === "experimental" || value === "stable" || value === "deprecated";
2636
+ }
2637
+ function readEffectiveStability(node) {
2638
+ const fromAnn = node.sidecar?.annotations?.["stability"];
2639
+ if (isStability(fromAnn)) return fromAnn;
2640
+ const legacy = readLegacyMetadataStability(node.frontmatter);
2641
+ return isStability(legacy) ? legacy : null;
2642
+ }
2643
+ function readLegacyMetadataStability(fm) {
2644
+ if (!fm) return void 0;
2645
+ const meta = fm["metadata"];
2646
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return void 0;
2647
+ return meta["stability"];
2648
+ }
2649
+
2691
2650
  // plugins/core/analyzers/node-stability/text.ts
2692
2651
  var NODE_STABILITY_TEXTS = {
2693
- /** Issue body (`<what>; <why>`) for an experimental-marked node. */
2694
- experimental: "Marked experimental; API may change",
2695
2652
  /** Issue body (`<what>; <why>`) for a deprecated-marked node. */
2696
- deprecated: "Marked deprecated; avoid in new code",
2697
- /** Label of the inspector action button that sets the lifecycle stage. */
2698
- setLabel: "Set stability",
2699
- /** Prompt label for the enum-pick stability input. */
2700
- promptLabel: "Stability",
2701
- /** Prompt option label for the `experimental` stage. */
2702
- optionExperimental: "Experimental",
2703
- /** Prompt option label for the `stable` stage. */
2704
- optionStable: "Stable",
2705
- /** Prompt option label for the `deprecated` stage. */
2706
- optionDeprecated: "Deprecated"
2653
+ deprecated: "Marked deprecated; avoid using it"
2707
2654
  };
2708
2655
 
2709
2656
  // plugins/core/analyzers/node-stability/index.ts
2710
- var ID20 = "node-stability";
2657
+ var ID19 = "node-stability";
2711
2658
  var EXPERIMENTAL_TOOLTIP = "Experimental: API may change";
2712
2659
  var DEPRECATED_TOOLTIP = "Deprecated: avoid in new code";
2713
2660
  var experimental = {
@@ -2724,36 +2671,22 @@ var deprecated = {
2724
2671
  emitWhenEmpty: false,
2725
2672
  priority: 10
2726
2673
  };
2727
- var setStabilityButton = {
2728
- slot: "inspector.action.button",
2729
- priority: 15
2730
- };
2731
2674
  var nodeStabilityAnalyzer = {
2732
- id: ID20,
2675
+ id: ID19,
2733
2676
  pluginId: CORE_PLUGIN_ID,
2734
2677
  kind: "analyzer",
2735
- description: "Reports a node's stability stage (`experimental`, `deprecated`) on the card.",
2678
+ description: "Surfaces a node's stability stage on the card: `deprecated` as a chip plus a finding, `experimental` as a chip only; `stable` and unset stay silent.",
2736
2679
  mode: "deterministic",
2737
- ui: { experimental, deprecated, setStabilityButton },
2680
+ ui: { experimental, deprecated },
2738
2681
  evaluate(ctx) {
2739
2682
  const issues = [];
2740
2683
  for (const node of ctx.nodes) {
2741
- const stability = readStability(node);
2742
- if (node.sidecar?.present === true) {
2743
- emitSetStabilityButton(ctx, node.path, stability ?? "stable");
2744
- }
2684
+ const stability = readEffectiveStability(node);
2745
2685
  if (stability === "experimental") {
2746
2686
  ctx.emitContribution(node.path, experimental, {
2747
2687
  value: 0,
2748
2688
  tooltip: EXPERIMENTAL_TOOLTIP
2749
2689
  });
2750
- issues.push({
2751
- analyzerId: ID20,
2752
- severity: "info",
2753
- nodeIds: [node.path],
2754
- message: formatFinding({ body: tx(NODE_STABILITY_TEXTS.experimental) }),
2755
- data: { stability }
2756
- });
2757
2690
  } else if (stability === "deprecated") {
2758
2691
  ctx.emitContribution(node.path, deprecated, {
2759
2692
  value: 0,
@@ -2761,7 +2694,7 @@ var nodeStabilityAnalyzer = {
2761
2694
  severity: "warn"
2762
2695
  });
2763
2696
  issues.push({
2764
- analyzerId: ID20,
2697
+ analyzerId: ID19,
2765
2698
  severity: "warn",
2766
2699
  nodeIds: [node.path],
2767
2700
  message: formatFinding({ body: tx(NODE_STABILITY_TEXTS.deprecated) }),
@@ -2772,93 +2705,6 @@ var nodeStabilityAnalyzer = {
2772
2705
  return issues;
2773
2706
  }
2774
2707
  };
2775
- function readStability(node) {
2776
- const fromAnn = node.sidecar?.annotations?.["stability"];
2777
- if (isStability(fromAnn)) return fromAnn;
2778
- const legacy = readLegacyMetadataStability(node.frontmatter);
2779
- return isStability(legacy) ? legacy : null;
2780
- }
2781
- function readLegacyMetadataStability(fm) {
2782
- if (!fm) return void 0;
2783
- const meta = fm["metadata"];
2784
- if (!meta || typeof meta !== "object" || Array.isArray(meta)) return void 0;
2785
- return meta["stability"];
2786
- }
2787
- function isStability(value) {
2788
- return value === "experimental" || value === "deprecated" || value === "stable";
2789
- }
2790
- function emitSetStabilityButton(ctx, nodePath, current) {
2791
- ctx.emitContribution(nodePath, setStabilityButton, {
2792
- actionId: "core/node-set-stability",
2793
- label: NODE_STABILITY_TEXTS.setLabel,
2794
- icon: "pi-flag",
2795
- enabled: true,
2796
- prompt: {
2797
- inputType: "enum-pick",
2798
- paramKey: "stability",
2799
- label: NODE_STABILITY_TEXTS.promptLabel,
2800
- options: [
2801
- { value: "experimental", label: NODE_STABILITY_TEXTS.optionExperimental },
2802
- { value: "stable", label: NODE_STABILITY_TEXTS.optionStable },
2803
- { value: "deprecated", label: NODE_STABILITY_TEXTS.optionDeprecated }
2804
- ],
2805
- defaultValue: current
2806
- }
2807
- });
2808
- }
2809
-
2810
- // plugins/core/analyzers/node-superseded/text.ts
2811
- var NODE_SUPERSEDED_TEXTS = {
2812
- /**
2813
- * Diagnosis body (`<what>; <why>`). The shared `formatFinding` helper
2814
- * wraps it with the backtick subject (the superseding artifact); the
2815
- * superseded node is the finding's own node, so its path never appears.
2816
- */
2817
- message: "Superseded; a newer node supersedes this one"
2818
- };
2819
-
2820
- // plugins/core/analyzers/node-superseded/index.ts
2821
- var ID21 = "node-superseded";
2822
- var nodeSupersededAnalyzer = {
2823
- id: ID21,
2824
- pluginId: CORE_PLUGIN_ID,
2825
- kind: "analyzer",
2826
- description: "Marks nodes replaced by a newer one via `supersededBy`.",
2827
- // Part of the experimental supersession feature: ships disabled by
2828
- // default alongside the declarer (`core/supersede` button +
2829
- // `core/node-supersede` action). With the declarer off by default a
2830
- // user rarely produces `supersededBy` data, so surfacing it stays
2831
- // experimental too; the operator opts the whole family in together.
2832
- stability: "experimental",
2833
- mode: "deterministic",
2834
- evaluate(ctx) {
2835
- const issues = [];
2836
- for (const node of ctx.nodes) {
2837
- const supersededBy = pickSupersededBy(node);
2838
- if (supersededBy === null) continue;
2839
- issues.push({
2840
- analyzerId: ID21,
2841
- severity: "info",
2842
- nodeIds: [node.path],
2843
- message: formatFinding({
2844
- subject: supersededBy,
2845
- body: tx(NODE_SUPERSEDED_TEXTS.message)
2846
- }),
2847
- data: { supersededBy }
2848
- });
2849
- }
2850
- return issues;
2851
- }
2852
- };
2853
- function pickSupersededBy(node) {
2854
- const sidecar = node.sidecar;
2855
- if (!sidecar || sidecar.present !== true) return null;
2856
- const ann = sidecar.annotations;
2857
- if (!ann || typeof ann !== "object" || Array.isArray(ann)) return null;
2858
- const value = ann["supersededBy"];
2859
- if (typeof value !== "string" || value.length === 0) return null;
2860
- return value;
2861
- }
2862
2708
 
2863
2709
  // plugins/core/analyzers/reference-broken/index.ts
2864
2710
  import { resolve as resolve2 } from "path";
@@ -2890,7 +2736,6 @@ var REFERENCE_BROKEN_TEXTS = {
2890
2736
  references: "reference",
2891
2737
  mentions: "mention",
2892
2738
  invokes: "invocation",
2893
- supersedes: "supersession",
2894
2739
  points: "pointer"
2895
2740
  },
2896
2741
  kindLabelFallback: "{{kind}} link",
@@ -2901,9 +2746,9 @@ var REFERENCE_BROKEN_TEXTS = {
2901
2746
  };
2902
2747
 
2903
2748
  // plugins/core/analyzers/reference-broken/index.ts
2904
- var ID22 = "reference-broken";
2749
+ var ID20 = "reference-broken";
2905
2750
  var referenceBrokenAnalyzer = {
2906
- id: ID22,
2751
+ id: ID20,
2907
2752
  pluginId: CORE_PLUGIN_ID,
2908
2753
  kind: "analyzer",
2909
2754
  description: "Flags arrows pointing at a node not part of the current scan.",
@@ -2946,7 +2791,7 @@ function penalizeBrokenConfidence(adjust, link) {
2946
2791
  }
2947
2792
  function buildIssue(link) {
2948
2793
  return {
2949
- analyzerId: ID22,
2794
+ analyzerId: ID20,
2950
2795
  // `error`, not `warn`: a link whose target is not in the scan is a
2951
2796
  // structural defect the operator must notice, and the card chip
2952
2797
  // paints `danger` (red) to match. Per the chip-vs-issue policy in
@@ -3010,9 +2855,9 @@ var REFERENCE_REDUNDANT_TEXTS = {
3010
2855
  };
3011
2856
 
3012
2857
  // plugins/core/analyzers/reference-redundant/index.ts
3013
- var ID23 = "reference-redundant";
2858
+ var ID21 = "reference-redundant";
3014
2859
  var referenceRedundantAnalyzer = {
3015
- id: ID23,
2860
+ id: ID21,
3016
2861
  pluginId: CORE_PLUGIN_ID,
3017
2862
  kind: "analyzer",
3018
2863
  description: "Flags when one node references the same target through two or more different links (e.g. a markdown link plus a `references:` entry).",
@@ -3035,7 +2880,7 @@ var referenceRedundantAnalyzer = {
3035
2880
  const [source, resolvedTarget] = key.split("\0");
3036
2881
  const flat = flattenOccurrences(links);
3037
2882
  issues.push({
3038
- analyzerId: ID23,
2883
+ analyzerId: ID21,
3039
2884
  severity: "info",
3040
2885
  nodeIds: [source],
3041
2886
  message: formatFinding({
@@ -3380,9 +3225,9 @@ var SCHEMA_VIOLATION_TEXTS = {
3380
3225
  };
3381
3226
 
3382
3227
  // plugins/core/analyzers/schema-violation/index.ts
3383
- var ID24 = "schema-violation";
3228
+ var ID22 = "schema-violation";
3384
3229
  var schemaViolationAnalyzer = {
3385
- id: ID24,
3230
+ id: ID22,
3386
3231
  pluginId: CORE_PLUGIN_ID,
3387
3232
  kind: "analyzer",
3388
3233
  description: "Flags nodes or links that violate the project schemas.",
@@ -3434,7 +3279,7 @@ function collectNodeFindings(v, node, out) {
3434
3279
  const result = v.validate("node", toNodeForSchema(node));
3435
3280
  if (result.ok) return;
3436
3281
  out.push({
3437
- analyzerId: ID24,
3282
+ analyzerId: ID22,
3438
3283
  severity: "error",
3439
3284
  nodeIds: [node.path],
3440
3285
  message: formatFinding({
@@ -3463,7 +3308,7 @@ function collectFrontmatterBaseFindings(node, out, kernelFlagged) {
3463
3308
  if (isMissingStringField(fm, "description")) missing.push("description");
3464
3309
  if (missing.length === 0) return;
3465
3310
  out.push({
3466
- analyzerId: ID24,
3311
+ analyzerId: ID22,
3467
3312
  // `warn` (not `error`) so the default `sm scan` exit code stays
3468
3313
  // 0 even when nodes are missing frontmatter base fields. Strict
3469
3314
  // mode (`sm scan --strict`) still escalates to exit 1. Matches
@@ -3486,7 +3331,7 @@ function collectLinkFindings(v, link, out) {
3486
3331
  const result = v.validate("link", toLinkForSchema(link));
3487
3332
  if (result.ok) return;
3488
3333
  out.push({
3489
- analyzerId: ID24,
3334
+ analyzerId: ID22,
3490
3335
  severity: "error",
3491
3336
  nodeIds: [link.source],
3492
3337
  message: formatFinding({
@@ -3555,13 +3400,13 @@ var ASCII_FORMATTER_TEXTS = {
3555
3400
  };
3556
3401
 
3557
3402
  // plugins/core/formatters/ascii/index.ts
3558
- var ID25 = "ascii";
3403
+ var ID23 = "ascii";
3559
3404
  var KIND_ORDER = ["agent", "command", "skill", "markdown"];
3560
3405
  var asciiFormatter = {
3561
- id: ID25,
3406
+ id: ID23,
3562
3407
  pluginId: CORE_PLUGIN_ID,
3563
3408
  kind: "formatter",
3564
- formatId: ID25,
3409
+ formatId: ID23,
3565
3410
  description: "Renders the scan as plain text in three sections: nodes (grouped by kind), arrows, and issues. Used by `sm scan --format ascii`.",
3566
3411
  // ASCII tree formatter, header + per-kind sections + per-issue
3567
3412
  // section. Each section iterates and renders; splitting per section
@@ -3655,13 +3500,13 @@ function renderSection(out, kind, group) {
3655
3500
  }
3656
3501
 
3657
3502
  // plugins/core/formatters/json/index.ts
3658
- var ID26 = "json";
3503
+ var ID24 = "json";
3659
3504
  var jsonFormatter = {
3660
- id: ID26,
3505
+ id: ID24,
3661
3506
  pluginId: CORE_PLUGIN_ID,
3662
3507
  kind: "formatter",
3663
3508
  description: "Renders the persisted scan as JSON (conforms to `scan-result.schema.json`). Used by `sm graph --format json` and `GET /api/graph?format=json`.",
3664
- formatId: ID26,
3509
+ formatId: ID24,
3665
3510
  format(ctx) {
3666
3511
  if (ctx.scanResult !== void 0) {
3667
3512
  return JSON.stringify(ctx.scanResult);
@@ -3808,13 +3653,13 @@ var BUMP_TEXTS = {
3808
3653
  };
3809
3654
 
3810
3655
  // plugins/core/actions/node-bump/index.ts
3811
- var ID27 = "node-bump";
3656
+ var ID25 = "node-bump";
3812
3657
  var bumpButton = {
3813
3658
  slot: "inspector.action.button",
3814
3659
  priority: 10
3815
3660
  };
3816
3661
  var nodeBumpAction = {
3817
- id: ID27,
3662
+ id: ID25,
3818
3663
  pluginId: CORE_PLUGIN_ID,
3819
3664
  kind: "action",
3820
3665
  description: "Marks a node as updated: bumps `annotations.version`, refreshes sidecar hashes, and records the timestamp.",
@@ -3822,8 +3667,9 @@ var nodeBumpAction = {
3822
3667
  ui: { bumpButton },
3823
3668
  project(ctx) {
3824
3669
  for (const node of ctx.nodes) {
3825
- if (node.sidecar?.present !== true) continue;
3826
- emitBumpButton(ctx, node.path, staleStatus2(node.sidecar) !== null);
3670
+ if (node.virtual === true) continue;
3671
+ const enabled = node.sidecar?.present !== true || staleStatus2(node.sidecar) !== null;
3672
+ emitBumpButton(ctx, node.path, enabled);
3827
3673
  }
3828
3674
  },
3829
3675
  // The runtime contract uses generic <TInput, TReport>; bump narrows
@@ -3892,15 +3738,39 @@ function pickCurrentVersion(overlay) {
3892
3738
  return typeof v === "number" && Number.isFinite(v) ? v : 0;
3893
3739
  }
3894
3740
 
3741
+ // plugins/core/actions/node-set-stability/text.ts
3742
+ var NODE_SET_STABILITY_TEXTS = {
3743
+ /** Label of the inspector action button that sets the lifecycle stage. */
3744
+ setLabel: "Set stability",
3745
+ /** Prompt label for the enum-pick stability input. */
3746
+ promptLabel: "Stability",
3747
+ /** Prompt option label for the `experimental` stage. */
3748
+ optionExperimental: "Experimental",
3749
+ /** Prompt option label for the `stable` stage. */
3750
+ optionStable: "Stable",
3751
+ /** Prompt option label for the `deprecated` stage. */
3752
+ optionDeprecated: "Deprecated"
3753
+ };
3754
+
3895
3755
  // plugins/core/actions/node-set-stability/index.ts
3896
- var STABILITY_VALUES = ["experimental", "stable", "deprecated"];
3897
- var ID28 = "node-set-stability";
3756
+ var ID26 = "node-set-stability";
3757
+ var setStabilityButton = {
3758
+ slot: "inspector.action.button",
3759
+ priority: 15
3760
+ };
3898
3761
  var nodeSetStabilityAction = {
3899
- id: ID28,
3762
+ id: ID26,
3900
3763
  pluginId: CORE_PLUGIN_ID,
3901
3764
  kind: "action",
3902
3765
  description: "Sets the lifecycle stage of the current node (writes `stability` to the sidecar).",
3903
3766
  mode: "deterministic",
3767
+ ui: { setStabilityButton },
3768
+ project(ctx) {
3769
+ for (const node of ctx.nodes) {
3770
+ if (node.virtual === true) continue;
3771
+ emitSetStabilityButton(ctx, node);
3772
+ }
3773
+ },
3904
3774
  // The runtime contract uses generic <TInput, TReport>; this narrows
3905
3775
  // both. The cast is the standard pattern for built-ins that want
3906
3776
  // typed local I/O while staying compatible with the open generic.
@@ -3909,6 +3779,27 @@ var nodeSetStabilityAction = {
3909
3779
  return invokeSetStability(input, ctx);
3910
3780
  }
3911
3781
  };
3782
+ function emitSetStabilityButton(ctx, node) {
3783
+ ctx.emitContribution(node.path, setStabilityButton, {
3784
+ actionId: "core/node-set-stability",
3785
+ label: NODE_SET_STABILITY_TEXTS.setLabel,
3786
+ icon: "pi-flag",
3787
+ enabled: true,
3788
+ prompt: {
3789
+ inputType: "enum-pick",
3790
+ paramKey: "stability",
3791
+ label: NODE_SET_STABILITY_TEXTS.promptLabel,
3792
+ options: [
3793
+ { value: "experimental", label: NODE_SET_STABILITY_TEXTS.optionExperimental },
3794
+ { value: "stable", label: NODE_SET_STABILITY_TEXTS.optionStable },
3795
+ { value: "deprecated", label: NODE_SET_STABILITY_TEXTS.optionDeprecated }
3796
+ ],
3797
+ // Pre-load the node's current stage so the picker opens on the active
3798
+ // value; `stable` when nothing is set yet.
3799
+ defaultValue: readEffectiveStability(node) ?? "stable"
3800
+ }
3801
+ });
3802
+ }
3912
3803
  function invokeSetStability(input, ctx) {
3913
3804
  const stability = input.stability;
3914
3805
  if (!STABILITY_VALUES.includes(stability)) {
@@ -3944,13 +3835,13 @@ var TAGS_TEXTS = {
3944
3835
  };
3945
3836
 
3946
3837
  // plugins/core/actions/node-set-tags/index.ts
3947
- var ID29 = "node-set-tags";
3838
+ var ID27 = "node-set-tags";
3948
3839
  var setTagsButton = {
3949
3840
  slot: "inspector.action.button",
3950
3841
  priority: 15
3951
3842
  };
3952
3843
  var nodeSetTagsAction = {
3953
- id: ID29,
3844
+ id: ID27,
3954
3845
  pluginId: CORE_PLUGIN_ID,
3955
3846
  kind: "action",
3956
3847
  description: "Sets the taxonomy tags of the current node (writes `tags` to the sidecar; whole-array replace).",
@@ -3958,7 +3849,7 @@ var nodeSetTagsAction = {
3958
3849
  ui: { setTagsButton },
3959
3850
  project(ctx) {
3960
3851
  for (const node of ctx.nodes) {
3961
- if (node.sidecar?.present !== true) continue;
3852
+ if (node.virtual === true) continue;
3962
3853
  emitSetTagsButton(ctx, node);
3963
3854
  }
3964
3855
  },
@@ -4014,107 +3905,6 @@ function invokeSetTags(input, ctx) {
4014
3905
  return { report, writes: [write] };
4015
3906
  }
4016
3907
 
4017
- // plugins/core/actions/node-supersede/text.ts
4018
- var SUPERSEDE_TEXTS = {
4019
- /** Label of the inspector action button that declares supersession. */
4020
- supersedeLabel: "Supersede",
4021
- /** Tooltip shown when the supersede button is disabled (already superseded). */
4022
- supersedeDisabledReason: "Already superseded.",
4023
- /** Tooltip shown when there is no other node to supersede this one. */
4024
- supersedeNoTargetsReason: "No other node to supersede this one.",
4025
- /** Prompt label for the target node-picker (enum-pick over the live node set). */
4026
- supersedePromptLabel: "Superseded by"
4027
- };
4028
-
4029
- // plugins/core/actions/node-supersede/index.ts
4030
- var ID30 = "node-supersede";
4031
- var supersedeButton = {
4032
- slot: "inspector.action.button",
4033
- priority: 10
4034
- };
4035
- var nodeSupersedeAction = {
4036
- id: ID30,
4037
- pluginId: CORE_PLUGIN_ID,
4038
- kind: "action",
4039
- description: "Declares the current node as superseded by another (writes `supersededBy` to the sidecar).",
4040
- // Ships disabled by default (the declarer feature is still settling its
4041
- // node-picker UX). The button self-projection gates as a unit with the
4042
- // invoke executor: an enabled button pointing at a disabled action
4043
- // would error on click, so the whole action stays experimental.
4044
- stability: "experimental",
4045
- mode: "deterministic",
4046
- ui: { supersedeButton },
4047
- project(ctx) {
4048
- const candidates = ctx.nodes.filter((n) => n.virtual !== true).map((n) => n.path);
4049
- for (const node of ctx.nodes) {
4050
- if (node.virtual === true) continue;
4051
- const options = candidates.filter((p) => p !== node.path).map((p) => ({ value: p, label: p }));
4052
- emitSupersedeButton(ctx, node, options);
4053
- }
4054
- },
4055
- // The runtime contract uses generic <TInput, TReport>; supersede
4056
- // narrows both. The cast is the standard pattern for built-ins that
4057
- // want typed local I/O while staying compatible with the open generic.
4058
- invoke(rawInput, ctx) {
4059
- const input = rawInput ?? {};
4060
- return invokeSupersede(input, ctx);
4061
- }
4062
- };
4063
- function emitSupersedeButton(ctx, node, options) {
4064
- const disabledReason = resolveDisabledReason(node, options.length);
4065
- ctx.emitContribution(node.path, supersedeButton, {
4066
- actionId: "core/node-supersede",
4067
- label: SUPERSEDE_TEXTS.supersedeLabel,
4068
- icon: "pi-arrow-right-arrow-left",
4069
- enabled: disabledReason === void 0,
4070
- ...disabledReason === void 0 ? {} : { disabledReason },
4071
- prompt: {
4072
- inputType: "enum-pick",
4073
- paramKey: "supersededBy",
4074
- label: SUPERSEDE_TEXTS.supersedePromptLabel,
4075
- options
4076
- }
4077
- });
4078
- }
4079
- function resolveDisabledReason(node, optionCount) {
4080
- if (alreadySuperseded(node)) return SUPERSEDE_TEXTS.supersedeDisabledReason;
4081
- if (optionCount === 0) return SUPERSEDE_TEXTS.supersedeNoTargetsReason;
4082
- return void 0;
4083
- }
4084
- function alreadySuperseded(node) {
4085
- const sidecar = node.sidecar;
4086
- if (!sidecar || sidecar.present !== true) return false;
4087
- const ann = sidecar.annotations;
4088
- if (!ann || typeof ann !== "object" || Array.isArray(ann)) return false;
4089
- const value = ann["supersededBy"];
4090
- return typeof value === "string" && value.length > 0;
4091
- }
4092
- function invokeSupersede(input, ctx) {
4093
- const supersededBy = input.supersededBy;
4094
- if (supersededBy === ctx.node.path) {
4095
- return { report: { ok: false, reason: "self" } };
4096
- }
4097
- const timestamp = ctx.now().toISOString();
4098
- const write = {
4099
- kind: "sidecar",
4100
- path: sidecarPathFor(ctx.nodeAbsolutePath),
4101
- changes: {
4102
- identity: {
4103
- path: ctx.node.path,
4104
- bodyHash: ctx.node.bodyHash,
4105
- frontmatterHash: ctx.node.frontmatterHash
4106
- },
4107
- annotations: { supersededBy },
4108
- audit: {
4109
- lastBumpedAt: timestamp,
4110
- lastBumpedBy: ctx.invoker
4111
- }
4112
- }
4113
- };
4114
- const report = { ok: true, supersededBy };
4115
- return { report, writes: [write] };
4116
- }
4117
-
4118
3908
  // kernel/update-check/index.ts
4119
3909
  var SEMVER_SHAPE_RE = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
4120
3910
  async function fetchLatestVersion(pkg, opts) {
@@ -4599,7 +4389,6 @@ var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity", ve
4599
4389
  var openaiProvider2 = { ...openaiProvider, pluginId: "openai", version: VERSION };
4600
4390
  var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills", version: VERSION };
4601
4391
  var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core", version: VERSION };
4602
- var annotationsExtractor2 = { ...annotationsExtractor, pluginId: "core", version: VERSION };
4603
4392
  var backtickPathExtractor2 = { ...backtickPathExtractor, pluginId: "core", version: VERSION };
4604
4393
  var externalUrlCounterExtractor2 = { ...externalUrlCounterExtractor, pluginId: "core", version: VERSION };
4605
4394
  var markdownLinkExtractor2 = { ...markdownLinkExtractor, pluginId: "core", version: VERSION };
@@ -4616,7 +4405,6 @@ var linkSelfLoopAnalyzer2 = { ...linkSelfLoopAnalyzer, pluginId: "core", version
4616
4405
  var nameCollisionAnalyzer2 = { ...nameCollisionAnalyzer, pluginId: "core", version: VERSION };
4617
4406
  var nameReservedAnalyzer2 = { ...nameReservedAnalyzer, pluginId: "core", version: VERSION };
4618
4407
  var nodeStabilityAnalyzer2 = { ...nodeStabilityAnalyzer, pluginId: "core", version: VERSION };
4619
- var nodeSupersededAnalyzer2 = { ...nodeSupersededAnalyzer, pluginId: "core", version: VERSION };
4620
4408
  var referenceBrokenAnalyzer2 = { ...referenceBrokenAnalyzer, pluginId: "core", version: VERSION };
4621
4409
  var referenceRedundantAnalyzer2 = { ...referenceRedundantAnalyzer, pluginId: "core", version: VERSION };
4622
4410
  var schemaViolationAnalyzer2 = { ...schemaViolationAnalyzer, pluginId: "core", version: VERSION };
@@ -4625,7 +4413,6 @@ var jsonFormatter2 = { ...jsonFormatter, pluginId: "core", version: VERSION };
4625
4413
  var nodeBumpAction2 = { ...nodeBumpAction, pluginId: "core", version: VERSION };
4626
4414
  var nodeSetStabilityAction2 = { ...nodeSetStabilityAction, pluginId: "core", version: VERSION };
4627
4415
  var nodeSetTagsAction2 = { ...nodeSetTagsAction, pluginId: "core", version: VERSION };
4628
- var nodeSupersedeAction2 = { ...nodeSupersedeAction, pluginId: "core", version: VERSION };
4629
4416
  var updateCheckHook2 = { ...updateCheckHook, pluginId: "core", version: VERSION };
4630
4417
  var builtInPlugins = [
4631
4418
  {
@@ -4664,7 +4451,6 @@ var builtInPlugins = [
4664
4451
  description: "Core extensions shared across providers: parsers, extractors, analyzers, actions, hooks, formatters, and the universal `.md` fallback provider.",
4665
4452
  extensions: [
4666
4453
  coreMarkdownProvider2,
4667
- annotationsExtractor2,
4668
4454
  backtickPathExtractor2,
4669
4455
  externalUrlCounterExtractor2,
4670
4456
  markdownLinkExtractor2,
@@ -4681,7 +4467,6 @@ var builtInPlugins = [
4681
4467
  nameCollisionAnalyzer2,
4682
4468
  nameReservedAnalyzer2,
4683
4469
  nodeStabilityAnalyzer2,
4684
- nodeSupersededAnalyzer2,
4685
4470
  referenceBrokenAnalyzer2,
4686
4471
  referenceRedundantAnalyzer2,
4687
4472
  schemaViolationAnalyzer2,
@@ -4690,7 +4475,6 @@ var builtInPlugins = [
4690
4475
  nodeBumpAction2,
4691
4476
  nodeSetStabilityAction2,
4692
4477
  nodeSetTagsAction2,
4693
- nodeSupersedeAction2,
4694
4478
  updateCheckHook2
4695
4479
  ]
4696
4480
  }
@@ -7593,7 +7377,6 @@ var LINK_KIND_VALUES = Object.freeze([
7593
7377
  "invokes",
7594
7378
  "references",
7595
7379
  "mentions",
7596
- "supersedes",
7597
7380
  "points"
7598
7381
  ]);
7599
7382
  var SEVERITY_VALUES = Object.freeze([
@@ -10734,17 +10517,6 @@ var LOCKED_PLUGIN_IDS = /* @__PURE__ */ new Set([
10734
10517
  // silently invisible, a foot-gun the host product does not want to
10735
10518
  // expose. Lock it in the enabled state.
10736
10519
  "core/markdown",
10737
- // `core/annotations` turns the `supersedes` / `supersededBy` /
10738
- // `requires` / `related` / `conflictsWith` entries of the sidecar
10739
- // `annotations:` block into the arrows the graph draws between nodes.
10740
- // It does NOT own the rest of the block (`version`, `stability`,
10741
- // `tags`, `description`, those live on the node bundle directly and
10742
- // keep rendering with the plugin off). Disabling it produces a
10743
- // confusing "edges disappear but the sidecar metadata stays" split
10744
- // that no operator actually wants; the lock makes the asymmetry
10745
- // unreachable from CLI / BFF / UI. Re-evaluate if a third-party ever
10746
- // ships a competing supersession extractor.
10747
- "core/annotations",
10748
10520
  // `core/schema-violation` validates every scanned Node against
10749
10521
  // `node.schema.json` and every Link against `link.schema.json` (the
10750
10522
  // authoritative @skill-map/spec). Disabling it makes the system
@@ -15709,7 +15481,7 @@ function buildVirtualNode(extractor, emitted, emitter) {
15709
15481
  if (emitted.frontmatter) node.frontmatter = emitted.frontmatter;
15710
15482
  return node;
15711
15483
  }
15712
- var KNOWN_LINK_KINDS = ["invokes", "references", "mentions", "supersedes", "points"];
15484
+ var KNOWN_LINK_KINDS = ["invokes", "references", "mentions", "points"];
15713
15485
  function validateLink(extractor, link, emitter) {
15714
15486
  const knownKinds = KNOWN_LINK_KINDS;
15715
15487
  if (!knownKinds.includes(link.kind)) {
@@ -16150,26 +15922,24 @@ function validateIssue(analyzer, issue, emitter) {
16150
15922
  // kernel/orchestrator/cache.ts
16151
15923
  function indexPriorSnapshot(prior) {
16152
15924
  const priorNodesByPath = /* @__PURE__ */ new Map();
16153
- const priorNodePaths = /* @__PURE__ */ new Set();
16154
15925
  const priorLinksByOriginating = /* @__PURE__ */ new Map();
16155
15926
  const priorFrontmatterIssuesByNode = /* @__PURE__ */ new Map();
16156
15927
  if (!prior) {
16157
- return { priorNodesByPath, priorNodePaths, priorLinksByOriginating, priorFrontmatterIssuesByNode };
15928
+ return { priorNodesByPath, priorLinksByOriginating, priorFrontmatterIssuesByNode };
16158
15929
  }
16159
- indexPriorNodes(prior.nodes, priorNodesByPath, priorNodePaths);
16160
- indexPriorLinks(prior.links, priorNodePaths, priorLinksByOriginating);
15930
+ indexPriorNodes(prior.nodes, priorNodesByPath);
15931
+ indexPriorLinks(prior.links, priorLinksByOriginating);
16161
15932
  indexPriorFrontmatterIssues(prior.issues, priorFrontmatterIssuesByNode);
16162
- return { priorNodesByPath, priorNodePaths, priorLinksByOriginating, priorFrontmatterIssuesByNode };
15933
+ return { priorNodesByPath, priorLinksByOriginating, priorFrontmatterIssuesByNode };
16163
15934
  }
16164
- function indexPriorNodes(nodes, byPath3, paths) {
15935
+ function indexPriorNodes(nodes, byPath3) {
16165
15936
  for (const node of nodes) {
16166
15937
  byPath3.set(node.path, node);
16167
- paths.add(node.path);
16168
15938
  }
16169
15939
  }
16170
- function indexPriorLinks(links, priorNodePaths, byOriginating) {
15940
+ function indexPriorLinks(links, byOriginating) {
16171
15941
  for (const link of links) {
16172
- const key = originatingNodeOf(link, priorNodePaths);
15942
+ const key = link.source;
16173
15943
  const list = byOriginating.get(key);
16174
15944
  if (list) list.push(link);
16175
15945
  else byOriginating.set(key, [link]);
@@ -16185,12 +15955,6 @@ function indexPriorFrontmatterIssues(issues, byNode) {
16185
15955
  else byNode.set(path, [issue]);
16186
15956
  }
16187
15957
  }
16188
- function originatingNodeOf(link, priorNodePaths) {
16189
- if (link.kind === "supersedes" && !priorNodePaths.has(link.source)) {
16190
- return link.target;
16191
- }
16192
- return link.source;
16193
- }
16194
15958
  function computeCacheDecision(opts) {
16195
15959
  const applicableExtractors = opts.extractors.filter((ex) => {
16196
15960
  if (!matchesKindPrecondition(ex, opts.kind)) return false;
@@ -24409,8 +24173,8 @@ var ScanCommand = class extends SmCommand {
24409
24173
  details: `
24410
24174
  Walks the given roots with the built-in claude Provider, runs the
24411
24175
  frontmatter / slash / at-directive / external-url-counter
24412
- extractors per node, then the name-collision / broken-ref /
24413
- superseded analyzers over the full graph. Emits a ScanResult
24176
+ extractors per node, then the name-collision / broken-ref
24177
+ analyzers over the full graph. Emits a ScanResult
24414
24178
  conforming to scan-result.schema.json.
24415
24179
 
24416
24180
  The result is persisted into <cwd>/.skill-map/skill-map.db
@@ -31209,4 +30973,4 @@ function resolveBareDefault() {
31209
30973
  process.exit(ExitCode.Error);
31210
30974
  }
31211
30975
  //# sourceMappingURL=cli.js.map
31212
- //# debugId=e6038423-ea97-5e66-b371-0916d382d819
30976
+ //# debugId=7e4fdbab-f037-5030-b67a-732bb7ee46fd