@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/cli.js
CHANGED
|
@@ -553,6 +553,63 @@ var claudeProvider = {
|
|
|
553
553
|
mentions: ["agent"],
|
|
554
554
|
invokes: ["command", "skill"]
|
|
555
555
|
},
|
|
556
|
+
// Reserved invocation names the Claude runtime owns. A user file
|
|
557
|
+
// declaring one of these (e.g. `.claude/commands/help.md`) is
|
|
558
|
+
// silently shadowed: the runtime runs the built-in instead.
|
|
559
|
+
//
|
|
560
|
+
// - `command`: canonical list of built-in slash commands documented
|
|
561
|
+
// at https://docs.claude.com/en/docs/claude-code/slash-commands.
|
|
562
|
+
// The list will drift as Anthropic adds / removes commands;
|
|
563
|
+
// updates ship via a kernel patch + changeset (the catalog is
|
|
564
|
+
// considered API surface that users rely on the analyzer to
|
|
565
|
+
// reflect).
|
|
566
|
+
// - `agent`: built-in agents Anthropic ships with the CLI. Smaller
|
|
567
|
+
// surface than commands today.
|
|
568
|
+
// - `skill`: no built-in skills today (skills are user-defined and
|
|
569
|
+
// discovered from disk); the key is omitted on purpose, defaulting
|
|
570
|
+
// to no reserved names for the kind.
|
|
571
|
+
reservedNames: {
|
|
572
|
+
command: [
|
|
573
|
+
"help",
|
|
574
|
+
"clear",
|
|
575
|
+
"compact",
|
|
576
|
+
"cost",
|
|
577
|
+
"init",
|
|
578
|
+
"model",
|
|
579
|
+
"agents",
|
|
580
|
+
"login",
|
|
581
|
+
"logout",
|
|
582
|
+
"mcp",
|
|
583
|
+
"memory",
|
|
584
|
+
"config",
|
|
585
|
+
"doctor",
|
|
586
|
+
"permissions",
|
|
587
|
+
"add-dir",
|
|
588
|
+
"bug",
|
|
589
|
+
"pr-comments",
|
|
590
|
+
"release-notes",
|
|
591
|
+
"review",
|
|
592
|
+
"terminal-setup",
|
|
593
|
+
"vim",
|
|
594
|
+
"output-style",
|
|
595
|
+
"hooks",
|
|
596
|
+
"install-github-app",
|
|
597
|
+
"migrate-installer",
|
|
598
|
+
"upgrade",
|
|
599
|
+
"resume",
|
|
600
|
+
"exit",
|
|
601
|
+
"quit",
|
|
602
|
+
"security-review",
|
|
603
|
+
"statusline",
|
|
604
|
+
"usage",
|
|
605
|
+
"feedback"
|
|
606
|
+
],
|
|
607
|
+
agent: [
|
|
608
|
+
"general-purpose",
|
|
609
|
+
"output-style-setup",
|
|
610
|
+
"statusline-setup"
|
|
611
|
+
]
|
|
612
|
+
},
|
|
556
613
|
// Auxiliary schemas the per-kind schemas $ref by $id. AJV needs them
|
|
557
614
|
// registered via addSchema BEFORE the per-kind schemas compile, so the
|
|
558
615
|
// validator builder pre-registers them. `skill-base.schema.json` is the
|
|
@@ -637,7 +694,7 @@ var atDirectiveExtractor = {
|
|
|
637
694
|
pluginId: "claude",
|
|
638
695
|
kind: "extractor",
|
|
639
696
|
version: "1.0.0",
|
|
640
|
-
description: "Detects `@<token>` directives in a node's body using Claude Code interpretation rules. 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. Gated by `precondition.provider: ['claude']` so
|
|
697
|
+
description: "Detects `@<token>` directives in a node's body using Claude Code interpretation rules. 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. Gated by `precondition.provider: ['claude']` so Antigravity / Cursor / Codex apply their own at-directive flavours via their own extractors.",
|
|
641
698
|
scope: "body",
|
|
642
699
|
precondition: { provider: ["claude"] },
|
|
643
700
|
extract(ctx) {
|
|
@@ -705,7 +762,7 @@ var slashExtractor = {
|
|
|
705
762
|
pluginId: "claude",
|
|
706
763
|
kind: "extractor",
|
|
707
764
|
version: "1.0.0",
|
|
708
|
-
description: "Detects `/command` invocations in a node's body using Claude Code routing rules and turns each one into an arrow between nodes in the graph. Gated by `precondition.provider: ['claude']` so
|
|
765
|
+
description: "Detects `/command` invocations in a node's body using Claude Code routing rules and turns each one into an arrow between nodes in the graph. Gated by `precondition.provider: ['claude']` so Antigravity / Cursor / Codex apply their own slash flavours (Antigravity ships subagent and skill panels, Codex deprecated user slash commands, etc.) via their own extractors.",
|
|
709
766
|
scope: "body",
|
|
710
767
|
precondition: { provider: ["claude"] },
|
|
711
768
|
extract(ctx) {
|
|
@@ -738,138 +795,40 @@ var slashExtractor = {
|
|
|
738
795
|
}
|
|
739
796
|
};
|
|
740
797
|
|
|
741
|
-
// plugins/
|
|
742
|
-
var
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
title: "FrontmatterGeminiAgent",
|
|
746
|
-
description: "Frontmatter shape for nodes classified as `agent` by the Gemini Provider. Mirrors Google's documented Gemini CLI subagent frontmatter verbatim (https://geminicli.com/docs/core/subagents/): `name` and `description` come from the spec base; this schema adds the 7 vendor-specific fields. skill-map AGGREGATES the vendor spec, it does not curate it. `additionalProperties: true` so future Google additions flow through unchanged until this schema catches up. Note: Gemini's `kind` field (enum `local|remote`) lives at a different layer than the kernel's extension-kind discriminator and the node-kind discriminator \u2014 both use the word `kind` but in distinct namespaces (manifest vs frontmatter).",
|
|
747
|
-
allOf: [
|
|
748
|
-
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
749
|
-
],
|
|
750
|
-
type: "object",
|
|
751
|
-
additionalProperties: true,
|
|
752
|
-
properties: {
|
|
753
|
-
kind: {
|
|
754
|
-
type: "string",
|
|
755
|
-
enum: ["local", "remote"],
|
|
756
|
-
default: "local",
|
|
757
|
-
description: "Subagent execution mode. `local` runs in-process; `remote` is the documented value for the future remote-agent surface (https://geminicli.com/docs/core/remote-agents/)."
|
|
758
|
-
},
|
|
759
|
-
tools: {
|
|
760
|
-
type: "array",
|
|
761
|
-
description: "Tool names this subagent can invoke. Wildcards supported: `*` (all), `mcp_*` (all MCP), `mcp_<server>_*` (one MCP server). When omitted, the subagent inherits the parent session's full tool set.",
|
|
762
|
-
items: { type: "string" }
|
|
763
|
-
},
|
|
764
|
-
mcpServers: {
|
|
765
|
-
type: "object",
|
|
766
|
-
additionalProperties: true,
|
|
767
|
-
description: "Inline MCP server configuration isolated to this subagent. Shape is platform-defined; preserved as an opaque object."
|
|
768
|
-
},
|
|
769
|
-
model: {
|
|
770
|
-
type: "string",
|
|
771
|
-
description: "Model id override (e.g. `gemini-3-flash-preview`). When omitted, inherits from the parent session."
|
|
772
|
-
},
|
|
773
|
-
temperature: {
|
|
774
|
-
type: "number",
|
|
775
|
-
minimum: 0,
|
|
776
|
-
maximum: 2,
|
|
777
|
-
default: 1,
|
|
778
|
-
description: "Model sampling temperature. Range 0.0\u20132.0 per Google docs."
|
|
779
|
-
},
|
|
780
|
-
max_turns: {
|
|
781
|
-
type: "integer",
|
|
782
|
-
minimum: 1,
|
|
783
|
-
default: 30,
|
|
784
|
-
description: "Hard cap on conversation turns before the subagent must return."
|
|
785
|
-
},
|
|
786
|
-
timeout_mins: {
|
|
787
|
-
type: "integer",
|
|
788
|
-
minimum: 1,
|
|
789
|
-
default: 10,
|
|
790
|
-
description: "Maximum execution duration in minutes."
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
};
|
|
794
|
-
|
|
795
|
-
// plugins/gemini/providers/gemini/schemas/skill.schema.json
|
|
796
|
-
var skill_schema_default2 = {
|
|
797
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
798
|
-
$id: "https://skill-map.dev/providers/gemini/v1/frontmatter/skill.schema.json",
|
|
799
|
-
title: "FrontmatterGeminiSkill",
|
|
800
|
-
description: "Frontmatter shape for nodes classified as `skill` by the Gemini Provider \u2014 Agent Skills delivered as `SKILL.md` files (https://geminicli.com/docs/cli/creating-skills/). Google documents only `name` and `description` as required frontmatter fields; both already live in the spec's universal `frontmatter/base.schema.json`. `additionalProperties: true` so vendor additions flow through unchanged.",
|
|
801
|
-
allOf: [
|
|
802
|
-
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
803
|
-
],
|
|
804
|
-
type: "object",
|
|
805
|
-
additionalProperties: true,
|
|
806
|
-
properties: {}
|
|
807
|
-
};
|
|
808
|
-
|
|
809
|
-
// plugins/gemini/providers/gemini/index.ts
|
|
810
|
-
var geminiProvider = {
|
|
811
|
-
id: "gemini",
|
|
812
|
-
pluginId: "gemini",
|
|
798
|
+
// plugins/antigravity/providers/antigravity/index.ts
|
|
799
|
+
var antigravityProvider = {
|
|
800
|
+
id: "antigravity",
|
|
801
|
+
pluginId: "antigravity",
|
|
813
802
|
kind: "provider",
|
|
814
803
|
version: "1.0.0",
|
|
815
|
-
description: "
|
|
816
|
-
read:
|
|
817
|
-
//
|
|
818
|
-
//
|
|
819
|
-
//
|
|
820
|
-
//
|
|
821
|
-
|
|
822
|
-
//
|
|
823
|
-
//
|
|
824
|
-
|
|
825
|
-
// color + icon as Claude, etc. The declaration STAYS per-Provider (the
|
|
826
|
-
// shape allows divergence the day a Provider wants its own identity for
|
|
827
|
-
// a kind), but today the values mirror Claude so the visual vocabulary
|
|
828
|
-
// is uniform regardless of where a node was sourced from.
|
|
829
|
-
kinds: {
|
|
830
|
-
agent: {
|
|
831
|
-
schema: "./schemas/agent.schema.json",
|
|
832
|
-
schemaJson: agent_schema_default2,
|
|
833
|
-
ui: {
|
|
834
|
-
label: "Agents",
|
|
835
|
-
color: "#3b82f6",
|
|
836
|
-
colorDark: "#60a5fa",
|
|
837
|
-
icon: { kind: "pi", id: "pi-user" }
|
|
838
|
-
},
|
|
839
|
-
identifiers: ["frontmatter.name", "filename-basename"]
|
|
840
|
-
},
|
|
841
|
-
skill: {
|
|
842
|
-
schema: "./schemas/skill.schema.json",
|
|
843
|
-
schemaJson: skill_schema_default2,
|
|
844
|
-
ui: {
|
|
845
|
-
label: "Skills",
|
|
846
|
-
color: "#10b981",
|
|
847
|
-
colorDark: "#34d399",
|
|
848
|
-
icon: { kind: "pi", id: "pi-bolt" }
|
|
849
|
-
},
|
|
850
|
-
// Gemini skills live at `.gemini/skills/<name>/SKILL.md`; the
|
|
851
|
-
// dirname is the invocation handle per Google's docs
|
|
852
|
-
// (https://geminicli.com/docs/cli/creating-skills/).
|
|
853
|
-
identifiers: ["frontmatter.name", "dirname"]
|
|
854
|
-
}
|
|
855
|
-
},
|
|
856
|
-
// Gemini's invocation surfaces mirror Claude's at the kernel level
|
|
857
|
-
// (mentions for agents, slash invokes for skills). Commands are not
|
|
858
|
-
// a Gemini concept; only `skill` belongs to `invokes`.
|
|
859
|
-
resolution: {
|
|
860
|
-
mentions: ["agent"],
|
|
861
|
-
invokes: ["skill"]
|
|
862
|
-
},
|
|
863
|
-
classify(path) {
|
|
864
|
-
const lower = path.toLowerCase();
|
|
865
|
-
if (lower.startsWith(".gemini/agents/")) return "agent";
|
|
866
|
-
if (/^\.gemini\/skills\/[^/]+\/skill\.md$/.test(lower)) return "skill";
|
|
804
|
+
description: "Google Antigravity CLI. Replaces the retired Gemini CLI; skills route through the neutral `agent-skills` Provider via `.agents/skills/`. This Provider contributes lens identity and a reserved-name seed catalog.",
|
|
805
|
+
// No `read` config: this Provider does not walk the filesystem. The
|
|
806
|
+
// kernel walker only fires for Providers with `read` or `walk`; an
|
|
807
|
+
// empty Provider participates in registration (its `ui` block is
|
|
808
|
+
// available, its `reservedNames` catalog is loaded) without owning
|
|
809
|
+
// any on-disk territory.
|
|
810
|
+
kinds: {},
|
|
811
|
+
// Always disclaim: paths are owned by other Providers (`.agents/` ->
|
|
812
|
+
// `agent-skills`, `AGENTS.md` -> `core/markdown` fallback).
|
|
813
|
+
classify() {
|
|
867
814
|
return null;
|
|
815
|
+
},
|
|
816
|
+
// Seed catalog. Built-in slash commands surfaced by the Antigravity
|
|
817
|
+
// TUI (`/agents`, `/help`, `/quit`, `/skills`, `/hooks`, etc.). The
|
|
818
|
+
// exact list will expand once Google publishes the full reference;
|
|
819
|
+
// start small and document the growth path here rather than over-
|
|
820
|
+
// commit to a catalog that may drift.
|
|
821
|
+
//
|
|
822
|
+
// Inactive today (no nodes are classified under `antigravity`), kept
|
|
823
|
+
// here so the day Antigravity gains an own kind or the analyzer keys
|
|
824
|
+
// on the active lens, the catalog is already in place.
|
|
825
|
+
reservedNames: {
|
|
826
|
+
command: ["agents", "help", "quit", "exit", "skills", "hooks"]
|
|
868
827
|
}
|
|
869
828
|
};
|
|
870
829
|
|
|
871
830
|
// plugins/openai/providers/openai/schemas/agent.schema.json
|
|
872
|
-
var
|
|
831
|
+
var agent_schema_default2 = {
|
|
873
832
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
874
833
|
$id: "https://skill-map.dev/providers/openai/v1/frontmatter/agent.schema.json",
|
|
875
834
|
title: "FrontmatterCodexAgent",
|
|
@@ -931,10 +890,10 @@ var openaiProvider = {
|
|
|
931
890
|
kinds: {
|
|
932
891
|
agent: {
|
|
933
892
|
schema: "./schemas/agent.schema.json",
|
|
934
|
-
schemaJson:
|
|
893
|
+
schemaJson: agent_schema_default2,
|
|
935
894
|
ui: {
|
|
936
895
|
label: "Codex agents",
|
|
937
|
-
// Codex green; distinct from claude
|
|
896
|
+
// Codex green; distinct from the claude palette.
|
|
938
897
|
color: "#22c55e",
|
|
939
898
|
colorDark: "#4ade80",
|
|
940
899
|
icon: { kind: "pi", id: "pi-bolt" }
|
|
@@ -960,7 +919,7 @@ var openaiProvider = {
|
|
|
960
919
|
};
|
|
961
920
|
|
|
962
921
|
// plugins/agent-skills/providers/agent-skills/schemas/skill.schema.json
|
|
963
|
-
var
|
|
922
|
+
var skill_schema_default2 = {
|
|
964
923
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
965
924
|
$id: "https://skill-map.dev/providers/agent-skills/v1/frontmatter/skill.schema.json",
|
|
966
925
|
title: "FrontmatterAgentSkillsSkill",
|
|
@@ -984,7 +943,7 @@ var agentSkillsProvider = {
|
|
|
984
943
|
kinds: {
|
|
985
944
|
skill: {
|
|
986
945
|
schema: "./schemas/skill.schema.json",
|
|
987
|
-
schemaJson:
|
|
946
|
+
schemaJson: skill_schema_default2,
|
|
988
947
|
ui: {
|
|
989
948
|
label: "Skills",
|
|
990
949
|
color: "#10b981",
|
|
@@ -1013,7 +972,7 @@ var markdown_schema_default = {
|
|
|
1013
972
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1014
973
|
$id: "https://skill-map.dev/providers/core/v1/frontmatter/markdown.schema.json",
|
|
1015
974
|
title: "FrontmatterMarkdown",
|
|
1016
|
-
description: "Frontmatter shape for nodes classified as `markdown` by the built-in `core/markdown` Provider
|
|
975
|
+
description: "Frontmatter shape for nodes classified as `markdown` by the built-in `core/markdown` Provider, the universal fallback for any markdown file no vendor-specific Provider claims (Claude, OpenAI Codex, agent-skills, plus the metadata-only Antigravity bundle). The kind is named after the format because the file is a generic fallback; format-named kinds apply only as the generic fallback, a TOML file that IS a Codex agent still classifies as `agent`, not `toml`. Extends the spec's universal `frontmatter/base.schema.json` via $ref-by-$id with no additional fields. Ownership relocated from the Claude Provider in spec 0.18.0, markdown is provider-agnostic and lives under `core` so adding new vendor Providers does not require choosing which one owns the universal fallback.",
|
|
1017
976
|
allOf: [
|
|
1018
977
|
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
1019
978
|
],
|
|
@@ -1034,8 +993,9 @@ var coreMarkdownProvider = {
|
|
|
1034
993
|
// as a registry entry (it ships later under the core bundle), but
|
|
1035
994
|
// the qualified form is the contract.
|
|
1036
995
|
//
|
|
1037
|
-
// UI presentation: same neutral teal that
|
|
1038
|
-
//
|
|
996
|
+
// UI presentation: same neutral teal that the per-vendor Providers
|
|
997
|
+
// (when they shipped their own markdown kind duplicates) used to
|
|
998
|
+
// declare. The kindRegistry
|
|
1039
999
|
// composer (`buildKindRegistry`) makes this entry the primary owner
|
|
1040
1000
|
// of the `markdown` kind because no other Provider declares it now;
|
|
1041
1001
|
// per-node painting still falls through `entry.providers[node.provider]`
|
|
@@ -1928,12 +1888,56 @@ function formatBreakdown(byKind, direction) {
|
|
|
1928
1888
|
return [direction, ...lines].join("\n");
|
|
1929
1889
|
}
|
|
1930
1890
|
|
|
1891
|
+
// plugins/core/analyzers/reserved-name/text.ts
|
|
1892
|
+
var RESERVED_NAME_TEXTS = {
|
|
1893
|
+
/**
|
|
1894
|
+
* `<path> shadows a built-in <provider> <kind>. The runtime ignores
|
|
1895
|
+
* this file in favour of its own built-in. Rename the file or
|
|
1896
|
+
* `frontmatter.name` to a non-reserved value.`
|
|
1897
|
+
*/
|
|
1898
|
+
message: "{{path}} shadows a built-in {{provider}} {{kind}}. The runtime ignores this file in favour of its own built-in. Rename the file or `frontmatter.name` to a non-reserved value."
|
|
1899
|
+
};
|
|
1900
|
+
|
|
1901
|
+
// plugins/core/analyzers/reserved-name/index.ts
|
|
1902
|
+
var ID15 = "reserved-name";
|
|
1903
|
+
var reservedNameAnalyzer = {
|
|
1904
|
+
id: ID15,
|
|
1905
|
+
pluginId: "core",
|
|
1906
|
+
kind: "analyzer",
|
|
1907
|
+
version: "1.0.0",
|
|
1908
|
+
description: "Flags user nodes whose name collides with a Provider runtime's built-in invocable (the runtime shadows the file silently).",
|
|
1909
|
+
mode: "deterministic",
|
|
1910
|
+
evaluate(ctx) {
|
|
1911
|
+
const reserved = ctx.reservedNodePaths;
|
|
1912
|
+
if (!reserved || reserved.size === 0) return [];
|
|
1913
|
+
const byPath3 = /* @__PURE__ */ new Map();
|
|
1914
|
+
for (const node of ctx.nodes) byPath3.set(node.path, node);
|
|
1915
|
+
const issues = [];
|
|
1916
|
+
for (const path of reserved) {
|
|
1917
|
+
const node = byPath3.get(path);
|
|
1918
|
+
if (!node) continue;
|
|
1919
|
+
issues.push({
|
|
1920
|
+
analyzerId: ID15,
|
|
1921
|
+
severity: "warn",
|
|
1922
|
+
nodeIds: [node.path],
|
|
1923
|
+
message: tx(RESERVED_NAME_TEXTS.message, {
|
|
1924
|
+
path: node.path,
|
|
1925
|
+
provider: node.provider,
|
|
1926
|
+
kind: node.kind
|
|
1927
|
+
}),
|
|
1928
|
+
data: { provider: node.provider, kind: node.kind }
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
return issues;
|
|
1932
|
+
}
|
|
1933
|
+
};
|
|
1934
|
+
|
|
1931
1935
|
// plugins/core/analyzers/stability/index.ts
|
|
1932
|
-
var
|
|
1936
|
+
var ID16 = "stability";
|
|
1933
1937
|
var EXPERIMENTAL_TOOLTIP = "Experimental: API may change";
|
|
1934
1938
|
var DEPRECATED_TOOLTIP = "Deprecated: avoid in new code";
|
|
1935
1939
|
var stabilityAnalyzer = {
|
|
1936
|
-
id:
|
|
1940
|
+
id: ID16,
|
|
1937
1941
|
pluginId: "core",
|
|
1938
1942
|
kind: "analyzer",
|
|
1939
1943
|
version: "1.0.0",
|
|
@@ -1965,7 +1969,7 @@ var stabilityAnalyzer = {
|
|
|
1965
1969
|
tooltip: EXPERIMENTAL_TOOLTIP
|
|
1966
1970
|
});
|
|
1967
1971
|
issues.push({
|
|
1968
|
-
analyzerId:
|
|
1972
|
+
analyzerId: ID16,
|
|
1969
1973
|
severity: "info",
|
|
1970
1974
|
nodeIds: [node.path],
|
|
1971
1975
|
message: `Node '${node.path}' is marked experimental: API may change.`,
|
|
@@ -1978,7 +1982,7 @@ var stabilityAnalyzer = {
|
|
|
1978
1982
|
severity: "warn"
|
|
1979
1983
|
});
|
|
1980
1984
|
issues.push({
|
|
1981
|
-
analyzerId:
|
|
1985
|
+
analyzerId: ID16,
|
|
1982
1986
|
severity: "warn",
|
|
1983
1987
|
nodeIds: [node.path],
|
|
1984
1988
|
message: `Node '${node.path}' is marked deprecated: avoid in new code.`,
|
|
@@ -2012,9 +2016,9 @@ var SUPERSEDED_TEXTS = {
|
|
|
2012
2016
|
};
|
|
2013
2017
|
|
|
2014
2018
|
// plugins/core/analyzers/superseded/index.ts
|
|
2015
|
-
var
|
|
2019
|
+
var ID17 = "superseded";
|
|
2016
2020
|
var supersededAnalyzer = {
|
|
2017
|
-
id:
|
|
2021
|
+
id: ID17,
|
|
2018
2022
|
pluginId: "core",
|
|
2019
2023
|
kind: "analyzer",
|
|
2020
2024
|
version: "1.0.0",
|
|
@@ -2026,7 +2030,7 @@ var supersededAnalyzer = {
|
|
|
2026
2030
|
const supersededBy = pickSupersededBy(node);
|
|
2027
2031
|
if (supersededBy === null) continue;
|
|
2028
2032
|
issues.push({
|
|
2029
|
-
analyzerId:
|
|
2033
|
+
analyzerId: ID17,
|
|
2030
2034
|
severity: "info",
|
|
2031
2035
|
nodeIds: [node.path],
|
|
2032
2036
|
message: tx(SUPERSEDED_TEXTS.message, {
|
|
@@ -2075,14 +2079,14 @@ var TRIGGER_COLLISION_TEXTS = {
|
|
|
2075
2079
|
};
|
|
2076
2080
|
|
|
2077
2081
|
// plugins/core/analyzers/trigger-collision/index.ts
|
|
2078
|
-
var
|
|
2082
|
+
var ID18 = "trigger-collision";
|
|
2079
2083
|
var ADVERTISING_KINDS = /* @__PURE__ */ new Set([
|
|
2080
2084
|
"command",
|
|
2081
2085
|
"skill",
|
|
2082
2086
|
"agent"
|
|
2083
2087
|
]);
|
|
2084
2088
|
var triggerCollisionAnalyzer = {
|
|
2085
|
-
id:
|
|
2089
|
+
id: ID18,
|
|
2086
2090
|
pluginId: "core",
|
|
2087
2091
|
kind: "analyzer",
|
|
2088
2092
|
mode: "deterministic",
|
|
@@ -2181,7 +2185,7 @@ function analyzeTriggerBucket(normalized, claims) {
|
|
|
2181
2185
|
part: parts[0]
|
|
2182
2186
|
});
|
|
2183
2187
|
return {
|
|
2184
|
-
analyzerId:
|
|
2188
|
+
analyzerId: ID18,
|
|
2185
2189
|
severity: "error",
|
|
2186
2190
|
nodeIds,
|
|
2187
2191
|
message,
|
|
@@ -2221,10 +2225,10 @@ var UNKNOWN_FIELD_TEXTS = {
|
|
|
2221
2225
|
};
|
|
2222
2226
|
|
|
2223
2227
|
// plugins/core/analyzers/unknown-field/index.ts
|
|
2224
|
-
var
|
|
2228
|
+
var ID19 = "unknown-field";
|
|
2225
2229
|
var RESERVED_ROOT_BLOCKS = /* @__PURE__ */ new Set(["identity", "annotations", "settings", "audit"]);
|
|
2226
2230
|
var unknownFieldAnalyzer = {
|
|
2227
|
-
id:
|
|
2231
|
+
id: ID19,
|
|
2228
2232
|
pluginId: "core",
|
|
2229
2233
|
kind: "analyzer",
|
|
2230
2234
|
version: "1.0.0",
|
|
@@ -2282,7 +2286,7 @@ var unknownFieldAnalyzer = {
|
|
|
2282
2286
|
for (const key of Object.keys(annotations)) {
|
|
2283
2287
|
if (!knownAnnotationKeys.has(key)) {
|
|
2284
2288
|
issues.push({
|
|
2285
|
-
analyzerId:
|
|
2289
|
+
analyzerId: ID19,
|
|
2286
2290
|
severity: "warn",
|
|
2287
2291
|
nodeIds: [node.path],
|
|
2288
2292
|
message: tx(UNKNOWN_FIELD_TEXTS.unknownAnnotationKey, {
|
|
@@ -2309,7 +2313,7 @@ var unknownFieldAnalyzer = {
|
|
|
2309
2313
|
if (validator(value)) continue;
|
|
2310
2314
|
const errors = (validator.errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message ?? e.keyword}`).join("; ");
|
|
2311
2315
|
issues.push({
|
|
2312
|
-
analyzerId:
|
|
2316
|
+
analyzerId: ID19,
|
|
2313
2317
|
severity: "warn",
|
|
2314
2318
|
nodeIds: [node.path],
|
|
2315
2319
|
message: tx(UNKNOWN_FIELD_TEXTS.pluginNamespaceInvalid, {
|
|
@@ -2325,7 +2329,7 @@ var unknownFieldAnalyzer = {
|
|
|
2325
2329
|
continue;
|
|
2326
2330
|
}
|
|
2327
2331
|
issues.push({
|
|
2328
|
-
analyzerId:
|
|
2332
|
+
analyzerId: ID19,
|
|
2329
2333
|
severity: "warn",
|
|
2330
2334
|
nodeIds: [node.path],
|
|
2331
2335
|
message: tx(UNKNOWN_FIELD_TEXTS.unknownRootKey, {
|
|
@@ -2618,9 +2622,9 @@ var VALIDATE_ALL_TEXTS = {
|
|
|
2618
2622
|
};
|
|
2619
2623
|
|
|
2620
2624
|
// plugins/core/analyzers/validate-all/index.ts
|
|
2621
|
-
var
|
|
2625
|
+
var ID20 = "validate-all";
|
|
2622
2626
|
var validateAllAnalyzer = {
|
|
2623
|
-
id:
|
|
2627
|
+
id: ID20,
|
|
2624
2628
|
pluginId: "core",
|
|
2625
2629
|
kind: "analyzer",
|
|
2626
2630
|
version: "1.0.0",
|
|
@@ -2683,7 +2687,7 @@ function collectNodeFindings(v, node, out) {
|
|
|
2683
2687
|
const result = v.validate("node", toNodeForSchema(node));
|
|
2684
2688
|
if (result.ok) return;
|
|
2685
2689
|
out.push({
|
|
2686
|
-
analyzerId:
|
|
2690
|
+
analyzerId: ID20,
|
|
2687
2691
|
severity: "error",
|
|
2688
2692
|
nodeIds: [node.path],
|
|
2689
2693
|
message: tx(VALIDATE_ALL_TEXTS.nodeFailure, {
|
|
@@ -2702,7 +2706,7 @@ function collectFrontmatterBaseFindings(node, out) {
|
|
|
2702
2706
|
if (isMissingStringField(fm, "description")) missing.push("description");
|
|
2703
2707
|
if (missing.length === 0) return;
|
|
2704
2708
|
out.push({
|
|
2705
|
-
analyzerId:
|
|
2709
|
+
analyzerId: ID20,
|
|
2706
2710
|
// `warn` (not `error`) so the default `sm scan` exit code stays
|
|
2707
2711
|
// 0 even when nodes are missing frontmatter base fields. Strict
|
|
2708
2712
|
// mode (`sm scan --strict`) still escalates to exit 1. Matches
|
|
@@ -2724,7 +2728,7 @@ function collectLinkFindings(v, link2, out) {
|
|
|
2724
2728
|
const result = v.validate("link", toLinkForSchema(link2));
|
|
2725
2729
|
if (result.ok) return;
|
|
2726
2730
|
out.push({
|
|
2727
|
-
analyzerId:
|
|
2731
|
+
analyzerId: ID20,
|
|
2728
2732
|
severity: "error",
|
|
2729
2733
|
nodeIds: [link2.source],
|
|
2730
2734
|
message: tx(VALIDATE_ALL_TEXTS.linkFailure, {
|
|
@@ -2792,13 +2796,13 @@ var ASCII_FORMATTER_TEXTS = {
|
|
|
2792
2796
|
};
|
|
2793
2797
|
|
|
2794
2798
|
// plugins/core/formatters/ascii/index.ts
|
|
2795
|
-
var
|
|
2799
|
+
var ID21 = "ascii";
|
|
2796
2800
|
var KIND_ORDER = ["agent", "command", "skill", "markdown"];
|
|
2797
2801
|
var asciiFormatter = {
|
|
2798
|
-
id:
|
|
2802
|
+
id: ID21,
|
|
2799
2803
|
pluginId: "core",
|
|
2800
2804
|
kind: "formatter",
|
|
2801
|
-
formatId:
|
|
2805
|
+
formatId: ID21,
|
|
2802
2806
|
version: "1.0.0",
|
|
2803
2807
|
description: "Renders the scan as plain text, grouped by kind, arrows, and issues. Used by `sm scan --format=ascii`.",
|
|
2804
2808
|
// ASCII tree formatter, header + per-kind sections + per-issue
|
|
@@ -2893,14 +2897,14 @@ function renderSection(out, kind, group) {
|
|
|
2893
2897
|
}
|
|
2894
2898
|
|
|
2895
2899
|
// plugins/core/formatters/json/index.ts
|
|
2896
|
-
var
|
|
2900
|
+
var ID22 = "json";
|
|
2897
2901
|
var jsonFormatter = {
|
|
2898
|
-
id:
|
|
2902
|
+
id: ID22,
|
|
2899
2903
|
pluginId: "core",
|
|
2900
2904
|
kind: "formatter",
|
|
2901
2905
|
version: "1.0.0",
|
|
2902
2906
|
description: "Renders the persisted scan as JSON (conforms to `scan-result.schema.json` when the full ScanResult is available). Used by `sm graph --format json` and `GET /api/graph?format=json`.",
|
|
2903
|
-
formatId:
|
|
2907
|
+
formatId: ID22,
|
|
2904
2908
|
format(ctx) {
|
|
2905
2909
|
if (ctx.scanResult !== void 0) {
|
|
2906
2910
|
return JSON.stringify(ctx.scanResult);
|
|
@@ -3039,10 +3043,10 @@ function resolveSpecRoot2() {
|
|
|
3039
3043
|
}
|
|
3040
3044
|
|
|
3041
3045
|
// plugins/core/actions/bump/index.ts
|
|
3042
|
-
var
|
|
3046
|
+
var ID23 = "bump";
|
|
3043
3047
|
var PLUGIN_ID = "core";
|
|
3044
3048
|
var bumpAction = {
|
|
3045
|
-
id:
|
|
3049
|
+
id: ID23,
|
|
3046
3050
|
pluginId: PLUGIN_ID,
|
|
3047
3051
|
kind: "action",
|
|
3048
3052
|
version: "1.0.0",
|
|
@@ -3101,10 +3105,10 @@ function pickCurrentVersion(overlay) {
|
|
|
3101
3105
|
}
|
|
3102
3106
|
|
|
3103
3107
|
// plugins/core/actions/mark-superseded/index.ts
|
|
3104
|
-
var
|
|
3108
|
+
var ID24 = "mark-superseded";
|
|
3105
3109
|
var PLUGIN_ID2 = "core";
|
|
3106
3110
|
var markSupersededAction = {
|
|
3107
|
-
id:
|
|
3111
|
+
id: ID24,
|
|
3108
3112
|
pluginId: PLUGIN_ID2,
|
|
3109
3113
|
kind: "action",
|
|
3110
3114
|
version: "0.0.0",
|
|
@@ -3214,7 +3218,7 @@ var UPDATE_CHECK_TEXTS = {
|
|
|
3214
3218
|
// package.json
|
|
3215
3219
|
var package_default = {
|
|
3216
3220
|
name: "@skill-map/cli",
|
|
3217
|
-
version: "0.
|
|
3221
|
+
version: "0.36.0",
|
|
3218
3222
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
3219
3223
|
license: "MIT",
|
|
3220
3224
|
type: "module",
|
|
@@ -3593,7 +3597,7 @@ var updateCheckHook = {
|
|
|
3593
3597
|
var claudeProvider2 = { ...claudeProvider, pluginId: "claude" };
|
|
3594
3598
|
var atDirectiveExtractor2 = { ...atDirectiveExtractor, pluginId: "claude" };
|
|
3595
3599
|
var slashExtractor2 = { ...slashExtractor, pluginId: "claude" };
|
|
3596
|
-
var
|
|
3600
|
+
var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity" };
|
|
3597
3601
|
var openaiProvider2 = { ...openaiProvider, pluginId: "openai" };
|
|
3598
3602
|
var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills" };
|
|
3599
3603
|
var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core" };
|
|
@@ -3609,6 +3613,7 @@ var contributionOrphanAnalyzer2 = { ...contributionOrphanAnalyzer, pluginId: "co
|
|
|
3609
3613
|
var jobOrphanFileAnalyzer2 = { ...jobOrphanFileAnalyzer, pluginId: "core" };
|
|
3610
3614
|
var linkConflictAnalyzer2 = { ...linkConflictAnalyzer, pluginId: "core" };
|
|
3611
3615
|
var linkCountsAnalyzer2 = { ...linkCountsAnalyzer, pluginId: "core" };
|
|
3616
|
+
var reservedNameAnalyzer2 = { ...reservedNameAnalyzer, pluginId: "core" };
|
|
3612
3617
|
var stabilityAnalyzer2 = { ...stabilityAnalyzer, pluginId: "core" };
|
|
3613
3618
|
var supersededAnalyzer2 = { ...supersededAnalyzer, pluginId: "core" };
|
|
3614
3619
|
var triggerCollisionAnalyzer2 = { ...triggerCollisionAnalyzer, pluginId: "core" };
|
|
@@ -3631,11 +3636,11 @@ var builtInBundles = [
|
|
|
3631
3636
|
]
|
|
3632
3637
|
},
|
|
3633
3638
|
{
|
|
3634
|
-
id: "
|
|
3639
|
+
id: "antigravity",
|
|
3635
3640
|
granularity: "bundle",
|
|
3636
|
-
description: "
|
|
3641
|
+
description: "Google Antigravity CLI platform integration (released 2026-05-19, replaces the retired Gemini CLI). Antigravity adopted the open-standard `.agents/` layout, so skills are classified by the neutral `agent-skills` Provider; this bundle contributes lens identity + a reserved-name seed catalog for future Antigravity built-in invocables.",
|
|
3637
3642
|
extensions: [
|
|
3638
|
-
|
|
3643
|
+
antigravityProvider2
|
|
3639
3644
|
]
|
|
3640
3645
|
},
|
|
3641
3646
|
{
|
|
@@ -3672,6 +3677,7 @@ var builtInBundles = [
|
|
|
3672
3677
|
jobOrphanFileAnalyzer2,
|
|
3673
3678
|
linkConflictAnalyzer2,
|
|
3674
3679
|
linkCountsAnalyzer2,
|
|
3680
|
+
reservedNameAnalyzer2,
|
|
3675
3681
|
stabilityAnalyzer2,
|
|
3676
3682
|
supersededAnalyzer2,
|
|
3677
3683
|
triggerCollisionAnalyzer2,
|
|
@@ -5148,7 +5154,7 @@ var AsyncMutex = class {
|
|
|
5148
5154
|
this.#locked = true;
|
|
5149
5155
|
return;
|
|
5150
5156
|
}
|
|
5151
|
-
await new Promise((
|
|
5157
|
+
await new Promise((resolve40) => this.#waiters.push(resolve40));
|
|
5152
5158
|
this.#locked = true;
|
|
5153
5159
|
}
|
|
5154
5160
|
unlock() {
|
|
@@ -9758,7 +9764,13 @@ import { existsSync as existsSync14 } from "fs";
|
|
|
9758
9764
|
import { join as join10 } from "path";
|
|
9759
9765
|
var DETECTION_RULES = [
|
|
9760
9766
|
{ providerId: "claude", marker: ".claude" },
|
|
9761
|
-
|
|
9767
|
+
// `gemini` retired 2026-05-22: Google replaced the Gemini CLI with the
|
|
9768
|
+
// Antigravity CLI (released 2026-05-19; Gemini CLI sunsets 2026-06-18).
|
|
9769
|
+
// Antigravity adopted the open-standard `.agents/` instead of a
|
|
9770
|
+
// vendor-specific directory, so detection of a Google CLI project
|
|
9771
|
+
// falls through to the universal `agent-skills` lens (`.agents/`
|
|
9772
|
+
// already classifies via that neutral provider). The lens can still
|
|
9773
|
+
// be set manually via `sm config set activeProvider antigravity`.
|
|
9762
9774
|
{ providerId: "openai", marker: ".codex" },
|
|
9763
9775
|
{ providerId: "openai", marker: "AGENTS.md" },
|
|
9764
9776
|
{ providerId: "cursor", marker: ".cursor" }
|
|
@@ -13139,7 +13151,7 @@ import { Command as Command17, Option as Option16 } from "clipanion";
|
|
|
13139
13151
|
|
|
13140
13152
|
// kernel/orchestrator/index.ts
|
|
13141
13153
|
import { existsSync as existsSync22, statSync as statSync7 } from "fs";
|
|
13142
|
-
import { isAbsolute as isAbsolute7, resolve as
|
|
13154
|
+
import { isAbsolute as isAbsolute7, resolve as resolve28 } from "path";
|
|
13143
13155
|
import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
13144
13156
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
13145
13157
|
|
|
@@ -13508,7 +13520,7 @@ function isExternalUrlLink(link2) {
|
|
|
13508
13520
|
}
|
|
13509
13521
|
|
|
13510
13522
|
// kernel/orchestrator/analyzers.ts
|
|
13511
|
-
async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sidecarRoots, annotationContributions, viewContributions, orphanJobFiles, referenceablePaths, cwd, registeredActionIds, emitter, hookDispatcher) {
|
|
13523
|
+
async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sidecarRoots, annotationContributions, viewContributions, orphanJobFiles, referenceablePaths, cwd, registeredActionIds, emitter, hookDispatcher, reservedNodePaths) {
|
|
13512
13524
|
const issues = [];
|
|
13513
13525
|
const contributions = [];
|
|
13514
13526
|
const validators = loadSchemaValidators();
|
|
@@ -13572,6 +13584,7 @@ async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sid
|
|
|
13572
13584
|
orphanJobFiles,
|
|
13573
13585
|
...referenceablePaths ? { referenceablePaths } : {},
|
|
13574
13586
|
...cwd ? { cwd } : {},
|
|
13587
|
+
...reservedNodePaths ? { reservedNodePaths } : {},
|
|
13575
13588
|
emitContribution
|
|
13576
13589
|
});
|
|
13577
13590
|
for (const issue of emitted) {
|
|
@@ -13792,15 +13805,54 @@ function classifyLinkSource(source, shortIdToQualified, cachedQualifiedIds, appl
|
|
|
13792
13805
|
return "obsolete";
|
|
13793
13806
|
}
|
|
13794
13807
|
|
|
13795
|
-
// kernel/orchestrator/
|
|
13808
|
+
// kernel/orchestrator/node-identifiers.ts
|
|
13796
13809
|
import { posix as pathPosix4 } from "path";
|
|
13810
|
+
function deriveNodeIdentifiers(node, kindDescriptor) {
|
|
13811
|
+
const sources = kindDescriptor?.identifiers;
|
|
13812
|
+
if (!sources || sources.length === 0) return [];
|
|
13813
|
+
const out = [];
|
|
13814
|
+
for (const source of sources) {
|
|
13815
|
+
const raw = readIdentifier(source, node);
|
|
13816
|
+
if (!raw) continue;
|
|
13817
|
+
const normalised = normalizeTrigger(raw);
|
|
13818
|
+
if (normalised) out.push(normalised);
|
|
13819
|
+
}
|
|
13820
|
+
return out;
|
|
13821
|
+
}
|
|
13822
|
+
function readIdentifier(source, node) {
|
|
13823
|
+
if (source === "frontmatter.name") return readFrontmatterName(node);
|
|
13824
|
+
if (source === "filename-basename") return readFilenameBasename(node);
|
|
13825
|
+
return readDirname(node);
|
|
13826
|
+
}
|
|
13827
|
+
function readFrontmatterName(node) {
|
|
13828
|
+
const raw = node.frontmatter?.["name"];
|
|
13829
|
+
if (typeof raw !== "string") return null;
|
|
13830
|
+
return raw.length > 0 ? raw : null;
|
|
13831
|
+
}
|
|
13832
|
+
function readFilenameBasename(node) {
|
|
13833
|
+
const base = pathPosix4.basename(node.path);
|
|
13834
|
+
if (!base) return null;
|
|
13835
|
+
const ext = pathPosix4.extname(base);
|
|
13836
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
13837
|
+
return stem.length > 0 ? stem : null;
|
|
13838
|
+
}
|
|
13839
|
+
function readDirname(node) {
|
|
13840
|
+
const dir = pathPosix4.dirname(node.path);
|
|
13841
|
+
if (!dir || dir === "." || dir === "/") return null;
|
|
13842
|
+
const base = pathPosix4.basename(dir);
|
|
13843
|
+
return base.length > 0 ? base : null;
|
|
13844
|
+
}
|
|
13845
|
+
|
|
13846
|
+
// kernel/orchestrator/lift-resolved-link-confidence.ts
|
|
13847
|
+
var RESERVED_TARGET_CONFIDENCE = 0.1;
|
|
13797
13848
|
function liftResolvedLinkConfidence(links, nodes, ctx) {
|
|
13798
13849
|
if (!links.some((l) => l.confidence < 1)) return;
|
|
13799
13850
|
const indexes = buildIndexes(nodes, ctx);
|
|
13800
13851
|
for (const link2 of links) {
|
|
13801
|
-
if (link2.confidence
|
|
13802
|
-
|
|
13803
|
-
|
|
13852
|
+
if (link2.confidence >= 1) continue;
|
|
13853
|
+
const resolution = resolve27(link2, indexes, ctx);
|
|
13854
|
+
if (resolution === "none") continue;
|
|
13855
|
+
link2.confidence = ctx.reservedNodePaths.has(resolution) ? RESERVED_TARGET_CONFIDENCE : 1;
|
|
13804
13856
|
}
|
|
13805
13857
|
}
|
|
13806
13858
|
function buildIndexes(nodes, ctx) {
|
|
@@ -13814,18 +13866,19 @@ function buildIndexes(nodes, ctx) {
|
|
|
13814
13866
|
}
|
|
13815
13867
|
return { byPath: byPath3, byName, nodeByPath };
|
|
13816
13868
|
}
|
|
13817
|
-
function
|
|
13818
|
-
if (indexes.byPath.has(link2.target)) return
|
|
13819
|
-
return
|
|
13869
|
+
function resolve27(link2, indexes, ctx) {
|
|
13870
|
+
if (indexes.byPath.has(link2.target)) return link2.target;
|
|
13871
|
+
return resolveByName(link2, indexes, ctx);
|
|
13820
13872
|
}
|
|
13821
|
-
function
|
|
13873
|
+
function resolveByName(link2, indexes, ctx) {
|
|
13822
13874
|
const stripped = stripTriggerSigil(link2.trigger?.normalizedTrigger);
|
|
13823
|
-
if (stripped === null) return
|
|
13875
|
+
if (stripped === null) return "none";
|
|
13824
13876
|
const candidates = indexes.byName.get(stripped);
|
|
13825
|
-
if (!candidates?.length) return
|
|
13877
|
+
if (!candidates?.length) return "none";
|
|
13826
13878
|
const allowedKinds = lookupAllowedKinds(link2, indexes, ctx);
|
|
13827
|
-
if (!allowedKinds?.length) return
|
|
13828
|
-
|
|
13879
|
+
if (!allowedKinds?.length) return "none";
|
|
13880
|
+
const winner = candidates.find((c) => allowedKinds.includes(c.kind));
|
|
13881
|
+
return winner ? winner.path : "none";
|
|
13829
13882
|
}
|
|
13830
13883
|
function lookupAllowedKinds(link2, indexes, ctx) {
|
|
13831
13884
|
const sourceNode = indexes.nodeByPath.get(link2.source);
|
|
@@ -13839,44 +13892,17 @@ function stripTriggerSigil(normalized) {
|
|
|
13839
13892
|
}
|
|
13840
13893
|
function indexNode(node, ctx, byName) {
|
|
13841
13894
|
const kindDescriptor = ctx.kindRegistry.get(kindKey(node));
|
|
13842
|
-
const
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
const
|
|
13846
|
-
if (!raw) continue;
|
|
13847
|
-
const normalized = normalizeTrigger(raw);
|
|
13848
|
-
if (!normalized) continue;
|
|
13849
|
-
const bucket = byName.get(normalized);
|
|
13895
|
+
const normalised = deriveNodeIdentifiers(node, kindDescriptor);
|
|
13896
|
+
for (const name of normalised) {
|
|
13897
|
+
const entry = { kind: node.kind, path: node.path };
|
|
13898
|
+
const bucket = byName.get(name);
|
|
13850
13899
|
if (bucket) {
|
|
13851
|
-
bucket.push(
|
|
13900
|
+
bucket.push(entry);
|
|
13852
13901
|
} else {
|
|
13853
|
-
byName.set(
|
|
13902
|
+
byName.set(name, [entry]);
|
|
13854
13903
|
}
|
|
13855
13904
|
}
|
|
13856
13905
|
}
|
|
13857
|
-
function deriveIdentifier(source, node) {
|
|
13858
|
-
if (source === "frontmatter.name") return readFrontmatterName(node);
|
|
13859
|
-
if (source === "filename-basename") return readFilenameBasename(node);
|
|
13860
|
-
return readDirname(node);
|
|
13861
|
-
}
|
|
13862
|
-
function readFrontmatterName(node) {
|
|
13863
|
-
const raw = node.frontmatter?.["name"];
|
|
13864
|
-
if (typeof raw !== "string") return null;
|
|
13865
|
-
return raw.length > 0 ? raw : null;
|
|
13866
|
-
}
|
|
13867
|
-
function readFilenameBasename(node) {
|
|
13868
|
-
const base = pathPosix4.basename(node.path);
|
|
13869
|
-
if (!base) return null;
|
|
13870
|
-
const ext = pathPosix4.extname(base);
|
|
13871
|
-
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
13872
|
-
return stem.length > 0 ? stem : null;
|
|
13873
|
-
}
|
|
13874
|
-
function readDirname(node) {
|
|
13875
|
-
const dir = pathPosix4.dirname(node.path);
|
|
13876
|
-
if (!dir || dir === "." || dir === "/") return null;
|
|
13877
|
-
const base = pathPosix4.basename(dir);
|
|
13878
|
-
return base.length > 0 ? base : null;
|
|
13879
|
-
}
|
|
13880
13906
|
function kindKey(node) {
|
|
13881
13907
|
return `${node.provider}/${node.kind}`;
|
|
13882
13908
|
}
|
|
@@ -14613,7 +14639,7 @@ async function runScanInternal(_kernel, options) {
|
|
|
14613
14639
|
pluginStores: options.pluginStores,
|
|
14614
14640
|
activeProvider: resolveActiveProviderOption(options.activeProvider, options.roots)
|
|
14615
14641
|
});
|
|
14616
|
-
const postWalkCtx = buildPostWalkTransformCtx(_kernel);
|
|
14642
|
+
const postWalkCtx = buildPostWalkTransformCtx(_kernel, walked.nodes);
|
|
14617
14643
|
walked.internalLinks = applyPostWalkTransforms(walked.internalLinks, walked.nodes, postWalkCtx);
|
|
14618
14644
|
recomputeLinkCounts(walked.nodes, walked.internalLinks);
|
|
14619
14645
|
recomputeExternalRefsCount(walked.nodes, walked.externalLinks, walked.cachedPaths);
|
|
@@ -14634,7 +14660,8 @@ async function runScanInternal(_kernel, options) {
|
|
|
14634
14660
|
options.cwd,
|
|
14635
14661
|
registeredActionIds,
|
|
14636
14662
|
emitter,
|
|
14637
|
-
hookDispatcher
|
|
14663
|
+
hookDispatcher,
|
|
14664
|
+
postWalkCtx.reservedNodePaths
|
|
14638
14665
|
);
|
|
14639
14666
|
mergeAnalyzerEmissions(walked, analyzerResult, exts.analyzers);
|
|
14640
14667
|
const issues = analyzerResult.issues;
|
|
@@ -14647,9 +14674,19 @@ async function runScanInternal(_kernel, options) {
|
|
|
14647
14674
|
await hookDispatcher.dispatch("scan.completed", scanCompletedEvent);
|
|
14648
14675
|
return buildScanReturn(walked, issues, renameOps, stats, options, setup);
|
|
14649
14676
|
}
|
|
14650
|
-
function buildPostWalkTransformCtx(kernel) {
|
|
14677
|
+
function buildPostWalkTransformCtx(kernel, nodes) {
|
|
14678
|
+
const { kindRegistry, providerResolution, reservedNamesByProviderKind } = buildProviderIndexes(kernel);
|
|
14679
|
+
const reservedNodePaths = buildReservedNodePaths(
|
|
14680
|
+
nodes,
|
|
14681
|
+
kindRegistry,
|
|
14682
|
+
reservedNamesByProviderKind
|
|
14683
|
+
);
|
|
14684
|
+
return { kindRegistry, providerResolution, reservedNodePaths };
|
|
14685
|
+
}
|
|
14686
|
+
function buildProviderIndexes(kernel) {
|
|
14651
14687
|
const kindRegistry = /* @__PURE__ */ new Map();
|
|
14652
14688
|
const providerResolution = /* @__PURE__ */ new Map();
|
|
14689
|
+
const reservedNamesByProviderKind = /* @__PURE__ */ new Map();
|
|
14653
14690
|
const providers = kernel.registry.all("provider");
|
|
14654
14691
|
for (const provider of providers) {
|
|
14655
14692
|
if (provider.kinds) {
|
|
@@ -14660,8 +14697,32 @@ function buildPostWalkTransformCtx(kernel) {
|
|
|
14660
14697
|
if (provider.resolution) {
|
|
14661
14698
|
providerResolution.set(provider.id, provider.resolution);
|
|
14662
14699
|
}
|
|
14700
|
+
if (provider.reservedNames) {
|
|
14701
|
+
indexReservedNames(provider, reservedNamesByProviderKind);
|
|
14702
|
+
}
|
|
14663
14703
|
}
|
|
14664
|
-
return { kindRegistry, providerResolution };
|
|
14704
|
+
return { kindRegistry, providerResolution, reservedNamesByProviderKind };
|
|
14705
|
+
}
|
|
14706
|
+
function indexReservedNames(provider, out) {
|
|
14707
|
+
for (const [kindName, list] of Object.entries(provider.reservedNames ?? {})) {
|
|
14708
|
+
const normalised = new Set(list.map((raw) => normalizeTrigger(raw)).filter(Boolean));
|
|
14709
|
+
if (normalised.size > 0) {
|
|
14710
|
+
out.set(`${provider.id}/${kindName}`, normalised);
|
|
14711
|
+
}
|
|
14712
|
+
}
|
|
14713
|
+
}
|
|
14714
|
+
function buildReservedNodePaths(nodes, kindRegistry, reservedNamesByProviderKind) {
|
|
14715
|
+
const out = /* @__PURE__ */ new Set();
|
|
14716
|
+
for (const node of nodes) {
|
|
14717
|
+
const key = `${node.provider}/${node.kind}`;
|
|
14718
|
+
const reservedSet = reservedNamesByProviderKind.get(key);
|
|
14719
|
+
if (!reservedSet || reservedSet.size === 0) continue;
|
|
14720
|
+
const ids = deriveNodeIdentifiers(node, kindRegistry.get(key));
|
|
14721
|
+
if (ids.some((id) => reservedSet.has(id))) {
|
|
14722
|
+
out.add(node.path);
|
|
14723
|
+
}
|
|
14724
|
+
}
|
|
14725
|
+
return out;
|
|
14665
14726
|
}
|
|
14666
14727
|
function buildScanSetup(options) {
|
|
14667
14728
|
const start = Date.now();
|
|
@@ -14754,7 +14815,7 @@ function validateRoots(roots) {
|
|
|
14754
14815
|
function resolveActiveProviderOption(optionValue, roots) {
|
|
14755
14816
|
if (optionValue !== void 0) return optionValue;
|
|
14756
14817
|
for (const root of roots) {
|
|
14757
|
-
const absRoot = isAbsolute7(root) ? root :
|
|
14818
|
+
const absRoot = isAbsolute7(root) ? root : resolve28(root);
|
|
14758
14819
|
if (!existsSync22(absRoot)) continue;
|
|
14759
14820
|
const detected = resolveActiveProvider(absRoot).resolved;
|
|
14760
14821
|
if (detected !== null) return detected;
|
|
@@ -14763,10 +14824,10 @@ function resolveActiveProviderOption(optionValue, roots) {
|
|
|
14763
14824
|
}
|
|
14764
14825
|
|
|
14765
14826
|
// kernel/scan/watcher.ts
|
|
14766
|
-
import { resolve as
|
|
14827
|
+
import { resolve as resolve29, relative as relative5, sep as sep4 } from "path";
|
|
14767
14828
|
import chokidar from "chokidar";
|
|
14768
14829
|
function createChokidarWatcher(opts) {
|
|
14769
|
-
const absRoots = opts.roots.map((r) =>
|
|
14830
|
+
const absRoots = opts.roots.map((r) => resolve29(opts.cwd, r));
|
|
14770
14831
|
const ignoreFilterOpt = opts.ignoreFilter;
|
|
14771
14832
|
const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
|
|
14772
14833
|
const ignored = getFilter ? (path) => {
|
|
@@ -14985,7 +15046,7 @@ function createKernel() {
|
|
|
14985
15046
|
|
|
14986
15047
|
// kernel/jobs/orphan-files.ts
|
|
14987
15048
|
import { readdirSync as readdirSync8, statSync as statSync8 } from "fs";
|
|
14988
|
-
import { join as join14, resolve as
|
|
15049
|
+
import { join as join14, resolve as resolve30 } from "path";
|
|
14989
15050
|
function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
14990
15051
|
let entries;
|
|
14991
15052
|
try {
|
|
@@ -15003,7 +15064,7 @@ function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
|
15003
15064
|
if (!entry.isFile()) continue;
|
|
15004
15065
|
const name = entry.name;
|
|
15005
15066
|
if (!name.endsWith(".md")) continue;
|
|
15006
|
-
const abs =
|
|
15067
|
+
const abs = resolve30(join14(jobsDir, name));
|
|
15007
15068
|
if (!referencedPaths.has(abs)) orphans.push(abs);
|
|
15008
15069
|
}
|
|
15009
15070
|
orphans.sort();
|
|
@@ -15070,12 +15131,12 @@ var SCAN_RUNNER_TEXTS = {
|
|
|
15070
15131
|
referenceWalkMissingRoot: 'scan.referencePaths: configured path "{{path}}" does not exist; skipped.',
|
|
15071
15132
|
/**
|
|
15072
15133
|
* Active-provider bootstrap: filesystem auto-detect found no
|
|
15073
|
-
* markers (`.claude/`, `.
|
|
15074
|
-
*
|
|
15075
|
-
*
|
|
15076
|
-
*
|
|
15134
|
+
* markers (`.claude/`, `.codex/`, `AGENTS.md`, `.cursor/`) anywhere
|
|
15135
|
+
* under cwd or the effective scan roots. Plain-markdown projects
|
|
15136
|
+
* keep scanning fine; provider-specific extractors silently no-op
|
|
15137
|
+
* for this scan.
|
|
15077
15138
|
*/
|
|
15078
|
-
activeProviderNoMarkerWarning: "No provider markers detected (.claude/, .
|
|
15139
|
+
activeProviderNoMarkerWarning: "No provider markers detected (.claude/, .codex/, AGENTS.md, .cursor/). Scanning as universal markdown only; provider-specific link types (e.g. claude @-directives, /-commands) will not appear in the graph. Set `activeProvider` in .skill-map/settings.json or install a provider plugin to enable them.",
|
|
15079
15140
|
/**
|
|
15080
15141
|
* Active-provider bootstrap: filesystem auto-detect found exactly
|
|
15081
15142
|
* one marker and persisted the detected id to project settings.
|
|
@@ -15122,7 +15183,7 @@ function resolveScanRoots(inputs) {
|
|
|
15122
15183
|
// core/runtime/reference-paths-walker.ts
|
|
15123
15184
|
import { readdirSync as readdirSync9, statSync as statSync9 } from "fs";
|
|
15124
15185
|
import { homedir as osHomedir2 } from "os";
|
|
15125
|
-
import { isAbsolute as isAbsolute8, join as join15, resolve as
|
|
15186
|
+
import { isAbsolute as isAbsolute8, join as join15, resolve as resolve31 } from "path";
|
|
15126
15187
|
var REFERENCE_WALK_MAX_FILES = 5e4;
|
|
15127
15188
|
var SKIPPED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
15128
15189
|
"node_modules",
|
|
@@ -15130,10 +15191,10 @@ var SKIPPED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
|
15130
15191
|
SKILL_MAP_DIR
|
|
15131
15192
|
]);
|
|
15132
15193
|
function resolveScanPath(raw, cwd) {
|
|
15133
|
-
if (raw.startsWith("~/")) return
|
|
15134
|
-
if (raw === "~") return
|
|
15135
|
-
if (isAbsolute8(raw)) return
|
|
15136
|
-
return
|
|
15194
|
+
if (raw.startsWith("~/")) return resolve31(join15(osHomedir2(), raw.slice(2)));
|
|
15195
|
+
if (raw === "~") return resolve31(osHomedir2());
|
|
15196
|
+
if (isAbsolute8(raw)) return resolve31(raw);
|
|
15197
|
+
return resolve31(cwd, raw);
|
|
15137
15198
|
}
|
|
15138
15199
|
function walkReferencePaths(rawRoots, cwd) {
|
|
15139
15200
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -17427,9 +17488,9 @@ var PLUGINS_TEXTS = {
|
|
|
17427
17488
|
};
|
|
17428
17489
|
|
|
17429
17490
|
// cli/commands/plugins/shared.ts
|
|
17430
|
-
import { resolve as
|
|
17491
|
+
import { resolve as resolve32 } from "path";
|
|
17431
17492
|
function resolveSearchPaths2(opts, cwd) {
|
|
17432
|
-
if (opts.pluginDir) return [
|
|
17493
|
+
if (opts.pluginDir) return [resolve32(opts.pluginDir)];
|
|
17433
17494
|
return [defaultProjectPluginsDir({ cwd })];
|
|
17434
17495
|
}
|
|
17435
17496
|
async function buildResolver() {
|
|
@@ -18451,7 +18512,7 @@ var PluginsEnableCommand = class extends TogglePluginsBase {
|
|
|
18451
18512
|
baseline.
|
|
18452
18513
|
|
|
18453
18514
|
Accepts one or more ids in one call, e.g.
|
|
18454
|
-
'sm plugins enable claude
|
|
18515
|
+
'sm plugins enable claude antigravity openai'. Batches are
|
|
18455
18516
|
all-or-nothing: a single unknown / mismatched id aborts before
|
|
18456
18517
|
any write. Repeated ids are deduped. Locked plugins inside a
|
|
18457
18518
|
batch are silently skipped.
|
|
@@ -18479,7 +18540,7 @@ var PluginsDisableCommand = class extends TogglePluginsBase {
|
|
|
18479
18540
|
will not run them.
|
|
18480
18541
|
|
|
18481
18542
|
Accepts one or more ids in one call, e.g.
|
|
18482
|
-
'sm plugins disable
|
|
18543
|
+
'sm plugins disable antigravity openai agent-skills'. Batches are
|
|
18483
18544
|
all-or-nothing: a single unknown / mismatched id aborts before
|
|
18484
18545
|
any write. Repeated ids are deduped. Locked plugins inside a
|
|
18485
18546
|
batch are silently skipped.
|
|
@@ -18589,7 +18650,7 @@ function resolveBareToggle(id, catalogue, verb, ansi) {
|
|
|
18589
18650
|
|
|
18590
18651
|
// cli/commands/plugins/create.ts
|
|
18591
18652
|
import { existsSync as existsSync23, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
18592
|
-
import { join as join18, resolve as
|
|
18653
|
+
import { join as join18, resolve as resolve33 } from "path";
|
|
18593
18654
|
import { Command as Command26, Option as Option25 } from "clipanion";
|
|
18594
18655
|
var PluginsCreateCommand = class extends SmCommand {
|
|
18595
18656
|
static paths = [["plugins", "create"]];
|
|
@@ -18615,7 +18676,7 @@ var PluginsCreateCommand = class extends SmCommand {
|
|
|
18615
18676
|
}
|
|
18616
18677
|
const ctx = defaultRuntimeContext();
|
|
18617
18678
|
const baseDir = defaultProjectPluginsDir(ctx);
|
|
18618
|
-
const targetDir = this.at ?
|
|
18679
|
+
const targetDir = this.at ? resolve33(this.at) : join18(baseDir, this.pluginId);
|
|
18619
18680
|
if (existsSync23(targetDir) && !this.force) {
|
|
18620
18681
|
this.printer.error(
|
|
18621
18682
|
tx(PLUGINS_TEXTS.createRefuseOverwrite, {
|
|
@@ -18856,7 +18917,7 @@ var PLUGIN_COMMANDS = [
|
|
|
18856
18917
|
|
|
18857
18918
|
// cli/commands/refresh.ts
|
|
18858
18919
|
import { readFile as readFile3 } from "fs/promises";
|
|
18859
|
-
import { resolve as
|
|
18920
|
+
import { resolve as resolve34 } from "path";
|
|
18860
18921
|
import { Command as Command29, Option as Option27 } from "clipanion";
|
|
18861
18922
|
|
|
18862
18923
|
// cli/i18n/refresh.texts.ts
|
|
@@ -19140,7 +19201,7 @@ var RefreshCommand = class extends SmCommand {
|
|
|
19140
19201
|
let body;
|
|
19141
19202
|
try {
|
|
19142
19203
|
assertContained(cwd, node.path);
|
|
19143
|
-
const raw = await readFile3(
|
|
19204
|
+
const raw = await readFile3(resolve34(cwd, node.path), "utf8");
|
|
19144
19205
|
body = stripFrontmatterFence(raw);
|
|
19145
19206
|
} catch (err) {
|
|
19146
19207
|
if (!this.json) {
|
|
@@ -19882,7 +19943,7 @@ var ScanCommand = class extends SmCommand {
|
|
|
19882
19943
|
description: "Long-running mode: watch the roots and trigger an incremental scan after each debounced batch of filesystem events. Alias of `sm watch`."
|
|
19883
19944
|
});
|
|
19884
19945
|
yes = Option29.Boolean("--yes", false, {
|
|
19885
|
-
description: "Non-interactive mode for ambiguous activeProvider auto-detect. With `--yes`, multiple provider markers (.claude/, .
|
|
19946
|
+
description: "Non-interactive mode for ambiguous activeProvider auto-detect. With `--yes`, multiple provider markers (.claude/, .codex/, AGENTS.md, .cursor/) under the scan tree exit non-zero instead of prompting the operator. Set the lens manually via `sm config set activeProvider <id>` and re-run."
|
|
19886
19947
|
});
|
|
19887
19948
|
// Each branch in the orchestrator maps to one validation gate
|
|
19888
19949
|
// (--watch alias / --changed mutex / -g mutex / dispatch).
|
|
@@ -21874,10 +21935,10 @@ import { HTTPException as HTTPException10 } from "hono/http-exception";
|
|
|
21874
21935
|
|
|
21875
21936
|
// server/util/skillmapignore-io.ts
|
|
21876
21937
|
import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync4 } from "fs";
|
|
21877
|
-
import { resolve as
|
|
21938
|
+
import { resolve as resolve35 } from "path";
|
|
21878
21939
|
var IGNORE_FILENAME2 = ".skillmapignore";
|
|
21879
21940
|
function readPatterns(cwd) {
|
|
21880
|
-
const path =
|
|
21941
|
+
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
21881
21942
|
if (!existsSync26(path)) return [];
|
|
21882
21943
|
let raw;
|
|
21883
21944
|
try {
|
|
@@ -21888,7 +21949,7 @@ function readPatterns(cwd) {
|
|
|
21888
21949
|
return raw.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#"));
|
|
21889
21950
|
}
|
|
21890
21951
|
function writePatterns(cwd, nextPatterns) {
|
|
21891
|
-
const path =
|
|
21952
|
+
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
21892
21953
|
const prior = existsSync26(path) ? safeRead(path) : "";
|
|
21893
21954
|
const content = buildContent(prior, nextPatterns);
|
|
21894
21955
|
writeFileSync4(path, content, "utf8");
|
|
@@ -22309,14 +22370,14 @@ async function withScanMutex(fn) {
|
|
|
22309
22370
|
if (inFlight !== null) {
|
|
22310
22371
|
throw new ScanBusyError();
|
|
22311
22372
|
}
|
|
22312
|
-
let
|
|
22373
|
+
let resolve40;
|
|
22313
22374
|
inFlight = new Promise((r) => {
|
|
22314
|
-
|
|
22375
|
+
resolve40 = r;
|
|
22315
22376
|
});
|
|
22316
22377
|
try {
|
|
22317
22378
|
return await fn();
|
|
22318
22379
|
} finally {
|
|
22319
|
-
|
|
22380
|
+
resolve40();
|
|
22320
22381
|
inFlight = null;
|
|
22321
22382
|
}
|
|
22322
22383
|
}
|
|
@@ -22628,7 +22689,7 @@ function emptyScanResult() {
|
|
|
22628
22689
|
|
|
22629
22690
|
// server/routes/sidecar.ts
|
|
22630
22691
|
import { HTTPException as HTTPException14 } from "hono/http-exception";
|
|
22631
|
-
import { resolve as
|
|
22692
|
+
import { resolve as resolve36 } from "path";
|
|
22632
22693
|
var STATUS_FRESH = "fresh";
|
|
22633
22694
|
var ENVELOPE_KIND2 = "sidecar.bumped";
|
|
22634
22695
|
var BUMP_BODY_SCHEMA = {
|
|
@@ -22662,7 +22723,7 @@ function registerSidecarRoutes(app, deps) {
|
|
|
22662
22723
|
let absPath;
|
|
22663
22724
|
try {
|
|
22664
22725
|
assertContained(deps.runtimeContext.cwd, node.path);
|
|
22665
|
-
absPath =
|
|
22726
|
+
absPath = resolve36(deps.runtimeContext.cwd, node.path);
|
|
22666
22727
|
} catch (err) {
|
|
22667
22728
|
throw new HTTPException14(500, { message: formatErrorMessage(err) });
|
|
22668
22729
|
}
|
|
@@ -23414,7 +23475,7 @@ function validateNoUi(noUi, uiDist) {
|
|
|
23414
23475
|
|
|
23415
23476
|
// server/paths.ts
|
|
23416
23477
|
import { existsSync as existsSync29, statSync as statSync11 } from "fs";
|
|
23417
|
-
import { dirname as dirname18, isAbsolute as isAbsolute11, join as join20, resolve as
|
|
23478
|
+
import { dirname as dirname18, isAbsolute as isAbsolute11, join as join20, resolve as resolve37 } from "path";
|
|
23418
23479
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23419
23480
|
var DEFAULT_UI_REL = join20("ui", "dist", "ui", "browser");
|
|
23420
23481
|
var PACKAGE_UI_REL = "ui";
|
|
@@ -23425,7 +23486,7 @@ function resolveDefaultUiDist(ctx) {
|
|
|
23425
23486
|
return walkUpForUi(ctx.cwd);
|
|
23426
23487
|
}
|
|
23427
23488
|
function resolveExplicitUiDist(ctx, raw) {
|
|
23428
|
-
return isAbsolute11(raw) ? raw :
|
|
23489
|
+
return isAbsolute11(raw) ? raw : resolve37(ctx.cwd, raw);
|
|
23429
23490
|
}
|
|
23430
23491
|
function isUiBundleDir(path) {
|
|
23431
23492
|
if (!existsSync29(path)) return false;
|
|
@@ -23459,7 +23520,7 @@ function resolvePackageBundledUiFrom(here) {
|
|
|
23459
23520
|
return null;
|
|
23460
23521
|
}
|
|
23461
23522
|
function walkUpForUi(startDir) {
|
|
23462
|
-
let current =
|
|
23523
|
+
let current = resolve37(startDir);
|
|
23463
23524
|
for (let i = 0; i < 64; i++) {
|
|
23464
23525
|
const candidate = join20(current, DEFAULT_UI_REL);
|
|
23465
23526
|
if (isUiBundleDir(candidate)) return candidate;
|
|
@@ -24399,7 +24460,7 @@ function rankConfidenceForGrouping(c) {
|
|
|
24399
24460
|
|
|
24400
24461
|
// cli/commands/sidecar.ts
|
|
24401
24462
|
import { existsSync as existsSync31, unlinkSync as unlinkSync2 } from "fs";
|
|
24402
|
-
import { resolve as
|
|
24463
|
+
import { resolve as resolve38 } from "path";
|
|
24403
24464
|
import { Command as Command35, Option as Option33 } from "clipanion";
|
|
24404
24465
|
|
|
24405
24466
|
// cli/i18n/sidecar.texts.ts
|
|
@@ -24550,7 +24611,7 @@ var SidecarRefreshCommand = class extends SmCommand {
|
|
|
24550
24611
|
let absPath;
|
|
24551
24612
|
try {
|
|
24552
24613
|
assertContained(ctx.cwd, node.path);
|
|
24553
|
-
absPath =
|
|
24614
|
+
absPath = resolve38(ctx.cwd, node.path);
|
|
24554
24615
|
} catch (err) {
|
|
24555
24616
|
this.printer.error(
|
|
24556
24617
|
tx(SIDECAR_TEXTS.refreshFailed, { glyph: errGlyph, message: formatErrorMessage(err) })
|
|
@@ -24831,7 +24892,7 @@ var SidecarAnnotateCommand = class extends SmCommand {
|
|
|
24831
24892
|
let absPath;
|
|
24832
24893
|
try {
|
|
24833
24894
|
assertContained(ctx.cwd, node.path);
|
|
24834
|
-
absPath =
|
|
24895
|
+
absPath = resolve38(ctx.cwd, node.path);
|
|
24835
24896
|
} catch (err) {
|
|
24836
24897
|
this.printer.error(
|
|
24837
24898
|
tx(SIDECAR_TEXTS.annotateFailed, { glyph: errGlyph, message: formatErrorMessage(err) })
|
|
@@ -25080,7 +25141,7 @@ var STUB_COMMANDS = [
|
|
|
25080
25141
|
|
|
25081
25142
|
// cli/commands/tutorial.ts
|
|
25082
25143
|
import { cpSync as cpSync2, existsSync as existsSync32, mkdirSync as mkdirSync7, rmSync as rmSync2, statSync as statSync12 } from "fs";
|
|
25083
|
-
import { dirname as dirname19, join as join21, resolve as
|
|
25144
|
+
import { dirname as dirname19, join as join21, resolve as resolve39 } from "path";
|
|
25084
25145
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
25085
25146
|
import { Command as Command37, Option as Option35 } from "clipanion";
|
|
25086
25147
|
|
|
@@ -25254,11 +25315,11 @@ function resolveSkillSourceDir(variant) {
|
|
|
25254
25315
|
const here = dirname19(fileURLToPath6(import.meta.url));
|
|
25255
25316
|
const candidates = [
|
|
25256
25317
|
// dev: src/cli/commands/ → repo-root .claude/skills/<slug>/
|
|
25257
|
-
|
|
25318
|
+
resolve39(here, "../../..", spec.sourceDir),
|
|
25258
25319
|
// bundled: dist/cli.js → dist/cli/tutorial/<slug> (sibling)
|
|
25259
|
-
|
|
25320
|
+
resolve39(here, "cli/tutorial", spec.slug),
|
|
25260
25321
|
// bundled fallback: any-depth → cli/tutorial/<slug>
|
|
25261
|
-
|
|
25322
|
+
resolve39(here, "../cli/tutorial", spec.slug)
|
|
25262
25323
|
];
|
|
25263
25324
|
for (const candidate of candidates) {
|
|
25264
25325
|
if (existsSync32(candidate) && statSync12(candidate).isDirectory()) {
|