patchcord 0.5.10 → 0.5.12

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 with push delivery. Messages from other agents arrive as native channel notifications.",
4
- "version": "0.5.10",
4
+ "version": "0.5.12",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -122,45 +122,10 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd === "--token" || cmd ===
122
122
  try { rmSync(npmCachePatchcord, { recursive: true, force: true }); } catch {}
123
123
  }
124
124
 
125
- // Stable plugin location: copy plugin files out of the bunx/npx temp
126
- // dir into a path under HOME that won't get reused across npx
127
- // invocations. Without this, `claude plugin marketplace add` points at
128
- // /tmp/bunx-1000-patchcord@latest/... which bunx aggressively caches
129
- // and may not re-download for "@latest" — so the marketplace can stay
130
- // pinned to a stale tarball, and `claude plugin update` resolves the
131
- // wrong (sometimes very old) version.
132
- let marketplaceSource = pluginRoot;
133
- try {
134
- const stableDir = join(HOME, ".patchcord", "plugin");
135
- if (existsSync(stableDir)) {
136
- rmSync(stableDir, { recursive: true, force: true });
137
- }
138
- mkdirSync(stableDir, { recursive: true });
139
- cpSync(pluginRoot, stableDir, { recursive: true });
140
- marketplaceSource = stableDir;
141
-
142
- // Some Claude Code versions silently keep the existing source path
143
- // on re-add for a marketplace name that's already registered. Wipe
144
- // any old patchcord-marketplace entry so the next `marketplace add`
145
- // is forced to write the new stable path.
146
- const kmpPath = join(HOME, ".claude", "plugins", "known_marketplaces.json");
147
- if (existsSync(kmpPath)) {
148
- try {
149
- const kmp = JSON.parse(readFileSync(kmpPath, "utf-8"));
150
- if (kmp["patchcord-marketplace"]) {
151
- delete kmp["patchcord-marketplace"];
152
- writeFileSync(kmpPath, JSON.stringify(kmp, null, 2) + "\n");
153
- }
154
- } catch {}
155
- }
156
- } catch (e) {
157
- globalChanges.push(`✗ Stable plugin path setup failed (${e.message}), falling back to bunx temp dir`);
158
- }
159
-
160
125
  // Always re-add marketplace (copies fresh files from this npx package)
161
126
  // and install/update plugin. Claude Code's built-in plugin update
162
127
  // doesn't detect new versions from local sources (#37252).
163
- run(`claude plugin marketplace add "${marketplaceSource}"`);
128
+ run(`claude plugin marketplace add "${pluginRoot}"`);
164
129
  const installed = run(`claude plugin list`)?.includes("patchcord");
165
130
  wasPluginInstalled = !!installed;
166
131
  if (installed) {
@@ -335,23 +300,45 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd === "--token" || cmd ===
335
300
  apiUrl = serverUrl;
336
301
  }
337
302
 
303
+ // --tool=<slug> — pre-select client type. The dashboard's
304
+ // /console/connect/<platform> tile pages emit `--tool=<slug>` in the
305
+ // displayed npx command so the user picks the agent type ONCE on the
306
+ // web UI; the installer skips its terminal picker, and the
307
+ // `&tool=<slug>` query param appended to the browser connectUrl below
308
+ // makes the web /connect page skip its picker too.
309
+ // Unknown slugs (incl. `replit`, `unknown`) silently fall through —
310
+ // the existing interactive flow takes over.
311
+ const toolFlag = flags.find(f => f.startsWith("--tool="))?.split("=")[1]
312
+ || (flags.includes("--tool") ? flags[flags.indexOf("--tool") + 1] : "");
313
+ let toolSlug = "";
314
+ if (toolFlag) {
315
+ const normalized = toolFlag.replace(/-/g, "_");
316
+ if (CLIENT_TYPE_MAP[normalized]) {
317
+ choice = CLIENT_TYPE_MAP[normalized];
318
+ }
319
+ toolSlug = toolFlag; // preserved as-is for the URL param
320
+ }
321
+
338
322
  // --token bypass for power users / CI / self-hosters
339
323
  const tokenFlag = flags.find(f => f.startsWith("--token="))?.split("=")[1]
340
324
  || (flags.includes("--token") ? flags[flags.indexOf("--token") + 1] : "");
341
325
 
342
326
  if (tokenFlag) {
343
- // --token bypass: need tool picker in terminal
344
- console.log(`\n${bold}Which tool are you setting up?${r}\n`);
345
- console.log(` ${cyan}1.${r} Claude Code ${cyan}5.${r} Gemini CLI`);
346
- console.log(` ${cyan}2.${r} Codex CLI ${cyan}6.${r} VS Code`);
347
- console.log(` ${cyan}3.${r} Cursor ${cyan}7.${r} Zed`);
348
- console.log(` ${cyan}4.${r} Windsurf ${cyan}8.${r} OpenCode`);
349
- console.log(` ${cyan}11.${r} Cline ${cyan}9.${r} OpenClaw\n`);
350
- choice = (await ask(`${dim}Choose (1-9, 11):${r} `)).trim();
351
- if (!["1","2","3","4","5","6","7","8","9","11"].includes(choice)) {
352
- console.error("Invalid choice.");
353
- rl.close();
354
- process.exit(1);
327
+ // --token bypass: need tool picker in terminal — unless --tool=<slug>
328
+ // already pre-selected one for us.
329
+ if (!choice) {
330
+ console.log(`\n${bold}Which tool are you setting up?${r}\n`);
331
+ console.log(` ${cyan}1.${r} Claude Code ${cyan}5.${r} Gemini CLI`);
332
+ console.log(` ${cyan}2.${r} Codex CLI ${cyan}6.${r} VS Code`);
333
+ console.log(` ${cyan}3.${r} Cursor ${cyan}7.${r} Zed`);
334
+ console.log(` ${cyan}4.${r} Windsurf ${cyan}8.${r} OpenCode`);
335
+ console.log(` ${cyan}11.${r} Cline ${cyan}9.${r} OpenClaw\n`);
336
+ choice = (await ask(`${dim}Choose (1-9, 11):${r} `)).trim();
337
+ if (!["1","2","3","4","5","6","7","8","9","11"].includes(choice)) {
338
+ console.error("Invalid choice.");
339
+ rl.close();
340
+ process.exit(1);
341
+ }
355
342
  }
356
343
  token = tokenFlag.trim();
357
344
  if (!isSafeToken(token)) {
@@ -516,8 +503,12 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd === "--token" || cmd ===
516
503
  process.exit(1);
517
504
  }
518
505
  } else {
519
- // Open browser or show URL
520
- const connectUrl = `https://patchcord.dev/connect?session=${sessionId}`;
506
+ // Open browser or show URL.
507
+ // Append &tool=<slug> when --tool was passed so the web /connect
508
+ // page skips its type picker (the user already chose on the
509
+ // dashboard tile).
510
+ const toolParam = toolSlug ? `&tool=${encodeURIComponent(toolSlug)}` : "";
511
+ const connectUrl = `https://patchcord.dev/connect?session=${sessionId}${toolParam}`;
521
512
 
522
513
  if (canOpenBrowser()) {
523
514
  const opened = openBrowser(connectUrl);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",