agent-skills-standard 2.7.3 → 2.7.4

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 CHANGED
@@ -181,12 +181,12 @@ The CLI **distributes** skills as static files. The companion [`agent-skills-sta
181
181
  ags mcp status # show current state + per-agent install
182
182
  ags mcp scope project # project | user | snippets-only | disabled
183
183
  ags mcp via auto # auto | npx | global launch mode (auto prefers a version-matched global ags-mcp)
184
- ags mcp enable --install-global # npm i -g agent-skills-standard-mcp@<pin>, then verify the reported version
184
+ ags mcp enable # opt in; global launch mode installs agent-skills-standard-mcp@<pin> and verifies it
185
185
  ags mcp install # apply changes
186
186
  ags mcp uninstall --from project # remove our entry; siblings preserved
187
187
  ```
188
188
 
189
- Launch mode defaults to `auto`: the generated entry uses a globally installed `ags-mcp` only when its `--version` exactly matches the CLI pin, and otherwise falls back to `npx -y --prefer-offline agent-skills-standard-mcp@<pin>`. `ags mcp status` prints the resolved launch line, the pin, and the detected global version; `ags mcp install --via <mode>` overrides the mode for that run without persisting it. `ags upgrade` does not rewrite runtime configs — run `ags sync` (or `ags mcp install`) to move them to the new pin; `ags mcp status` and `ags doctor` flag configured-vs-expected drift.
189
+ Launch mode defaults to `auto`: the generated entry uses a globally installed `ags-mcp` only when its `--version` exactly matches the CLI pin, and otherwise falls back to `npx -y --prefer-offline agent-skills-standard-mcp@<pin>`. With `via: global` (saved mode, or `ags mcp enable --via global`), `ags mcp enable` installs `agent-skills-standard-mcp@<pin>` globally via npm, verifies the reported version, then writes the runtime configs; a failed install or mismatched probe exits `1` and leaves `.skillsrc` and the configs untouched. `--install-global` remains available as an explicit trigger for the same install. `ags mcp status` prints the resolved launch line, the pin, and the detected global version; `ags mcp install --via <mode>` overrides the mode for that run without persisting it. `ags upgrade` does not rewrite runtime configs — run `ags sync` (or `ags mcp install`) to move them to the new pin; `ags mcp status` and `ags doctor` flag configured-vs-expected drift.
190
190
 
191
191
  The CLI **never** modifies user-home files (`~/.cursor/mcp.json`, `~/.gemini/settings.json`, etc.) unless you explicitly choose `scope: user` AND confirm each write. See [`mcp/README.md`](../mcp/README.md) for full details and [`mcp/ARCHITECTURE.md`](../mcp/ARCHITECTURE.md) for the threat model.
192
192
 
package/dist/index.js CHANGED
@@ -53,7 +53,7 @@ let crypto = require("crypto");
53
53
  crypto = __toESM(crypto);
54
54
  var package_default = {
55
55
  name: "agent-skills-standard",
56
- version: "2.7.3",
56
+ version: "2.7.4",
57
57
  description: "A CLI to manage and sync AI agent skills standard for Cursor, Claude, Copilot, Windsurf, and more.",
58
58
  main: "dist/index.js",
59
59
  bin: {
@@ -3638,7 +3638,7 @@ var LockfileService = class {
3638
3638
  * Bumped automatically by `scripts/release-mcp.ts` when the MCP package is
3639
3639
  * released and gated in CI, so this pin always matches `mcp/package.json`.
3640
3640
  */
3641
- var MCP_COMPATIBLE_VERSION = "0.8.0";
3641
+ var MCP_COMPATIBLE_VERSION = "0.8.1";
3642
3642
  /**
3643
3643
  * Minimum `agent-skills-standard-mcp` version required for session retrospectives.
3644
3644
  */
@@ -3817,6 +3817,27 @@ var getTargets = (home = os.default.homedir(), platform = process.platform) => {
3817
3817
  return out;
3818
3818
  };
3819
3819
  /**
3820
+ * Command used to run `ags-mcp --version`.
3821
+ *
3822
+ * On Windows npm exposes the binary as a `.cmd` shim, which `execFileSync`
3823
+ * cannot spawn directly (ENOENT), so the probe goes through `cmd /c` — the
3824
+ * same shape the generated global launch entry uses. POSIX keeps the bare
3825
+ * binary with no shell.
3826
+ */
3827
+ function globalVersionProbeCommand(platform = process.platform) {
3828
+ return platform === "win32" ? {
3829
+ command: "cmd",
3830
+ args: [
3831
+ "/c",
3832
+ "ags-mcp",
3833
+ "--version"
3834
+ ]
3835
+ } : {
3836
+ command: "ags-mcp",
3837
+ args: ["--version"]
3838
+ };
3839
+ }
3840
+ /**
3820
3841
  * Owns all MCP-config writes. Pure logic — never prompts the user directly.
3821
3842
  * The caller (sync command, mcp subcommand) supplies a `userScopePrompt`
3822
3843
  * callback that is invoked ONLY when the user has chosen `scope: 'user'` AND
@@ -3835,7 +3856,7 @@ var McpConfigService = class {
3835
3856
  * stale global must never be silently preferred over the pin.
3836
3857
  */
3837
3858
  buildEntry(opts = {}) {
3838
- const version = opts.version || "0.8.0";
3859
+ const version = opts.version || "0.8.1";
3839
3860
  const via = opts.via ?? "auto";
3840
3861
  const platform = this.testPlatform ?? process.platform;
3841
3862
  if (via === "global" || via === "auto" && platform !== "win32" && this.detectGlobalVersion() === version) return platform === "win32" ? {
@@ -3863,19 +3884,46 @@ var McpConfigService = class {
3863
3884
  * 2. the manifest under `npm root -g` — required for servers published
3864
3885
  * before `--version` existed, where probe 1 either prints nothing or
3865
3886
  * times out because the stdio server starts normally instead.
3866
- * A missing binary (ENOENT) never falls through: an installed manifest
3867
- * alone does not prove the command is on the client's PATH.
3887
+ * A missing binary never falls through: an installed manifest alone does
3888
+ * not prove the command is on the client's PATH. POSIX surfaces that as
3889
+ * ENOENT; win32 (which probes through `cmd /c`) proves it with
3890
+ * `where.exe ags-mcp` before allowing the legacy manifest fallback.
3868
3891
  */
3869
3892
  detectGlobalVersion() {
3870
3893
  const binaryVersion = this.probeGlobalBinaryVersion();
3871
3894
  if (binaryVersion === GLOBAL_BINARY_MISSING) return null;
3872
- return binaryVersion ?? this.probeGlobalManifestVersion();
3895
+ if (binaryVersion) return binaryVersion;
3896
+ if (!this.probeGlobalBinaryOnPath()) return null;
3897
+ return this.probeGlobalManifestVersion();
3898
+ }
3899
+ /**
3900
+ * Whether `ags-mcp` resolves on PATH. POSIX misses already surface as
3901
+ * ENOENT in the version probe, so only win32 needs the explicit check.
3902
+ */
3903
+ probeGlobalBinaryOnPath() {
3904
+ if ((this.testPlatform ?? process.platform) !== "win32") return true;
3905
+ if (this.testGlobalPathProbe) return this.testGlobalPathProbe();
3906
+ try {
3907
+ const output = (0, child_process.execFileSync)("where.exe", ["ags-mcp"], {
3908
+ encoding: "utf8",
3909
+ timeout: 2e3,
3910
+ stdio: [
3911
+ "ignore",
3912
+ "pipe",
3913
+ "ignore"
3914
+ ]
3915
+ });
3916
+ return String(output).trim().length > 0;
3917
+ } catch {
3918
+ return false;
3919
+ }
3873
3920
  }
3874
3921
  /** `ags-mcp --version`, or the sentinel when the command is not on PATH. */
3875
3922
  probeGlobalBinaryVersion() {
3876
3923
  try {
3877
3924
  if (this.testGlobalVersionProbe) return this.testGlobalVersionProbe();
3878
- const output = (0, child_process.execFileSync)("ags-mcp", ["--version"], {
3925
+ const { command, args } = globalVersionProbeCommand(this.testPlatform ?? process.platform);
3926
+ const output = (0, child_process.execFileSync)(command, args, {
3879
3927
  encoding: "utf8",
3880
3928
  timeout: 2e3,
3881
3929
  stdio: [
@@ -3934,6 +3982,11 @@ var McpConfigService = class {
3934
3982
  setGlobalManifestProbeForTesting(fn) {
3935
3983
  this.testGlobalManifestProbe = fn;
3936
3984
  }
3985
+ /** For testing: allows overriding the win32 PATH-resolution probe. */
3986
+ testGlobalPathProbe = null;
3987
+ setGlobalPathProbeForTesting(fn) {
3988
+ this.testGlobalPathProbe = fn;
3989
+ }
3937
3990
  getTargets() {
3938
3991
  return getTargets(this.testHome ?? void 0);
3939
3992
  }
@@ -4424,7 +4477,7 @@ var DoctorService = class {
4424
4477
  version: config.mcp.version,
4425
4478
  via: config.mcp.via
4426
4479
  });
4427
- const pin = config.mcp.version ?? "0.8.0";
4480
+ const pin = config.mcp.version ?? "0.8.1";
4428
4481
  const drifted = [];
4429
4482
  for (const row of rows) {
4430
4483
  if (scope === "project") {
@@ -10615,8 +10668,10 @@ function formatEntry(entry) {
10615
10668
  * uninstall [--from=...] Remove our entry from configs (project | user | all)
10616
10669
  * snippets [--via=...] Generate fresh snippet files in ./mcp-config-snippets/
10617
10670
  *
10618
- * `--install-global` (on enable) installs `agent-skills-standard-mcp@<pin>`
10619
- * globally, then verifies the installed binary reports the pin.
10671
+ * `enable` also installs `agent-skills-standard-mcp@<pin>` globally and
10672
+ * verifies the reported version whenever the effective launch mode is
10673
+ * `global` (saved mode or `--via global`) — no extra flag required.
10674
+ * `--install-global` remains as an explicit trigger for the same install.
10620
10675
  */
10621
10676
  var McpCommand = class {
10622
10677
  configService;
@@ -10630,6 +10685,32 @@ var McpCommand = class {
10630
10685
  setGlobalInstallerForTesting(fn) {
10631
10686
  this.globalInstaller = fn ?? defaultGlobalInstaller;
10632
10687
  }
10688
+ /**
10689
+ * Install the pinned package globally and prove the installed binary
10690
+ * reports that exact pin. Returns false (with exit code 1) when either
10691
+ * step fails so callers can abort before persisting or writing configs.
10692
+ */
10693
+ ensureGlobalPin(pin) {
10694
+ const spec = `${PACKAGE}@${pin}`;
10695
+ try {
10696
+ this.globalInstaller(spec);
10697
+ } catch {
10698
+ console.log(picocolors.default.red(`❌ Global install failed. Run manually:`));
10699
+ console.log(picocolors.default.gray(` npm i -g ${spec}`));
10700
+ process.exitCode = 1;
10701
+ return false;
10702
+ }
10703
+ const detected = this.mcpService.detectGlobalVersion();
10704
+ if (detected !== pin) {
10705
+ console.log(picocolors.default.red(`❌ Global ags-mcp reports ${detected ?? "no version"} but the CLI pin is ${pin}.`));
10706
+ if (!detected) console.log(picocolors.default.gray(" Probe found no usable version: check that npm's global bin directory is on PATH and that `ags-mcp --version` prints the expected pin."));
10707
+ console.log(picocolors.default.gray(` Run manually: npm i -g ${spec}`));
10708
+ process.exitCode = 1;
10709
+ return false;
10710
+ }
10711
+ console.log(picocolors.default.green(`✅ Global ags-mcp ${pin} installed and verified.`));
10712
+ return true;
10713
+ }
10633
10714
  async run(action, options = {}) {
10634
10715
  const config = await this.configService.loadConfig();
10635
10716
  if (!config) {
@@ -10663,7 +10744,7 @@ var McpCommand = class {
10663
10744
  console.log(` via : ${picocolors.default.cyan(mcp.via ?? "auto")}`);
10664
10745
  console.log(` prompted: ${mcp.prompted ? "yes" : "no"}`);
10665
10746
  if (mcp.version) console.log(` version : ${mcp.version}`);
10666
- const pin = mcp.version ?? "0.8.0";
10747
+ const pin = mcp.version ?? "0.8.1";
10667
10748
  const entry = this.mcpService.buildEntry({
10668
10749
  version: mcp.version,
10669
10750
  via: mcp.via
@@ -10714,6 +10795,19 @@ var McpCommand = class {
10714
10795
  console.log(picocolors.default.gray(" Run `ags mcp install` to write the entries, or `ags mcp disable` to clear the consent flag."));
10715
10796
  }
10716
10797
  }
10798
+ /**
10799
+ * Per-file consent for user-home MCP configs. Shared by every install path
10800
+ * so `enable` (including global mode) cannot drift from `actionInstall`.
10801
+ */
10802
+ async promptUserScopeWrite(agent, file) {
10803
+ const { ok } = await inquirer.default.prompt([{
10804
+ type: "confirm",
10805
+ name: "ok",
10806
+ message: `Write user-scope MCP config for ${picocolors.default.cyan(agent)} at ${picocolors.default.gray(file)}?`,
10807
+ default: false
10808
+ }]);
10809
+ return ok;
10810
+ }
10717
10811
  async actionEnable(config, agents, cwd, options) {
10718
10812
  const mcp = config.mcp ?? defaultMcpConfig();
10719
10813
  const viaOverrideRaw = options.via;
@@ -10726,25 +10820,10 @@ var McpCommand = class {
10726
10820
  console.log(picocolors.default.yellow("⚠️ scope is currently \"disabled\". Set a real scope first: `ags mcp scope project`"));
10727
10821
  return;
10728
10822
  }
10729
- if (options.installGlobal) {
10730
- const pin = mcp.version ?? "0.8.0";
10731
- const spec = `${PACKAGE}@${pin}`;
10732
- try {
10733
- this.globalInstaller(spec);
10734
- } catch {
10735
- console.log(picocolors.default.red(`❌ Global install failed. Run manually:`));
10736
- console.log(picocolors.default.gray(` npm i -g ${spec}`));
10737
- process.exitCode = 1;
10738
- return;
10739
- }
10740
- const detected = this.mcpService.detectGlobalVersion();
10741
- if (detected !== pin) {
10742
- console.log(picocolors.default.red(`❌ Global ags-mcp reports ${detected ?? "no version"} but the CLI pin is ${pin}.`));
10743
- console.log(picocolors.default.gray(` Run manually: npm i -g ${spec}`));
10744
- process.exitCode = 1;
10745
- return;
10746
- }
10747
- console.log(picocolors.default.green(`✅ Global ags-mcp ${pin} installed and verified.`));
10823
+ const effectiveVia = viaOverride ?? mcp.via ?? "auto";
10824
+ if (Boolean(options.installGlobal) || effectiveVia === "global") {
10825
+ const pin = mcp.version ?? "0.8.1";
10826
+ if (!this.ensureGlobalPin(pin)) return;
10748
10827
  }
10749
10828
  config.mcp = {
10750
10829
  ...mcp,
@@ -10753,16 +10832,18 @@ var McpCommand = class {
10753
10832
  };
10754
10833
  await this.configService.saveConfig(config);
10755
10834
  console.log(picocolors.default.green("✅ MCP enabled."));
10756
- if (viaOverride) {
10835
+ if (viaOverride || effectiveVia === "global") {
10836
+ const installVia = viaOverride ?? "global";
10757
10837
  const report = await this.mcpService.install({
10758
10838
  rootDir: cwd,
10759
10839
  agents,
10760
10840
  mcp: {
10761
10841
  ...config.mcp,
10762
- via: viaOverride
10763
- }
10842
+ via: installVia
10843
+ },
10844
+ userScopePrompt: (agent, file) => this.promptUserScopeWrite(agent, file)
10764
10845
  });
10765
- console.log(picocolors.default.gray(` Installed configs using launch mode "${viaOverride}".`));
10846
+ console.log(picocolors.default.gray(` Installed configs using launch mode "${installVia}".`));
10766
10847
  this.printReport(report, cwd);
10767
10848
  return;
10768
10849
  }
@@ -10781,7 +10862,7 @@ var McpCommand = class {
10781
10862
  };
10782
10863
  await this.configService.saveConfig(config);
10783
10864
  console.log(picocolors.default.green(`✅ MCP launch mode set to "${via}".`));
10784
- if (via === "global") console.log(picocolors.default.yellow("⚠️ \"global\" requires a matching global install: `ags mcp enable --install-global`."));
10865
+ if (via === "global") console.log(picocolors.default.yellow("⚠️ \"global\" requires a matching global install: `ags mcp enable` installs and verifies it automatically."));
10785
10866
  else if (via === "auto") console.log(picocolors.default.gray(" \"auto\" uses a version-matched global ags-mcp when present, otherwise npx."));
10786
10867
  }
10787
10868
  async actionDisable(config) {
@@ -10827,15 +10908,6 @@ var McpCommand = class {
10827
10908
  console.log(picocolors.default.yellow("Scope is \"disabled\" — nothing to install."));
10828
10909
  return;
10829
10910
  }
10830
- const userPrompt = async (agent, file) => {
10831
- const { ok } = await inquirer.default.prompt([{
10832
- type: "confirm",
10833
- name: "ok",
10834
- message: `Write user-scope MCP config for ${picocolors.default.cyan(agent)} at ${picocolors.default.gray(file)}?`,
10835
- default: false
10836
- }]);
10837
- return ok;
10838
- };
10839
10911
  const report = await this.mcpService.install({
10840
10912
  rootDir: cwd,
10841
10913
  agents,
@@ -10845,7 +10917,7 @@ var McpCommand = class {
10845
10917
  scope: effectiveScope,
10846
10918
  ...viaOverride ? { via: viaOverride } : {}
10847
10919
  },
10848
- userScopePrompt: userPrompt
10920
+ userScopePrompt: (agent, file) => this.promptUserScopeWrite(agent, file)
10849
10921
  });
10850
10922
  this.printReport(report, cwd);
10851
10923
  }
@@ -10992,7 +11064,7 @@ var RetrospectiveCommand = class {
10992
11064
  this.env = deps.env ?? process.env;
10993
11065
  this.customExit = deps.exit;
10994
11066
  this.log = deps.log ?? console.log;
10995
- this.mcpVersion = deps.mcpVersion ?? "0.8.0";
11067
+ this.mcpVersion = deps.mcpVersion ?? "0.8.1";
10996
11068
  }
10997
11069
  exit(code) {
10998
11070
  process.exitCode = code;
@@ -13804,7 +13876,7 @@ program.command("feedback").description("Report skill improvement opportunities
13804
13876
  program.command("upgrade").description("Upgrade the CLI to the latest version").option("--dry-run", "Check for updates without installing").action(async (options) => {
13805
13877
  await new UpgradeCommand().run(options);
13806
13878
  });
13807
- program.command("mcp <action> [scope]").description("Manage the optional MCP server integration. Actions: status | enable | disable | scope <project|user|snippets-only|disabled> | via <auto|npx|global> | install | uninstall | snippets").option("--scope <scope>", "Override scope for install (project|user|snippets-only|disabled)").option("--via <via>", "Override launch mode for this run (auto|npx|global)").option("--install-global", "On enable: install agent-skills-standard-mcp@<pin> globally, then verify its version").option("--from <from>", "For uninstall: project | user | all (default: project)").action(async (action, positional, opts) => {
13879
+ program.command("mcp <action> [scope]").description("Manage the optional MCP server integration. Actions: status | enable | disable | scope <project|user|snippets-only|disabled> | via <auto|npx|global> | install | uninstall | snippets").option("--scope <scope>", "Override scope for install (project|user|snippets-only|disabled)").option("--via <via>", "Override launch mode for this run (auto|npx|global)").option("--install-global", "On enable: install agent-skills-standard-mcp@<pin> globally, then verify its version (automatic when launch mode is global)").option("--from <from>", "For uninstall: project | user | all (default: project)").action(async (action, positional, opts) => {
13808
13880
  const merged = { ...opts };
13809
13881
  if (positional) {
13810
13882
  if (action === "via") merged.via = opts.via ?? positional;