@skill-map/cli 0.35.0 → 0.36.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/README.md +1 -1
- package/dist/cli/tutorial/sm-master/SKILL.md +12 -14
- package/dist/cli/tutorial/sm-master/references/fixture-templates.md +10 -9
- package/dist/cli/tutorial/sm-master/references/tour-plugins.md +3 -3
- package/dist/cli/tutorial/sm-tutorial/SKILL.md +47 -41
- package/dist/cli.js +325 -264
- package/dist/cli.js.map +1 -1
- package/dist/index.js +119 -64
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +58 -8
- package/dist/kernel/index.js +119 -64
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/{chunk-P25ABCQU.js → chunk-GQ5YNA5Q.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/ui/{main-MNZ7YAUE.js → main-MGFSWAOX.js} +1 -1
- package/package.json +2 -2
package/dist/kernel/index.d.ts
CHANGED
|
@@ -1756,12 +1756,12 @@ interface IProviderKind {
|
|
|
1756
1756
|
* kinds (`agent`, `command`, `skill` per their schemas) typically
|
|
1757
1757
|
* declare this first.
|
|
1758
1758
|
* - `'filename-basename'`, `basename(path)` without the extension.
|
|
1759
|
-
* For Claude/
|
|
1759
|
+
* For Claude/OpenAI agents and commands the filename IS the
|
|
1760
1760
|
* invocation handle when `name:` is absent.
|
|
1761
|
-
* - `'dirname'`, `basename(dirname(path))`. Anthropic skills +
|
|
1762
|
-
*
|
|
1763
|
-
* skills root and the
|
|
1764
|
-
* `.claude/skills/foo/SKILL.md` → `foo`).
|
|
1761
|
+
* - `'dirname'`, `basename(dirname(path))`. Anthropic skills +
|
|
1762
|
+
* agent-skills (open standard, also adopted by Antigravity)
|
|
1763
|
+
* resolve to the directory between the skills root and the
|
|
1764
|
+
* SKILL.md (e.g. `.claude/skills/foo/SKILL.md` → `foo`).
|
|
1765
1765
|
*
|
|
1766
1766
|
* Compare with `IProvider.resolution` (which declares which target
|
|
1767
1767
|
* kinds resolve which link.kind): `identifiers` is a per-kind detail
|
|
@@ -1930,7 +1930,7 @@ interface IProvider extends IExtensionBase {
|
|
|
1930
1930
|
* orchestrator drops the duplicate.
|
|
1931
1931
|
*
|
|
1932
1932
|
* Convention: a Provider's classify returns one of its own `kinds`
|
|
1933
|
-
* map keys for paths in its territory (`.claude/`, `.
|
|
1933
|
+
* map keys for paths in its territory (`.claude/`, `.codex/`,
|
|
1934
1934
|
* `.agents/skills/`, etc.) and `null` elsewhere. External Providers
|
|
1935
1935
|
* (Cursor, Obsidian, …) follow the same rule: claim what's yours,
|
|
1936
1936
|
* disclaim everything else. The orchestrator does not validate the
|
|
@@ -1969,6 +1969,41 @@ interface IProvider extends IExtensionBase {
|
|
|
1969
1969
|
* confidence-lift contract, which runs against the merged Link graph.
|
|
1970
1970
|
*/
|
|
1971
1971
|
resolution?: Record<string, string[]>;
|
|
1972
|
+
/**
|
|
1973
|
+
* Reserved invocation names this Provider's runtime owns for each
|
|
1974
|
+
* kind. Maps a `node.kind` to the set of normalised names the runtime
|
|
1975
|
+
* uses for its built-in invocables (e.g. `claude` reserves
|
|
1976
|
+
* `['help', 'clear', 'init', …]` under `command` because typing
|
|
1977
|
+
* `/help` in the Claude CLI runs the built-in help screen, not a
|
|
1978
|
+
* user-authored `.claude/commands/help.md`).
|
|
1979
|
+
*
|
|
1980
|
+
* Two consumers share the catalog:
|
|
1981
|
+
*
|
|
1982
|
+
* 1. The `core/reserved-name` analyzer scans every user node and
|
|
1983
|
+
* emits a `warn` issue when the node's normalised identifiers
|
|
1984
|
+
* (per `IProviderKind.identifiers`) intersect the reserved list
|
|
1985
|
+
* for its provider + kind. The user file is silently shadowed
|
|
1986
|
+
* by the runtime, the analyzer surfaces it so the operator can
|
|
1987
|
+
* rename.
|
|
1988
|
+
* 2. The post-walk confidence-lift transform downgrades any link
|
|
1989
|
+
* that resolves to a reserved node (by path OR by name) to a
|
|
1990
|
+
* very low confidence floor (today `0.1`) instead of bumping
|
|
1991
|
+
* to `1.0`. The graph then reflects "this edge exists in disk
|
|
1992
|
+
* but the runtime ignores the target".
|
|
1993
|
+
*
|
|
1994
|
+
* Default `undefined` ≡ empty map ≡ no reserved names. Reserved
|
|
1995
|
+
* lookup normalises both sides via the §Extractor · trigger
|
|
1996
|
+
* normalization pipeline (lowercase, NFD, separator unification),
|
|
1997
|
+
* so a literal `Init-Project` in the manifest still matches a user
|
|
1998
|
+
* `name: init project` or filename `Init-Project.md`.
|
|
1999
|
+
*
|
|
2000
|
+
* The set is intentionally per-kind, not global: a name reserved for
|
|
2001
|
+
* commands (`/help`) may legitimately appear as a skill (a "help"
|
|
2002
|
+
* skill that triggers via something other than the command channel).
|
|
2003
|
+
* Providers MUST scope each entry to the kind the runtime actually
|
|
2004
|
+
* consumes.
|
|
2005
|
+
*/
|
|
2006
|
+
reservedNames?: Record<string, readonly string[]>;
|
|
1972
2007
|
}
|
|
1973
2008
|
/**
|
|
1974
2009
|
* Declarative read config a Provider declares via `IProvider.read`.
|
|
@@ -2234,6 +2269,21 @@ interface IAnalyzerContext {
|
|
|
2234
2269
|
* adapter does not maintain the side index. Treat as read-only.
|
|
2235
2270
|
*/
|
|
2236
2271
|
referenceablePaths?: ReadonlySet<string>;
|
|
2272
|
+
/**
|
|
2273
|
+
* Paths of nodes whose normalised identifier(s) intersect their
|
|
2274
|
+
* Provider's `reservedNames[kind]` catalog (e.g. a user-authored
|
|
2275
|
+
* `.claude/commands/help.md` whose name normalises to `help`,
|
|
2276
|
+
* shadowed by Claude's built-in `/help` command). The set is
|
|
2277
|
+
* computed once per scan by the orchestrator (mirroring the same
|
|
2278
|
+
* set threaded to the post-walk confidence-lift transform), so
|
|
2279
|
+
* analyzers consume it without re-deriving every node's
|
|
2280
|
+
* identifiers. The single consumer today is `core/reserved-name`,
|
|
2281
|
+
* which projects one warn issue per entry; future analyzers MAY
|
|
2282
|
+
* read the set for cross-rule cohesion (e.g. an action that
|
|
2283
|
+
* suggests rename targets). Absent for legacy callers (older
|
|
2284
|
+
* `runScan` sites that never wired the field through).
|
|
2285
|
+
*/
|
|
2286
|
+
reservedNodePaths?: ReadonlySet<string>;
|
|
2237
2287
|
/**
|
|
2238
2288
|
* Absolute path of the scan's project root (cwd of the invocation).
|
|
2239
2289
|
* Threaded into the analyzer pass so an analyzer that needs to
|
|
@@ -3048,8 +3098,8 @@ interface RunScanOptions {
|
|
|
3048
3098
|
* - `null`: explicit "no lens". Provider-specific extractors are
|
|
3049
3099
|
* unconditionally skipped (spec-strict).
|
|
3050
3100
|
* - `undefined`: kernel auto-detects from `options.roots[0]` using
|
|
3051
|
-
* filesystem markers (`.claude/`, `.
|
|
3052
|
-
*
|
|
3101
|
+
* filesystem markers (`.claude/`, `.codex/`, `AGENTS.md`).
|
|
3102
|
+
* Convenient default for out-of-band callers
|
|
3053
3103
|
* (integration tests, embedders) that don't thread a settings
|
|
3054
3104
|
* reader. Production callers (scan-runner) resolve upstream and
|
|
3055
3105
|
* pass `string | null` explicitly, never `undefined`.
|
package/dist/kernel/index.js
CHANGED
|
@@ -94,14 +94,14 @@ var Registry = class {
|
|
|
94
94
|
|
|
95
95
|
// kernel/orchestrator/index.ts
|
|
96
96
|
import { existsSync as existsSync11, statSync as statSync4 } from "fs";
|
|
97
|
-
import { isAbsolute as isAbsolute4, resolve as
|
|
97
|
+
import { isAbsolute as isAbsolute4, resolve as resolve11 } from "path";
|
|
98
98
|
import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
99
99
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
100
100
|
|
|
101
101
|
// package.json
|
|
102
102
|
var package_default = {
|
|
103
103
|
name: "@skill-map/cli",
|
|
104
|
-
version: "0.
|
|
104
|
+
version: "0.36.0",
|
|
105
105
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
106
106
|
license: "MIT",
|
|
107
107
|
type: "module",
|
|
@@ -1051,7 +1051,13 @@ function loadConfigForScope(opts) {
|
|
|
1051
1051
|
// core/config/active-provider.ts
|
|
1052
1052
|
var DETECTION_RULES = [
|
|
1053
1053
|
{ providerId: "claude", marker: ".claude" },
|
|
1054
|
-
|
|
1054
|
+
// `gemini` retired 2026-05-22: Google replaced the Gemini CLI with the
|
|
1055
|
+
// Antigravity CLI (released 2026-05-19; Gemini CLI sunsets 2026-06-18).
|
|
1056
|
+
// Antigravity adopted the open-standard `.agents/` instead of a
|
|
1057
|
+
// vendor-specific directory, so detection of a Google CLI project
|
|
1058
|
+
// falls through to the universal `agent-skills` lens (`.agents/`
|
|
1059
|
+
// already classifies via that neutral provider). The lens can still
|
|
1060
|
+
// be set manually via `sm config set activeProvider antigravity`.
|
|
1055
1061
|
{ providerId: "openai", marker: ".codex" },
|
|
1056
1062
|
{ providerId: "openai", marker: "AGENTS.md" },
|
|
1057
1063
|
{ providerId: "cursor", marker: ".cursor" }
|
|
@@ -1429,7 +1435,7 @@ function isExternalUrlLink(link) {
|
|
|
1429
1435
|
}
|
|
1430
1436
|
|
|
1431
1437
|
// kernel/orchestrator/analyzers.ts
|
|
1432
|
-
async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sidecarRoots, annotationContributions, viewContributions, orphanJobFiles, referenceablePaths, cwd, registeredActionIds, emitter, hookDispatcher) {
|
|
1438
|
+
async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sidecarRoots, annotationContributions, viewContributions, orphanJobFiles, referenceablePaths, cwd, registeredActionIds, emitter, hookDispatcher, reservedNodePaths) {
|
|
1433
1439
|
const issues = [];
|
|
1434
1440
|
const contributions = [];
|
|
1435
1441
|
const validators = loadSchemaValidators();
|
|
@@ -1493,6 +1499,7 @@ async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sid
|
|
|
1493
1499
|
orphanJobFiles,
|
|
1494
1500
|
...referenceablePaths ? { referenceablePaths } : {},
|
|
1495
1501
|
...cwd ? { cwd } : {},
|
|
1502
|
+
...reservedNodePaths ? { reservedNodePaths } : {},
|
|
1496
1503
|
emitContribution
|
|
1497
1504
|
});
|
|
1498
1505
|
for (const issue of emitted) {
|
|
@@ -1713,7 +1720,7 @@ function classifyLinkSource(source, shortIdToQualified, cachedQualifiedIds, appl
|
|
|
1713
1720
|
return "obsolete";
|
|
1714
1721
|
}
|
|
1715
1722
|
|
|
1716
|
-
// kernel/orchestrator/
|
|
1723
|
+
// kernel/orchestrator/node-identifiers.ts
|
|
1717
1724
|
import { posix as pathPosix } from "path";
|
|
1718
1725
|
|
|
1719
1726
|
// kernel/trigger-normalize.ts
|
|
@@ -1726,14 +1733,53 @@ function normalizeTrigger(source) {
|
|
|
1726
1733
|
return out.trim();
|
|
1727
1734
|
}
|
|
1728
1735
|
|
|
1736
|
+
// kernel/orchestrator/node-identifiers.ts
|
|
1737
|
+
function deriveNodeIdentifiers(node, kindDescriptor) {
|
|
1738
|
+
const sources = kindDescriptor?.identifiers;
|
|
1739
|
+
if (!sources || sources.length === 0) return [];
|
|
1740
|
+
const out = [];
|
|
1741
|
+
for (const source of sources) {
|
|
1742
|
+
const raw = readIdentifier(source, node);
|
|
1743
|
+
if (!raw) continue;
|
|
1744
|
+
const normalised = normalizeTrigger(raw);
|
|
1745
|
+
if (normalised) out.push(normalised);
|
|
1746
|
+
}
|
|
1747
|
+
return out;
|
|
1748
|
+
}
|
|
1749
|
+
function readIdentifier(source, node) {
|
|
1750
|
+
if (source === "frontmatter.name") return readFrontmatterName(node);
|
|
1751
|
+
if (source === "filename-basename") return readFilenameBasename(node);
|
|
1752
|
+
return readDirname(node);
|
|
1753
|
+
}
|
|
1754
|
+
function readFrontmatterName(node) {
|
|
1755
|
+
const raw = node.frontmatter?.["name"];
|
|
1756
|
+
if (typeof raw !== "string") return null;
|
|
1757
|
+
return raw.length > 0 ? raw : null;
|
|
1758
|
+
}
|
|
1759
|
+
function readFilenameBasename(node) {
|
|
1760
|
+
const base = pathPosix.basename(node.path);
|
|
1761
|
+
if (!base) return null;
|
|
1762
|
+
const ext = pathPosix.extname(base);
|
|
1763
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
1764
|
+
return stem.length > 0 ? stem : null;
|
|
1765
|
+
}
|
|
1766
|
+
function readDirname(node) {
|
|
1767
|
+
const dir = pathPosix.dirname(node.path);
|
|
1768
|
+
if (!dir || dir === "." || dir === "/") return null;
|
|
1769
|
+
const base = pathPosix.basename(dir);
|
|
1770
|
+
return base.length > 0 ? base : null;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1729
1773
|
// kernel/orchestrator/lift-resolved-link-confidence.ts
|
|
1774
|
+
var RESERVED_TARGET_CONFIDENCE = 0.1;
|
|
1730
1775
|
function liftResolvedLinkConfidence(links, nodes, ctx) {
|
|
1731
1776
|
if (!links.some((l) => l.confidence < 1)) return;
|
|
1732
1777
|
const indexes = buildIndexes(nodes, ctx);
|
|
1733
1778
|
for (const link of links) {
|
|
1734
|
-
if (link.confidence
|
|
1735
|
-
|
|
1736
|
-
|
|
1779
|
+
if (link.confidence >= 1) continue;
|
|
1780
|
+
const resolution = resolve7(link, indexes, ctx);
|
|
1781
|
+
if (resolution === "none") continue;
|
|
1782
|
+
link.confidence = ctx.reservedNodePaths.has(resolution) ? RESERVED_TARGET_CONFIDENCE : 1;
|
|
1737
1783
|
}
|
|
1738
1784
|
}
|
|
1739
1785
|
function buildIndexes(nodes, ctx) {
|
|
@@ -1747,18 +1793,19 @@ function buildIndexes(nodes, ctx) {
|
|
|
1747
1793
|
}
|
|
1748
1794
|
return { byPath: byPath2, byName, nodeByPath };
|
|
1749
1795
|
}
|
|
1750
|
-
function
|
|
1751
|
-
if (indexes.byPath.has(link.target)) return
|
|
1752
|
-
return
|
|
1796
|
+
function resolve7(link, indexes, ctx) {
|
|
1797
|
+
if (indexes.byPath.has(link.target)) return link.target;
|
|
1798
|
+
return resolveByName(link, indexes, ctx);
|
|
1753
1799
|
}
|
|
1754
|
-
function
|
|
1800
|
+
function resolveByName(link, indexes, ctx) {
|
|
1755
1801
|
const stripped = stripTriggerSigil(link.trigger?.normalizedTrigger);
|
|
1756
|
-
if (stripped === null) return
|
|
1802
|
+
if (stripped === null) return "none";
|
|
1757
1803
|
const candidates = indexes.byName.get(stripped);
|
|
1758
|
-
if (!candidates?.length) return
|
|
1804
|
+
if (!candidates?.length) return "none";
|
|
1759
1805
|
const allowedKinds = lookupAllowedKinds(link, indexes, ctx);
|
|
1760
|
-
if (!allowedKinds?.length) return
|
|
1761
|
-
|
|
1806
|
+
if (!allowedKinds?.length) return "none";
|
|
1807
|
+
const winner = candidates.find((c) => allowedKinds.includes(c.kind));
|
|
1808
|
+
return winner ? winner.path : "none";
|
|
1762
1809
|
}
|
|
1763
1810
|
function lookupAllowedKinds(link, indexes, ctx) {
|
|
1764
1811
|
const sourceNode = indexes.nodeByPath.get(link.source);
|
|
@@ -1772,44 +1819,17 @@ function stripTriggerSigil(normalized) {
|
|
|
1772
1819
|
}
|
|
1773
1820
|
function indexNode(node, ctx, byName) {
|
|
1774
1821
|
const kindDescriptor = ctx.kindRegistry.get(kindKey(node));
|
|
1775
|
-
const
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
const
|
|
1779
|
-
if (!raw) continue;
|
|
1780
|
-
const normalized = normalizeTrigger(raw);
|
|
1781
|
-
if (!normalized) continue;
|
|
1782
|
-
const bucket = byName.get(normalized);
|
|
1822
|
+
const normalised = deriveNodeIdentifiers(node, kindDescriptor);
|
|
1823
|
+
for (const name of normalised) {
|
|
1824
|
+
const entry = { kind: node.kind, path: node.path };
|
|
1825
|
+
const bucket = byName.get(name);
|
|
1783
1826
|
if (bucket) {
|
|
1784
|
-
bucket.push(
|
|
1827
|
+
bucket.push(entry);
|
|
1785
1828
|
} else {
|
|
1786
|
-
byName.set(
|
|
1829
|
+
byName.set(name, [entry]);
|
|
1787
1830
|
}
|
|
1788
1831
|
}
|
|
1789
1832
|
}
|
|
1790
|
-
function deriveIdentifier(source, node) {
|
|
1791
|
-
if (source === "frontmatter.name") return readFrontmatterName(node);
|
|
1792
|
-
if (source === "filename-basename") return readFilenameBasename(node);
|
|
1793
|
-
return readDirname(node);
|
|
1794
|
-
}
|
|
1795
|
-
function readFrontmatterName(node) {
|
|
1796
|
-
const raw = node.frontmatter?.["name"];
|
|
1797
|
-
if (typeof raw !== "string") return null;
|
|
1798
|
-
return raw.length > 0 ? raw : null;
|
|
1799
|
-
}
|
|
1800
|
-
function readFilenameBasename(node) {
|
|
1801
|
-
const base = pathPosix.basename(node.path);
|
|
1802
|
-
if (!base) return null;
|
|
1803
|
-
const ext = pathPosix.extname(base);
|
|
1804
|
-
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
1805
|
-
return stem.length > 0 ? stem : null;
|
|
1806
|
-
}
|
|
1807
|
-
function readDirname(node) {
|
|
1808
|
-
const dir = pathPosix.dirname(node.path);
|
|
1809
|
-
if (!dir || dir === "." || dir === "/") return null;
|
|
1810
|
-
const base = pathPosix.basename(dir);
|
|
1811
|
-
return base.length > 0 ? base : null;
|
|
1812
|
-
}
|
|
1813
1833
|
function kindKey(node) {
|
|
1814
1834
|
return `${node.provider}/${node.kind}`;
|
|
1815
1835
|
}
|
|
@@ -1978,7 +1998,7 @@ import { join as join7, relative as relative2, sep } from "path";
|
|
|
1978
1998
|
|
|
1979
1999
|
// kernel/scan/ignore.ts
|
|
1980
2000
|
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
1981
|
-
import { dirname as dirname4, resolve as
|
|
2001
|
+
import { dirname as dirname4, resolve as resolve8 } from "path";
|
|
1982
2002
|
import { fileURLToPath } from "url";
|
|
1983
2003
|
import ignoreFactory from "ignore";
|
|
1984
2004
|
function buildIgnoreFilter(opts = {}) {
|
|
@@ -2012,11 +2032,11 @@ function loadDefaultsText() {
|
|
|
2012
2032
|
function readDefaultsFromDisk() {
|
|
2013
2033
|
const here = dirname4(fileURLToPath(import.meta.url));
|
|
2014
2034
|
const candidates = [
|
|
2015
|
-
|
|
2035
|
+
resolve8(here, "../../config/defaults/skillmapignore"),
|
|
2016
2036
|
// src/kernel/scan/ → src/config/defaults/
|
|
2017
|
-
|
|
2037
|
+
resolve8(here, "../config/defaults/skillmapignore"),
|
|
2018
2038
|
// dist/cli.js → dist/config/defaults/ (siblings)
|
|
2019
|
-
|
|
2039
|
+
resolve8(here, "config/defaults/skillmapignore")
|
|
2020
2040
|
];
|
|
2021
2041
|
for (const candidate of candidates) {
|
|
2022
2042
|
if (existsSync6(candidate)) {
|
|
@@ -2207,7 +2227,7 @@ function resolveProviderWalk(provider) {
|
|
|
2207
2227
|
|
|
2208
2228
|
// kernel/sidecar/parse.ts
|
|
2209
2229
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
2210
|
-
import { dirname as dirname5, resolve as
|
|
2230
|
+
import { dirname as dirname5, resolve as resolve9 } from "path";
|
|
2211
2231
|
import { createRequire as createRequire3 } from "module";
|
|
2212
2232
|
import { Ajv2020 as Ajv20204 } from "ajv/dist/2020.js";
|
|
2213
2233
|
import yaml2 from "js-yaml";
|
|
@@ -2286,10 +2306,10 @@ function getSidecarValidator() {
|
|
|
2286
2306
|
applyAjvFormats(ajv);
|
|
2287
2307
|
const specRoot = resolveSpecRoot2();
|
|
2288
2308
|
const annotationsSchema = JSON.parse(
|
|
2289
|
-
readFileSync8(
|
|
2309
|
+
readFileSync8(resolve9(specRoot, "schemas/annotations.schema.json"), "utf8")
|
|
2290
2310
|
);
|
|
2291
2311
|
const sidecarSchema = JSON.parse(
|
|
2292
|
-
readFileSync8(
|
|
2312
|
+
readFileSync8(resolve9(specRoot, "schemas/sidecar.schema.json"), "utf8")
|
|
2293
2313
|
);
|
|
2294
2314
|
ajv.addSchema(annotationsSchema);
|
|
2295
2315
|
cachedSidecarValidator = ajv.compile(sidecarSchema);
|
|
@@ -2360,7 +2380,7 @@ function safeIsFile(path) {
|
|
|
2360
2380
|
|
|
2361
2381
|
// kernel/sidecar/store.ts
|
|
2362
2382
|
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
|
|
2363
|
-
import { dirname as dirname6, resolve as
|
|
2383
|
+
import { dirname as dirname6, resolve as resolve10 } from "path";
|
|
2364
2384
|
import { createRequire as createRequire4 } from "module";
|
|
2365
2385
|
import { Ajv2020 as Ajv20205 } from "ajv/dist/2020.js";
|
|
2366
2386
|
import yaml3 from "js-yaml";
|
|
@@ -2904,7 +2924,7 @@ async function runScanInternal(_kernel, options) {
|
|
|
2904
2924
|
pluginStores: options.pluginStores,
|
|
2905
2925
|
activeProvider: resolveActiveProviderOption(options.activeProvider, options.roots)
|
|
2906
2926
|
});
|
|
2907
|
-
const postWalkCtx = buildPostWalkTransformCtx(_kernel);
|
|
2927
|
+
const postWalkCtx = buildPostWalkTransformCtx(_kernel, walked.nodes);
|
|
2908
2928
|
walked.internalLinks = applyPostWalkTransforms(walked.internalLinks, walked.nodes, postWalkCtx);
|
|
2909
2929
|
recomputeLinkCounts(walked.nodes, walked.internalLinks);
|
|
2910
2930
|
recomputeExternalRefsCount(walked.nodes, walked.externalLinks, walked.cachedPaths);
|
|
@@ -2925,7 +2945,8 @@ async function runScanInternal(_kernel, options) {
|
|
|
2925
2945
|
options.cwd,
|
|
2926
2946
|
registeredActionIds,
|
|
2927
2947
|
emitter,
|
|
2928
|
-
hookDispatcher
|
|
2948
|
+
hookDispatcher,
|
|
2949
|
+
postWalkCtx.reservedNodePaths
|
|
2929
2950
|
);
|
|
2930
2951
|
mergeAnalyzerEmissions(walked, analyzerResult, exts.analyzers);
|
|
2931
2952
|
const issues = analyzerResult.issues;
|
|
@@ -2938,9 +2959,19 @@ async function runScanInternal(_kernel, options) {
|
|
|
2938
2959
|
await hookDispatcher.dispatch("scan.completed", scanCompletedEvent);
|
|
2939
2960
|
return buildScanReturn(walked, issues, renameOps, stats, options, setup);
|
|
2940
2961
|
}
|
|
2941
|
-
function buildPostWalkTransformCtx(kernel) {
|
|
2962
|
+
function buildPostWalkTransformCtx(kernel, nodes) {
|
|
2963
|
+
const { kindRegistry, providerResolution, reservedNamesByProviderKind } = buildProviderIndexes(kernel);
|
|
2964
|
+
const reservedNodePaths = buildReservedNodePaths(
|
|
2965
|
+
nodes,
|
|
2966
|
+
kindRegistry,
|
|
2967
|
+
reservedNamesByProviderKind
|
|
2968
|
+
);
|
|
2969
|
+
return { kindRegistry, providerResolution, reservedNodePaths };
|
|
2970
|
+
}
|
|
2971
|
+
function buildProviderIndexes(kernel) {
|
|
2942
2972
|
const kindRegistry = /* @__PURE__ */ new Map();
|
|
2943
2973
|
const providerResolution = /* @__PURE__ */ new Map();
|
|
2974
|
+
const reservedNamesByProviderKind = /* @__PURE__ */ new Map();
|
|
2944
2975
|
const providers = kernel.registry.all("provider");
|
|
2945
2976
|
for (const provider of providers) {
|
|
2946
2977
|
if (provider.kinds) {
|
|
@@ -2951,8 +2982,32 @@ function buildPostWalkTransformCtx(kernel) {
|
|
|
2951
2982
|
if (provider.resolution) {
|
|
2952
2983
|
providerResolution.set(provider.id, provider.resolution);
|
|
2953
2984
|
}
|
|
2985
|
+
if (provider.reservedNames) {
|
|
2986
|
+
indexReservedNames(provider, reservedNamesByProviderKind);
|
|
2987
|
+
}
|
|
2954
2988
|
}
|
|
2955
|
-
return { kindRegistry, providerResolution };
|
|
2989
|
+
return { kindRegistry, providerResolution, reservedNamesByProviderKind };
|
|
2990
|
+
}
|
|
2991
|
+
function indexReservedNames(provider, out) {
|
|
2992
|
+
for (const [kindName, list] of Object.entries(provider.reservedNames ?? {})) {
|
|
2993
|
+
const normalised = new Set(list.map((raw) => normalizeTrigger(raw)).filter(Boolean));
|
|
2994
|
+
if (normalised.size > 0) {
|
|
2995
|
+
out.set(`${provider.id}/${kindName}`, normalised);
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
function buildReservedNodePaths(nodes, kindRegistry, reservedNamesByProviderKind) {
|
|
3000
|
+
const out = /* @__PURE__ */ new Set();
|
|
3001
|
+
for (const node of nodes) {
|
|
3002
|
+
const key = `${node.provider}/${node.kind}`;
|
|
3003
|
+
const reservedSet = reservedNamesByProviderKind.get(key);
|
|
3004
|
+
if (!reservedSet || reservedSet.size === 0) continue;
|
|
3005
|
+
const ids = deriveNodeIdentifiers(node, kindRegistry.get(key));
|
|
3006
|
+
if (ids.some((id) => reservedSet.has(id))) {
|
|
3007
|
+
out.add(node.path);
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
return out;
|
|
2956
3011
|
}
|
|
2957
3012
|
function buildScanSetup(options) {
|
|
2958
3013
|
const start = Date.now();
|
|
@@ -3045,7 +3100,7 @@ function validateRoots(roots) {
|
|
|
3045
3100
|
function resolveActiveProviderOption(optionValue, roots) {
|
|
3046
3101
|
if (optionValue !== void 0) return optionValue;
|
|
3047
3102
|
for (const root of roots) {
|
|
3048
|
-
const absRoot = isAbsolute4(root) ? root :
|
|
3103
|
+
const absRoot = isAbsolute4(root) ? root : resolve11(root);
|
|
3049
3104
|
if (!existsSync11(absRoot)) continue;
|
|
3050
3105
|
const detected = resolveActiveProvider(absRoot).resolved;
|
|
3051
3106
|
if (detected !== null) return detected;
|
|
@@ -3054,10 +3109,10 @@ function resolveActiveProviderOption(optionValue, roots) {
|
|
|
3054
3109
|
}
|
|
3055
3110
|
|
|
3056
3111
|
// kernel/scan/watcher.ts
|
|
3057
|
-
import { resolve as
|
|
3112
|
+
import { resolve as resolve12, relative as relative4, sep as sep3 } from "path";
|
|
3058
3113
|
import chokidar from "chokidar";
|
|
3059
3114
|
function createChokidarWatcher(opts) {
|
|
3060
|
-
const absRoots = opts.roots.map((r) =>
|
|
3115
|
+
const absRoots = opts.roots.map((r) => resolve12(opts.cwd, r));
|
|
3061
3116
|
const ignoreFilterOpt = opts.ignoreFilter;
|
|
3062
3117
|
const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
|
|
3063
3118
|
const ignored = getFilter ? (path) => {
|