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.
- package/.claude-plugin/plugin.json +1 -1
- package/bin/patchcord.mjs +92 -24
- package/package.json +1 -1
|
@@ -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.
|
|
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 (
|
|
21
|
-
console.log(`patchcord — agent messaging for
|
|
20
|
+
if (cmd === "help" || cmd === "--help" || cmd === "-h") {
|
|
21
|
+
console.log(`patchcord — agent messaging for AI coding agents
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
patchcord
|
|
25
|
-
patchcord
|
|
26
|
-
patchcord
|
|
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
|
-
|
|
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
|
-
// ──
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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 (
|
|
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
|
}
|