@skill-map/cli 0.34.1 → 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 +457 -243
- package/dist/cli.js.map +1 -1
- package/dist/index.js +178 -48
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +120 -3
- package/dist/kernel/index.js +178 -48
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/{chunk-K3VXQ5PI.js → chunk-GQ5YNA5Q.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/ui/{main-OQDTVVQA.js → main-MGFSWAOX.js} +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -470,7 +470,13 @@ var claudeProvider = {
|
|
|
470
470
|
color: "#3b82f6",
|
|
471
471
|
colorDark: "#60a5fa",
|
|
472
472
|
icon: { kind: "pi", id: "pi-user" }
|
|
473
|
-
}
|
|
473
|
+
},
|
|
474
|
+
// `frontmatter.name` is the documented canonical identifier
|
|
475
|
+
// (https://code.claude.com/docs/en/agents.md); `filename-basename`
|
|
476
|
+
// is a graceful fallback for agents authored without an explicit
|
|
477
|
+
// `name:` field, the file at `.claude/agents/<id>.md` resolves
|
|
478
|
+
// `@<id>` even when frontmatter is partial.
|
|
479
|
+
identifiers: ["frontmatter.name", "filename-basename"]
|
|
474
480
|
},
|
|
475
481
|
command: {
|
|
476
482
|
schema: "./schemas/command.schema.json",
|
|
@@ -483,7 +489,12 @@ var claudeProvider = {
|
|
|
483
489
|
kind: "svg",
|
|
484
490
|
path: "M4 17 L10 11 L4 5 M12 19 L20 19"
|
|
485
491
|
}
|
|
486
|
-
}
|
|
492
|
+
},
|
|
493
|
+
// Commands share Anthropic's documented merger with skills
|
|
494
|
+
// (skills.md), so the same dual-source applies: explicit
|
|
495
|
+
// `frontmatter.name` first, filename basename fallback for
|
|
496
|
+
// `.claude/commands/<name>.md`.
|
|
497
|
+
identifiers: ["frontmatter.name", "filename-basename"]
|
|
487
498
|
},
|
|
488
499
|
skill: {
|
|
489
500
|
schema: "./schemas/skill.schema.json",
|
|
@@ -493,7 +504,13 @@ var claudeProvider = {
|
|
|
493
504
|
color: "#10b981",
|
|
494
505
|
colorDark: "#34d399",
|
|
495
506
|
icon: { kind: "pi", id: "pi-bolt" }
|
|
496
|
-
}
|
|
507
|
+
},
|
|
508
|
+
// Anthropic explicitly documents the directory name as the
|
|
509
|
+
// canonical identifier for skills (skills.md: "The directory name
|
|
510
|
+
// becomes the command you type"). `frontmatter.name` is an
|
|
511
|
+
// optional override; when absent, the dirname between
|
|
512
|
+
// `.claude/skills/` and `/SKILL.md` is the invocation handle.
|
|
513
|
+
identifiers: ["frontmatter.name", "dirname"]
|
|
497
514
|
},
|
|
498
515
|
/**
|
|
499
516
|
* Phase 5 of the active-lens migration: MCP servers surface as
|
|
@@ -518,9 +535,81 @@ var claudeProvider = {
|
|
|
518
535
|
color: "#8b5cf6",
|
|
519
536
|
colorDark: "#a78bfa",
|
|
520
537
|
icon: { kind: "pi", id: "pi-server" }
|
|
521
|
-
}
|
|
538
|
+
},
|
|
539
|
+
// MCP nodes are virtual (`mcp://<server>`), no filesystem path
|
|
540
|
+
// and no Claude invocation surface (mentions / slashes don't
|
|
541
|
+
// resolve to MCPs). `frontmatter.name` is set by the
|
|
542
|
+
// `core/mcp-tools` extractor at emission so the index stays
|
|
543
|
+
// consistent if a future link.kind ever targets MCPs by name.
|
|
544
|
+
identifiers: ["frontmatter.name"]
|
|
522
545
|
}
|
|
523
546
|
},
|
|
547
|
+
// Strict resolution matrix consumed by `liftResolvedLinkConfidence`:
|
|
548
|
+
// an `@<name>` mention resolves to an agent only; a `/<name>` slash
|
|
549
|
+
// resolves to a command OR skill (Anthropic merged the two surfaces
|
|
550
|
+
// per skills.md). MCP nodes are not invocable through either
|
|
551
|
+
// mention or slash, so they intentionally do not appear here.
|
|
552
|
+
resolution: {
|
|
553
|
+
mentions: ["agent"],
|
|
554
|
+
invokes: ["command", "skill"]
|
|
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
|
+
},
|
|
524
613
|
// Auxiliary schemas the per-kind schemas $ref by $id. AJV needs them
|
|
525
614
|
// registered via addSchema BEFORE the per-kind schemas compile, so the
|
|
526
615
|
// validator builder pre-registers them. `skill-base.schema.json` is the
|
|
@@ -605,7 +694,7 @@ var atDirectiveExtractor = {
|
|
|
605
694
|
pluginId: "claude",
|
|
606
695
|
kind: "extractor",
|
|
607
696
|
version: "1.0.0",
|
|
608
|
-
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.",
|
|
609
698
|
scope: "body",
|
|
610
699
|
precondition: { provider: ["claude"] },
|
|
611
700
|
extract(ctx) {
|
|
@@ -673,7 +762,7 @@ var slashExtractor = {
|
|
|
673
762
|
pluginId: "claude",
|
|
674
763
|
kind: "extractor",
|
|
675
764
|
version: "1.0.0",
|
|
676
|
-
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.",
|
|
677
766
|
scope: "body",
|
|
678
767
|
precondition: { provider: ["claude"] },
|
|
679
768
|
extract(ctx) {
|
|
@@ -706,126 +795,40 @@ var slashExtractor = {
|
|
|
706
795
|
}
|
|
707
796
|
};
|
|
708
797
|
|
|
709
|
-
// plugins/
|
|
710
|
-
var
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
title: "FrontmatterGeminiAgent",
|
|
714
|
-
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).",
|
|
715
|
-
allOf: [
|
|
716
|
-
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
717
|
-
],
|
|
718
|
-
type: "object",
|
|
719
|
-
additionalProperties: true,
|
|
720
|
-
properties: {
|
|
721
|
-
kind: {
|
|
722
|
-
type: "string",
|
|
723
|
-
enum: ["local", "remote"],
|
|
724
|
-
default: "local",
|
|
725
|
-
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/)."
|
|
726
|
-
},
|
|
727
|
-
tools: {
|
|
728
|
-
type: "array",
|
|
729
|
-
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.",
|
|
730
|
-
items: { type: "string" }
|
|
731
|
-
},
|
|
732
|
-
mcpServers: {
|
|
733
|
-
type: "object",
|
|
734
|
-
additionalProperties: true,
|
|
735
|
-
description: "Inline MCP server configuration isolated to this subagent. Shape is platform-defined; preserved as an opaque object."
|
|
736
|
-
},
|
|
737
|
-
model: {
|
|
738
|
-
type: "string",
|
|
739
|
-
description: "Model id override (e.g. `gemini-3-flash-preview`). When omitted, inherits from the parent session."
|
|
740
|
-
},
|
|
741
|
-
temperature: {
|
|
742
|
-
type: "number",
|
|
743
|
-
minimum: 0,
|
|
744
|
-
maximum: 2,
|
|
745
|
-
default: 1,
|
|
746
|
-
description: "Model sampling temperature. Range 0.0\u20132.0 per Google docs."
|
|
747
|
-
},
|
|
748
|
-
max_turns: {
|
|
749
|
-
type: "integer",
|
|
750
|
-
minimum: 1,
|
|
751
|
-
default: 30,
|
|
752
|
-
description: "Hard cap on conversation turns before the subagent must return."
|
|
753
|
-
},
|
|
754
|
-
timeout_mins: {
|
|
755
|
-
type: "integer",
|
|
756
|
-
minimum: 1,
|
|
757
|
-
default: 10,
|
|
758
|
-
description: "Maximum execution duration in minutes."
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
|
|
763
|
-
// plugins/gemini/providers/gemini/schemas/skill.schema.json
|
|
764
|
-
var skill_schema_default2 = {
|
|
765
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
766
|
-
$id: "https://skill-map.dev/providers/gemini/v1/frontmatter/skill.schema.json",
|
|
767
|
-
title: "FrontmatterGeminiSkill",
|
|
768
|
-
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.",
|
|
769
|
-
allOf: [
|
|
770
|
-
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
771
|
-
],
|
|
772
|
-
type: "object",
|
|
773
|
-
additionalProperties: true,
|
|
774
|
-
properties: {}
|
|
775
|
-
};
|
|
776
|
-
|
|
777
|
-
// plugins/gemini/providers/gemini/index.ts
|
|
778
|
-
var geminiProvider = {
|
|
779
|
-
id: "gemini",
|
|
780
|
-
pluginId: "gemini",
|
|
798
|
+
// plugins/antigravity/providers/antigravity/index.ts
|
|
799
|
+
var antigravityProvider = {
|
|
800
|
+
id: "antigravity",
|
|
801
|
+
pluginId: "antigravity",
|
|
781
802
|
kind: "provider",
|
|
782
803
|
version: "1.0.0",
|
|
783
|
-
description: "
|
|
784
|
-
read:
|
|
785
|
-
//
|
|
786
|
-
//
|
|
787
|
-
//
|
|
788
|
-
//
|
|
789
|
-
|
|
790
|
-
//
|
|
791
|
-
//
|
|
792
|
-
|
|
793
|
-
// color + icon as Claude, etc. The declaration STAYS per-Provider (the
|
|
794
|
-
// shape allows divergence the day a Provider wants its own identity for
|
|
795
|
-
// a kind), but today the values mirror Claude so the visual vocabulary
|
|
796
|
-
// is uniform regardless of where a node was sourced from.
|
|
797
|
-
kinds: {
|
|
798
|
-
agent: {
|
|
799
|
-
schema: "./schemas/agent.schema.json",
|
|
800
|
-
schemaJson: agent_schema_default2,
|
|
801
|
-
ui: {
|
|
802
|
-
label: "Agents",
|
|
803
|
-
color: "#3b82f6",
|
|
804
|
-
colorDark: "#60a5fa",
|
|
805
|
-
icon: { kind: "pi", id: "pi-user" }
|
|
806
|
-
}
|
|
807
|
-
},
|
|
808
|
-
skill: {
|
|
809
|
-
schema: "./schemas/skill.schema.json",
|
|
810
|
-
schemaJson: skill_schema_default2,
|
|
811
|
-
ui: {
|
|
812
|
-
label: "Skills",
|
|
813
|
-
color: "#10b981",
|
|
814
|
-
colorDark: "#34d399",
|
|
815
|
-
icon: { kind: "pi", id: "pi-bolt" }
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
},
|
|
819
|
-
classify(path) {
|
|
820
|
-
const lower = path.toLowerCase();
|
|
821
|
-
if (lower.startsWith(".gemini/agents/")) return "agent";
|
|
822
|
-
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() {
|
|
823
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"]
|
|
824
827
|
}
|
|
825
828
|
};
|
|
826
829
|
|
|
827
830
|
// plugins/openai/providers/openai/schemas/agent.schema.json
|
|
828
|
-
var
|
|
831
|
+
var agent_schema_default2 = {
|
|
829
832
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
830
833
|
$id: "https://skill-map.dev/providers/openai/v1/frontmatter/agent.schema.json",
|
|
831
834
|
title: "FrontmatterCodexAgent",
|
|
@@ -887,16 +890,27 @@ var openaiProvider = {
|
|
|
887
890
|
kinds: {
|
|
888
891
|
agent: {
|
|
889
892
|
schema: "./schemas/agent.schema.json",
|
|
890
|
-
schemaJson:
|
|
893
|
+
schemaJson: agent_schema_default2,
|
|
891
894
|
ui: {
|
|
892
895
|
label: "Codex agents",
|
|
893
|
-
// Codex green; distinct from claude
|
|
896
|
+
// Codex green; distinct from the claude palette.
|
|
894
897
|
color: "#22c55e",
|
|
895
898
|
colorDark: "#4ade80",
|
|
896
899
|
icon: { kind: "pi", id: "pi-bolt" }
|
|
897
|
-
}
|
|
900
|
+
},
|
|
901
|
+
// Codex sub-agents are referenced by file basename
|
|
902
|
+
// (`.codex/agents/<name>.toml`). `frontmatter.name` lives inside
|
|
903
|
+
// the TOML structured frontmatter when the author declared it
|
|
904
|
+
// explicitly.
|
|
905
|
+
identifiers: ["frontmatter.name", "filename-basename"]
|
|
898
906
|
}
|
|
899
907
|
},
|
|
908
|
+
// Codex's invocation surface is mention-style today (`@<name>`); slash
|
|
909
|
+
// invocation and skill nodes land in Phase 6b. Empty `invokes` keeps
|
|
910
|
+
// the contract narrow until skills arrive.
|
|
911
|
+
resolution: {
|
|
912
|
+
mentions: ["agent"]
|
|
913
|
+
},
|
|
900
914
|
classify(path) {
|
|
901
915
|
const lower = path.toLowerCase();
|
|
902
916
|
if (lower.startsWith(".codex/agents/") && lower.endsWith(".toml")) return "agent";
|
|
@@ -905,7 +919,7 @@ var openaiProvider = {
|
|
|
905
919
|
};
|
|
906
920
|
|
|
907
921
|
// plugins/agent-skills/providers/agent-skills/schemas/skill.schema.json
|
|
908
|
-
var
|
|
922
|
+
var skill_schema_default2 = {
|
|
909
923
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
910
924
|
$id: "https://skill-map.dev/providers/agent-skills/v1/frontmatter/skill.schema.json",
|
|
911
925
|
title: "FrontmatterAgentSkillsSkill",
|
|
@@ -929,15 +943,24 @@ var agentSkillsProvider = {
|
|
|
929
943
|
kinds: {
|
|
930
944
|
skill: {
|
|
931
945
|
schema: "./schemas/skill.schema.json",
|
|
932
|
-
schemaJson:
|
|
946
|
+
schemaJson: skill_schema_default2,
|
|
933
947
|
ui: {
|
|
934
948
|
label: "Skills",
|
|
935
949
|
color: "#10b981",
|
|
936
950
|
colorDark: "#34d399",
|
|
937
951
|
icon: { kind: "pi", id: "pi-bolt" }
|
|
938
|
-
}
|
|
952
|
+
},
|
|
953
|
+
// Open-standard skills mirror Anthropic's: dirname between
|
|
954
|
+
// `.agents/skills/` and `/SKILL.md` is the canonical handle,
|
|
955
|
+
// `frontmatter.name` overrides when present.
|
|
956
|
+
identifiers: ["frontmatter.name", "dirname"]
|
|
939
957
|
}
|
|
940
958
|
},
|
|
959
|
+
// The open standard documents slash-style invocation of skills; no
|
|
960
|
+
// mention surface (no agents in this Provider's territory).
|
|
961
|
+
resolution: {
|
|
962
|
+
invokes: ["skill"]
|
|
963
|
+
},
|
|
941
964
|
classify(path) {
|
|
942
965
|
if (/^\.agents\/skills\/[^/]+\/skill\.md$/.test(path.toLowerCase())) return "skill";
|
|
943
966
|
return null;
|
|
@@ -949,7 +972,7 @@ var markdown_schema_default = {
|
|
|
949
972
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
950
973
|
$id: "https://skill-map.dev/providers/core/v1/frontmatter/markdown.schema.json",
|
|
951
974
|
title: "FrontmatterMarkdown",
|
|
952
|
-
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.",
|
|
953
976
|
allOf: [
|
|
954
977
|
{ $ref: "https://skill-map.dev/spec/v0/frontmatter/base.schema.json" }
|
|
955
978
|
],
|
|
@@ -970,8 +993,9 @@ var coreMarkdownProvider = {
|
|
|
970
993
|
// as a registry entry (it ships later under the core bundle), but
|
|
971
994
|
// the qualified form is the contract.
|
|
972
995
|
//
|
|
973
|
-
// UI presentation: same neutral teal that
|
|
974
|
-
//
|
|
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
|
|
975
999
|
// composer (`buildKindRegistry`) makes this entry the primary owner
|
|
976
1000
|
// of the `markdown` kind because no other Provider declares it now;
|
|
977
1001
|
// per-node painting still falls through `entry.providers[node.provider]`
|
|
@@ -989,8 +1013,18 @@ var coreMarkdownProvider = {
|
|
|
989
1013
|
path: "M14 2 H6 a2 2 0 0 0 -2 2 V20 a2 2 0 0 0 2 2 H18 a2 2 0 0 0 2 -2 V8 L14 2 M14 2 V8 H20 M16 13 H8 M16 17 H8 M10 9 H8"
|
|
990
1014
|
}
|
|
991
1015
|
}
|
|
1016
|
+
// No `identifiers`: markdown nodes are addressed by path, not by a
|
|
1017
|
+
// canonical name. The name index built by `liftResolvedLinkConfidence`
|
|
1018
|
+
// never sees markdown entries; resolution falls through to the
|
|
1019
|
+
// path-match rule only.
|
|
992
1020
|
}
|
|
993
1021
|
},
|
|
1022
|
+
// No `resolution`: `core/markdown` is the universal fallback Provider,
|
|
1023
|
+
// it does not declare an invocation surface of its own. Mentions /
|
|
1024
|
+
// slashes sourced from markdown bodies still resolve via OTHER
|
|
1025
|
+
// Providers' resolution maps (the lookup keys on the source node's
|
|
1026
|
+
// Provider id, not on `core/markdown`). Leaving the field absent keeps
|
|
1027
|
+
// the contract narrow.
|
|
994
1028
|
classify() {
|
|
995
1029
|
return "markdown";
|
|
996
1030
|
}
|
|
@@ -1174,7 +1208,13 @@ var markdownLinkExtractor = {
|
|
|
1174
1208
|
source: ctx.node.path,
|
|
1175
1209
|
target: resolved,
|
|
1176
1210
|
kind: "references",
|
|
1177
|
-
|
|
1211
|
+
// 1.0: the `[text](path)` syntax is unambiguous. Markdown
|
|
1212
|
+
// explicitly designates an out-link via the brackets +
|
|
1213
|
+
// parentheses pair; there is no inference left to discount.
|
|
1214
|
+
// Whether the path resolves to a real node is a separate
|
|
1215
|
+
// concern (the `core/broken-ref` analyzer flags unresolved
|
|
1216
|
+
// targets), not a confidence question.
|
|
1217
|
+
confidence: 1,
|
|
1178
1218
|
sources: [ID5],
|
|
1179
1219
|
trigger: {
|
|
1180
1220
|
originalTrigger: original,
|
|
@@ -1848,12 +1888,56 @@ function formatBreakdown(byKind, direction) {
|
|
|
1848
1888
|
return [direction, ...lines].join("\n");
|
|
1849
1889
|
}
|
|
1850
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
|
+
|
|
1851
1935
|
// plugins/core/analyzers/stability/index.ts
|
|
1852
|
-
var
|
|
1936
|
+
var ID16 = "stability";
|
|
1853
1937
|
var EXPERIMENTAL_TOOLTIP = "Experimental: API may change";
|
|
1854
1938
|
var DEPRECATED_TOOLTIP = "Deprecated: avoid in new code";
|
|
1855
1939
|
var stabilityAnalyzer = {
|
|
1856
|
-
id:
|
|
1940
|
+
id: ID16,
|
|
1857
1941
|
pluginId: "core",
|
|
1858
1942
|
kind: "analyzer",
|
|
1859
1943
|
version: "1.0.0",
|
|
@@ -1885,7 +1969,7 @@ var stabilityAnalyzer = {
|
|
|
1885
1969
|
tooltip: EXPERIMENTAL_TOOLTIP
|
|
1886
1970
|
});
|
|
1887
1971
|
issues.push({
|
|
1888
|
-
analyzerId:
|
|
1972
|
+
analyzerId: ID16,
|
|
1889
1973
|
severity: "info",
|
|
1890
1974
|
nodeIds: [node.path],
|
|
1891
1975
|
message: `Node '${node.path}' is marked experimental: API may change.`,
|
|
@@ -1898,7 +1982,7 @@ var stabilityAnalyzer = {
|
|
|
1898
1982
|
severity: "warn"
|
|
1899
1983
|
});
|
|
1900
1984
|
issues.push({
|
|
1901
|
-
analyzerId:
|
|
1985
|
+
analyzerId: ID16,
|
|
1902
1986
|
severity: "warn",
|
|
1903
1987
|
nodeIds: [node.path],
|
|
1904
1988
|
message: `Node '${node.path}' is marked deprecated: avoid in new code.`,
|
|
@@ -1932,9 +2016,9 @@ var SUPERSEDED_TEXTS = {
|
|
|
1932
2016
|
};
|
|
1933
2017
|
|
|
1934
2018
|
// plugins/core/analyzers/superseded/index.ts
|
|
1935
|
-
var
|
|
2019
|
+
var ID17 = "superseded";
|
|
1936
2020
|
var supersededAnalyzer = {
|
|
1937
|
-
id:
|
|
2021
|
+
id: ID17,
|
|
1938
2022
|
pluginId: "core",
|
|
1939
2023
|
kind: "analyzer",
|
|
1940
2024
|
version: "1.0.0",
|
|
@@ -1946,7 +2030,7 @@ var supersededAnalyzer = {
|
|
|
1946
2030
|
const supersededBy = pickSupersededBy(node);
|
|
1947
2031
|
if (supersededBy === null) continue;
|
|
1948
2032
|
issues.push({
|
|
1949
|
-
analyzerId:
|
|
2033
|
+
analyzerId: ID17,
|
|
1950
2034
|
severity: "info",
|
|
1951
2035
|
nodeIds: [node.path],
|
|
1952
2036
|
message: tx(SUPERSEDED_TEXTS.message, {
|
|
@@ -1995,14 +2079,14 @@ var TRIGGER_COLLISION_TEXTS = {
|
|
|
1995
2079
|
};
|
|
1996
2080
|
|
|
1997
2081
|
// plugins/core/analyzers/trigger-collision/index.ts
|
|
1998
|
-
var
|
|
2082
|
+
var ID18 = "trigger-collision";
|
|
1999
2083
|
var ADVERTISING_KINDS = /* @__PURE__ */ new Set([
|
|
2000
2084
|
"command",
|
|
2001
2085
|
"skill",
|
|
2002
2086
|
"agent"
|
|
2003
2087
|
]);
|
|
2004
2088
|
var triggerCollisionAnalyzer = {
|
|
2005
|
-
id:
|
|
2089
|
+
id: ID18,
|
|
2006
2090
|
pluginId: "core",
|
|
2007
2091
|
kind: "analyzer",
|
|
2008
2092
|
mode: "deterministic",
|
|
@@ -2101,7 +2185,7 @@ function analyzeTriggerBucket(normalized, claims) {
|
|
|
2101
2185
|
part: parts[0]
|
|
2102
2186
|
});
|
|
2103
2187
|
return {
|
|
2104
|
-
analyzerId:
|
|
2188
|
+
analyzerId: ID18,
|
|
2105
2189
|
severity: "error",
|
|
2106
2190
|
nodeIds,
|
|
2107
2191
|
message,
|
|
@@ -2141,10 +2225,10 @@ var UNKNOWN_FIELD_TEXTS = {
|
|
|
2141
2225
|
};
|
|
2142
2226
|
|
|
2143
2227
|
// plugins/core/analyzers/unknown-field/index.ts
|
|
2144
|
-
var
|
|
2228
|
+
var ID19 = "unknown-field";
|
|
2145
2229
|
var RESERVED_ROOT_BLOCKS = /* @__PURE__ */ new Set(["identity", "annotations", "settings", "audit"]);
|
|
2146
2230
|
var unknownFieldAnalyzer = {
|
|
2147
|
-
id:
|
|
2231
|
+
id: ID19,
|
|
2148
2232
|
pluginId: "core",
|
|
2149
2233
|
kind: "analyzer",
|
|
2150
2234
|
version: "1.0.0",
|
|
@@ -2202,7 +2286,7 @@ var unknownFieldAnalyzer = {
|
|
|
2202
2286
|
for (const key of Object.keys(annotations)) {
|
|
2203
2287
|
if (!knownAnnotationKeys.has(key)) {
|
|
2204
2288
|
issues.push({
|
|
2205
|
-
analyzerId:
|
|
2289
|
+
analyzerId: ID19,
|
|
2206
2290
|
severity: "warn",
|
|
2207
2291
|
nodeIds: [node.path],
|
|
2208
2292
|
message: tx(UNKNOWN_FIELD_TEXTS.unknownAnnotationKey, {
|
|
@@ -2229,7 +2313,7 @@ var unknownFieldAnalyzer = {
|
|
|
2229
2313
|
if (validator(value)) continue;
|
|
2230
2314
|
const errors = (validator.errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message ?? e.keyword}`).join("; ");
|
|
2231
2315
|
issues.push({
|
|
2232
|
-
analyzerId:
|
|
2316
|
+
analyzerId: ID19,
|
|
2233
2317
|
severity: "warn",
|
|
2234
2318
|
nodeIds: [node.path],
|
|
2235
2319
|
message: tx(UNKNOWN_FIELD_TEXTS.pluginNamespaceInvalid, {
|
|
@@ -2245,7 +2329,7 @@ var unknownFieldAnalyzer = {
|
|
|
2245
2329
|
continue;
|
|
2246
2330
|
}
|
|
2247
2331
|
issues.push({
|
|
2248
|
-
analyzerId:
|
|
2332
|
+
analyzerId: ID19,
|
|
2249
2333
|
severity: "warn",
|
|
2250
2334
|
nodeIds: [node.path],
|
|
2251
2335
|
message: tx(UNKNOWN_FIELD_TEXTS.unknownRootKey, {
|
|
@@ -2538,9 +2622,9 @@ var VALIDATE_ALL_TEXTS = {
|
|
|
2538
2622
|
};
|
|
2539
2623
|
|
|
2540
2624
|
// plugins/core/analyzers/validate-all/index.ts
|
|
2541
|
-
var
|
|
2625
|
+
var ID20 = "validate-all";
|
|
2542
2626
|
var validateAllAnalyzer = {
|
|
2543
|
-
id:
|
|
2627
|
+
id: ID20,
|
|
2544
2628
|
pluginId: "core",
|
|
2545
2629
|
kind: "analyzer",
|
|
2546
2630
|
version: "1.0.0",
|
|
@@ -2603,7 +2687,7 @@ function collectNodeFindings(v, node, out) {
|
|
|
2603
2687
|
const result = v.validate("node", toNodeForSchema(node));
|
|
2604
2688
|
if (result.ok) return;
|
|
2605
2689
|
out.push({
|
|
2606
|
-
analyzerId:
|
|
2690
|
+
analyzerId: ID20,
|
|
2607
2691
|
severity: "error",
|
|
2608
2692
|
nodeIds: [node.path],
|
|
2609
2693
|
message: tx(VALIDATE_ALL_TEXTS.nodeFailure, {
|
|
@@ -2622,7 +2706,7 @@ function collectFrontmatterBaseFindings(node, out) {
|
|
|
2622
2706
|
if (isMissingStringField(fm, "description")) missing.push("description");
|
|
2623
2707
|
if (missing.length === 0) return;
|
|
2624
2708
|
out.push({
|
|
2625
|
-
analyzerId:
|
|
2709
|
+
analyzerId: ID20,
|
|
2626
2710
|
// `warn` (not `error`) so the default `sm scan` exit code stays
|
|
2627
2711
|
// 0 even when nodes are missing frontmatter base fields. Strict
|
|
2628
2712
|
// mode (`sm scan --strict`) still escalates to exit 1. Matches
|
|
@@ -2644,7 +2728,7 @@ function collectLinkFindings(v, link2, out) {
|
|
|
2644
2728
|
const result = v.validate("link", toLinkForSchema(link2));
|
|
2645
2729
|
if (result.ok) return;
|
|
2646
2730
|
out.push({
|
|
2647
|
-
analyzerId:
|
|
2731
|
+
analyzerId: ID20,
|
|
2648
2732
|
severity: "error",
|
|
2649
2733
|
nodeIds: [link2.source],
|
|
2650
2734
|
message: tx(VALIDATE_ALL_TEXTS.linkFailure, {
|
|
@@ -2712,13 +2796,13 @@ var ASCII_FORMATTER_TEXTS = {
|
|
|
2712
2796
|
};
|
|
2713
2797
|
|
|
2714
2798
|
// plugins/core/formatters/ascii/index.ts
|
|
2715
|
-
var
|
|
2799
|
+
var ID21 = "ascii";
|
|
2716
2800
|
var KIND_ORDER = ["agent", "command", "skill", "markdown"];
|
|
2717
2801
|
var asciiFormatter = {
|
|
2718
|
-
id:
|
|
2802
|
+
id: ID21,
|
|
2719
2803
|
pluginId: "core",
|
|
2720
2804
|
kind: "formatter",
|
|
2721
|
-
formatId:
|
|
2805
|
+
formatId: ID21,
|
|
2722
2806
|
version: "1.0.0",
|
|
2723
2807
|
description: "Renders the scan as plain text, grouped by kind, arrows, and issues. Used by `sm scan --format=ascii`.",
|
|
2724
2808
|
// ASCII tree formatter, header + per-kind sections + per-issue
|
|
@@ -2813,14 +2897,14 @@ function renderSection(out, kind, group) {
|
|
|
2813
2897
|
}
|
|
2814
2898
|
|
|
2815
2899
|
// plugins/core/formatters/json/index.ts
|
|
2816
|
-
var
|
|
2900
|
+
var ID22 = "json";
|
|
2817
2901
|
var jsonFormatter = {
|
|
2818
|
-
id:
|
|
2902
|
+
id: ID22,
|
|
2819
2903
|
pluginId: "core",
|
|
2820
2904
|
kind: "formatter",
|
|
2821
2905
|
version: "1.0.0",
|
|
2822
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`.",
|
|
2823
|
-
formatId:
|
|
2907
|
+
formatId: ID22,
|
|
2824
2908
|
format(ctx) {
|
|
2825
2909
|
if (ctx.scanResult !== void 0) {
|
|
2826
2910
|
return JSON.stringify(ctx.scanResult);
|
|
@@ -2959,10 +3043,10 @@ function resolveSpecRoot2() {
|
|
|
2959
3043
|
}
|
|
2960
3044
|
|
|
2961
3045
|
// plugins/core/actions/bump/index.ts
|
|
2962
|
-
var
|
|
3046
|
+
var ID23 = "bump";
|
|
2963
3047
|
var PLUGIN_ID = "core";
|
|
2964
3048
|
var bumpAction = {
|
|
2965
|
-
id:
|
|
3049
|
+
id: ID23,
|
|
2966
3050
|
pluginId: PLUGIN_ID,
|
|
2967
3051
|
kind: "action",
|
|
2968
3052
|
version: "1.0.0",
|
|
@@ -3021,10 +3105,10 @@ function pickCurrentVersion(overlay) {
|
|
|
3021
3105
|
}
|
|
3022
3106
|
|
|
3023
3107
|
// plugins/core/actions/mark-superseded/index.ts
|
|
3024
|
-
var
|
|
3108
|
+
var ID24 = "mark-superseded";
|
|
3025
3109
|
var PLUGIN_ID2 = "core";
|
|
3026
3110
|
var markSupersededAction = {
|
|
3027
|
-
id:
|
|
3111
|
+
id: ID24,
|
|
3028
3112
|
pluginId: PLUGIN_ID2,
|
|
3029
3113
|
kind: "action",
|
|
3030
3114
|
version: "0.0.0",
|
|
@@ -3134,7 +3218,7 @@ var UPDATE_CHECK_TEXTS = {
|
|
|
3134
3218
|
// package.json
|
|
3135
3219
|
var package_default = {
|
|
3136
3220
|
name: "@skill-map/cli",
|
|
3137
|
-
version: "0.
|
|
3221
|
+
version: "0.36.0",
|
|
3138
3222
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
3139
3223
|
license: "MIT",
|
|
3140
3224
|
type: "module",
|
|
@@ -3513,7 +3597,7 @@ var updateCheckHook = {
|
|
|
3513
3597
|
var claudeProvider2 = { ...claudeProvider, pluginId: "claude" };
|
|
3514
3598
|
var atDirectiveExtractor2 = { ...atDirectiveExtractor, pluginId: "claude" };
|
|
3515
3599
|
var slashExtractor2 = { ...slashExtractor, pluginId: "claude" };
|
|
3516
|
-
var
|
|
3600
|
+
var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity" };
|
|
3517
3601
|
var openaiProvider2 = { ...openaiProvider, pluginId: "openai" };
|
|
3518
3602
|
var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills" };
|
|
3519
3603
|
var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core" };
|
|
@@ -3529,6 +3613,7 @@ var contributionOrphanAnalyzer2 = { ...contributionOrphanAnalyzer, pluginId: "co
|
|
|
3529
3613
|
var jobOrphanFileAnalyzer2 = { ...jobOrphanFileAnalyzer, pluginId: "core" };
|
|
3530
3614
|
var linkConflictAnalyzer2 = { ...linkConflictAnalyzer, pluginId: "core" };
|
|
3531
3615
|
var linkCountsAnalyzer2 = { ...linkCountsAnalyzer, pluginId: "core" };
|
|
3616
|
+
var reservedNameAnalyzer2 = { ...reservedNameAnalyzer, pluginId: "core" };
|
|
3532
3617
|
var stabilityAnalyzer2 = { ...stabilityAnalyzer, pluginId: "core" };
|
|
3533
3618
|
var supersededAnalyzer2 = { ...supersededAnalyzer, pluginId: "core" };
|
|
3534
3619
|
var triggerCollisionAnalyzer2 = { ...triggerCollisionAnalyzer, pluginId: "core" };
|
|
@@ -3551,11 +3636,11 @@ var builtInBundles = [
|
|
|
3551
3636
|
]
|
|
3552
3637
|
},
|
|
3553
3638
|
{
|
|
3554
|
-
id: "
|
|
3639
|
+
id: "antigravity",
|
|
3555
3640
|
granularity: "bundle",
|
|
3556
|
-
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.",
|
|
3557
3642
|
extensions: [
|
|
3558
|
-
|
|
3643
|
+
antigravityProvider2
|
|
3559
3644
|
]
|
|
3560
3645
|
},
|
|
3561
3646
|
{
|
|
@@ -3592,6 +3677,7 @@ var builtInBundles = [
|
|
|
3592
3677
|
jobOrphanFileAnalyzer2,
|
|
3593
3678
|
linkConflictAnalyzer2,
|
|
3594
3679
|
linkCountsAnalyzer2,
|
|
3680
|
+
reservedNameAnalyzer2,
|
|
3595
3681
|
stabilityAnalyzer2,
|
|
3596
3682
|
supersededAnalyzer2,
|
|
3597
3683
|
triggerCollisionAnalyzer2,
|
|
@@ -5068,7 +5154,7 @@ var AsyncMutex = class {
|
|
|
5068
5154
|
this.#locked = true;
|
|
5069
5155
|
return;
|
|
5070
5156
|
}
|
|
5071
|
-
await new Promise((
|
|
5157
|
+
await new Promise((resolve40) => this.#waiters.push(resolve40));
|
|
5072
5158
|
this.#locked = true;
|
|
5073
5159
|
}
|
|
5074
5160
|
unlock() {
|
|
@@ -9678,7 +9764,13 @@ import { existsSync as existsSync14 } from "fs";
|
|
|
9678
9764
|
import { join as join10 } from "path";
|
|
9679
9765
|
var DETECTION_RULES = [
|
|
9680
9766
|
{ providerId: "claude", marker: ".claude" },
|
|
9681
|
-
|
|
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`.
|
|
9682
9774
|
{ providerId: "openai", marker: ".codex" },
|
|
9683
9775
|
{ providerId: "openai", marker: "AGENTS.md" },
|
|
9684
9776
|
{ providerId: "cursor", marker: ".cursor" }
|
|
@@ -13059,7 +13151,7 @@ import { Command as Command17, Option as Option16 } from "clipanion";
|
|
|
13059
13151
|
|
|
13060
13152
|
// kernel/orchestrator/index.ts
|
|
13061
13153
|
import { existsSync as existsSync22, statSync as statSync7 } from "fs";
|
|
13062
|
-
import { isAbsolute as isAbsolute7, resolve as
|
|
13154
|
+
import { isAbsolute as isAbsolute7, resolve as resolve28 } from "path";
|
|
13063
13155
|
import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
13064
13156
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
13065
13157
|
|
|
@@ -13428,7 +13520,7 @@ function isExternalUrlLink(link2) {
|
|
|
13428
13520
|
}
|
|
13429
13521
|
|
|
13430
13522
|
// kernel/orchestrator/analyzers.ts
|
|
13431
|
-
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) {
|
|
13432
13524
|
const issues = [];
|
|
13433
13525
|
const contributions = [];
|
|
13434
13526
|
const validators = loadSchemaValidators();
|
|
@@ -13492,6 +13584,7 @@ async function runAnalyzers(analyzers, nodes, internalLinks, orphanSidecars, sid
|
|
|
13492
13584
|
orphanJobFiles,
|
|
13493
13585
|
...referenceablePaths ? { referenceablePaths } : {},
|
|
13494
13586
|
...cwd ? { cwd } : {},
|
|
13587
|
+
...reservedNodePaths ? { reservedNodePaths } : {},
|
|
13495
13588
|
emitContribution
|
|
13496
13589
|
});
|
|
13497
13590
|
for (const issue of emitted) {
|
|
@@ -13712,37 +13805,106 @@ function classifyLinkSource(source, shortIdToQualified, cachedQualifiedIds, appl
|
|
|
13712
13805
|
return "obsolete";
|
|
13713
13806
|
}
|
|
13714
13807
|
|
|
13715
|
-
// kernel/orchestrator/
|
|
13716
|
-
|
|
13717
|
-
|
|
13718
|
-
const
|
|
13719
|
-
|
|
13720
|
-
const
|
|
13721
|
-
for (const
|
|
13722
|
-
|
|
13723
|
-
if (
|
|
13724
|
-
|
|
13725
|
-
|
|
13808
|
+
// kernel/orchestrator/node-identifiers.ts
|
|
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);
|
|
13726
13819
|
}
|
|
13820
|
+
return out;
|
|
13727
13821
|
}
|
|
13728
|
-
function
|
|
13729
|
-
|
|
13730
|
-
if (
|
|
13731
|
-
|
|
13732
|
-
|
|
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;
|
|
13848
|
+
function liftResolvedLinkConfidence(links, nodes, ctx) {
|
|
13849
|
+
if (!links.some((l) => l.confidence < 1)) return;
|
|
13850
|
+
const indexes = buildIndexes(nodes, ctx);
|
|
13851
|
+
for (const link2 of links) {
|
|
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;
|
|
13733
13856
|
}
|
|
13734
|
-
if (byPath3.has(link2.target)) return true;
|
|
13735
|
-
return false;
|
|
13736
13857
|
}
|
|
13737
|
-
function
|
|
13738
|
-
const
|
|
13858
|
+
function buildIndexes(nodes, ctx) {
|
|
13859
|
+
const byPath3 = /* @__PURE__ */ new Set();
|
|
13860
|
+
const byName = /* @__PURE__ */ new Map();
|
|
13861
|
+
const nodeByPath = /* @__PURE__ */ new Map();
|
|
13739
13862
|
for (const node of nodes) {
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13863
|
+
byPath3.add(node.path);
|
|
13864
|
+
nodeByPath.set(node.path, node);
|
|
13865
|
+
indexNode(node, ctx, byName);
|
|
13866
|
+
}
|
|
13867
|
+
return { byPath: byPath3, byName, nodeByPath };
|
|
13868
|
+
}
|
|
13869
|
+
function resolve27(link2, indexes, ctx) {
|
|
13870
|
+
if (indexes.byPath.has(link2.target)) return link2.target;
|
|
13871
|
+
return resolveByName(link2, indexes, ctx);
|
|
13872
|
+
}
|
|
13873
|
+
function resolveByName(link2, indexes, ctx) {
|
|
13874
|
+
const stripped = stripTriggerSigil(link2.trigger?.normalizedTrigger);
|
|
13875
|
+
if (stripped === null) return "none";
|
|
13876
|
+
const candidates = indexes.byName.get(stripped);
|
|
13877
|
+
if (!candidates?.length) return "none";
|
|
13878
|
+
const allowedKinds = lookupAllowedKinds(link2, indexes, ctx);
|
|
13879
|
+
if (!allowedKinds?.length) return "none";
|
|
13880
|
+
const winner = candidates.find((c) => allowedKinds.includes(c.kind));
|
|
13881
|
+
return winner ? winner.path : "none";
|
|
13882
|
+
}
|
|
13883
|
+
function lookupAllowedKinds(link2, indexes, ctx) {
|
|
13884
|
+
const sourceNode = indexes.nodeByPath.get(link2.source);
|
|
13885
|
+
if (!sourceNode) return void 0;
|
|
13886
|
+
return ctx.providerResolution.get(sourceNode.provider)?.[link2.kind];
|
|
13887
|
+
}
|
|
13888
|
+
function stripTriggerSigil(normalized) {
|
|
13889
|
+
if (!normalized) return null;
|
|
13890
|
+
const trimmed = normalized.replace(/^[/@]/, "").trim();
|
|
13891
|
+
return trimmed.length === 0 ? null : trimmed;
|
|
13892
|
+
}
|
|
13893
|
+
function indexNode(node, ctx, byName) {
|
|
13894
|
+
const kindDescriptor = ctx.kindRegistry.get(kindKey(node));
|
|
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);
|
|
13899
|
+
if (bucket) {
|
|
13900
|
+
bucket.push(entry);
|
|
13901
|
+
} else {
|
|
13902
|
+
byName.set(name, [entry]);
|
|
13903
|
+
}
|
|
13744
13904
|
}
|
|
13745
|
-
|
|
13905
|
+
}
|
|
13906
|
+
function kindKey(node) {
|
|
13907
|
+
return `${node.provider}/${node.kind}`;
|
|
13746
13908
|
}
|
|
13747
13909
|
|
|
13748
13910
|
// kernel/orchestrator/post-walk-transforms.ts
|
|
@@ -13755,17 +13917,17 @@ var POST_WALK_TRANSFORMS = [
|
|
|
13755
13917
|
}
|
|
13756
13918
|
},
|
|
13757
13919
|
{
|
|
13758
|
-
id: "lift-
|
|
13759
|
-
description: "Bump
|
|
13760
|
-
run(links, nodes) {
|
|
13761
|
-
|
|
13920
|
+
id: "lift-resolved-link-confidence",
|
|
13921
|
+
description: "Bump invocation links to confidence 1.0 when target / trigger resolves against the full node graph per the source Provider rules.",
|
|
13922
|
+
run(links, nodes, ctx) {
|
|
13923
|
+
liftResolvedLinkConfidence(links, nodes, ctx);
|
|
13762
13924
|
}
|
|
13763
13925
|
}
|
|
13764
13926
|
];
|
|
13765
|
-
function applyPostWalkTransforms(links, nodes, transforms = POST_WALK_TRANSFORMS) {
|
|
13927
|
+
function applyPostWalkTransforms(links, nodes, ctx, transforms = POST_WALK_TRANSFORMS) {
|
|
13766
13928
|
let current = links;
|
|
13767
13929
|
for (const transform of transforms) {
|
|
13768
|
-
const next = transform.run(current, nodes);
|
|
13930
|
+
const next = transform.run(current, nodes, ctx);
|
|
13769
13931
|
if (next) current = next;
|
|
13770
13932
|
}
|
|
13771
13933
|
return current;
|
|
@@ -14477,7 +14639,8 @@ async function runScanInternal(_kernel, options) {
|
|
|
14477
14639
|
pluginStores: options.pluginStores,
|
|
14478
14640
|
activeProvider: resolveActiveProviderOption(options.activeProvider, options.roots)
|
|
14479
14641
|
});
|
|
14480
|
-
|
|
14642
|
+
const postWalkCtx = buildPostWalkTransformCtx(_kernel, walked.nodes);
|
|
14643
|
+
walked.internalLinks = applyPostWalkTransforms(walked.internalLinks, walked.nodes, postWalkCtx);
|
|
14481
14644
|
recomputeLinkCounts(walked.nodes, walked.internalLinks);
|
|
14482
14645
|
recomputeExternalRefsCount(walked.nodes, walked.externalLinks, walked.cachedPaths);
|
|
14483
14646
|
await dispatchExtractorCompleted(exts.extractors, emitter, hookDispatcher);
|
|
@@ -14497,7 +14660,8 @@ async function runScanInternal(_kernel, options) {
|
|
|
14497
14660
|
options.cwd,
|
|
14498
14661
|
registeredActionIds,
|
|
14499
14662
|
emitter,
|
|
14500
|
-
hookDispatcher
|
|
14663
|
+
hookDispatcher,
|
|
14664
|
+
postWalkCtx.reservedNodePaths
|
|
14501
14665
|
);
|
|
14502
14666
|
mergeAnalyzerEmissions(walked, analyzerResult, exts.analyzers);
|
|
14503
14667
|
const issues = analyzerResult.issues;
|
|
@@ -14510,6 +14674,56 @@ async function runScanInternal(_kernel, options) {
|
|
|
14510
14674
|
await hookDispatcher.dispatch("scan.completed", scanCompletedEvent);
|
|
14511
14675
|
return buildScanReturn(walked, issues, renameOps, stats, options, setup);
|
|
14512
14676
|
}
|
|
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) {
|
|
14687
|
+
const kindRegistry = /* @__PURE__ */ new Map();
|
|
14688
|
+
const providerResolution = /* @__PURE__ */ new Map();
|
|
14689
|
+
const reservedNamesByProviderKind = /* @__PURE__ */ new Map();
|
|
14690
|
+
const providers = kernel.registry.all("provider");
|
|
14691
|
+
for (const provider of providers) {
|
|
14692
|
+
if (provider.kinds) {
|
|
14693
|
+
for (const [kindName, descriptor] of Object.entries(provider.kinds)) {
|
|
14694
|
+
kindRegistry.set(`${provider.id}/${kindName}`, descriptor);
|
|
14695
|
+
}
|
|
14696
|
+
}
|
|
14697
|
+
if (provider.resolution) {
|
|
14698
|
+
providerResolution.set(provider.id, provider.resolution);
|
|
14699
|
+
}
|
|
14700
|
+
if (provider.reservedNames) {
|
|
14701
|
+
indexReservedNames(provider, reservedNamesByProviderKind);
|
|
14702
|
+
}
|
|
14703
|
+
}
|
|
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;
|
|
14726
|
+
}
|
|
14513
14727
|
function buildScanSetup(options) {
|
|
14514
14728
|
const start = Date.now();
|
|
14515
14729
|
const emitter = options.emitter ?? new InMemoryProgressEmitter();
|
|
@@ -14601,7 +14815,7 @@ function validateRoots(roots) {
|
|
|
14601
14815
|
function resolveActiveProviderOption(optionValue, roots) {
|
|
14602
14816
|
if (optionValue !== void 0) return optionValue;
|
|
14603
14817
|
for (const root of roots) {
|
|
14604
|
-
const absRoot = isAbsolute7(root) ? root :
|
|
14818
|
+
const absRoot = isAbsolute7(root) ? root : resolve28(root);
|
|
14605
14819
|
if (!existsSync22(absRoot)) continue;
|
|
14606
14820
|
const detected = resolveActiveProvider(absRoot).resolved;
|
|
14607
14821
|
if (detected !== null) return detected;
|
|
@@ -14610,10 +14824,10 @@ function resolveActiveProviderOption(optionValue, roots) {
|
|
|
14610
14824
|
}
|
|
14611
14825
|
|
|
14612
14826
|
// kernel/scan/watcher.ts
|
|
14613
|
-
import { resolve as
|
|
14827
|
+
import { resolve as resolve29, relative as relative5, sep as sep4 } from "path";
|
|
14614
14828
|
import chokidar from "chokidar";
|
|
14615
14829
|
function createChokidarWatcher(opts) {
|
|
14616
|
-
const absRoots = opts.roots.map((r) =>
|
|
14830
|
+
const absRoots = opts.roots.map((r) => resolve29(opts.cwd, r));
|
|
14617
14831
|
const ignoreFilterOpt = opts.ignoreFilter;
|
|
14618
14832
|
const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
|
|
14619
14833
|
const ignored = getFilter ? (path) => {
|
|
@@ -14832,7 +15046,7 @@ function createKernel() {
|
|
|
14832
15046
|
|
|
14833
15047
|
// kernel/jobs/orphan-files.ts
|
|
14834
15048
|
import { readdirSync as readdirSync8, statSync as statSync8 } from "fs";
|
|
14835
|
-
import { join as join14, resolve as
|
|
15049
|
+
import { join as join14, resolve as resolve30 } from "path";
|
|
14836
15050
|
function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
14837
15051
|
let entries;
|
|
14838
15052
|
try {
|
|
@@ -14850,7 +15064,7 @@ function findOrphanJobFiles(jobsDir, referencedPaths) {
|
|
|
14850
15064
|
if (!entry.isFile()) continue;
|
|
14851
15065
|
const name = entry.name;
|
|
14852
15066
|
if (!name.endsWith(".md")) continue;
|
|
14853
|
-
const abs =
|
|
15067
|
+
const abs = resolve30(join14(jobsDir, name));
|
|
14854
15068
|
if (!referencedPaths.has(abs)) orphans.push(abs);
|
|
14855
15069
|
}
|
|
14856
15070
|
orphans.sort();
|
|
@@ -14917,12 +15131,12 @@ var SCAN_RUNNER_TEXTS = {
|
|
|
14917
15131
|
referenceWalkMissingRoot: 'scan.referencePaths: configured path "{{path}}" does not exist; skipped.',
|
|
14918
15132
|
/**
|
|
14919
15133
|
* Active-provider bootstrap: filesystem auto-detect found no
|
|
14920
|
-
* markers (`.claude/`, `.
|
|
14921
|
-
*
|
|
14922
|
-
*
|
|
14923
|
-
*
|
|
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.
|
|
14924
15138
|
*/
|
|
14925
|
-
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.",
|
|
14926
15140
|
/**
|
|
14927
15141
|
* Active-provider bootstrap: filesystem auto-detect found exactly
|
|
14928
15142
|
* one marker and persisted the detected id to project settings.
|
|
@@ -14969,7 +15183,7 @@ function resolveScanRoots(inputs) {
|
|
|
14969
15183
|
// core/runtime/reference-paths-walker.ts
|
|
14970
15184
|
import { readdirSync as readdirSync9, statSync as statSync9 } from "fs";
|
|
14971
15185
|
import { homedir as osHomedir2 } from "os";
|
|
14972
|
-
import { isAbsolute as isAbsolute8, join as join15, resolve as
|
|
15186
|
+
import { isAbsolute as isAbsolute8, join as join15, resolve as resolve31 } from "path";
|
|
14973
15187
|
var REFERENCE_WALK_MAX_FILES = 5e4;
|
|
14974
15188
|
var SKIPPED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
14975
15189
|
"node_modules",
|
|
@@ -14977,10 +15191,10 @@ var SKIPPED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
|
14977
15191
|
SKILL_MAP_DIR
|
|
14978
15192
|
]);
|
|
14979
15193
|
function resolveScanPath(raw, cwd) {
|
|
14980
|
-
if (raw.startsWith("~/")) return
|
|
14981
|
-
if (raw === "~") return
|
|
14982
|
-
if (isAbsolute8(raw)) return
|
|
14983
|
-
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);
|
|
14984
15198
|
}
|
|
14985
15199
|
function walkReferencePaths(rawRoots, cwd) {
|
|
14986
15200
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -17274,9 +17488,9 @@ var PLUGINS_TEXTS = {
|
|
|
17274
17488
|
};
|
|
17275
17489
|
|
|
17276
17490
|
// cli/commands/plugins/shared.ts
|
|
17277
|
-
import { resolve as
|
|
17491
|
+
import { resolve as resolve32 } from "path";
|
|
17278
17492
|
function resolveSearchPaths2(opts, cwd) {
|
|
17279
|
-
if (opts.pluginDir) return [
|
|
17493
|
+
if (opts.pluginDir) return [resolve32(opts.pluginDir)];
|
|
17280
17494
|
return [defaultProjectPluginsDir({ cwd })];
|
|
17281
17495
|
}
|
|
17282
17496
|
async function buildResolver() {
|
|
@@ -18298,7 +18512,7 @@ var PluginsEnableCommand = class extends TogglePluginsBase {
|
|
|
18298
18512
|
baseline.
|
|
18299
18513
|
|
|
18300
18514
|
Accepts one or more ids in one call, e.g.
|
|
18301
|
-
'sm plugins enable claude
|
|
18515
|
+
'sm plugins enable claude antigravity openai'. Batches are
|
|
18302
18516
|
all-or-nothing: a single unknown / mismatched id aborts before
|
|
18303
18517
|
any write. Repeated ids are deduped. Locked plugins inside a
|
|
18304
18518
|
batch are silently skipped.
|
|
@@ -18326,7 +18540,7 @@ var PluginsDisableCommand = class extends TogglePluginsBase {
|
|
|
18326
18540
|
will not run them.
|
|
18327
18541
|
|
|
18328
18542
|
Accepts one or more ids in one call, e.g.
|
|
18329
|
-
'sm plugins disable
|
|
18543
|
+
'sm plugins disable antigravity openai agent-skills'. Batches are
|
|
18330
18544
|
all-or-nothing: a single unknown / mismatched id aborts before
|
|
18331
18545
|
any write. Repeated ids are deduped. Locked plugins inside a
|
|
18332
18546
|
batch are silently skipped.
|
|
@@ -18436,7 +18650,7 @@ function resolveBareToggle(id, catalogue, verb, ansi) {
|
|
|
18436
18650
|
|
|
18437
18651
|
// cli/commands/plugins/create.ts
|
|
18438
18652
|
import { existsSync as existsSync23, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
18439
|
-
import { join as join18, resolve as
|
|
18653
|
+
import { join as join18, resolve as resolve33 } from "path";
|
|
18440
18654
|
import { Command as Command26, Option as Option25 } from "clipanion";
|
|
18441
18655
|
var PluginsCreateCommand = class extends SmCommand {
|
|
18442
18656
|
static paths = [["plugins", "create"]];
|
|
@@ -18462,7 +18676,7 @@ var PluginsCreateCommand = class extends SmCommand {
|
|
|
18462
18676
|
}
|
|
18463
18677
|
const ctx = defaultRuntimeContext();
|
|
18464
18678
|
const baseDir = defaultProjectPluginsDir(ctx);
|
|
18465
|
-
const targetDir = this.at ?
|
|
18679
|
+
const targetDir = this.at ? resolve33(this.at) : join18(baseDir, this.pluginId);
|
|
18466
18680
|
if (existsSync23(targetDir) && !this.force) {
|
|
18467
18681
|
this.printer.error(
|
|
18468
18682
|
tx(PLUGINS_TEXTS.createRefuseOverwrite, {
|
|
@@ -18703,7 +18917,7 @@ var PLUGIN_COMMANDS = [
|
|
|
18703
18917
|
|
|
18704
18918
|
// cli/commands/refresh.ts
|
|
18705
18919
|
import { readFile as readFile3 } from "fs/promises";
|
|
18706
|
-
import { resolve as
|
|
18920
|
+
import { resolve as resolve34 } from "path";
|
|
18707
18921
|
import { Command as Command29, Option as Option27 } from "clipanion";
|
|
18708
18922
|
|
|
18709
18923
|
// cli/i18n/refresh.texts.ts
|
|
@@ -18987,7 +19201,7 @@ var RefreshCommand = class extends SmCommand {
|
|
|
18987
19201
|
let body;
|
|
18988
19202
|
try {
|
|
18989
19203
|
assertContained(cwd, node.path);
|
|
18990
|
-
const raw = await readFile3(
|
|
19204
|
+
const raw = await readFile3(resolve34(cwd, node.path), "utf8");
|
|
18991
19205
|
body = stripFrontmatterFence(raw);
|
|
18992
19206
|
} catch (err) {
|
|
18993
19207
|
if (!this.json) {
|
|
@@ -19729,7 +19943,7 @@ var ScanCommand = class extends SmCommand {
|
|
|
19729
19943
|
description: "Long-running mode: watch the roots and trigger an incremental scan after each debounced batch of filesystem events. Alias of `sm watch`."
|
|
19730
19944
|
});
|
|
19731
19945
|
yes = Option29.Boolean("--yes", false, {
|
|
19732
|
-
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."
|
|
19733
19947
|
});
|
|
19734
19948
|
// Each branch in the orchestrator maps to one validation gate
|
|
19735
19949
|
// (--watch alias / --changed mutex / -g mutex / dispatch).
|
|
@@ -21721,10 +21935,10 @@ import { HTTPException as HTTPException10 } from "hono/http-exception";
|
|
|
21721
21935
|
|
|
21722
21936
|
// server/util/skillmapignore-io.ts
|
|
21723
21937
|
import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync4 } from "fs";
|
|
21724
|
-
import { resolve as
|
|
21938
|
+
import { resolve as resolve35 } from "path";
|
|
21725
21939
|
var IGNORE_FILENAME2 = ".skillmapignore";
|
|
21726
21940
|
function readPatterns(cwd) {
|
|
21727
|
-
const path =
|
|
21941
|
+
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
21728
21942
|
if (!existsSync26(path)) return [];
|
|
21729
21943
|
let raw;
|
|
21730
21944
|
try {
|
|
@@ -21735,7 +21949,7 @@ function readPatterns(cwd) {
|
|
|
21735
21949
|
return raw.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#"));
|
|
21736
21950
|
}
|
|
21737
21951
|
function writePatterns(cwd, nextPatterns) {
|
|
21738
|
-
const path =
|
|
21952
|
+
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
21739
21953
|
const prior = existsSync26(path) ? safeRead(path) : "";
|
|
21740
21954
|
const content = buildContent(prior, nextPatterns);
|
|
21741
21955
|
writeFileSync4(path, content, "utf8");
|
|
@@ -22156,14 +22370,14 @@ async function withScanMutex(fn) {
|
|
|
22156
22370
|
if (inFlight !== null) {
|
|
22157
22371
|
throw new ScanBusyError();
|
|
22158
22372
|
}
|
|
22159
|
-
let
|
|
22373
|
+
let resolve40;
|
|
22160
22374
|
inFlight = new Promise((r) => {
|
|
22161
|
-
|
|
22375
|
+
resolve40 = r;
|
|
22162
22376
|
});
|
|
22163
22377
|
try {
|
|
22164
22378
|
return await fn();
|
|
22165
22379
|
} finally {
|
|
22166
|
-
|
|
22380
|
+
resolve40();
|
|
22167
22381
|
inFlight = null;
|
|
22168
22382
|
}
|
|
22169
22383
|
}
|
|
@@ -22475,7 +22689,7 @@ function emptyScanResult() {
|
|
|
22475
22689
|
|
|
22476
22690
|
// server/routes/sidecar.ts
|
|
22477
22691
|
import { HTTPException as HTTPException14 } from "hono/http-exception";
|
|
22478
|
-
import { resolve as
|
|
22692
|
+
import { resolve as resolve36 } from "path";
|
|
22479
22693
|
var STATUS_FRESH = "fresh";
|
|
22480
22694
|
var ENVELOPE_KIND2 = "sidecar.bumped";
|
|
22481
22695
|
var BUMP_BODY_SCHEMA = {
|
|
@@ -22509,7 +22723,7 @@ function registerSidecarRoutes(app, deps) {
|
|
|
22509
22723
|
let absPath;
|
|
22510
22724
|
try {
|
|
22511
22725
|
assertContained(deps.runtimeContext.cwd, node.path);
|
|
22512
|
-
absPath =
|
|
22726
|
+
absPath = resolve36(deps.runtimeContext.cwd, node.path);
|
|
22513
22727
|
} catch (err) {
|
|
22514
22728
|
throw new HTTPException14(500, { message: formatErrorMessage(err) });
|
|
22515
22729
|
}
|
|
@@ -23261,7 +23475,7 @@ function validateNoUi(noUi, uiDist) {
|
|
|
23261
23475
|
|
|
23262
23476
|
// server/paths.ts
|
|
23263
23477
|
import { existsSync as existsSync29, statSync as statSync11 } from "fs";
|
|
23264
|
-
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";
|
|
23265
23479
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23266
23480
|
var DEFAULT_UI_REL = join20("ui", "dist", "ui", "browser");
|
|
23267
23481
|
var PACKAGE_UI_REL = "ui";
|
|
@@ -23272,7 +23486,7 @@ function resolveDefaultUiDist(ctx) {
|
|
|
23272
23486
|
return walkUpForUi(ctx.cwd);
|
|
23273
23487
|
}
|
|
23274
23488
|
function resolveExplicitUiDist(ctx, raw) {
|
|
23275
|
-
return isAbsolute11(raw) ? raw :
|
|
23489
|
+
return isAbsolute11(raw) ? raw : resolve37(ctx.cwd, raw);
|
|
23276
23490
|
}
|
|
23277
23491
|
function isUiBundleDir(path) {
|
|
23278
23492
|
if (!existsSync29(path)) return false;
|
|
@@ -23306,7 +23520,7 @@ function resolvePackageBundledUiFrom(here) {
|
|
|
23306
23520
|
return null;
|
|
23307
23521
|
}
|
|
23308
23522
|
function walkUpForUi(startDir) {
|
|
23309
|
-
let current =
|
|
23523
|
+
let current = resolve37(startDir);
|
|
23310
23524
|
for (let i = 0; i < 64; i++) {
|
|
23311
23525
|
const candidate = join20(current, DEFAULT_UI_REL);
|
|
23312
23526
|
if (isUiBundleDir(candidate)) return candidate;
|
|
@@ -24246,7 +24460,7 @@ function rankConfidenceForGrouping(c) {
|
|
|
24246
24460
|
|
|
24247
24461
|
// cli/commands/sidecar.ts
|
|
24248
24462
|
import { existsSync as existsSync31, unlinkSync as unlinkSync2 } from "fs";
|
|
24249
|
-
import { resolve as
|
|
24463
|
+
import { resolve as resolve38 } from "path";
|
|
24250
24464
|
import { Command as Command35, Option as Option33 } from "clipanion";
|
|
24251
24465
|
|
|
24252
24466
|
// cli/i18n/sidecar.texts.ts
|
|
@@ -24397,7 +24611,7 @@ var SidecarRefreshCommand = class extends SmCommand {
|
|
|
24397
24611
|
let absPath;
|
|
24398
24612
|
try {
|
|
24399
24613
|
assertContained(ctx.cwd, node.path);
|
|
24400
|
-
absPath =
|
|
24614
|
+
absPath = resolve38(ctx.cwd, node.path);
|
|
24401
24615
|
} catch (err) {
|
|
24402
24616
|
this.printer.error(
|
|
24403
24617
|
tx(SIDECAR_TEXTS.refreshFailed, { glyph: errGlyph, message: formatErrorMessage(err) })
|
|
@@ -24678,7 +24892,7 @@ var SidecarAnnotateCommand = class extends SmCommand {
|
|
|
24678
24892
|
let absPath;
|
|
24679
24893
|
try {
|
|
24680
24894
|
assertContained(ctx.cwd, node.path);
|
|
24681
|
-
absPath =
|
|
24895
|
+
absPath = resolve38(ctx.cwd, node.path);
|
|
24682
24896
|
} catch (err) {
|
|
24683
24897
|
this.printer.error(
|
|
24684
24898
|
tx(SIDECAR_TEXTS.annotateFailed, { glyph: errGlyph, message: formatErrorMessage(err) })
|
|
@@ -24927,7 +25141,7 @@ var STUB_COMMANDS = [
|
|
|
24927
25141
|
|
|
24928
25142
|
// cli/commands/tutorial.ts
|
|
24929
25143
|
import { cpSync as cpSync2, existsSync as existsSync32, mkdirSync as mkdirSync7, rmSync as rmSync2, statSync as statSync12 } from "fs";
|
|
24930
|
-
import { dirname as dirname19, join as join21, resolve as
|
|
25144
|
+
import { dirname as dirname19, join as join21, resolve as resolve39 } from "path";
|
|
24931
25145
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
24932
25146
|
import { Command as Command37, Option as Option35 } from "clipanion";
|
|
24933
25147
|
|
|
@@ -25101,11 +25315,11 @@ function resolveSkillSourceDir(variant) {
|
|
|
25101
25315
|
const here = dirname19(fileURLToPath6(import.meta.url));
|
|
25102
25316
|
const candidates = [
|
|
25103
25317
|
// dev: src/cli/commands/ → repo-root .claude/skills/<slug>/
|
|
25104
|
-
|
|
25318
|
+
resolve39(here, "../../..", spec.sourceDir),
|
|
25105
25319
|
// bundled: dist/cli.js → dist/cli/tutorial/<slug> (sibling)
|
|
25106
|
-
|
|
25320
|
+
resolve39(here, "cli/tutorial", spec.slug),
|
|
25107
25321
|
// bundled fallback: any-depth → cli/tutorial/<slug>
|
|
25108
|
-
|
|
25322
|
+
resolve39(here, "../cli/tutorial", spec.slug)
|
|
25109
25323
|
];
|
|
25110
25324
|
for (const candidate of candidates) {
|
|
25111
25325
|
if (existsSync32(candidate) && statSync12(candidate).isDirectory()) {
|