patchcord 0.3.18 → 0.3.20

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 auto-inbox checking. Agents automatically respond to messages from other agents without human intervention.",
4
- "version": "0.3.18",
4
+ "version": "0.3.20",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -17,16 +17,15 @@ function run(cmd) {
17
17
  }
18
18
  }
19
19
 
20
- if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
21
- console.log(`patchcord — agent messaging for Claude Code & Codex
20
+ if (cmd === "help" || cmd === "--help" || cmd === "-h") {
21
+ console.log(`patchcord — agent messaging for AI coding agents
22
22
 
23
- Commands:
24
- patchcord install One-time global setup (auto-detects Claude Code + Codex)
25
- patchcord install --full Same + enable full statusline (model, context%, git)
26
- patchcord agent Set up MCP config for this project (auto-detects tool)
27
- patchcord skill apply Fetch custom skill from web console
23
+ Usage:
24
+ npx patchcord@latest Full setup (global + project) run in your project folder
25
+ npx patchcord@latest --full Same + full statusline (model, context%, git)
26
+ npx patchcord@latest skill apply Fetch custom skill from web console
28
27
 
29
- Run "patchcord install" once. Run "patchcord agent" in each project.`);
28
+ That's it. One command does everything.`);
30
29
  process.exit(0);
31
30
  }
32
31
 
@@ -35,8 +34,8 @@ if (cmd === "plugin-path") {
35
34
  process.exit(0);
36
35
  }
37
36
 
38
- // ── install: global setup for all detected tools (idempotent) ──
39
- if (cmd === "install") {
37
+ // ── main flow: global setup + project setup (or just install/agent for back-compat) ──
38
+ if (!cmd || cmd === "install" || cmd === "agent") {
40
39
  const flags = process.argv.slice(3);
41
40
  const fullStatusline = flags.includes("--full");
42
41
  const { readFileSync, writeFileSync } = await import("fs");
@@ -135,16 +134,8 @@ Then run: npx patchcord@latest install`);
135
134
  process.exit(1);
136
135
  }
137
136
 
138
- console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
139
- console.log(`Next: cd into your project and run:`);
140
- console.log(` npx patchcord@latest agent`);
141
- process.exit(0);
142
- }
143
-
144
- // ── agent: per-project interactive setup ──────────────────────
145
- if (cmd === "agent") {
137
+ // ── project setup (inline, not a separate command) ──────────
146
138
  const cwd = process.cwd();
147
- const { readFileSync, writeFileSync } = await import("fs");
148
139
  const { createInterface } = await import("readline");
149
140
 
150
141
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -158,14 +149,25 @@ if (cmd === "agent") {
158
149
  const bold = "\x1b[1m";
159
150
  const r = "\x1b[0m";
160
151
 
152
+ // Project directory confirmation
153
+ console.log(`\n${dim}Project folder:${r} ${bold}${cwd}${r}`);
154
+ console.log(`${dim}Patchcord config will be created here. Run this in your project folder.${r}`);
155
+ const proceed = (await ask(`\n${dim}Continue? (Y/n):${r} `)).trim().toLowerCase();
156
+ if (proceed === "n" || proceed === "no") {
157
+ rl.close();
158
+ process.exit(0);
159
+ }
160
+
161
161
  console.log(`\n${bold}Which tool are you setting up?${r}\n`);
162
162
  console.log(` ${cyan}1.${r} Claude Code`);
163
- console.log(` ${cyan}2.${r} Codex CLI\n`);
163
+ console.log(` ${cyan}2.${r} Codex CLI`);
164
+ console.log(` ${cyan}3.${r} Cursor\n`);
164
165
 
165
- const choice = (await ask(`${dim}Choose (1/2):${r} `)).trim();
166
+ const choice = (await ask(`${dim}Choose (1/2/3):${r} `)).trim();
166
167
  const isCodex = choice === "2";
168
+ const isCursor = choice === "3";
167
169
 
168
- if (choice !== "1" && choice !== "2") {
170
+ if (!["1", "2", "3"].includes(choice)) {
169
171
  console.error("Invalid choice.");
170
172
  rl.close();
171
173
  process.exit(1);
@@ -192,6 +194,36 @@ if (cmd === "agent") {
192
194
  }
193
195
  } catch {}
194
196
  }
197
+ } else if (isCursor) {
198
+ const cursorPath = join(cwd, ".cursor", "mcp.json");
199
+ if (existsSync(cursorPath)) {
200
+ try {
201
+ const existing = JSON.parse(readFileSync(cursorPath, "utf-8"));
202
+ if (existing.mcpServers?.patchcord) {
203
+ console.log(`\n ${yellow}⚠ Cursor already configured in this project${r}`);
204
+ console.log(` ${dim}${cursorPath}${r}`);
205
+ const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
206
+ if (replace !== "y" && replace !== "yes") {
207
+ console.log("Keeping existing config.");
208
+ rl.close();
209
+ process.exit(0);
210
+ }
211
+ }
212
+ } catch {}
213
+ }
214
+ // Warn about global config conflict
215
+ const globalCursor = join(process.env.HOME || "", ".cursor", "mcp.json");
216
+ if (existsSync(globalCursor)) {
217
+ try {
218
+ const global = JSON.parse(readFileSync(globalCursor, "utf-8"));
219
+ if (global.mcpServers?.patchcord) {
220
+ console.log(`\n ${yellow}⚠ Patchcord is also configured globally in Cursor${r}`);
221
+ console.log(` ${dim}${globalCursor}${r}`);
222
+ console.log(` ${yellow}Having both global AND per-project will cause duplicate tool calls.${r}`);
223
+ console.log(` ${dim}Remove patchcord from global config: Cursor Settings → MCP → remove patchcord${r}`);
224
+ }
225
+ } catch {}
226
+ }
195
227
  } else {
196
228
  const configPath = join(cwd, ".codex", "config.toml");
197
229
  if (existsSync(configPath)) {
@@ -213,6 +245,9 @@ if (cmd === "agent") {
213
245
  let identity = "";
214
246
  let serverUrl = "https://mcp.patchcord.dev";
215
247
 
248
+ console.log(`\n${dim}Get your token at:${r} ${cyan}https://patchcord.dev/console${r}`);
249
+ console.log(`${dim}Create a project → Add agent → Copy token${r}`);
250
+
216
251
  while (!identity) {
217
252
  token = (await ask(`\n${bold}Paste your agent token:${r} `)).trim();
218
253
 
@@ -262,7 +297,40 @@ if (cmd === "agent") {
262
297
 
263
298
  rl.close();
264
299
 
265
- if (isCodex) {
300
+ if (isCursor) {
301
+ // Cursor: write .cursor/mcp.json (per-project)
302
+ const cursorDir = join(cwd, ".cursor");
303
+ mkdirSync(cursorDir, { recursive: true });
304
+ const cursorPath = join(cursorDir, "mcp.json");
305
+ const cursorConfig = {
306
+ mcpServers: {
307
+ patchcord: {
308
+ command: "npx",
309
+ args: [
310
+ "-y", "mcp-remote",
311
+ serverUrl,
312
+ "--header",
313
+ `Authorization: Bearer ${token}`,
314
+ ],
315
+ },
316
+ },
317
+ };
318
+
319
+ if (existsSync(cursorPath)) {
320
+ try {
321
+ const existing = JSON.parse(readFileSync(cursorPath, "utf-8"));
322
+ existing.mcpServers = existing.mcpServers || {};
323
+ existing.mcpServers.patchcord = cursorConfig.mcpServers.patchcord;
324
+ writeFileSync(cursorPath, JSON.stringify(existing, null, 2) + "\n");
325
+ } catch {
326
+ writeFileSync(cursorPath, JSON.stringify(cursorConfig, null, 2) + "\n");
327
+ }
328
+ } else {
329
+ writeFileSync(cursorPath, JSON.stringify(cursorConfig, null, 2) + "\n");
330
+ }
331
+ console.log(`\n ${green}✓${r} Cursor configured: ${dim}${cursorPath}${r}`);
332
+ console.log(` ${dim}Per-project only — other projects won't see this agent.${r}`);
333
+ } else if (isCodex) {
266
334
  // Codex: copy skill + write config
267
335
  const dest = join(cwd, ".agents", "skills", "patchcord");
268
336
  mkdirSync(dest, { recursive: true });
@@ -308,7 +376,7 @@ if (cmd === "agent") {
308
376
  console.log(`\n ${green}✓${r} Claude Code configured: ${dim}${mcpPath}${r}`);
309
377
  }
310
378
 
311
- const toolName = isCodex ? "Codex" : "Claude Code";
379
+ const toolName = isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
312
380
  console.log(`\n${dim}Restart your ${toolName} session, then run:${r} ${bold}inbox()${r}`);
313
381
  process.exit(0);
314
382
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.3.18",
3
+ "version": "0.3.20",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",