patchcord 0.3.49 → 0.3.51

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/bin/patchcord.mjs +64 -20
  2. package/package.json +1 -1
package/bin/patchcord.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { existsSync, mkdirSync, cpSync } from "fs";
3
+ import { existsSync, mkdirSync, cpSync, readdirSync } from "fs";
4
4
  import { join, dirname } from "path";
5
5
  import { fileURLToPath } from "url";
6
6
  import { execSync } from "child_process";
@@ -35,6 +35,29 @@ function isSafeId(s) {
35
35
  return /^[A-Za-z0-9_\-]+$/.test(s) && s.length < 100;
36
36
  }
37
37
 
38
+ const PROJECT_MARKERS = [
39
+ ".git", "package.json", "package-lock.json", "Cargo.toml", "go.mod", "go.sum",
40
+ "pyproject.toml", "pom.xml", "build.gradle", "Makefile", "CMakeLists.txt",
41
+ "Gemfile", "composer.json", "mix.exs", "requirements.txt", "setup.py",
42
+ ".claude", ".codex", ".cursor", ".vscode",
43
+ ];
44
+
45
+ function detectFolder(dir) {
46
+ if (dir === HOME || dir === HOME + "/" || dir === "/") return "HOME";
47
+ for (const m of PROJECT_MARKERS) {
48
+ if (existsSync(join(dir, m))) return "PROJECT";
49
+ }
50
+ let entries;
51
+ try {
52
+ entries = readdirSync(dir, { withFileTypes: true });
53
+ } catch { return "UNKNOWN"; }
54
+ if (entries.length === 0) return "EMPTY";
55
+ const files = entries.filter(e => e.isFile());
56
+ const dirs = entries.filter(e => e.isDirectory());
57
+ if (files.length === 0 && dirs.length >= 2) return "CONTAINER";
58
+ return "UNKNOWN";
59
+ }
60
+
38
61
 
39
62
  if (cmd === "help" || cmd === "--help" || cmd === "-h") {
40
63
  console.log(`patchcord — agent messaging for AI coding agents
@@ -258,7 +281,30 @@ if (!cmd || cmd === "install" || cmd === "agent") {
258
281
  const toolLabel = isZed ? "Zed" : isWindsurf ? "Windsurf" : "Gemini CLI";
259
282
  console.log(`\n ${yellow}Note: ${toolLabel} uses global config — applies to all projects.${r}`);
260
283
  } else {
261
- console.log(`\n${dim}Project:${r} ${bold}${cwd}${r}`);
284
+ const folderType = detectFolder(cwd);
285
+ const folderName = cwd.split("/").pop() || cwd.split("\\").pop() || cwd;
286
+
287
+ if (folderType === "HOME") {
288
+ console.log(`\n ${red}✗ You're in your home folder.${r}`);
289
+ console.log(` ${yellow}Patchcord must be installed inside a project folder —${r}`);
290
+ console.log(` ${yellow}the folder where your agent actually runs.${r}`);
291
+ console.log(` ${dim}cd into your project first, then run this again.${r}`);
292
+ rl.close();
293
+ process.exit(0);
294
+ } else if (folderType === "CONTAINER") {
295
+ console.log(`\n ${yellow}⚠ This looks like a projects container, not a project.${r}`);
296
+ console.log(` ${dim}${cwd}${r}`);
297
+ console.log(` ${dim}Patchcord should be installed inside a project, not the folder above it.${r}`);
298
+ const proceed = (await ask(` ${dim}Set up here anyway? (y/N):${r} `)).trim().toLowerCase();
299
+ if (proceed !== "y" && proceed !== "yes") {
300
+ console.log(` ${dim}cd into your project and run this again.${r}`);
301
+ rl.close();
302
+ process.exit(0);
303
+ }
304
+ }
305
+
306
+ console.log(`\n ${dim}Agent identity:${r} ${bold}${folderName}${r}`);
307
+ console.log(` ${dim}Folder:${r} ${cwd}`);
262
308
  }
263
309
 
264
310
 
@@ -497,15 +543,11 @@ if (!cmd || cmd === "install" || cmd === "agent") {
497
543
  const cursorConfig = {
498
544
  mcpServers: {
499
545
  patchcord: {
500
- command: "npx",
501
- args: [
502
- "-y", "mcp-remote",
503
- `${serverUrl}/mcp`,
504
- "--header",
505
- `Authorization: Bearer ${token}`,
506
- "--header",
507
- `X-Patchcord-Machine: ${hostname}`,
508
- ],
546
+ url: `${serverUrl}/mcp/bearer`,
547
+ headers: {
548
+ Authorization: `Bearer ${token}`,
549
+ "X-Patchcord-Machine": hostname,
550
+ },
509
551
  },
510
552
  },
511
553
  };
@@ -530,15 +572,11 @@ if (!cmd || cmd === "install" || cmd === "agent") {
530
572
  const wsConfig = {
531
573
  mcpServers: {
532
574
  patchcord: {
533
- command: "npx",
534
- args: [
535
- "-y", "mcp-remote",
536
- `${serverUrl}/mcp`,
537
- "--header",
538
- `Authorization: Bearer ${token}`,
539
- "--header",
540
- `X-Patchcord-Machine: ${hostname}`,
541
- ],
575
+ url: `${serverUrl}/mcp/bearer`,
576
+ headers: {
577
+ Authorization: `Bearer ${token}`,
578
+ "X-Patchcord-Machine": hostname,
579
+ },
542
580
  },
543
581
  },
544
582
  };
@@ -732,6 +770,12 @@ if (!cmd || cmd === "install" || cmd === "agent") {
732
770
  }
733
771
 
734
772
  const toolName = isOpenCode ? "OpenCode" : isZed ? "Zed" : isVSCode ? "VS Code" : isGemini ? "Gemini CLI" : isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
773
+
774
+ if (!isWindsurf && !isGemini && !isZed) {
775
+ console.log(`\n ${dim}To connect a second agent:${r}`);
776
+ console.log(` ${dim}cd into another project and run${r} ${bold}npx patchcord@latest${r} ${dim}there.${r}`);
777
+ }
778
+
735
779
  console.log(`\n${dim}Restart your ${toolName} session, then run:${r} ${bold}inbox()${r}`);
736
780
  process.exit(0);
737
781
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.3.49",
3
+ "version": "0.3.51",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",