@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/cli/tutorial/sm-tutorial/references/_core.md +27 -20
- package/dist/cli/tutorial/sm-tutorial/references/_manifest.yml +2 -2
- package/dist/cli/tutorial/sm-tutorial/references/part-authoring.md +0 -7
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-daily.md +0 -21
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-fundamentals.md +4 -11
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-kickoff.md +12 -31
- package/dist/cli/tutorial/sm-tutorial/references/part-cli.md +0 -4
- package/dist/cli/tutorial/sm-tutorial/references/part-daily-loop.md +0 -17
- package/dist/cli/tutorial/sm-tutorial/references/part-fundamentals.md +0 -4
- package/dist/cli/tutorial/sm-tutorial/references/part-mcp.md +4 -14
- package/dist/cli/tutorial/sm-tutorial/references/part-plugins.md +0 -8
- package/dist/cli/tutorial/sm-tutorial/references/part-project-kickoff.md +5 -25
- package/dist/cli/tutorial/sm-tutorial/references/part-settings.md +2 -10
- package/dist/cli.js +274 -241
- package/dist/index.js +109 -14
- package/dist/kernel/index.js +109 -14
- package/dist/ui/chunk-CK4C2IIP.js +3 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui/{main-K4O6LCIJ.js → main-GY4PAVQW.js} +1 -1
- package/package.json +2 -2
- package/dist/ui/chunk-RJUHQQOF.js +0 -3
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]="
|
|
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]="81f53ca6-a8bf-5fc1-909d-ce926a83f056")}catch(e){}}();
|
|
4
4
|
import { existsSync as existsSync34 } 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.
|
|
253
|
+
version: "0.71.0",
|
|
254
254
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
255
255
|
license: "MIT",
|
|
256
256
|
type: "module",
|
|
@@ -581,7 +581,7 @@ var command_schema_default = {
|
|
|
581
581
|
// plugins/ids.ts
|
|
582
582
|
var CORE_PLUGIN_ID = "core";
|
|
583
583
|
var CLAUDE_PLUGIN_ID = "claude";
|
|
584
|
-
var
|
|
584
|
+
var CODEX_PLUGIN_ID = "codex";
|
|
585
585
|
var ANTIGRAVITY_PLUGIN_ID = "antigravity";
|
|
586
586
|
var AGENT_SKILLS_PLUGIN_ID = "agent-skills";
|
|
587
587
|
|
|
@@ -808,9 +808,6 @@ var claudeProvider = {
|
|
|
808
808
|
}
|
|
809
809
|
};
|
|
810
810
|
|
|
811
|
-
// plugins/claude/extractors/at-directive/index.ts
|
|
812
|
-
import { posix as pathPosix } from "path";
|
|
813
|
-
|
|
814
811
|
// kernel/util/strip-code-blocks.ts
|
|
815
812
|
var FENCE_RE = /^(?<indent> {0,3})(?<fence>`{3,}|~{3,})/;
|
|
816
813
|
function stripCodeBlocks(input) {
|
|
@@ -818,6 +815,28 @@ function stripCodeBlocks(input) {
|
|
|
818
815
|
const fenceless = stripFences(input);
|
|
819
816
|
return stripInline(fenceless);
|
|
820
817
|
}
|
|
818
|
+
function findBacktickImbalance(body) {
|
|
819
|
+
if (!body) return null;
|
|
820
|
+
const { stripped, openFenceLine } = scanFences(body);
|
|
821
|
+
if (openFenceLine > 0) {
|
|
822
|
+
return { kind: "fence", line: openFenceLine, sourceLine: sourceLineAt(body, openFenceLine) };
|
|
823
|
+
}
|
|
824
|
+
const survivor = stripInline(maskEscapes(stripped)).indexOf("`");
|
|
825
|
+
if (survivor < 0) return null;
|
|
826
|
+
const line = lineOfIndex(stripped, survivor);
|
|
827
|
+
return { kind: "inline", line, sourceLine: sourceLineAt(body, line) };
|
|
828
|
+
}
|
|
829
|
+
function maskEscapes(text) {
|
|
830
|
+
return text.replace(/\\[^\n]/g, " ");
|
|
831
|
+
}
|
|
832
|
+
function lineOfIndex(text, idx) {
|
|
833
|
+
let line = 1;
|
|
834
|
+
for (let i = 0; i < idx; i++) if (text[i] === "\n") line++;
|
|
835
|
+
return line;
|
|
836
|
+
}
|
|
837
|
+
function sourceLineAt(text, line) {
|
|
838
|
+
return text.split("\n")[line - 1]?.trim() ?? "";
|
|
839
|
+
}
|
|
821
840
|
function extractCodeRegions(input) {
|
|
822
841
|
if (!input) return input;
|
|
823
842
|
const stripped = stripCodeBlocks(input);
|
|
@@ -837,30 +856,31 @@ function stripHtml(input) {
|
|
|
837
856
|
function stripCodeAndHtml(input) {
|
|
838
857
|
return stripHtml(stripCodeBlocks(input));
|
|
839
858
|
}
|
|
840
|
-
function
|
|
859
|
+
function scanFences(input) {
|
|
841
860
|
const out = [];
|
|
842
861
|
const lines = input.split("\n");
|
|
843
862
|
let openFence = null;
|
|
844
|
-
|
|
863
|
+
let openFenceLine = 0;
|
|
864
|
+
for (let i = 0; i < lines.length; i++) {
|
|
865
|
+
const line = lines[i];
|
|
845
866
|
if (openFence) {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
out.push(blank(line));
|
|
849
|
-
openFence = null;
|
|
850
|
-
} else {
|
|
851
|
-
out.push(blank(line));
|
|
852
|
-
}
|
|
867
|
+
if (matchClosingFence(line, openFence)) openFence = null;
|
|
868
|
+
out.push(blank(line));
|
|
853
869
|
continue;
|
|
854
870
|
}
|
|
855
871
|
const open3 = FENCE_RE.exec(line);
|
|
856
872
|
if (open3?.groups) {
|
|
857
873
|
openFence = open3.groups["fence"];
|
|
874
|
+
openFenceLine = i + 1;
|
|
858
875
|
out.push(blank(line));
|
|
859
876
|
continue;
|
|
860
877
|
}
|
|
861
878
|
out.push(line);
|
|
862
879
|
}
|
|
863
|
-
return out.join("\n");
|
|
880
|
+
return { stripped: out.join("\n"), openFenceLine: openFence ? openFenceLine : 0 };
|
|
881
|
+
}
|
|
882
|
+
function stripFences(input) {
|
|
883
|
+
return scanFences(input).stripped;
|
|
864
884
|
}
|
|
865
885
|
function matchClosingFence(line, openFence) {
|
|
866
886
|
const m = FENCE_RE.exec(line);
|
|
@@ -906,82 +926,61 @@ function normalizeTrigger(source) {
|
|
|
906
926
|
return out.trim();
|
|
907
927
|
}
|
|
908
928
|
|
|
929
|
+
// kernel/util/at-token.ts
|
|
930
|
+
import { posix as pathPosix } from "path";
|
|
931
|
+
var AT_TOKEN_RE = /(?:^|[^A-Za-z0-9_@])(@(?:(?:\.{1,2}\/)+|\/)?[a-z0-9](?:[a-z0-9_\-./]*[a-z0-9_])?(?::[a-z0-9][a-z0-9_-]*)?)/gi;
|
|
932
|
+
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;
|
|
933
|
+
function classifyAtFileToken(bare) {
|
|
934
|
+
if (bare.startsWith("/")) return null;
|
|
935
|
+
if (bare.startsWith("./") || bare.startsWith("../")) return "relative path prefix";
|
|
936
|
+
if (FILE_EXT_RE.test(bare)) return "known file extension";
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
function resolveAtFileTarget(sourceDir, bare) {
|
|
940
|
+
const joined = sourceDir === "." ? bare : `${sourceDir}/${bare}`;
|
|
941
|
+
return pathPosix.normalize(joined);
|
|
942
|
+
}
|
|
943
|
+
|
|
909
944
|
// plugins/claude/extractors/at-directive/index.ts
|
|
910
945
|
var ID = "at-directive";
|
|
911
|
-
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;
|
|
912
|
-
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;
|
|
913
946
|
var atDirectiveExtractor = {
|
|
914
947
|
id: ID,
|
|
915
948
|
pluginId: CLAUDE_PLUGIN_ID,
|
|
916
949
|
kind: "extractor",
|
|
917
|
-
description: "Detects `@<
|
|
950
|
+
description: "Detects bare `@<handle>` mentions in a node's body using Claude Code rules and emits a `mentions` link to the named entity. Example: `@team` becomes a `mentions` link. File-shaped tokens like `@docs/api.md` are handled by `core/at-file` instead.",
|
|
918
951
|
scope: "body",
|
|
919
|
-
// Claude-only. This is Claude's `@<
|
|
920
|
-
//
|
|
921
|
-
//
|
|
922
|
-
// extractor
|
|
952
|
+
// Claude-only. This is Claude's bare `@<handle>` MENTION grammar. The
|
|
953
|
+
// file-reference half of `@` (file-shaped tokens) is the shared
|
|
954
|
+
// `core/at-file` extractor, which also serves codex / antigravity; this
|
|
955
|
+
// extractor defers file-shaped tokens to it.
|
|
923
956
|
precondition: { provider: ["claude"] },
|
|
924
|
-
// eslint-disable-next-line complexity
|
|
925
957
|
extract(ctx) {
|
|
926
958
|
const seenMentions = /* @__PURE__ */ new Set();
|
|
927
|
-
const seenReferences = /* @__PURE__ */ new Set();
|
|
928
959
|
const body = stripCodeAndHtml(ctx.body);
|
|
929
960
|
const lineStarts = computeLineStarts(body);
|
|
930
|
-
const
|
|
931
|
-
for (const match of body.matchAll(AT_RE)) {
|
|
961
|
+
for (const match of body.matchAll(AT_TOKEN_RE)) {
|
|
932
962
|
const original = match[1];
|
|
933
963
|
const bare = original.slice(1);
|
|
934
|
-
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
935
|
-
const line = lineFor(lineStarts, captureOffset);
|
|
936
|
-
const range = { start: captureOffset, end: captureOffset + original.length, line };
|
|
937
964
|
if (bare.startsWith("/")) continue;
|
|
938
|
-
|
|
939
|
-
if (isReference) {
|
|
940
|
-
const target = resolveSourceRelative(sourceDir, bare);
|
|
941
|
-
const dedupKey = target.toLowerCase();
|
|
942
|
-
if (seenReferences.has(dedupKey)) continue;
|
|
943
|
-
seenReferences.add(dedupKey);
|
|
944
|
-
ctx.emitSignal({
|
|
945
|
-
source: ctx.node.path,
|
|
946
|
-
scope: "body",
|
|
947
|
-
range,
|
|
948
|
-
raw: original,
|
|
949
|
-
candidates: [
|
|
950
|
-
{
|
|
951
|
-
extractorId: ID,
|
|
952
|
-
kind: "references",
|
|
953
|
-
target,
|
|
954
|
-
// 0.85: strong file signal (path prefix `./` / `../` OR
|
|
955
|
-
// a known file extension on the tail). One degree of
|
|
956
|
-
// inference (the runtime still resolves the path).
|
|
957
|
-
confidence: 0.85,
|
|
958
|
-
rationale: bare.startsWith("./") || bare.startsWith("../") ? "relative path prefix" : "known file extension",
|
|
959
|
-
trigger: {
|
|
960
|
-
originalTrigger: original,
|
|
961
|
-
normalizedTrigger: target
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
]
|
|
965
|
-
});
|
|
966
|
-
continue;
|
|
967
|
-
}
|
|
965
|
+
if (classifyAtFileToken(bare) !== null) continue;
|
|
968
966
|
const normalized = normalizeTrigger(original);
|
|
969
967
|
if (seenMentions.has(normalized)) continue;
|
|
970
968
|
seenMentions.add(normalized);
|
|
969
|
+
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
970
|
+
const line = lineFor(lineStarts, captureOffset);
|
|
971
971
|
ctx.emitSignal({
|
|
972
972
|
source: ctx.node.path,
|
|
973
973
|
scope: "body",
|
|
974
|
-
range,
|
|
974
|
+
range: { start: captureOffset, end: captureOffset + original.length, line },
|
|
975
975
|
raw: original,
|
|
976
976
|
candidates: [
|
|
977
977
|
{
|
|
978
978
|
extractorId: ID,
|
|
979
979
|
kind: "mentions",
|
|
980
980
|
target: original,
|
|
981
|
-
// 0.5: genuine ambiguity. A bare `@handle` (no extension, no
|
|
982
|
-
//
|
|
983
|
-
//
|
|
984
|
-
// the question open.
|
|
981
|
+
// 0.5: genuine ambiguity. A bare `@handle` (no extension, no path
|
|
982
|
+
// prefix) could be an agent, a handle, or generic prose. The
|
|
983
|
+
// runtime decides at invocation time; the extractor leaves it open.
|
|
985
984
|
confidence: 0.5,
|
|
986
985
|
rationale: "no extension, no path prefix",
|
|
987
986
|
trigger: {
|
|
@@ -994,72 +993,9 @@ var atDirectiveExtractor = {
|
|
|
994
993
|
}
|
|
995
994
|
}
|
|
996
995
|
};
|
|
997
|
-
function resolveSourceRelative(sourceDir, bare) {
|
|
998
|
-
const joined = sourceDir === "." ? bare : `${sourceDir}/${bare}`;
|
|
999
|
-
return pathPosix.normalize(joined);
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
// plugins/claude/extractors/slash-command/index.ts
|
|
1003
|
-
var ID2 = "slash-command";
|
|
1004
|
-
var SLASH_RE = /(?<![A-Za-z0-9_/.:?#=&])(\/[a-z0-9][a-z0-9_-]*(?::[a-z0-9][a-z0-9_-]*)?)/gi;
|
|
1005
|
-
var slashCommandExtractor = {
|
|
1006
|
-
id: ID2,
|
|
1007
|
-
pluginId: CLAUDE_PLUGIN_ID,
|
|
1008
|
-
kind: "extractor",
|
|
1009
|
-
description: "Turns `/command` invocations in a node's body into arrows that point at the resolved slash command or skill, using Claude Code routing rules. Example: `/deploy` in the body draws an arrow to the `deploy` command.",
|
|
1010
|
-
scope: "body",
|
|
1011
|
-
// Also authorised under the antigravity lens, which shares the `/command`
|
|
1012
|
-
// grammar: a workflow / skill / AGENTS.md body's `/name` tokens resolve to
|
|
1013
|
-
// BOTH skills and workflows (`invokes: ['skill', 'workflow']`), since
|
|
1014
|
-
// Antigravity invokes either by the same slash. NOT gated under codex:
|
|
1015
|
-
// OpenAI Codex reserves `/` for its OWN built-in commands (`/model`,
|
|
1016
|
-
// `/init`, ...) and invokes user skills with `$` instead (parsed by the
|
|
1017
|
-
// codex `dollar-skill` extractor). A lens that declares no `invokes`
|
|
1018
|
-
// resolution leaves the signals unresolved (no spurious edges).
|
|
1019
|
-
precondition: { provider: ["claude", "antigravity"] },
|
|
1020
|
-
extract(ctx) {
|
|
1021
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1022
|
-
const body = stripCodeAndHtml(ctx.body);
|
|
1023
|
-
const lineStarts = computeLineStarts(body);
|
|
1024
|
-
for (const match of body.matchAll(SLASH_RE)) {
|
|
1025
|
-
const original = match[1];
|
|
1026
|
-
const endIdx = (match.index ?? 0) + match[0].length;
|
|
1027
|
-
const nextChar = body[endIdx];
|
|
1028
|
-
if (nextChar && /[A-Za-z0-9_/-]/.test(nextChar)) continue;
|
|
1029
|
-
const normalized = normalizeTrigger(original);
|
|
1030
|
-
if (seen.has(normalized)) continue;
|
|
1031
|
-
seen.add(normalized);
|
|
1032
|
-
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
1033
|
-
const line = lineFor(lineStarts, captureOffset);
|
|
1034
|
-
ctx.emitSignal({
|
|
1035
|
-
source: ctx.node.path,
|
|
1036
|
-
scope: "body",
|
|
1037
|
-
range: { start: captureOffset, end: captureOffset + original.length, line },
|
|
1038
|
-
raw: original,
|
|
1039
|
-
candidates: [
|
|
1040
|
-
{
|
|
1041
|
-
extractorId: ID2,
|
|
1042
|
-
kind: "invokes",
|
|
1043
|
-
target: original,
|
|
1044
|
-
// 0.8: clean `/command` match after code-block strip. The
|
|
1045
|
-
// post-match path guard above filters URL / file-path noise,
|
|
1046
|
-
// so a hit is unambiguous syntax. Resolution against the
|
|
1047
|
-
// live skill / command catalog happens downstream.
|
|
1048
|
-
confidence: 0.8,
|
|
1049
|
-
rationale: "unambiguous slash syntax post code-block strip",
|
|
1050
|
-
trigger: {
|
|
1051
|
-
originalTrigger: original,
|
|
1052
|
-
normalizedTrigger: normalized
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
]
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
};
|
|
1060
996
|
|
|
1061
997
|
// plugins/claude/extractors/tools-counter/index.ts
|
|
1062
|
-
var
|
|
998
|
+
var ID2 = "tools-counter";
|
|
1063
999
|
var count = {
|
|
1064
1000
|
slot: "card.footer.left",
|
|
1065
1001
|
icon: "pi-wrench",
|
|
@@ -1069,7 +1005,7 @@ var count = {
|
|
|
1069
1005
|
};
|
|
1070
1006
|
var TOOLTIP_MAX = 255;
|
|
1071
1007
|
var toolsCounterExtractor = {
|
|
1072
|
-
id:
|
|
1008
|
+
id: ID2,
|
|
1073
1009
|
pluginId: CLAUDE_PLUGIN_ID,
|
|
1074
1010
|
kind: "extractor",
|
|
1075
1011
|
description: "Counts the tools an agent declares in its frontmatter and shows the count on the agent card. Example: an agent with `tools: [Bash, Read, Grep]` shows a count of 3.",
|
|
@@ -1355,10 +1291,15 @@ var antigravityProvider = {
|
|
|
1355
1291
|
schemaJson: workflow_schema_default,
|
|
1356
1292
|
ui: {
|
|
1357
1293
|
label: "Workflows",
|
|
1358
|
-
//
|
|
1359
|
-
//
|
|
1360
|
-
color
|
|
1361
|
-
|
|
1294
|
+
// A workflow is Antigravity's command-equivalent (its own slash-
|
|
1295
|
+
// invocable procedural kind, the slot Claude fills with `command`),
|
|
1296
|
+
// so it adopts the SAME color as Claude's `command` kind (amber) for a
|
|
1297
|
+
// uniform cross-provider vocabulary, the same way skills normalise to
|
|
1298
|
+
// the cross-provider green of COMMONS_KINDS. The Antigravity violet
|
|
1299
|
+
// stays on the provider-level `presentation` (the lens identity), not
|
|
1300
|
+
// on this kind.
|
|
1301
|
+
color: "#f59e0b",
|
|
1302
|
+
colorDark: "#fbbf24",
|
|
1362
1303
|
icon: { kind: "pi", id: "pi-sitemap" }
|
|
1363
1304
|
},
|
|
1364
1305
|
// The handle is ALWAYS the filename stem (`/<name>`): Antigravity
|
|
@@ -1370,7 +1311,12 @@ var antigravityProvider = {
|
|
|
1370
1311
|
// `/<name>` slash invocations resolve to BOTH skills and workflows: under
|
|
1371
1312
|
// the antigravity lens a `/deploy` links to either `.agents/skills/deploy`
|
|
1372
1313
|
// or `.agent/workflows/deploy.md`. Overrides the open-standard default
|
|
1373
|
-
// (`invokes: ['skill']`) to add the own `workflow` kind.
|
|
1314
|
+
// (`invokes: ['skill']`) to add the own `workflow` kind. Antigravity's OTHER
|
|
1315
|
+
// connector, `@filename` file references (the documented rules / skill /
|
|
1316
|
+
// workflow file pointer, a file-picker grammar like Codex's, distinct from
|
|
1317
|
+
// Claude's `@`-agent-mention), needs no entry here: the shared `core/at-file`
|
|
1318
|
+
// extractor (gated to claude / codex / antigravity) emits them as
|
|
1319
|
+
// `references` resolved by PATH, lens-independent.
|
|
1374
1320
|
resolution: { invokes: ["skill", "workflow"] },
|
|
1375
1321
|
classify(path) {
|
|
1376
1322
|
if (/^\.agent\/workflows\/[^/]+\.md$/.test(path.toLowerCase())) return "workflow";
|
|
@@ -1461,7 +1407,7 @@ var agent_schema_default2 = {
|
|
|
1461
1407
|
// plugins/codex/providers/codex/index.ts
|
|
1462
1408
|
var codexProvider = {
|
|
1463
1409
|
id: "codex",
|
|
1464
|
-
pluginId:
|
|
1410
|
+
pluginId: CODEX_PLUGIN_ID,
|
|
1465
1411
|
kind: "provider",
|
|
1466
1412
|
description: "Classifies `.codex/agents/*.toml` as OpenAI Codex CLI sub-agents and `.agents/skills/*/SKILL.md` as Codex skills (open standard).",
|
|
1467
1413
|
// Provider identity for the active-lens dropdown, the topbar lens chip,
|
|
@@ -1562,78 +1508,12 @@ var codexProvider = {
|
|
|
1562
1508
|
}
|
|
1563
1509
|
};
|
|
1564
1510
|
|
|
1565
|
-
// plugins/codex/extractors/at-file/index.ts
|
|
1566
|
-
import { posix as pathPosix2 } from "path";
|
|
1567
|
-
var ID4 = "at-file";
|
|
1568
|
-
var AT_RE2 = /(?:^|[^A-Za-z0-9_@])(@(?:\.{1,2}\/|\/)?[a-z0-9](?:[a-z0-9_\-./]*[a-z0-9_])?(?::[a-z0-9][a-z0-9_-]*)?)/gi;
|
|
1569
|
-
var FILE_EXT_RE2 = /\.(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;
|
|
1570
|
-
var atFileExtractor = {
|
|
1571
|
-
id: ID4,
|
|
1572
|
-
pluginId: OPENAI_PLUGIN_ID,
|
|
1573
|
-
kind: "extractor",
|
|
1574
|
-
description: "Detects `@<file>` references in a node's body under the OpenAI Codex lens, where `@` is a file picker. A path- or extension-shaped token becomes a `references` link to that file; a bare `@handle` forms no edge. Example: `@builder.toml` in an agent's prompt draws an arrow to the `builder` agent file.",
|
|
1575
|
-
scope: "body",
|
|
1576
|
-
// Codex-only: under the codex lens `@` is a file-path picker, so only
|
|
1577
|
-
// file-shaped tokens form references. The claude `at-directive` (bare
|
|
1578
|
-
// `@handle` → agent mention) is NOT gated under codex.
|
|
1579
|
-
precondition: { provider: ["codex"] },
|
|
1580
|
-
extract(ctx) {
|
|
1581
|
-
const seenReferences = /* @__PURE__ */ new Set();
|
|
1582
|
-
const body = stripCodeAndHtml(ctx.body);
|
|
1583
|
-
const lineStarts = computeLineStarts(body);
|
|
1584
|
-
const sourceDir = pathPosix2.dirname(ctx.node.path);
|
|
1585
|
-
for (const match of body.matchAll(AT_RE2)) {
|
|
1586
|
-
const original = match[1];
|
|
1587
|
-
const bare = original.slice(1);
|
|
1588
|
-
const rationale = classifyAtToken(bare);
|
|
1589
|
-
if (rationale === null) continue;
|
|
1590
|
-
const target = resolveSourceRelative2(sourceDir, bare);
|
|
1591
|
-
const dedupKey = target.toLowerCase();
|
|
1592
|
-
if (seenReferences.has(dedupKey)) continue;
|
|
1593
|
-
seenReferences.add(dedupKey);
|
|
1594
|
-
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
1595
|
-
const line = lineFor(lineStarts, captureOffset);
|
|
1596
|
-
ctx.emitSignal({
|
|
1597
|
-
source: ctx.node.path,
|
|
1598
|
-
scope: "body",
|
|
1599
|
-
range: { start: captureOffset, end: captureOffset + original.length, line },
|
|
1600
|
-
raw: original,
|
|
1601
|
-
candidates: [
|
|
1602
|
-
{
|
|
1603
|
-
extractorId: ID4,
|
|
1604
|
-
kind: "references",
|
|
1605
|
-
target,
|
|
1606
|
-
// 0.85: strong file signal (path prefix or known extension),
|
|
1607
|
-
// one degree of inference (the runtime resolves the path).
|
|
1608
|
-
confidence: 0.85,
|
|
1609
|
-
rationale,
|
|
1610
|
-
trigger: {
|
|
1611
|
-
originalTrigger: original,
|
|
1612
|
-
normalizedTrigger: target
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
]
|
|
1616
|
-
});
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
};
|
|
1620
|
-
function classifyAtToken(bare) {
|
|
1621
|
-
if (bare.startsWith("/")) return null;
|
|
1622
|
-
if (bare.startsWith("./") || bare.startsWith("../")) return "relative path prefix";
|
|
1623
|
-
if (FILE_EXT_RE2.test(bare)) return "known file extension";
|
|
1624
|
-
return null;
|
|
1625
|
-
}
|
|
1626
|
-
function resolveSourceRelative2(sourceDir, bare) {
|
|
1627
|
-
const joined = sourceDir === "." ? bare : `${sourceDir}/${bare}`;
|
|
1628
|
-
return pathPosix2.normalize(joined);
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
1511
|
// plugins/codex/extractors/dollar-skill/index.ts
|
|
1632
|
-
var
|
|
1512
|
+
var ID3 = "dollar-skill";
|
|
1633
1513
|
var DOLLAR_RE = /(?<![A-Za-z0-9_$])(\$[a-z][a-z0-9_-]*)/g;
|
|
1634
1514
|
var dollarSkillExtractor = {
|
|
1635
|
-
id:
|
|
1636
|
-
pluginId:
|
|
1515
|
+
id: ID3,
|
|
1516
|
+
pluginId: CODEX_PLUGIN_ID,
|
|
1637
1517
|
kind: "extractor",
|
|
1638
1518
|
description: "Turns `$skill` invocations in a node's body into arrows that point at the resolved Codex skill, using OpenAI Codex routing rules. Example: `$check-links` in the body draws an arrow to the `check-links` skill.",
|
|
1639
1519
|
scope: "body",
|
|
@@ -1659,7 +1539,7 @@ var dollarSkillExtractor = {
|
|
|
1659
1539
|
raw: original,
|
|
1660
1540
|
candidates: [
|
|
1661
1541
|
{
|
|
1662
|
-
extractorId:
|
|
1542
|
+
extractorId: ID3,
|
|
1663
1543
|
kind: "invokes",
|
|
1664
1544
|
target: original,
|
|
1665
1545
|
// 0.8: clean `$skill` match after code-block strip. The
|
|
@@ -1765,12 +1645,68 @@ var coreMarkdownProvider = {
|
|
|
1765
1645
|
}
|
|
1766
1646
|
};
|
|
1767
1647
|
|
|
1648
|
+
// plugins/core/extractors/at-file/index.ts
|
|
1649
|
+
import { posix as pathPosix2 } from "path";
|
|
1650
|
+
var ID4 = "at-file";
|
|
1651
|
+
var atFileExtractor = {
|
|
1652
|
+
id: ID4,
|
|
1653
|
+
pluginId: CORE_PLUGIN_ID,
|
|
1654
|
+
kind: "extractor",
|
|
1655
|
+
description: "Detects `@<file>` references in a node's body for the `@`-file-picker lenses (Codex, Antigravity, Claude), where `@` points at a workspace file. A path- or extension-shaped token becomes a `references` link to that file; a bare `@handle` forms no edge. Example: `@builder.toml` in a body draws an arrow to the `builder` file.",
|
|
1656
|
+
scope: "body",
|
|
1657
|
+
// The lenses whose runtime reads `@` as a file-path picker. Codex (`@` is a
|
|
1658
|
+
// file picker, `$` invokes skills), Antigravity (documented `@filename` file
|
|
1659
|
+
// refs), and Claude (`@file.md` file ref; its bare-handle MENTION half lives
|
|
1660
|
+
// in `claude/at-directive`). NOT gated under `agent-skills` / `markdown`,
|
|
1661
|
+
// whose runtimes read `@` as nothing (no phantom edges).
|
|
1662
|
+
precondition: { provider: ["claude", "codex", "antigravity"] },
|
|
1663
|
+
extract(ctx) {
|
|
1664
|
+
const seenReferences = /* @__PURE__ */ new Set();
|
|
1665
|
+
const body = stripCodeAndHtml(ctx.body);
|
|
1666
|
+
const lineStarts = computeLineStarts(body);
|
|
1667
|
+
const sourceDir = pathPosix2.dirname(ctx.node.path);
|
|
1668
|
+
for (const match of body.matchAll(AT_TOKEN_RE)) {
|
|
1669
|
+
const original = match[1];
|
|
1670
|
+
const bare = original.slice(1);
|
|
1671
|
+
const rationale = classifyAtFileToken(bare);
|
|
1672
|
+
if (rationale === null) continue;
|
|
1673
|
+
const target = resolveAtFileTarget(sourceDir, bare);
|
|
1674
|
+
const dedupKey = target.toLowerCase();
|
|
1675
|
+
if (seenReferences.has(dedupKey)) continue;
|
|
1676
|
+
seenReferences.add(dedupKey);
|
|
1677
|
+
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
1678
|
+
const line = lineFor(lineStarts, captureOffset);
|
|
1679
|
+
ctx.emitSignal({
|
|
1680
|
+
source: ctx.node.path,
|
|
1681
|
+
scope: "body",
|
|
1682
|
+
range: { start: captureOffset, end: captureOffset + original.length, line },
|
|
1683
|
+
raw: original,
|
|
1684
|
+
candidates: [
|
|
1685
|
+
{
|
|
1686
|
+
extractorId: ID4,
|
|
1687
|
+
kind: "references",
|
|
1688
|
+
target,
|
|
1689
|
+
// 0.85: strong file signal (path prefix or known extension),
|
|
1690
|
+
// one degree of inference (the runtime resolves the path).
|
|
1691
|
+
confidence: 0.85,
|
|
1692
|
+
rationale,
|
|
1693
|
+
trigger: {
|
|
1694
|
+
originalTrigger: original,
|
|
1695
|
+
normalizedTrigger: target
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
]
|
|
1699
|
+
});
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
|
|
1768
1704
|
// plugins/core/extractors/backtick-path/index.ts
|
|
1769
1705
|
import { posix as pathPosix3 } from "path";
|
|
1770
|
-
var
|
|
1706
|
+
var ID5 = "backtick-path";
|
|
1771
1707
|
var PATH_RE = /(?<![\w/:.-])(?:\.{1,2}\/)?[\w][\w.-]*(?:\/[\w.-]+)*\.md\b(?![\w/])/g;
|
|
1772
1708
|
var backtickPathExtractor = {
|
|
1773
|
-
id:
|
|
1709
|
+
id: ID5,
|
|
1774
1710
|
pluginId: CORE_PLUGIN_ID,
|
|
1775
1711
|
kind: "extractor",
|
|
1776
1712
|
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.",
|
|
@@ -1795,7 +1731,7 @@ var backtickPathExtractor = {
|
|
|
1795
1731
|
raw: original,
|
|
1796
1732
|
candidates: [
|
|
1797
1733
|
{
|
|
1798
|
-
extractorId:
|
|
1734
|
+
extractorId: ID5,
|
|
1799
1735
|
kind: "points",
|
|
1800
1736
|
target: resolved,
|
|
1801
1737
|
// 0.85: a strong file signal with one degree of inference,
|
|
@@ -1824,7 +1760,7 @@ function resolveTarget(sourceDir, raw) {
|
|
|
1824
1760
|
}
|
|
1825
1761
|
|
|
1826
1762
|
// plugins/core/extractors/external-url-counter/index.ts
|
|
1827
|
-
var
|
|
1763
|
+
var ID6 = "external-url-counter";
|
|
1828
1764
|
var count2 = {
|
|
1829
1765
|
slot: "card.footer.left",
|
|
1830
1766
|
icon: "pi-link",
|
|
@@ -1844,7 +1780,7 @@ var settings = {
|
|
|
1844
1780
|
var URL_RE = /https?:\/\/[^\s<>"'`)\]]+/g;
|
|
1845
1781
|
var TRAILING_PUNCT = /[.,;:!?]+$/;
|
|
1846
1782
|
var externalUrlCounterExtractor = {
|
|
1847
|
-
id:
|
|
1783
|
+
id: ID6,
|
|
1848
1784
|
pluginId: CORE_PLUGIN_ID,
|
|
1849
1785
|
kind: "extractor",
|
|
1850
1786
|
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.",
|
|
@@ -1896,7 +1832,7 @@ var externalUrlCounterExtractor = {
|
|
|
1896
1832
|
raw: original,
|
|
1897
1833
|
candidates: [
|
|
1898
1834
|
{
|
|
1899
|
-
extractorId:
|
|
1835
|
+
extractorId: ID6,
|
|
1900
1836
|
kind: "references",
|
|
1901
1837
|
target: normalized.href,
|
|
1902
1838
|
confidence: 0.3,
|
|
@@ -1938,11 +1874,11 @@ function normalizeUrl(raw) {
|
|
|
1938
1874
|
|
|
1939
1875
|
// plugins/core/extractors/markdown-link/index.ts
|
|
1940
1876
|
import { posix as pathPosix4 } from "path";
|
|
1941
|
-
var
|
|
1877
|
+
var ID7 = "markdown-link";
|
|
1942
1878
|
var LINK_RE = /(?<!!)\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
|
|
1943
1879
|
var URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
|
|
1944
1880
|
var markdownLinkExtractor = {
|
|
1945
|
-
id:
|
|
1881
|
+
id: ID7,
|
|
1946
1882
|
pluginId: CORE_PLUGIN_ID,
|
|
1947
1883
|
kind: "extractor",
|
|
1948
1884
|
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`.",
|
|
@@ -1967,7 +1903,7 @@ var markdownLinkExtractor = {
|
|
|
1967
1903
|
raw: match[0],
|
|
1968
1904
|
candidates: [
|
|
1969
1905
|
{
|
|
1970
|
-
extractorId:
|
|
1906
|
+
extractorId: ID7,
|
|
1971
1907
|
kind: "references",
|
|
1972
1908
|
target: resolved,
|
|
1973
1909
|
// 0.95: the `[text](path)` syntax is unambiguous (the spec's
|
|
@@ -2002,10 +1938,10 @@ function resolveTarget2(sourceDir, raw) {
|
|
|
2002
1938
|
}
|
|
2003
1939
|
|
|
2004
1940
|
// plugins/core/extractors/mcp-tools/index.ts
|
|
2005
|
-
var
|
|
1941
|
+
var ID8 = "mcp-tools";
|
|
2006
1942
|
var MCP_PATTERN = /^mcp__([a-z0-9][a-z0-9_-]*)__[a-z0-9_-]+$/i;
|
|
2007
1943
|
var mcpToolsExtractor = {
|
|
2008
|
-
id:
|
|
1944
|
+
id: ID8,
|
|
2009
1945
|
pluginId: CORE_PLUGIN_ID,
|
|
2010
1946
|
kind: "extractor",
|
|
2011
1947
|
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.",
|
|
@@ -2036,7 +1972,7 @@ var mcpToolsExtractor = {
|
|
|
2036
1972
|
raw: `mcp__${server}__*`,
|
|
2037
1973
|
candidates: [
|
|
2038
1974
|
{
|
|
2039
|
-
extractorId:
|
|
1975
|
+
extractorId: ID8,
|
|
2040
1976
|
kind: "references",
|
|
2041
1977
|
target: mcpPath,
|
|
2042
1978
|
confidence: 0.85,
|
|
@@ -2066,6 +2002,65 @@ function collectMcpServers(tools) {
|
|
|
2066
2002
|
return out;
|
|
2067
2003
|
}
|
|
2068
2004
|
|
|
2005
|
+
// plugins/core/extractors/slash-command/index.ts
|
|
2006
|
+
var ID9 = "slash-command";
|
|
2007
|
+
var SLASH_RE = /(?<![A-Za-z0-9_/.:?#=&])(\/[a-z0-9][a-z0-9_-]*(?::[a-z0-9][a-z0-9_-]*)?)/gi;
|
|
2008
|
+
var slashCommandExtractor = {
|
|
2009
|
+
id: ID9,
|
|
2010
|
+
pluginId: CORE_PLUGIN_ID,
|
|
2011
|
+
kind: "extractor",
|
|
2012
|
+
description: "Turns `/command` invocations in a node's body into arrows that point at the resolved slash command, skill, or workflow, using the `/`-grammar shared by Claude and Antigravity. Example: `/deploy` in the body draws an arrow to the `deploy` command.",
|
|
2013
|
+
scope: "body",
|
|
2014
|
+
// Also authorised under the antigravity lens, which shares the `/command`
|
|
2015
|
+
// grammar: a workflow / skill / AGENTS.md body's `/name` tokens resolve to
|
|
2016
|
+
// BOTH skills and workflows (`invokes: ['skill', 'workflow']`), since
|
|
2017
|
+
// Antigravity invokes either by the same slash. NOT gated under codex:
|
|
2018
|
+
// OpenAI Codex reserves `/` for its OWN built-in commands (`/model`,
|
|
2019
|
+
// `/init`, ...) and invokes user skills with `$` instead (parsed by the
|
|
2020
|
+
// codex `dollar-skill` extractor). A lens that declares no `invokes`
|
|
2021
|
+
// resolution leaves the signals unresolved (no spurious edges).
|
|
2022
|
+
precondition: { provider: ["claude", "antigravity"] },
|
|
2023
|
+
extract(ctx) {
|
|
2024
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2025
|
+
const body = stripCodeAndHtml(ctx.body);
|
|
2026
|
+
const lineStarts = computeLineStarts(body);
|
|
2027
|
+
for (const match of body.matchAll(SLASH_RE)) {
|
|
2028
|
+
const original = match[1];
|
|
2029
|
+
const endIdx = (match.index ?? 0) + match[0].length;
|
|
2030
|
+
const nextChar = body[endIdx];
|
|
2031
|
+
if (nextChar && /[A-Za-z0-9_/-]/.test(nextChar)) continue;
|
|
2032
|
+
const normalized = normalizeTrigger(original);
|
|
2033
|
+
if (seen.has(normalized)) continue;
|
|
2034
|
+
seen.add(normalized);
|
|
2035
|
+
const captureOffset = (match.index ?? 0) + match[0].indexOf(original);
|
|
2036
|
+
const line = lineFor(lineStarts, captureOffset);
|
|
2037
|
+
ctx.emitSignal({
|
|
2038
|
+
source: ctx.node.path,
|
|
2039
|
+
scope: "body",
|
|
2040
|
+
range: { start: captureOffset, end: captureOffset + original.length, line },
|
|
2041
|
+
raw: original,
|
|
2042
|
+
candidates: [
|
|
2043
|
+
{
|
|
2044
|
+
extractorId: ID9,
|
|
2045
|
+
kind: "invokes",
|
|
2046
|
+
target: original,
|
|
2047
|
+
// 0.8: clean `/command` match after code-block strip. The
|
|
2048
|
+
// post-match path guard above filters URL / file-path noise,
|
|
2049
|
+
// so a hit is unambiguous syntax. Resolution against the
|
|
2050
|
+
// live skill / command catalog happens downstream.
|
|
2051
|
+
confidence: 0.8,
|
|
2052
|
+
rationale: "unambiguous slash syntax post code-block strip",
|
|
2053
|
+
trigger: {
|
|
2054
|
+
originalTrigger: original,
|
|
2055
|
+
normalizedTrigger: normalized
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
]
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
|
|
2069
2064
|
// plugins/core/analyzers/annotation-field-unknown/index.ts
|
|
2070
2065
|
import { readFileSync } from "fs";
|
|
2071
2066
|
import { dirname, resolve } from "path";
|
|
@@ -4651,18 +4646,18 @@ var updateCheckHook = {
|
|
|
4651
4646
|
// plugins/built-ins.ts
|
|
4652
4647
|
var claudeProvider2 = { ...claudeProvider, pluginId: "claude", version: VERSION };
|
|
4653
4648
|
var atDirectiveExtractor2 = { ...atDirectiveExtractor, pluginId: "claude", version: VERSION };
|
|
4654
|
-
var slashCommandExtractor2 = { ...slashCommandExtractor, pluginId: "claude", version: VERSION };
|
|
4655
4649
|
var toolsCounterExtractor2 = { ...toolsCounterExtractor, pluginId: "claude", version: VERSION };
|
|
4656
4650
|
var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity", version: VERSION };
|
|
4657
4651
|
var codexProvider2 = { ...codexProvider, pluginId: "codex", version: VERSION };
|
|
4658
|
-
var atFileExtractor2 = { ...atFileExtractor, pluginId: "codex", version: VERSION };
|
|
4659
4652
|
var dollarSkillExtractor2 = { ...dollarSkillExtractor, pluginId: "codex", version: VERSION };
|
|
4660
4653
|
var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills", version: VERSION };
|
|
4661
4654
|
var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core", version: VERSION };
|
|
4655
|
+
var atFileExtractor2 = { ...atFileExtractor, pluginId: "core", version: VERSION };
|
|
4662
4656
|
var backtickPathExtractor2 = { ...backtickPathExtractor, pluginId: "core", version: VERSION };
|
|
4663
4657
|
var externalUrlCounterExtractor2 = { ...externalUrlCounterExtractor, pluginId: "core", version: VERSION };
|
|
4664
4658
|
var markdownLinkExtractor2 = { ...markdownLinkExtractor, pluginId: "core", version: VERSION };
|
|
4665
4659
|
var mcpToolsExtractor2 = { ...mcpToolsExtractor, pluginId: "core", version: VERSION };
|
|
4660
|
+
var slashCommandExtractor2 = { ...slashCommandExtractor, pluginId: "core", version: VERSION };
|
|
4666
4661
|
var annotationFieldUnknownAnalyzer2 = { ...annotationFieldUnknownAnalyzer, pluginId: "core", version: VERSION };
|
|
4667
4662
|
var annotationOrphanAnalyzer2 = { ...annotationOrphanAnalyzer, pluginId: "core", version: VERSION };
|
|
4668
4663
|
var annotationStaleAnalyzer2 = { ...annotationStaleAnalyzer, pluginId: "core", version: VERSION };
|
|
@@ -4691,7 +4686,6 @@ var builtInPlugins = [
|
|
|
4691
4686
|
extensions: [
|
|
4692
4687
|
claudeProvider2,
|
|
4693
4688
|
atDirectiveExtractor2,
|
|
4694
|
-
slashCommandExtractor2,
|
|
4695
4689
|
toolsCounterExtractor2
|
|
4696
4690
|
]
|
|
4697
4691
|
},
|
|
@@ -4707,7 +4701,6 @@ var builtInPlugins = [
|
|
|
4707
4701
|
description: "OpenAI Codex CLI platform integration. Classifies TOML sub-agent definitions under `.codex/agents/*.toml`.",
|
|
4708
4702
|
extensions: [
|
|
4709
4703
|
codexProvider2,
|
|
4710
|
-
atFileExtractor2,
|
|
4711
4704
|
dollarSkillExtractor2
|
|
4712
4705
|
]
|
|
4713
4706
|
},
|
|
@@ -4723,10 +4716,12 @@ var builtInPlugins = [
|
|
|
4723
4716
|
description: "Core extensions shared across providers: parsers, extractors, analyzers, actions, hooks, formatters, and the universal `.md` fallback provider.",
|
|
4724
4717
|
extensions: [
|
|
4725
4718
|
coreMarkdownProvider2,
|
|
4719
|
+
atFileExtractor2,
|
|
4726
4720
|
backtickPathExtractor2,
|
|
4727
4721
|
externalUrlCounterExtractor2,
|
|
4728
4722
|
markdownLinkExtractor2,
|
|
4729
4723
|
mcpToolsExtractor2,
|
|
4724
|
+
slashCommandExtractor2,
|
|
4730
4725
|
annotationFieldUnknownAnalyzer2,
|
|
4731
4726
|
annotationOrphanAnalyzer2,
|
|
4732
4727
|
annotationStaleAnalyzer2,
|
|
@@ -16538,6 +16533,8 @@ var ORCHESTRATOR_TEXTS = {
|
|
|
16538
16533
|
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.",
|
|
16539
16534
|
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.",
|
|
16540
16535
|
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.",
|
|
16536
|
+
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.",
|
|
16537
|
+
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.",
|
|
16541
16538
|
extensionErrorLinkKindNotDeclared: 'Extractor "{{extractorId}}" emitted a link of kind "{{linkKind}}" outside its declared `emitsLinkKinds` set [{{declaredKinds}}]. Link dropped.',
|
|
16542
16539
|
extensionErrorIssueInvalidSeverity: `Rule "{{analyzerId}}" emitted an issue with invalid severity {{severity}} (allowed: 'error' | 'warn' | 'info'). Issue dropped.`,
|
|
16543
16540
|
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.',
|
|
@@ -17223,6 +17220,11 @@ var FRONTMATTER_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
|
|
|
17223
17220
|
"frontmatter-malformed",
|
|
17224
17221
|
"frontmatter-parse-error"
|
|
17225
17222
|
]);
|
|
17223
|
+
var BACKTICK_ISSUE_ID = "backtick-unbalanced";
|
|
17224
|
+
var CACHED_KERNEL_ISSUE_ANALYZERS = /* @__PURE__ */ new Set([
|
|
17225
|
+
...FRONTMATTER_ISSUE_ANALYZERS,
|
|
17226
|
+
BACKTICK_ISSUE_ID
|
|
17227
|
+
]);
|
|
17226
17228
|
|
|
17227
17229
|
// kernel/orchestrator/cache.ts
|
|
17228
17230
|
function indexPriorSnapshot(prior) {
|
|
@@ -17252,7 +17254,7 @@ function indexPriorLinks(links, byOriginating) {
|
|
|
17252
17254
|
}
|
|
17253
17255
|
function indexPriorFrontmatterIssues(issues, byNode) {
|
|
17254
17256
|
for (const issue of issues) {
|
|
17255
|
-
if (!
|
|
17257
|
+
if (!CACHED_KERNEL_ISSUE_ANALYZERS.has(issue.analyzerId)) continue;
|
|
17256
17258
|
if (issue.nodeIds.length !== 1) continue;
|
|
17257
17259
|
const path = issue.nodeIds[0];
|
|
17258
17260
|
const list = byNode.get(path);
|
|
@@ -17996,6 +17998,21 @@ function malformedMessage(hint, path) {
|
|
|
17996
17998
|
}
|
|
17997
17999
|
}
|
|
17998
18000
|
|
|
18001
|
+
// kernel/orchestrator/body-syntax.ts
|
|
18002
|
+
function detectUnclosedBacktick(body, path, strict) {
|
|
18003
|
+
const imbalance = findBacktickImbalance(body);
|
|
18004
|
+
if (!imbalance) return null;
|
|
18005
|
+
const template = imbalance.kind === "fence" ? ORCHESTRATOR_TEXTS.bodyBacktickUnclosedFence : ORCHESTRATOR_TEXTS.bodyBacktickUnclosedInline;
|
|
18006
|
+
return {
|
|
18007
|
+
analyzerId: BACKTICK_ISSUE_ID,
|
|
18008
|
+
severity: strict ? "error" : "warn",
|
|
18009
|
+
nodeIds: [path],
|
|
18010
|
+
message: tx(template, { path, line: imbalance.line }),
|
|
18011
|
+
detail: imbalance.sourceLine,
|
|
18012
|
+
data: { kind: imbalance.kind, line: imbalance.line }
|
|
18013
|
+
};
|
|
18014
|
+
}
|
|
18015
|
+
|
|
17999
18016
|
// kernel/orchestrator/node-build.ts
|
|
18000
18017
|
function buildNode(args2) {
|
|
18001
18018
|
const bytesFrontmatter = Buffer.byteLength(args2.frontmatterRaw, "utf8");
|
|
@@ -18122,6 +18139,9 @@ function relativePathFromRoots(absolutePath, roots) {
|
|
|
18122
18139
|
}
|
|
18123
18140
|
return absolutePath;
|
|
18124
18141
|
}
|
|
18142
|
+
function pushIssue(list, issue) {
|
|
18143
|
+
if (issue) list.push(issue);
|
|
18144
|
+
}
|
|
18125
18145
|
function buildFreshNodeAndValidateFrontmatter(opts) {
|
|
18126
18146
|
const node = buildNode({
|
|
18127
18147
|
path: opts.raw.path,
|
|
@@ -18149,19 +18169,27 @@ function buildFreshNodeAndValidateFrontmatter(opts) {
|
|
|
18149
18169
|
}
|
|
18150
18170
|
}
|
|
18151
18171
|
if (opts.raw.frontmatterRaw.length > 0) {
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18172
|
+
pushIssue(
|
|
18173
|
+
frontmatterIssues,
|
|
18174
|
+
validateFrontmatter(
|
|
18175
|
+
opts.providerFrontmatter,
|
|
18176
|
+
opts.provider,
|
|
18177
|
+
opts.kind,
|
|
18178
|
+
opts.raw.frontmatter,
|
|
18179
|
+
opts.raw.path,
|
|
18180
|
+
opts.strict
|
|
18181
|
+
)
|
|
18159
18182
|
);
|
|
18160
|
-
if (fmIssue) frontmatterIssues.push(fmIssue);
|
|
18161
18183
|
} else {
|
|
18162
|
-
|
|
18163
|
-
|
|
18184
|
+
pushIssue(
|
|
18185
|
+
frontmatterIssues,
|
|
18186
|
+
detectMalformedFrontmatter(opts.raw.body, opts.raw.path, opts.strict)
|
|
18187
|
+
);
|
|
18164
18188
|
}
|
|
18189
|
+
pushIssue(
|
|
18190
|
+
frontmatterIssues,
|
|
18191
|
+
detectUnclosedBacktick(opts.raw.body, opts.raw.path, opts.strict)
|
|
18192
|
+
);
|
|
18165
18193
|
return { node, frontmatterIssues };
|
|
18166
18194
|
}
|
|
18167
18195
|
|
|
@@ -32575,15 +32603,20 @@ var TUTORIAL_TEXTS = {
|
|
|
32575
32603
|
writtenLabelEs: "Espa\xF1ol",
|
|
32576
32604
|
// Destination-provider prompt (interactive stdin, no `--for`). Header
|
|
32577
32605
|
// uses a yellow `?` glyph; options are a numbered list of the provider's
|
|
32578
|
-
//
|
|
32579
|
-
//
|
|
32580
|
-
// the
|
|
32581
|
-
//
|
|
32582
|
-
// identify the lens. The input line
|
|
32583
|
-
// an empty answer (which takes the
|
|
32606
|
+
// label (for a provider with an `aka`, the standard label leads and the
|
|
32607
|
+
// supporting vendors follow in parentheses, closed by `akaOthers` to mark
|
|
32608
|
+
// the set as open), with a `(default)` marker on the first option (Claude).
|
|
32609
|
+
// The destination folder is deliberately NOT shown: several providers share
|
|
32610
|
+
// `.agents/skills`, so the folder does not identify the lens. The input line
|
|
32611
|
+
// accepts a number, a provider id, or an empty answer (which takes the
|
|
32612
|
+
// default).
|
|
32584
32613
|
promptHeader: "{{glyph}} Which agent should host the tutorial skill?",
|
|
32585
32614
|
promptOption: " {{index}}) {{label}}{{marker}}",
|
|
32586
32615
|
promptDefaultMarker: " (default)",
|
|
32616
|
+
// Trailing token appended to the `aka` vendor list in the open-lens label
|
|
32617
|
+
// ("... (Google's Antigravity, others)"), signalling the open standard is
|
|
32618
|
+
// not tied to a single vendor and more will support it.
|
|
32619
|
+
akaOthers: "others",
|
|
32587
32620
|
promptInput: " Enter the number or provider id [default {{index}}]: ",
|
|
32588
32621
|
// Prompt answer matched neither an index nor an id. Goes to stderr,
|
|
32589
32622
|
// exit code 2. Mirrors the error shape: glyph + headline + dim hint.
|
|
@@ -32833,7 +32866,7 @@ function listScaffoldTargets(includeExperimental = false) {
|
|
|
32833
32866
|
return out;
|
|
32834
32867
|
}
|
|
32835
32868
|
function labelWithAka(target) {
|
|
32836
|
-
return target.aka.length > 0 ? `${target.aka.join(", ")}
|
|
32869
|
+
return target.aka.length > 0 ? `${target.label} (${[...target.aka, TUTORIAL_TEXTS.akaOthers].join(", ")})` : target.label;
|
|
32837
32870
|
}
|
|
32838
32871
|
function renderTargetLines(targets, def, glyph) {
|
|
32839
32872
|
const lines = [tx(TUTORIAL_TEXTS.promptHeader, { glyph })];
|
|
@@ -33128,4 +33161,4 @@ function resolveBareDefault() {
|
|
|
33128
33161
|
process.exit(ExitCode.Error);
|
|
33129
33162
|
}
|
|
33130
33163
|
//# sourceMappingURL=cli.js.map
|
|
33131
|
-
//# debugId=
|
|
33164
|
+
//# debugId=81f53ca6-a8bf-5fc1-909d-ce926a83f056
|