patchcord 0.3.17 → 0.3.19
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 +108 -5
- 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.19",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ppravdin"
|
|
7
7
|
},
|
package/bin/patchcord.mjs
CHANGED
|
@@ -160,17 +160,87 @@ if (cmd === "agent") {
|
|
|
160
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);
|
|
172
174
|
}
|
|
173
175
|
|
|
176
|
+
const yellow = "\x1b[33m";
|
|
177
|
+
|
|
178
|
+
// Check if already configured
|
|
179
|
+
if (!isCodex) {
|
|
180
|
+
const mcpPath = join(cwd, ".mcp.json");
|
|
181
|
+
if (existsSync(mcpPath)) {
|
|
182
|
+
try {
|
|
183
|
+
const existing = JSON.parse(readFileSync(mcpPath, "utf-8"));
|
|
184
|
+
if (existing.mcpServers?.patchcord) {
|
|
185
|
+
const existingToken = existing.mcpServers.patchcord.headers?.Authorization || "";
|
|
186
|
+
console.log(`\n ${yellow}⚠ Claude Code already configured in this project${r}`);
|
|
187
|
+
console.log(` ${dim}${mcpPath}${r}`);
|
|
188
|
+
const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
|
|
189
|
+
if (replace !== "y" && replace !== "yes") {
|
|
190
|
+
console.log("Keeping existing config.");
|
|
191
|
+
rl.close();
|
|
192
|
+
process.exit(0);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch {}
|
|
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
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
const configPath = join(cwd, ".codex", "config.toml");
|
|
229
|
+
if (existsSync(configPath)) {
|
|
230
|
+
const content = readFileSync(configPath, "utf-8");
|
|
231
|
+
if (content.includes("[mcp_servers.patchcord]")) {
|
|
232
|
+
console.log(`\n ${yellow}⚠ Codex CLI already configured in this project${r}`);
|
|
233
|
+
console.log(` ${dim}${configPath}${r}`);
|
|
234
|
+
const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
|
|
235
|
+
if (replace !== "y" && replace !== "yes") {
|
|
236
|
+
console.log("Keeping existing config.");
|
|
237
|
+
rl.close();
|
|
238
|
+
process.exit(0);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
174
244
|
let token = "";
|
|
175
245
|
let identity = "";
|
|
176
246
|
let serverUrl = "https://mcp.patchcord.dev";
|
|
@@ -224,7 +294,40 @@ if (cmd === "agent") {
|
|
|
224
294
|
|
|
225
295
|
rl.close();
|
|
226
296
|
|
|
227
|
-
if (
|
|
297
|
+
if (isCursor) {
|
|
298
|
+
// Cursor: write .cursor/mcp.json (per-project)
|
|
299
|
+
const cursorDir = join(cwd, ".cursor");
|
|
300
|
+
mkdirSync(cursorDir, { recursive: true });
|
|
301
|
+
const cursorPath = join(cursorDir, "mcp.json");
|
|
302
|
+
const cursorConfig = {
|
|
303
|
+
mcpServers: {
|
|
304
|
+
patchcord: {
|
|
305
|
+
command: "npx",
|
|
306
|
+
args: [
|
|
307
|
+
"-y", "mcp-remote",
|
|
308
|
+
serverUrl,
|
|
309
|
+
"--header",
|
|
310
|
+
`Authorization: Bearer ${token}`,
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
if (existsSync(cursorPath)) {
|
|
317
|
+
try {
|
|
318
|
+
const existing = JSON.parse(readFileSync(cursorPath, "utf-8"));
|
|
319
|
+
existing.mcpServers = existing.mcpServers || {};
|
|
320
|
+
existing.mcpServers.patchcord = cursorConfig.mcpServers.patchcord;
|
|
321
|
+
writeFileSync(cursorPath, JSON.stringify(existing, null, 2) + "\n");
|
|
322
|
+
} catch {
|
|
323
|
+
writeFileSync(cursorPath, JSON.stringify(cursorConfig, null, 2) + "\n");
|
|
324
|
+
}
|
|
325
|
+
} else {
|
|
326
|
+
writeFileSync(cursorPath, JSON.stringify(cursorConfig, null, 2) + "\n");
|
|
327
|
+
}
|
|
328
|
+
console.log(`\n ${green}✓${r} Cursor configured: ${dim}${cursorPath}${r}`);
|
|
329
|
+
console.log(` ${dim}Per-project only — other projects won't see this agent.${r}`);
|
|
330
|
+
} else if (isCodex) {
|
|
228
331
|
// Codex: copy skill + write config
|
|
229
332
|
const dest = join(cwd, ".agents", "skills", "patchcord");
|
|
230
333
|
mkdirSync(dest, { recursive: true });
|
|
@@ -270,7 +373,7 @@ if (cmd === "agent") {
|
|
|
270
373
|
console.log(`\n ${green}✓${r} Claude Code configured: ${dim}${mcpPath}${r}`);
|
|
271
374
|
}
|
|
272
375
|
|
|
273
|
-
const toolName = isCodex ? "Codex" : "Claude Code";
|
|
376
|
+
const toolName = isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
|
|
274
377
|
console.log(`\n${dim}Restart your ${toolName} session, then run:${r} ${bold}inbox()${r}`);
|
|
275
378
|
process.exit(0);
|
|
276
379
|
}
|