patchcord 0.3.28 → 0.3.30

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.
Files changed (2) hide show
  1. package/bin/patchcord.mjs +70 -10
  2. package/package.json +1 -1
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)) {
@@ -160,21 +168,24 @@ if (!cmd || cmd === "install" || cmd === "agent") {
160
168
  console.log(` ${cyan}1.${r} Claude Code`);
161
169
  console.log(` ${cyan}2.${r} Codex CLI`);
162
170
  console.log(` ${cyan}3.${r} Cursor`);
163
- console.log(` ${cyan}4.${r} Windsurf\n`);
171
+ console.log(` ${cyan}4.${r} Windsurf`);
172
+ console.log(` ${cyan}5.${r} Gemini CLI\n`);
164
173
 
165
- 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();
166
175
  const isCodex = choice === "2";
167
176
  const isCursor = choice === "3";
168
177
  const isWindsurf = choice === "4";
178
+ const isGemini = choice === "5";
169
179
 
170
- if (!["1", "2", "3", "4"].includes(choice)) {
180
+ if (!["1", "2", "3", "4", "5"].includes(choice)) {
171
181
  console.error("Invalid choice.");
172
182
  rl.close();
173
183
  process.exit(1);
174
184
  }
175
185
 
176
- if (isWindsurf) {
177
- console.log(`\n ${yellow}Note: Windsurf uses global config applies to all projects.${r}`);
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}`);
178
189
  } else {
179
190
  console.log(`\n${dim}Project folder:${r} ${bold}${cwd}${r}`);
180
191
  console.log(`${dim}Config will be created here. Run this in your project folder.${r}`);
@@ -187,13 +198,12 @@ if (!cmd || cmd === "install" || cmd === "agent") {
187
198
 
188
199
 
189
200
  // Check if already configured
190
- if (!isCodex) {
201
+ if (choice === "1") {
191
202
  const mcpPath = join(cwd, ".mcp.json");
192
203
  if (existsSync(mcpPath)) {
193
204
  try {
194
205
  const existing = JSON.parse(readFileSync(mcpPath, "utf-8"));
195
206
  if (existing.mcpServers?.patchcord) {
196
- const existingToken = existing.mcpServers.patchcord.headers?.Authorization || "";
197
207
  console.log(`\n ${yellow}⚠ Claude Code already configured in this project${r}`);
198
208
  console.log(` ${dim}${mcpPath}${r}`);
199
209
  const replace = (await ask(` ${dim}Replace? (y/N):${r} `)).trim().toLowerCase();
@@ -236,7 +246,6 @@ if (!cmd || cmd === "install" || cmd === "agent") {
236
246
  } catch {}
237
247
  }
238
248
  } else if (isWindsurf) {
239
- // Windsurf is global only
240
249
  const wsPath = join(process.env.HOME || "", ".codeium", "windsurf", "mcp_config.json");
241
250
  if (existsSync(wsPath)) {
242
251
  try {
@@ -254,7 +263,24 @@ if (!cmd || cmd === "install" || cmd === "agent") {
254
263
  }
255
264
  } catch {}
256
265
  }
257
- } 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) {
258
284
  const configPath = join(cwd, ".codex", "config.toml");
259
285
  if (existsSync(configPath)) {
260
286
  const content = readFileSync(configPath, "utf-8");
@@ -394,6 +420,40 @@ if (!cmd || cmd === "install" || cmd === "agent") {
394
420
  console.log(`\n ${green}✓${r} Windsurf configured: ${dim}${wsPath}${r}`);
395
421
  console.log(` ${yellow}Global config — all Windsurf projects share this agent.${r}`);
396
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
+ // Auto-approve patchcord tools (skip confirmation dialogs)
440
+ if (!geminiSettings.tools) geminiSettings.tools = {};
441
+ if (!geminiSettings.tools.allowed) geminiSettings.tools.allowed = [];
442
+ const patchcordTools = [
443
+ "mcp_patchcord_inbox", "mcp_patchcord_send_message", "mcp_patchcord_reply",
444
+ "mcp_patchcord_wait_for_message", "mcp_patchcord_attachment",
445
+ "mcp_patchcord_recall", "mcp_patchcord_unsend",
446
+ ];
447
+ for (const t of patchcordTools) {
448
+ if (!geminiSettings.tools.allowed.includes(t)) {
449
+ geminiSettings.tools.allowed.push(t);
450
+ }
451
+ }
452
+ mkdirSync(join(process.env.HOME || "", ".gemini"), { recursive: true });
453
+ writeFileSync(geminiPath, JSON.stringify(geminiSettings, null, 2) + "\n");
454
+ console.log(`\n ${green}✓${r} Gemini CLI configured: ${dim}${geminiPath}${r}`);
455
+ console.log(` ${green}✓${r} Tool auto-approval configured`);
456
+ console.log(` ${yellow}Global config — all Gemini CLI projects share this agent.${r}`);
397
457
  } else if (isCodex) {
398
458
  // Codex: copy skill + write config
399
459
  const dest = join(cwd, ".agents", "skills", "patchcord");
@@ -440,7 +500,7 @@ if (!cmd || cmd === "install" || cmd === "agent") {
440
500
  console.log(`\n ${green}✓${r} Claude Code configured: ${dim}${mcpPath}${r}`);
441
501
  }
442
502
 
443
- const toolName = isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
503
+ const toolName = isGemini ? "Gemini CLI" : isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
444
504
  console.log(`\n${dim}Restart your ${toolName} session, then run:${r} ${bold}inbox()${r}`);
445
505
  process.exit(0);
446
506
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.3.28",
3
+ "version": "0.3.30",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",