patchcord 0.6.21 → 0.6.22

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "patchcord",
3
3
  "description": "Cross-machine agent messaging. Messages from other agents land in the inbox and wake the agent to reply.",
4
- "version": "0.6.21",
4
+ "version": "0.6.22",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -1900,6 +1900,29 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
1900
1900
  } else if (allowlistChanged) {
1901
1901
  globalChanges.push("Cursor MCP allowlist configured");
1902
1902
  }
1903
+
1904
+ // cursor-agent v2026.07+ reads ~/.cursor/cli-config.json permissions.allow
1905
+ // for MCP — permissions.json mcpAllowlist alone leaves patchcord unloaded.
1906
+ const cliConfigPath = join(HOME, ".cursor", "cli-config.json");
1907
+ let cliAllowChanged = false;
1908
+ const cliOk = updateJsonConfig(cliConfigPath, (obj) => {
1909
+ obj.permissions = obj.permissions || {};
1910
+ if (!obj.permissions.allow) obj.permissions.allow = [];
1911
+ if (!Array.isArray(obj.permissions.allow)) {
1912
+ console.log(`\n ${yellow}⚠${r} Skipped Cursor CLI MCP allow — ${cliConfigPath} permissions.allow is not an array.`);
1913
+ return;
1914
+ }
1915
+ const pat = "Mcp(patchcord:*)";
1916
+ if (!obj.permissions.allow.includes(pat)) {
1917
+ obj.permissions.allow.push(pat);
1918
+ cliAllowChanged = true;
1919
+ }
1920
+ });
1921
+ if (!cliOk) {
1922
+ globalChanges.push("✗ Cursor CLI permissions error");
1923
+ } else if (cliAllowChanged) {
1924
+ globalChanges.push("Cursor CLI MCP allowlist configured");
1925
+ }
1903
1926
  }
1904
1927
  }
1905
1928
 
@@ -2337,6 +2360,12 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
2337
2360
  }
2338
2361
  toolSlug = toolFlag; // preserved as-is for the URL param
2339
2362
  }
2363
+ // cursor-agent --yolo runs npx patchcord without --tool=cursor; auto-select
2364
+ // Cursor so provision writes .cursor/mcp.json for this harness.
2365
+ if (!choice && process.env.CURSOR_AGENT) {
2366
+ choice = CLIENT_TYPE_MAP.cursor;
2367
+ toolSlug = toolSlug || "cursor";
2368
+ }
2340
2369
 
2341
2370
  // --token bypass for power users / CI / self-hosters
2342
2371
  const tokenFlag = flags.find(f => f.startsWith("--token="))?.split("=")[1]
@@ -2387,12 +2416,14 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
2387
2416
  let existingToken = "";
2388
2417
  let existingConfigFile = "";
2389
2418
  const mcpJsonPath = join(cwd, ".mcp.json");
2419
+ const cursorMcpPath = join(cwd, ".cursor", "mcp.json");
2390
2420
  const codexTomlPath = join(cwd, ".codex", "config.toml");
2391
2421
  const grokTomlPath = join(cwd, ".grok", "config.toml");
2392
2422
  const kimiJsonPath = join(cwd, ".kimi", "mcp.json");
2393
2423
 
2394
- const slugForCheck = toolSlug ? toolSlug.replace(/-/g, "_") : "";
2424
+ const slugForCheck = toolSlug ? toolSlug.replace(/-/g, "_") : (process.env.CURSOR_AGENT ? "cursor" : "");
2395
2425
  const checkMcpJson = !slugForCheck || slugForCheck === "claude_code";
2426
+ const checkCursorJson = !slugForCheck || slugForCheck === "cursor";
2396
2427
  const checkCodexToml = !slugForCheck || slugForCheck === "codex";
2397
2428
  const checkGrokToml = !slugForCheck || ["grok", "grok_cli", "grok_build"].includes(slugForCheck);
2398
2429
  const checkKimiJson = !slugForCheck || slugForCheck === "kimi";
@@ -2407,6 +2438,16 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
2407
2438
  }
2408
2439
  } catch {}
2409
2440
  }
2441
+ if (!existingToken && checkCursorJson && existsSync(cursorMcpPath)) {
2442
+ try {
2443
+ const existing = JSON.parse(readFileSync(cursorMcpPath, "utf-8"));
2444
+ const pt = existing?.mcpServers?.patchcord;
2445
+ if (pt?.headers?.Authorization) {
2446
+ existingToken = pt.headers.Authorization.replace(/^Bearer\s+/i, "");
2447
+ existingConfigFile = cursorMcpPath;
2448
+ }
2449
+ } catch {}
2450
+ }
2410
2451
  if (!existingToken && checkCodexToml && existsSync(codexTomlPath)) {
2411
2452
  try {
2412
2453
  const content = readFileSync(codexTomlPath, "utf-8");
@@ -2729,6 +2770,17 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
2729
2770
  console.log(`\n ${green}✓${r} Cursor configured: ${dim}${cursorPath}${r}`);
2730
2771
  console.log(` ${dim}Per-project only — other projects won't see this agent.${r}`);
2731
2772
  }
2773
+ const cursorCliPath = join(cursorDir, "cli.json");
2774
+ const cursorCliOk = updateJsonConfig(cursorCliPath, (obj) => {
2775
+ obj.permissions = obj.permissions || {};
2776
+ if (!obj.permissions.allow) obj.permissions.allow = [];
2777
+ if (!Array.isArray(obj.permissions.allow)) return;
2778
+ const pat = "Mcp(patchcord:*)";
2779
+ if (!obj.permissions.allow.includes(pat)) obj.permissions.allow.push(pat);
2780
+ });
2781
+ if (cursorCliOk) {
2782
+ console.log(` ${green}✓${r} Cursor CLI permissions: ${dim}${cursorCliPath}${r}`);
2783
+ }
2732
2784
  } else if (isGrok) {
2733
2785
  // Grok CLI: project-scoped .grok/config.toml. Grok loads this file from
2734
2786
  // the current directory up through the git root, so the bearer remains
@@ -3381,6 +3433,8 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
3381
3433
 
3382
3434
  if (isOpenClaw) {
3383
3435
  console.log(`\n${dim}Run${r} ${bold}openclaw gateway restart${r}${dim}, then tools will be available in your channels.${r}`);
3436
+ } else if (isCursor && hasCursorAgent) {
3437
+ console.log(`\n ${green}→${r} ${bold}Exit and start a new ${cyan}cursor-agent${r}${bold} session${r} ${dim}(MCP loads at session start)${r}`);
3384
3438
  } else if (isKimiCode) {
3385
3439
  console.log(`\n ${green}→${r} ${bold}Restart ${cyan}kimi${r}${bold} in this project (or run ${cyan}/reload${r}${bold}), then say: ${cyan}${bold}check inbox${r}`);
3386
3440
  } else if (isKimi) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.6.21",
3
+ "version": "0.6.22",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "scripts": {
6
6
  "version": "node scripts/sync-plugin-version.mjs && git add .claude-plugin/plugin.json"