patchcord 0.3.27 → 0.3.29

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.27",
4
+ "version": "0.3.28",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -126,6 +126,14 @@ if (!cmd || cmd === "install" || cmd === "agent") {
126
126
  globalChanges.push("Windsurf skill installed");
127
127
  }
128
128
 
129
+ // Gemini CLI
130
+ const geminiSkillDir = join(process.env.HOME || "", ".gemini", "skills", "patchcord");
131
+ if (existsSync(join(process.env.HOME || "", ".gemini")) && !existsSync(geminiSkillDir)) {
132
+ mkdirSync(geminiSkillDir, { recursive: true });
133
+ cpSync(join(pluginRoot, "skills", "inbox", "SKILL.md"), join(geminiSkillDir, "SKILL.md"));
134
+ globalChanges.push("Gemini CLI skill installed");
135
+ }
136
+
129
137
  // Codex CLI
130
138
  const codexConfig = join(process.env.HOME || "", ".codex", "config.toml");
131
139
  if (existsSync(codexConfig)) {
@@ -156,41 +164,46 @@ if (!cmd || cmd === "install" || cmd === "agent") {
156
164
  const rl = createInterface({ input: process.stdin, output: process.stdout });
157
165
  const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
158
166
 
159
- // Project directory confirmation
160
- console.log(`\n${dim}Project folder:${r} ${bold}${cwd}${r}`);
161
- console.log(`${dim}Patchcord config will be created here. Run this in your project folder.${r}`);
162
- const proceed = (await ask(`\n${dim}Continue? (Y/n):${r} `)).trim().toLowerCase();
163
- if (proceed === "n" || proceed === "no") {
164
- rl.close();
165
- process.exit(0);
166
- }
167
-
168
167
  console.log(`\n${bold}Which tool are you setting up?${r}\n`);
169
168
  console.log(` ${cyan}1.${r} Claude Code`);
170
169
  console.log(` ${cyan}2.${r} Codex CLI`);
171
170
  console.log(` ${cyan}3.${r} Cursor`);
172
- console.log(` ${cyan}4.${r} Windsurf\n`);
171
+ console.log(` ${cyan}4.${r} Windsurf`);
172
+ console.log(` ${cyan}5.${r} Gemini CLI\n`);
173
173
 
174
- const choice = (await ask(`${dim}Choose (1/2/3/4):${r} `)).trim();
174
+ const choice = (await ask(`${dim}Choose (1/2/3/4/5):${r} `)).trim();
175
175
  const isCodex = choice === "2";
176
176
  const isCursor = choice === "3";
177
177
  const isWindsurf = choice === "4";
178
+ const isGemini = choice === "5";
178
179
 
179
- if (!["1", "2", "3", "4"].includes(choice)) {
180
+ if (!["1", "2", "3", "4", "5"].includes(choice)) {
180
181
  console.error("Invalid choice.");
181
182
  rl.close();
182
183
  process.exit(1);
183
184
  }
184
185
 
186
+ if (isWindsurf || isGemini) {
187
+ const toolLabel = isWindsurf ? "Windsurf" : "Gemini CLI";
188
+ console.log(`\n ${yellow}Note: ${toolLabel} uses global config — applies to all projects.${r}`);
189
+ } else {
190
+ console.log(`\n${dim}Project folder:${r} ${bold}${cwd}${r}`);
191
+ console.log(`${dim}Config will be created here. Run this in your project folder.${r}`);
192
+ const proceed = (await ask(`${dim}Continue? (Y/n):${r} `)).trim().toLowerCase();
193
+ if (proceed === "n" || proceed === "no") {
194
+ rl.close();
195
+ process.exit(0);
196
+ }
197
+ }
198
+
185
199
 
186
200
  // Check if already configured
187
- if (!isCodex) {
201
+ if (choice === "1") {
188
202
  const mcpPath = join(cwd, ".mcp.json");
189
203
  if (existsSync(mcpPath)) {
190
204
  try {
191
205
  const existing = JSON.parse(readFileSync(mcpPath, "utf-8"));
192
206
  if (existing.mcpServers?.patchcord) {
193
- const existingToken = existing.mcpServers.patchcord.headers?.Authorization || "";
194
207
  console.log(`\n ${yellow}⚠ Claude Code already configured in this project${r}`);
195
208
  console.log(` ${dim}${mcpPath}${r}`);
196
209
  const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
@@ -233,7 +246,6 @@ if (!cmd || cmd === "install" || cmd === "agent") {
233
246
  } catch {}
234
247
  }
235
248
  } else if (isWindsurf) {
236
- // Windsurf is global only
237
249
  const wsPath = join(process.env.HOME || "", ".codeium", "windsurf", "mcp_config.json");
238
250
  if (existsSync(wsPath)) {
239
251
  try {
@@ -251,7 +263,24 @@ if (!cmd || cmd === "install" || cmd === "agent") {
251
263
  }
252
264
  } catch {}
253
265
  }
254
- } else {
266
+ } else if (isGemini) {
267
+ const geminiPath = join(process.env.HOME || "", ".gemini", "settings.json");
268
+ if (existsSync(geminiPath)) {
269
+ try {
270
+ const existing = JSON.parse(readFileSync(geminiPath, "utf-8"));
271
+ if (existing.mcpServers?.patchcord) {
272
+ console.log(`\n ${yellow}⚠ Gemini CLI already configured${r}`);
273
+ console.log(` ${dim}${geminiPath}${r}`);
274
+ const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
275
+ if (replace !== "y" && replace !== "yes") {
276
+ console.log("Keeping existing config.");
277
+ rl.close();
278
+ process.exit(0);
279
+ }
280
+ }
281
+ } catch {}
282
+ }
283
+ } else if (isCodex) {
255
284
  const configPath = join(cwd, ".codex", "config.toml");
256
285
  if (existsSync(configPath)) {
257
286
  const content = readFileSync(configPath, "utf-8");
@@ -391,6 +420,26 @@ if (!cmd || cmd === "install" || cmd === "agent") {
391
420
  console.log(`\n ${green}✓${r} Windsurf configured: ${dim}${wsPath}${r}`);
392
421
  console.log(` ${yellow}Global config — all Windsurf projects share this agent.${r}`);
393
422
  console.log(` ${dim}Windsurf does not support per-project MCP configs.${r}`);
423
+ } else if (isGemini) {
424
+ // Gemini CLI: global only (~/.gemini/settings.json)
425
+ const geminiPath = join(process.env.HOME || "", ".gemini", "settings.json");
426
+ let geminiSettings = {};
427
+ if (existsSync(geminiPath)) {
428
+ try {
429
+ geminiSettings = JSON.parse(readFileSync(geminiPath, "utf-8"));
430
+ } catch {}
431
+ }
432
+ if (!geminiSettings.mcpServers) geminiSettings.mcpServers = {};
433
+ geminiSettings.mcpServers.patchcord = {
434
+ httpUrl: `${serverUrl}/mcp`,
435
+ headers: {
436
+ Authorization: `Bearer ${token}`,
437
+ },
438
+ };
439
+ mkdirSync(join(process.env.HOME || "", ".gemini"), { recursive: true });
440
+ writeFileSync(geminiPath, JSON.stringify(geminiSettings, null, 2) + "\n");
441
+ console.log(`\n ${green}✓${r} Gemini CLI configured: ${dim}${geminiPath}${r}`);
442
+ console.log(` ${yellow}Global config — all Gemini CLI projects share this agent.${r}`);
394
443
  } else if (isCodex) {
395
444
  // Codex: copy skill + write config
396
445
  const dest = join(cwd, ".agents", "skills", "patchcord");
@@ -437,7 +486,7 @@ if (!cmd || cmd === "install" || cmd === "agent") {
437
486
  console.log(`\n ${green}✓${r} Claude Code configured: ${dim}${mcpPath}${r}`);
438
487
  }
439
488
 
440
- const toolName = isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
489
+ const toolName = isGemini ? "Gemini CLI" : isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
441
490
  console.log(`\n${dim}Restart your ${toolName} session, then run:${r} ${bold}inbox()${r}`);
442
491
  process.exit(0);
443
492
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",