patchcord 0.3.14 → 0.3.16

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.14",
4
+ "version": "0.3.16",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -46,7 +46,7 @@ if (cmd === "install") {
46
46
  |__] |__| | | |__| | | | |__/ | \\
47
47
  | | | | |___ | | |___ |__| | \\ |__/
48
48
 
49
- Messenger for AI agents.
49
+ Messenger for AI agents.
50
50
  `);
51
51
 
52
52
  let installedSomething = false;
@@ -141,7 +141,7 @@ Then run: npx patchcord@latest install`);
141
141
  process.exit(0);
142
142
  }
143
143
 
144
- // ── agent: per-project MCP setup (interactive, auto-detects tool) ──
144
+ // ── agent: per-project interactive setup ──────────────────────
145
145
  if (cmd === "agent") {
146
146
  const cwd = process.cwd();
147
147
  const { readFileSync, writeFileSync } = await import("fs");
@@ -150,20 +150,71 @@ if (cmd === "agent") {
150
150
  const rl = createInterface({ input: process.stdin, output: process.stdout });
151
151
  const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
152
152
 
153
- // Ask for server URL with default
154
- const serverUrl = (await ask("Server URL [https://mcp.patchcord.dev]: ")).trim() || "https://mcp.patchcord.dev";
153
+ console.log(`\nWhich tool are you setting up?\n`);
154
+ console.log(` 1. Claude Code`);
155
+ console.log(` 2. Codex CLI\n`);
155
156
 
156
- // Ask for token
157
- const token = (await ask("Paste your agent token: ")).trim();
158
- rl.close();
157
+ const choice = (await ask("Choose (1/2): ")).trim();
158
+ const isCodex = choice === "2";
159
159
 
160
- if (!token) {
161
- console.error("Token is required. Get one from your patchcord dashboard.");
160
+ if (choice !== "1" && choice !== "2") {
161
+ console.error("Invalid choice.");
162
+ rl.close();
162
163
  process.exit(1);
163
164
  }
164
165
 
165
- // Auto-detect: Codex project has .agents folder or .codex folder
166
- const isCodex = existsSync(join(cwd, ".agents")) || existsSync(join(cwd, ".codex"));
166
+ let token = "";
167
+ let identity = "";
168
+ let serverUrl = "https://mcp.patchcord.dev";
169
+
170
+ while (!identity) {
171
+ token = (await ask("\nPaste your agent token: ")).trim();
172
+
173
+ if (!token) {
174
+ console.error("Token is required. Get one from your patchcord dashboard.");
175
+ rl.close();
176
+ process.exit(1);
177
+ }
178
+
179
+ console.log("Validating...");
180
+ const validateResp = run(`curl -sf --max-time 5 -H "Authorization: Bearer ${token}" "${serverUrl}/api/inbox?limit=0"`);
181
+ if (validateResp) {
182
+ try {
183
+ const data = JSON.parse(validateResp);
184
+ identity = `${data.agent_id}@${data.namespace_id}`;
185
+ console.log(` ✓ ${identity}`);
186
+ } catch {}
187
+ }
188
+ if (!identity) {
189
+ console.log(" ✗ Token not recognized");
190
+ const retry = (await ask("Try again? (Y/n): ")).trim().toLowerCase();
191
+ if (retry === "n" || retry === "no") {
192
+ rl.close();
193
+ process.exit(1);
194
+ }
195
+ }
196
+ }
197
+
198
+ const customUrl = (await ask("\nCustom server URL? (y/N): ")).trim().toLowerCase();
199
+ if (customUrl === "y" || customUrl === "yes") {
200
+ const url = (await ask("Server URL: ")).trim();
201
+ if (url) serverUrl = url;
202
+
203
+ // Re-validate against custom server if identity wasn't found
204
+ if (!identity) {
205
+ console.log("Validating token...");
206
+ const resp2 = run(`curl -sf --max-time 5 -H "Authorization: Bearer ${token}" "${serverUrl}/api/inbox?limit=0"`);
207
+ if (resp2) {
208
+ try {
209
+ const data = JSON.parse(resp2);
210
+ identity = `${data.agent_id}@${data.namespace_id}`;
211
+ console.log(` ✓ ${identity}`);
212
+ } catch {}
213
+ }
214
+ }
215
+ }
216
+
217
+ rl.close();
167
218
 
168
219
  if (isCodex) {
169
220
  // Codex: copy skill + write config
@@ -179,7 +230,8 @@ if (cmd === "agent") {
179
230
  existing = existing.trimEnd() + `\n\n[mcp_servers.patchcord]\nurl = "${serverUrl}/mcp/bearer"\nhttp_headers = { "Authorization" = "Bearer ${token}", "X-Patchcord-Client-Type" = "codex" }\n`;
180
231
  writeFileSync(configPath, existing);
181
232
  }
182
- console.log(`✓ Codex configured: ${configPath}\n✓ Skill installed: ${dest}/SKILL.md`);
233
+ console.log(`\n ✓ Codex configured: ${configPath}`);
234
+ console.log(` ✓ Skill installed`);
183
235
  } else {
184
236
  // Claude Code: write .mcp.json
185
237
  const mcpPath = join(cwd, ".mcp.json");
@@ -207,10 +259,10 @@ if (cmd === "agent") {
207
259
  } else {
208
260
  writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
209
261
  }
210
- console.log(`✓ Claude Code configured: ${mcpPath}`);
262
+ console.log(`\n ✓ Claude Code configured: ${mcpPath}`);
211
263
  }
212
264
 
213
- console.log("\nRestart your session, then run: inbox()");
265
+ console.log(`\nRestart your session, then run: inbox()`);
214
266
  process.exit(0);
215
267
  }
216
268
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.3.14",
3
+ "version": "0.3.16",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",