@yawlabs/mcp 0.60.1 → 0.60.3

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/CHANGELOG.md CHANGED
@@ -1,6 +1,23 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to `@yawlabs/mcp` (formerly `@yawlabs/mcph`) are documented here. This project uses [semantic versioning](https://semver.org) and a CI-gated release flow: pushing a `vX.Y.Z` tag triggers `.github/workflows/release.yml`, which publishes to npm.
3
+ All notable changes to `@yawlabs/mcp` (formerly `@yawlabs/mcph`) are documented here. This project uses [semantic versioning](https://semver.org) and a script-gated release flow: `./release.sh <version>` runs lint + tests + build, bumps, tags, publishes to npm, and creates the GitHub release.
4
+
5
+ ## 0.60.2 -- pnpm/bun global stores upgrade with their owning tool
6
+
7
+ - `yaw-mcp upgrade` now detects pnpm global stores (`<pnpm-home>/global/<n>/node_modules/...`) and bun global installs (`~/.bun/install/global/...`) as their own install methods. `--run` spawns `pnpm add -g` / `bun add -g @yawlabs/mcp@latest` instead of misclassifying them as local node_modules trees -- which would have npm-installed a foreign package-lock + node_modules into the tool manager's internal store.
8
+ - `yaw-mcp doctor`'s UPGRADE AVAILABLE hint includes pnpm/bun globals in the "`yaw-mcp upgrade --run` works here" set.
9
+
10
+ ## 0.60.1 -- scoop/custom-prefix npm globals detected correctly
11
+
12
+ - npm prefixes that live in a `bin` directory (scoop's nodejs persist dir, custom prefixes) put globals at `<prefix>/node_modules` with no `npm`/`lib`/`AppData` marker in the path, so they misclassified as `local-node-modules` -- `upgrade --run` then refused (pre-0.60.0) or npm-installed into the node prefix instead of upgrading the global. New `/bin/node_modules/` marker classifies them as `global-npm`.
13
+
14
+ ## 0.60.0 -- nag removed; `upgrade --run` actually upgrades
15
+
16
+ - **The free-tier nag interstitial is gone.** Yaw MCP is free (the Pro tier is retired); `src/nag.ts`, its state file handling, and the dispatch gate were deleted. `YAW_MCP_NO_NAG` no longer has any effect -- there is nothing left to suppress. Remaining Pro references in help text, README, and the package description now read Yaw Team.
17
+ - **`yaw-mcp upgrade --run` upgrades local node_modules installs in place** instead of refusing and printing another command: it derives the package-tree root from the running entrypoint's path and runs `npm install @yawlabs/mcp@latest` there.
18
+ - **New `bundled-app` install method** for the copy that ships inside Yaw Terminal (`app.asar.unpacked`): upgrade/doctor say plainly that it updates with the app instead of suggesting an npm command that can never affect it.
19
+ - **Method-aware `doctor` upgrade hints**: the UPGRADE AVAILABLE section prints the user's terminal action for their install method, never a command that turns around and prints another command.
20
+ - Upgrade/doctor output puts commands on their own line with no trailing punctuation so they copy cleanly.
4
21
 
5
22
  ## 0.58.0 -- Rename to Yaw MCP + local-first Free mode + Pro nag + sync client
6
23
 
package/dist/index.js CHANGED
@@ -2820,6 +2820,7 @@ async function gcExpiredTrials(opts) {
2820
2820
 
2821
2821
  // src/upgrade-cmd.ts
2822
2822
  import { spawn as spawn2 } from "child_process";
2823
+ import { realpathSync } from "fs";
2823
2824
  var UPGRADE_USAGE = `Usage: yaw-mcp upgrade [--run] [--json]
2824
2825
 
2825
2826
  Show (or execute) the command to upgrade @yawlabs/mcp to the latest version.
@@ -2849,6 +2850,8 @@ function detectInstallMethod(argvPath) {
2849
2850
  if (/\/lib\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "global-npm";
2850
2851
  if (/\/AppData\/Roaming\/npm\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "global-npm";
2851
2852
  if (/\/bin\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "global-npm";
2853
+ if (/\/pnpm\/global\/\d+\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "pnpm-global";
2854
+ if (/\/\.bun\/install\/global\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "bun-global";
2852
2855
  if (/\/node_modules\/@yawlabs\/mcp\//.test(normalized)) return "local-node-modules";
2853
2856
  if (/\/(yaw-mcp|mcph)\/(dist|src)\//.test(normalized)) return "dev-checkout";
2854
2857
  return "unknown";
@@ -2858,6 +2861,52 @@ function localInstallRoot(argvPath) {
2858
2861
  const idx = argvPath.replace(/\\/g, "/").indexOf("/node_modules/");
2859
2862
  return idx > 0 ? argvPath.slice(0, idx) : null;
2860
2863
  }
2864
+ async function defaultNpmPrefix() {
2865
+ if (process.env.VITEST) return null;
2866
+ return new Promise((resolve5) => {
2867
+ const child = spawn2("npm", ["prefix", "-g"], {
2868
+ shell: process.platform === "win32",
2869
+ stdio: ["ignore", "pipe", "ignore"]
2870
+ });
2871
+ let out = "";
2872
+ const timer = setTimeout(() => {
2873
+ child.kill();
2874
+ resolve5(null);
2875
+ }, 3e3);
2876
+ child.stdout?.on("data", (d) => {
2877
+ out += String(d);
2878
+ });
2879
+ child.on("close", (code) => {
2880
+ clearTimeout(timer);
2881
+ resolve5(code === 0 && out.trim() ? out.trim() : null);
2882
+ });
2883
+ child.on("error", () => {
2884
+ clearTimeout(timer);
2885
+ resolve5(null);
2886
+ });
2887
+ });
2888
+ }
2889
+ function comparablePath(p) {
2890
+ let real = p;
2891
+ try {
2892
+ real = realpathSync(p);
2893
+ } catch {
2894
+ }
2895
+ const normalized = real.replace(/\\/g, "/");
2896
+ return process.platform === "win32" ? normalized.toLowerCase() : normalized;
2897
+ }
2898
+ async function refineInstallMethod(method, argvPath, npmPrefix = defaultNpmPrefix) {
2899
+ if (method !== "local-node-modules" && method !== "unknown") return method;
2900
+ if (!argvPath) return method;
2901
+ const prefix = await npmPrefix();
2902
+ if (!prefix) return method;
2903
+ const entry = comparablePath(argvPath);
2904
+ const pfx = comparablePath(prefix);
2905
+ if (entry.startsWith(`${pfx}/node_modules/`) || entry.startsWith(`${pfx}/lib/node_modules/`)) {
2906
+ return "global-npm";
2907
+ }
2908
+ return method;
2909
+ }
2861
2910
  function buildUpgradePlan(input) {
2862
2911
  const { current, latest, method } = input;
2863
2912
  const stale = latest !== null && current !== "dev" && compareSemverLocal(current, latest) < 0;
@@ -2866,6 +2915,12 @@ function buildUpgradePlan(input) {
2866
2915
  case "global-npm":
2867
2916
  command = "npm install -g @yawlabs/mcp@latest";
2868
2917
  break;
2918
+ case "pnpm-global":
2919
+ command = "pnpm add -g @yawlabs/mcp@latest";
2920
+ break;
2921
+ case "bun-global":
2922
+ command = "bun add -g @yawlabs/mcp@latest";
2923
+ break;
2869
2924
  case "npx":
2870
2925
  command = null;
2871
2926
  break;
@@ -2940,7 +2995,7 @@ async function runUpgrade(opts = {}) {
2940
2995
  const fetcher = opts.fetchLatest ?? defaultFetchLatest;
2941
2996
  const current = opts.currentVersion ?? readCurrentVersion();
2942
2997
  const argvPath = opts.argvPath ?? process.argv[1];
2943
- const method = detectInstallMethod(argvPath);
2998
+ const method = await refineInstallMethod(detectInstallMethod(argvPath), argvPath, opts.npmPrefix);
2944
2999
  let latest;
2945
3000
  try {
2946
3001
  latest = await fetcher();
@@ -2988,9 +3043,9 @@ async function runUpgrade(opts = {}) {
2988
3043
  return { exitCode: 0, lines };
2989
3044
  }
2990
3045
  const installRoot = method === "local-node-modules" ? localInstallRoot(argvPath) : null;
2991
- const autoRunnable = method === "global-npm" || method === "local-node-modules" && installRoot !== null;
3046
+ const runSpec = method === "global-npm" ? { cmd: "npm", args: ["install", "-g", "@yawlabs/mcp@latest"] } : method === "pnpm-global" ? { cmd: "pnpm", args: ["add", "-g", "@yawlabs/mcp@latest"] } : method === "bun-global" ? { cmd: "bun", args: ["add", "-g", "@yawlabs/mcp@latest"] } : method === "local-node-modules" && installRoot !== null ? { cmd: "npm", args: ["install", "@yawlabs/mcp@latest"], cwd: installRoot } : null;
2992
3047
  if (!opts.run) {
2993
- if (autoRunnable) {
3048
+ if (runSpec) {
2994
3049
  print("Run `yaw-mcp upgrade --run` to upgrade in place, or run it yourself:");
2995
3050
  } else {
2996
3051
  print("Run it yourself (--run can't safely automate this install method):");
@@ -2999,34 +3054,33 @@ async function runUpgrade(opts = {}) {
2999
3054
  print(` ${plan.command}`);
3000
3055
  return { exitCode: 1, lines };
3001
3056
  }
3002
- if (!autoRunnable) {
3057
+ if (!runSpec) {
3003
3058
  printErr(`yaw-mcp upgrade --run: a "${method}" install can't be upgraded automatically. Run it yourself:`);
3004
3059
  printErr("");
3005
3060
  printErr(` ${plan.command}`);
3006
3061
  return { exitCode: 2, lines };
3007
3062
  }
3008
3063
  const runner = opts.spawnImpl ?? defaultSpawn;
3009
- const npmArgs = method === "global-npm" ? ["install", "-g", "@yawlabs/mcp@latest"] : ["install", "@yawlabs/mcp@latest"];
3010
- if (installRoot) {
3011
- print(`Running in ${installRoot}:`);
3064
+ if (runSpec.cwd) {
3065
+ print(`Running in ${runSpec.cwd}:`);
3012
3066
  } else {
3013
3067
  print("Running:");
3014
3068
  }
3015
3069
  print(` ${plan.command}`);
3016
3070
  print("");
3017
- const code = await runner("npm", npmArgs, installRoot ?? void 0);
3071
+ const code = await runner(runSpec.cmd, runSpec.args, runSpec.cwd);
3018
3072
  if (code === 0) {
3019
3073
  print("");
3020
3074
  print(`\u2713 Upgraded @yawlabs/mcp to ${latest}`);
3021
3075
  return { exitCode: 0, lines };
3022
3076
  }
3023
- printErr(`yaw-mcp upgrade: npm exited ${code}. Try running the command yourself:`);
3077
+ printErr(`yaw-mcp upgrade: ${runSpec.cmd} exited ${code}. Try running the command yourself:`);
3024
3078
  printErr("");
3025
3079
  printErr(` ${plan.command}`);
3026
3080
  return { exitCode: 3, lines };
3027
3081
  }
3028
3082
  function readCurrentVersion() {
3029
- return true ? "0.60.1" : "dev";
3083
+ return true ? "0.60.3" : "dev";
3030
3084
  }
3031
3085
 
3032
3086
  // src/usage-hints.ts
@@ -3088,7 +3142,7 @@ function selectFlakyNamespaces(entries, limit) {
3088
3142
  }
3089
3143
 
3090
3144
  // src/doctor-cmd.ts
3091
- var VERSION = true ? "0.60.1" : "dev";
3145
+ var VERSION = true ? "0.60.3" : "dev";
3092
3146
  async function runDoctor(opts = {}) {
3093
3147
  if (opts.json) return runDoctorJson(opts);
3094
3148
  const lines = [];
@@ -3160,7 +3214,7 @@ async function runDoctor(opts = {}) {
3160
3214
  const latest = skipCheck ? null : await fetchLatestVersion(opts.registryFetch);
3161
3215
  const staleHint = latest && VERSION !== "dev" && compareSemver(VERSION, latest) < 0 ? latest : null;
3162
3216
  if (staleHint) {
3163
- const method = detectInstallMethod(process.argv[1]);
3217
+ const method = await refineInstallMethod(detectInstallMethod(process.argv[1]), process.argv[1]);
3164
3218
  print("UPGRADE AVAILABLE");
3165
3219
  if (method === "bundled-app") {
3166
3220
  print(` Running ${VERSION}; npm latest is ${staleHint}. This copy ships inside`);
@@ -3168,7 +3222,7 @@ async function runDoctor(opts = {}) {
3168
3222
  } else if (method === "npx") {
3169
3223
  print(` Running ${VERSION}; npm latest is ${staleHint}. npx fetches the latest`);
3170
3224
  print(" on each spawn \u2014 restart your MCP client to pick it up.");
3171
- } else if (method === "global-npm" || method === "local-node-modules") {
3225
+ } else if (method === "global-npm" || method === "pnpm-global" || method === "bun-global" || method === "local-node-modules") {
3172
3226
  print(` Running ${VERSION}; npm latest is ${staleHint}. To upgrade in place:`);
3173
3227
  print("");
3174
3228
  print(" yaw-mcp upgrade --run");
@@ -5076,16 +5130,21 @@ function defaultSpawn2(cmd, args) {
5076
5130
  async function maybeAutoUpgrade(deps = {}) {
5077
5131
  const optOut = process.env.YAW_MCP_AUTO_UPGRADE;
5078
5132
  if (optOut === "0" || optOut?.toLowerCase() === "false") return;
5079
- const current = deps.currentVersion ?? (true ? "0.60.1" : "dev");
5133
+ const current = deps.currentVersion ?? (true ? "0.60.3" : "dev");
5080
5134
  if (current === "dev") return;
5081
5135
  const method = detectInstallMethod(deps.argvPath ?? process.argv[1]);
5082
5136
  const latest = await (deps.fetchLatestImpl ?? fetchLatestVersion2)();
5083
5137
  if (latest === null) return;
5084
5138
  const plan = buildUpgradePlan({ current, latest, method });
5085
5139
  if (!plan.stale) return;
5086
- if (method === "global-npm") {
5087
- log("info", "yaw-mcp is out of date; upgrading the global install in the background", { current, latest });
5088
- (deps.spawnImpl ?? defaultSpawn2)("npm", ["install", "-g", "@yawlabs/mcp@latest"]);
5140
+ const globalSpec = method === "global-npm" ? { cmd: "npm", args: ["install", "-g", "@yawlabs/mcp@latest"] } : method === "pnpm-global" ? { cmd: "pnpm", args: ["add", "-g", "@yawlabs/mcp@latest"] } : method === "bun-global" ? { cmd: "bun", args: ["add", "-g", "@yawlabs/mcp@latest"] } : null;
5141
+ if (globalSpec) {
5142
+ log("info", "yaw-mcp is out of date; upgrading the global install in the background", {
5143
+ current,
5144
+ latest,
5145
+ tool: globalSpec.cmd
5146
+ });
5147
+ (deps.spawnImpl ?? defaultSpawn2)(globalSpec.cmd, globalSpec.args);
5089
5148
  return;
5090
5149
  }
5091
5150
  if (method === "bundled-app") {
@@ -7349,7 +7408,7 @@ function categorizeSpawnError(err) {
7349
7408
  }
7350
7409
  async function connectToUpstream(config, onDisconnect, onListChanged) {
7351
7410
  const client = new Client(
7352
- { name: "yaw-mcp", version: true ? "0.60.1" : "dev" },
7411
+ { name: "yaw-mcp", version: true ? "0.60.3" : "dev" },
7353
7412
  { capabilities: {} }
7354
7413
  );
7355
7414
  let transport;
@@ -7658,7 +7717,7 @@ var ConnectServer = class _ConnectServer {
7658
7717
  this.apiUrl = apiUrl5;
7659
7718
  this.token = token5;
7660
7719
  this.server = new Server(
7661
- { name: "yaw-mcp", version: true ? "0.60.1" : "dev" },
7720
+ { name: "yaw-mcp", version: true ? "0.60.3" : "dev" },
7662
7721
  {
7663
7722
  capabilities: {
7664
7723
  tools: { listChanged: true },
@@ -10629,7 +10688,7 @@ if (subcommand === "compliance") {
10629
10688
  `);
10630
10689
  process.exit(0);
10631
10690
  } else if (subcommand === "--version" || subcommand === "-V") {
10632
- process.stdout.write(`yaw-mcp ${true ? "0.60.1" : "dev"}
10691
+ process.stdout.write(`yaw-mcp ${true ? "0.60.3" : "dev"}
10633
10692
  `);
10634
10693
  process.exit(0);
10635
10694
  } else if (subcommand && !subcommand.startsWith("-")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/mcp",
3
- "version": "0.60.1",
3
+ "version": "0.60.3",
4
4
  "mcpName": "io.github.YawLabs/mcp",
5
5
  "description": "Yaw MCP -- MCP servers, managed. Free to run locally; Yaw Team adds cross-machine sync.",
6
6
  "license": "UNLICENSED",