@skill-map/cli 0.29.0 → 0.30.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 +150 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.js +1 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/{chunk-EFKSD7PT.js → chunk-HOJFYUH4.js} +1 -1
- package/dist/ui/{chunk-DMSZOXER.js → chunk-LNRQ7VKE.js} +1 -1
- package/dist/ui/chunk-YQIWQVJ6.js +317 -0
- package/dist/ui/favicon-matrix.svg +15 -0
- package/dist/ui/index.html +12 -2
- package/dist/ui/main-X5YGJFU6.js +2 -0
- package/dist/ui/{styles-CDN434T2.css → styles-2WO3KNOY.css} +1 -1
- package/package.json +2 -2
- package/dist/ui/chunk-BL7KARTN.js +0 -317
- package/dist/ui/main-LGW7AYEA.js +0 -2
package/dist/cli.js
CHANGED
|
@@ -775,6 +775,53 @@ function link(source, target) {
|
|
|
775
775
|
};
|
|
776
776
|
}
|
|
777
777
|
|
|
778
|
+
// kernel/util/strip-code-blocks.ts
|
|
779
|
+
var FENCE_RE = /^(?<indent> {0,3})(?<fence>`{3,}|~{3,})/;
|
|
780
|
+
function stripCodeBlocks(input) {
|
|
781
|
+
if (!input) return input;
|
|
782
|
+
const fenceless = stripFences(input);
|
|
783
|
+
return stripInline(fenceless);
|
|
784
|
+
}
|
|
785
|
+
function stripFences(input) {
|
|
786
|
+
const out = [];
|
|
787
|
+
const lines = input.split("\n");
|
|
788
|
+
let openFence = null;
|
|
789
|
+
for (const line of lines) {
|
|
790
|
+
if (openFence) {
|
|
791
|
+
const closer = matchClosingFence(line, openFence);
|
|
792
|
+
if (closer) {
|
|
793
|
+
out.push(blank(line));
|
|
794
|
+
openFence = null;
|
|
795
|
+
} else {
|
|
796
|
+
out.push(blank(line));
|
|
797
|
+
}
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
const open = FENCE_RE.exec(line);
|
|
801
|
+
if (open?.groups) {
|
|
802
|
+
openFence = open.groups["fence"];
|
|
803
|
+
out.push(blank(line));
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
out.push(line);
|
|
807
|
+
}
|
|
808
|
+
return out.join("\n");
|
|
809
|
+
}
|
|
810
|
+
function matchClosingFence(line, openFence) {
|
|
811
|
+
const m = FENCE_RE.exec(line);
|
|
812
|
+
if (!m?.groups) return false;
|
|
813
|
+
const fence = m.groups["fence"];
|
|
814
|
+
return fence[0] === openFence[0] && fence.length >= openFence.length;
|
|
815
|
+
}
|
|
816
|
+
function stripInline(input) {
|
|
817
|
+
return input.replace(/(`+)([\s\S]*?)\1/g, (_full, ticks, body) => {
|
|
818
|
+
return ticks.replace(/`/g, " ") + blank(body) + ticks.replace(/`/g, " ");
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
function blank(s) {
|
|
822
|
+
return s.replace(/[^\s]/g, " ");
|
|
823
|
+
}
|
|
824
|
+
|
|
778
825
|
// kernel/trigger-normalize.ts
|
|
779
826
|
function normalizeTrigger(source) {
|
|
780
827
|
let out = source.normalize("NFD");
|
|
@@ -787,21 +834,43 @@ function normalizeTrigger(source) {
|
|
|
787
834
|
|
|
788
835
|
// plugins/core/extractors/at-directive/index.ts
|
|
789
836
|
var ID2 = "at-directive";
|
|
790
|
-
var AT_RE = /(?:^|[^A-Za-z0-9_@])(@[a-z0-9][a-z0-9_
|
|
837
|
+
var AT_RE = /(?:^|[^A-Za-z0-9_@])(@(?:\.{1,2}\/|\/)?[a-z0-9](?:[a-z0-9_\-./]*[a-z0-9_])?(?::[a-z0-9][a-z0-9_-]*)?)/gi;
|
|
838
|
+
var FILE_EXT_RE = /\.(md|mdx|js|jsx|ts|tsx|json|yml|yaml|toml|txt|html|css|scss|less|py|rb|go|rs|java|c|cpp|h|hpp|sh|sql|svg|png|jpg|jpeg|gif|webp|pdf)$/i;
|
|
791
839
|
var atDirectiveExtractor = {
|
|
792
840
|
id: ID2,
|
|
793
841
|
pluginId: "core",
|
|
794
842
|
kind: "extractor",
|
|
795
843
|
version: "1.0.0",
|
|
796
|
-
description: "Detects
|
|
844
|
+
description: "Detects `@<token>` directives in a node's body. A bare handle (e.g. `@team`) becomes a `mentions` link; a file-flavoured token (e.g. `@docs/api.md`, `@./readme.md`) becomes a `references` link, matching how Claude Code / Gemini CLI / Cursor read the same syntax.",
|
|
797
845
|
scope: "body",
|
|
798
846
|
extract(ctx) {
|
|
799
|
-
const
|
|
800
|
-
|
|
847
|
+
const seenMentions = /* @__PURE__ */ new Set();
|
|
848
|
+
const seenReferences = /* @__PURE__ */ new Set();
|
|
849
|
+
const body = stripCodeBlocks(ctx.body);
|
|
850
|
+
for (const match of body.matchAll(AT_RE)) {
|
|
801
851
|
const original = match[1];
|
|
852
|
+
const bare = original.slice(1);
|
|
853
|
+
const isReference = bare.startsWith("./") || bare.startsWith("../") || bare.startsWith("/") || FILE_EXT_RE.test(bare);
|
|
854
|
+
if (isReference) {
|
|
855
|
+
const target = bare.replace(/^\.\//, "");
|
|
856
|
+
if (seenReferences.has(target)) continue;
|
|
857
|
+
seenReferences.add(target);
|
|
858
|
+
ctx.emitLink({
|
|
859
|
+
source: ctx.node.path,
|
|
860
|
+
target,
|
|
861
|
+
kind: "references",
|
|
862
|
+
confidence: "medium",
|
|
863
|
+
sources: [ID2],
|
|
864
|
+
trigger: {
|
|
865
|
+
originalTrigger: original,
|
|
866
|
+
normalizedTrigger: target.toLowerCase()
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
802
871
|
const normalized = normalizeTrigger(original);
|
|
803
|
-
if (
|
|
804
|
-
|
|
872
|
+
if (seenMentions.has(normalized)) continue;
|
|
873
|
+
seenMentions.add(normalized);
|
|
805
874
|
ctx.emitLink({
|
|
806
875
|
source: ctx.node.path,
|
|
807
876
|
target: original,
|
|
@@ -993,8 +1062,12 @@ var slashExtractor = {
|
|
|
993
1062
|
scope: "body",
|
|
994
1063
|
extract(ctx) {
|
|
995
1064
|
const seen = /* @__PURE__ */ new Set();
|
|
996
|
-
|
|
1065
|
+
const body = stripCodeBlocks(ctx.body);
|
|
1066
|
+
for (const match of body.matchAll(SLASH_RE)) {
|
|
997
1067
|
const original = match[1];
|
|
1068
|
+
const endIdx = (match.index ?? 0) + match[0].length;
|
|
1069
|
+
const nextChar = body[endIdx];
|
|
1070
|
+
if (nextChar && /[A-Za-z0-9_/-]/.test(nextChar)) continue;
|
|
998
1071
|
const normalized = normalizeTrigger(original);
|
|
999
1072
|
if (seen.has(normalized)) continue;
|
|
1000
1073
|
seen.add(normalized);
|
|
@@ -1176,7 +1249,7 @@ function tooltipFor(status) {
|
|
|
1176
1249
|
}
|
|
1177
1250
|
|
|
1178
1251
|
// plugins/core/analyzers/broken-ref/index.ts
|
|
1179
|
-
import { resolve } from "path";
|
|
1252
|
+
import { posix as pathPosix2, resolve } from "path";
|
|
1180
1253
|
|
|
1181
1254
|
// plugins/core/analyzers/broken-ref/text.ts
|
|
1182
1255
|
var BROKEN_REF_TEXTS = {
|
|
@@ -1185,7 +1258,13 @@ var BROKEN_REF_TEXTS = {
|
|
|
1185
1258
|
// Tooltips for the per-node view-contribution badges. Singular vs
|
|
1186
1259
|
// plural keeps the count grammar correct without a sub-template.
|
|
1187
1260
|
alertTooltipSingle: "This node has a broken reference. Open the inspector for details.",
|
|
1188
|
-
alertTooltipMany: "This node has {{count}} broken references. Open the inspector for details."
|
|
1261
|
+
alertTooltipMany: "This node has {{count}} broken references. Open the inspector for details.",
|
|
1262
|
+
// Fix-summary copy when the broken trigger has a same-named file on
|
|
1263
|
+
// disk that does not advertise `name:` in its frontmatter. Two
|
|
1264
|
+
// variants for single vs multiple candidates; same template family
|
|
1265
|
+
// as the alert tooltips above.
|
|
1266
|
+
hintSummarySingle: "Add `name: {{name}}` to the frontmatter of {{candidate}} so this reference resolves.",
|
|
1267
|
+
hintSummaryMany: "Add `name: {{name}}` to the frontmatter of one of these files so this reference resolves: {{candidates}}."
|
|
1189
1268
|
};
|
|
1190
1269
|
|
|
1191
1270
|
// plugins/core/analyzers/broken-ref/index.ts
|
|
@@ -1225,13 +1304,15 @@ var brokenRefAnalyzer = {
|
|
|
1225
1304
|
evaluate(ctx) {
|
|
1226
1305
|
const byPath3 = new Set(ctx.nodes.map((n) => n.path));
|
|
1227
1306
|
const byNormalizedName = indexByNormalizedName(ctx.nodes);
|
|
1307
|
+
const byBasenameWithoutName = indexByBasenameWithoutName(ctx.nodes);
|
|
1228
1308
|
const refIndex = ctx.referenceablePaths && ctx.referenceablePaths.size > 0 && ctx.cwd ? { paths: ctx.referenceablePaths, cwd: ctx.cwd } : null;
|
|
1229
1309
|
const issues = [];
|
|
1230
1310
|
const perNode = /* @__PURE__ */ new Map();
|
|
1231
1311
|
for (const link2 of ctx.links) {
|
|
1232
1312
|
if (isResolved(link2, byPath3, byNormalizedName)) continue;
|
|
1233
1313
|
if (refIndex && resolvesViaReferencePaths(link2, refIndex)) continue;
|
|
1234
|
-
|
|
1314
|
+
const candidates = findHintCandidates(link2, byBasenameWithoutName);
|
|
1315
|
+
issues.push(buildIssue(link2, candidates));
|
|
1235
1316
|
perNode.set(link2.source, (perNode.get(link2.source) ?? 0) + 1);
|
|
1236
1317
|
}
|
|
1237
1318
|
for (const [nodePath, count] of perNode) {
|
|
@@ -1251,8 +1332,13 @@ var brokenRefAnalyzer = {
|
|
|
1251
1332
|
return issues;
|
|
1252
1333
|
}
|
|
1253
1334
|
};
|
|
1254
|
-
function buildIssue(link2) {
|
|
1255
|
-
|
|
1335
|
+
function buildIssue(link2, hintCandidates = []) {
|
|
1336
|
+
const data = {
|
|
1337
|
+
target: link2.target,
|
|
1338
|
+
kind: link2.kind,
|
|
1339
|
+
trigger: link2.trigger?.normalizedTrigger ?? null
|
|
1340
|
+
};
|
|
1341
|
+
const issue = {
|
|
1256
1342
|
analyzerId: ID9,
|
|
1257
1343
|
severity: "warn",
|
|
1258
1344
|
nodeIds: [link2.source],
|
|
@@ -1261,12 +1347,28 @@ function buildIssue(link2) {
|
|
|
1261
1347
|
source: link2.source,
|
|
1262
1348
|
target: link2.target
|
|
1263
1349
|
}),
|
|
1264
|
-
data
|
|
1265
|
-
target: link2.target,
|
|
1266
|
-
kind: link2.kind,
|
|
1267
|
-
trigger: link2.trigger?.normalizedTrigger ?? null
|
|
1268
|
-
}
|
|
1350
|
+
data
|
|
1269
1351
|
};
|
|
1352
|
+
if (hintCandidates.length > 0) {
|
|
1353
|
+
const suggestedName = (link2.trigger?.normalizedTrigger ?? "").replace(/^[/@]/, "").trim();
|
|
1354
|
+
const candidatePaths = hintCandidates.map((n) => n.path);
|
|
1355
|
+
data["hint"] = {
|
|
1356
|
+
kind: "missing-frontmatter-name",
|
|
1357
|
+
suggestedName,
|
|
1358
|
+
candidates: candidatePaths
|
|
1359
|
+
};
|
|
1360
|
+
issue.fix = {
|
|
1361
|
+
summary: candidatePaths.length === 1 ? tx(BROKEN_REF_TEXTS.hintSummarySingle, {
|
|
1362
|
+
name: suggestedName,
|
|
1363
|
+
candidate: candidatePaths[0]
|
|
1364
|
+
}) : tx(BROKEN_REF_TEXTS.hintSummaryMany, {
|
|
1365
|
+
name: suggestedName,
|
|
1366
|
+
candidates: candidatePaths.join(", ")
|
|
1367
|
+
}),
|
|
1368
|
+
autofixable: false
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1371
|
+
return issue;
|
|
1270
1372
|
}
|
|
1271
1373
|
function resolvesViaReferencePaths(link2, refIndex) {
|
|
1272
1374
|
if (!isPathStyleLink(link2)) return false;
|
|
@@ -1285,6 +1387,36 @@ function indexByNormalizedName(nodes) {
|
|
|
1285
1387
|
}
|
|
1286
1388
|
return out;
|
|
1287
1389
|
}
|
|
1390
|
+
function basenameWithoutExt(path) {
|
|
1391
|
+
const base = pathPosix2.basename(path);
|
|
1392
|
+
const ext = pathPosix2.extname(base);
|
|
1393
|
+
return ext ? base.slice(0, -ext.length) : base;
|
|
1394
|
+
}
|
|
1395
|
+
function indexByBasenameWithoutName(nodes) {
|
|
1396
|
+
const out = /* @__PURE__ */ new Map();
|
|
1397
|
+
for (const node of nodes) {
|
|
1398
|
+
const raw = node.frontmatter?.["name"];
|
|
1399
|
+
const name = typeof raw === "string" ? raw : "";
|
|
1400
|
+
if (name) continue;
|
|
1401
|
+
const bare = basenameWithoutExt(node.path);
|
|
1402
|
+
if (!bare) continue;
|
|
1403
|
+
const key = normalizeTrigger(bare);
|
|
1404
|
+
if (!key) continue;
|
|
1405
|
+
const bucket = out.get(key) ?? [];
|
|
1406
|
+
bucket.push(node);
|
|
1407
|
+
out.set(key, bucket);
|
|
1408
|
+
}
|
|
1409
|
+
return out;
|
|
1410
|
+
}
|
|
1411
|
+
function findHintCandidates(link2, idx) {
|
|
1412
|
+
const normalized = link2.trigger?.normalizedTrigger;
|
|
1413
|
+
if (!normalized) return [];
|
|
1414
|
+
const sigil = normalized.charAt(0);
|
|
1415
|
+
if (sigil !== "/" && sigil !== "@") return [];
|
|
1416
|
+
const withoutSigil = normalized.slice(1).trim();
|
|
1417
|
+
if (!withoutSigil) return [];
|
|
1418
|
+
return idx.get(withoutSigil) ?? [];
|
|
1419
|
+
}
|
|
1288
1420
|
function isResolved(link2, byPath3, byNormalizedName) {
|
|
1289
1421
|
const normalized = link2.trigger?.normalizedTrigger;
|
|
1290
1422
|
if (normalized) {
|
|
@@ -2831,7 +2963,7 @@ var UPDATE_CHECK_TEXTS = {
|
|
|
2831
2963
|
// package.json
|
|
2832
2964
|
var package_default = {
|
|
2833
2965
|
name: "@skill-map/cli",
|
|
2834
|
-
version: "0.
|
|
2966
|
+
version: "0.30.0",
|
|
2835
2967
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
2836
2968
|
license: "MIT",
|
|
2837
2969
|
type: "module",
|