@heretyc/subagent-mcp 2.7.0 → 2.7.1

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.
Files changed (2) hide show
  1. package/dist/index.js +69 -5
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { z } from "zod";
5
- import { spawn, execSync } from "child_process";
6
- import { unlinkSync, existsSync, realpathSync } from "node:fs";
5
+ import { spawn, spawnSync, execSync } from "child_process";
6
+ import { unlinkSync, existsSync, realpathSync, readFileSync } from "node:fs";
7
7
  import { randomUUID } from "crypto";
8
- import { isAbsolute, basename } from "node:path";
8
+ import { isAbsolute, basename, join, dirname } from "node:path";
9
9
  import { pathToFileURL } from "url";
10
10
  import { buildCommand } from "./effort.js";
11
11
  import { resolveExeFor } from "./platform.js";
@@ -888,15 +888,79 @@ server.tool("orchestration-mode", "Toggle or query per-project ORCHESTRATION MOD
888
888
  const isMain = process.argv[1] !== undefined &&
889
889
  import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href;
890
890
  if (isMain) {
891
- if (process.argv[2] === "setup") {
891
+ // CLI argument guard — runs BEFORE the stdio transport connects. Any argv[2]
892
+ // other than the known commands used to fall through and silently start the
893
+ // MCP server, which blocks forever waiting on stdin (`subagent-mcp --version`
894
+ // hung indefinitely). Only a bare invocation may reach the server below.
895
+ const arg = process.argv[2];
896
+ const usage = [
897
+ "Usage: subagent-mcp [command]",
898
+ "",
899
+ " (no command) start the MCP stdio server (how vendor CLIs run it)",
900
+ " setup [--dry-run] wire Claude Code CLI / Codex CLI (--dry-run: preview only)",
901
+ " doctor check install and wiring health",
902
+ " --update update to the latest release (npm install -g)",
903
+ " --version, -v print the installed version",
904
+ " --help, -h show this help",
905
+ ].join("\n");
906
+ // dist/index.js -> ../package.json (the installed package manifest).
907
+ const readPkg = () => JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
908
+ if (arg === "--version" || arg === "-v") {
909
+ console.log(readPkg().version);
910
+ process.exit(0);
911
+ }
912
+ if (arg === "--help" || arg === "-h") {
913
+ console.log(usage);
914
+ process.exit(0);
915
+ }
916
+ if (arg === "--update") {
917
+ const pkg = readPkg();
918
+ const npmArgs = ["install", "-g", `${pkg.name}@latest`];
919
+ console.log(`subagent-mcp ${pkg.version} -> npm ${npmArgs.join(" ")}`);
920
+ // npm on Windows is npm.cmd; spawning a .cmd without a shell fails
921
+ // (EINVAL on modern Node). Resolve the underlying npm-cli.js and run it
922
+ // with this same node binary: cmd-shim layout first (npm installed into a
923
+ // prefix), then the official Node-for-Windows layout (npm.cmd sitting
924
+ // next to node_modules\npm). POSIX spawns the npm executable directly.
925
+ const { findOnPath, resolveCmdShimNodeScript } = await import("./setup.js");
926
+ const npm = findOnPath("npm") ?? "npm";
927
+ let r;
928
+ if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(npm)) {
929
+ const sibling = join(dirname(npm), "node_modules", "npm", "bin", "npm-cli.js");
930
+ const js = resolveCmdShimNodeScript(npm) ?? (existsSync(sibling) ? sibling : null);
931
+ r = js
932
+ ? spawnSync(process.execPath, [js, ...npmArgs], { stdio: "inherit" })
933
+ : // Last resort: cmd.exe via shell. The arg vector is a fixed literal
934
+ // list (safe charset only), so there is no quoting/injection surface.
935
+ spawnSync("npm", npmArgs, { stdio: "inherit", shell: true });
936
+ }
937
+ else {
938
+ r = spawnSync(npm, npmArgs, { stdio: "inherit" });
939
+ }
940
+ if (r.error) {
941
+ console.error(`update failed to start npm: ${r.error.message}`);
942
+ process.exit(1);
943
+ }
944
+ const code = r.status ?? 1;
945
+ if (code === 0) {
946
+ console.log("Update complete. Restart your CLI sessions so the MCP server picks up the new build.");
947
+ }
948
+ process.exit(code);
949
+ }
950
+ if (arg === "setup") {
892
951
  const { runSetup } = await import("./setup.js");
893
952
  await runSetup();
894
953
  process.exit(0);
895
954
  }
896
- if (process.argv[2] === "doctor") {
955
+ if (arg === "doctor") {
897
956
  const { runDoctor } = await import("./doctor.js");
898
957
  process.exit(await runDoctor());
899
958
  }
959
+ if (arg !== undefined && arg !== "") {
960
+ console.error(`unknown argument: ${arg}`);
961
+ console.error(usage);
962
+ process.exit(1);
963
+ }
900
964
  // ORCHESTRATION MODE PERSISTS across restarts/sessions: the server does NOT
901
965
  // clear the marker on startup. DEFAULT OFF now means ABSENCE of a marker — a
902
966
  // project never enabled stays OFF; a project explicitly enabled persists ON
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heretyc/subagent-mcp",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "MCP server that launches and manages local Claude Code and Codex CLI sub-agents as child processes (no direct Anthropic/OpenAI API).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "postinstall": "node scripts/postinstall.mjs",
22
22
  "prepare": "npm run build",
23
23
  "prepublishOnly": "npm test",
24
- "test": "node test/effort.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-directives.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/mcp-compliance.test.mjs"
24
+ "test": "node test/effort.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-directives.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node test/cli-args.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/mcp-compliance.test.mjs"
25
25
  },
26
26
  "author": "Lexi Blackburn",
27
27
  "license": "Apache-2.0",