patchcord 0.3.7 → 0.3.9
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 +67 -36
- 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.9",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ppravdin"
|
|
7
7
|
},
|
package/bin/patchcord.mjs
CHANGED
|
@@ -41,12 +41,14 @@ if (cmd === "install") {
|
|
|
41
41
|
const fullStatusline = flags.includes("--full");
|
|
42
42
|
const { readFileSync, writeFileSync } = await import("fs");
|
|
43
43
|
|
|
44
|
+
console.log("Patchcord — setting up agent messaging\n");
|
|
45
|
+
|
|
44
46
|
let installedSomething = false;
|
|
45
47
|
|
|
46
48
|
// ── Claude Code ──
|
|
47
49
|
const hasClaude = run("which claude");
|
|
48
50
|
if (hasClaude) {
|
|
49
|
-
console.log(
|
|
51
|
+
console.log(`\n🔧 Claude Code`);
|
|
50
52
|
|
|
51
53
|
// Register npm package as a local marketplace (idempotent)
|
|
52
54
|
const marketplaceExists = run(`claude plugin marketplace list`)?.includes("patchcord");
|
|
@@ -83,81 +85,110 @@ if (cmd === "install") {
|
|
|
83
85
|
run(`bash "${enableScript}"${slArg}`);
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
console.log(
|
|
88
|
+
console.log(` ✓ Plugin installed${fullStatusline ? " (full statusline)" : ""}`);
|
|
89
|
+
console.log(` ✓ OAuth tool leakage blocked`);
|
|
87
90
|
installedSomething = true;
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
// ── Codex CLI ──
|
|
91
94
|
const codexConfig = join(process.env.HOME || "", ".codex", "config.toml");
|
|
92
95
|
if (existsSync(codexConfig)) {
|
|
93
|
-
console.log("Found Codex CLI config.");
|
|
94
|
-
|
|
95
|
-
// Disable patchcord as ChatGPT app (prevents OAuth identity conflict)
|
|
96
96
|
const content = readFileSync(codexConfig, "utf-8");
|
|
97
97
|
if (!content.includes("[apps.patchcord]")) {
|
|
98
98
|
writeFileSync(codexConfig, content.trimEnd() + "\n\n[apps.patchcord]\nenabled = false\n");
|
|
99
|
-
console.log("✓ Disabled patchcord ChatGPT app in Codex (prevents identity conflict).");
|
|
100
99
|
}
|
|
101
|
-
|
|
100
|
+
console.log(`\n🔧 Codex CLI`);
|
|
101
|
+
console.log(` ✓ ChatGPT app conflict prevented`);
|
|
102
102
|
installedSomething = true;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
if (!installedSomething) {
|
|
106
|
-
console.log(`No Claude Code or Codex CLI
|
|
106
|
+
console.log(`No Claude Code or Codex CLI found on this machine.
|
|
107
107
|
|
|
108
108
|
Install one first:
|
|
109
|
-
Claude Code
|
|
110
|
-
Codex CLI
|
|
109
|
+
Claude Code → https://claude.ai/code
|
|
110
|
+
Codex CLI → npm install -g @openai/codex
|
|
111
111
|
|
|
112
112
|
Then run: npx patchcord@latest install`);
|
|
113
113
|
process.exit(1);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
console.log(`\
|
|
116
|
+
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
117
|
+
console.log(`Next: cd into your project and run:`);
|
|
118
|
+
console.log(` npx patchcord@latest agent`);
|
|
117
119
|
process.exit(0);
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
// ── agent: per-project MCP setup (auto-detects tool)
|
|
122
|
+
// ── agent: per-project MCP setup (interactive, auto-detects tool) ──
|
|
121
123
|
if (cmd === "agent") {
|
|
122
124
|
const cwd = process.cwd();
|
|
125
|
+
const { readFileSync, writeFileSync } = await import("fs");
|
|
126
|
+
const { createInterface } = await import("readline");
|
|
127
|
+
|
|
128
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
129
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
130
|
+
|
|
131
|
+
// Ask for server URL with default
|
|
132
|
+
const serverUrl = (await ask("Server URL [https://mcp.patchcord.dev]: ")).trim() || "https://mcp.patchcord.dev";
|
|
133
|
+
|
|
134
|
+
// Ask for token
|
|
135
|
+
const token = (await ask("Paste your agent token: ")).trim();
|
|
136
|
+
rl.close();
|
|
137
|
+
|
|
138
|
+
if (!token) {
|
|
139
|
+
console.error("Token is required. Get one from your patchcord dashboard.");
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
123
142
|
|
|
124
143
|
// Auto-detect: Codex project has .agents folder or .codex folder
|
|
125
144
|
const isCodex = existsSync(join(cwd, ".agents")) || existsSync(join(cwd, ".codex"));
|
|
126
145
|
|
|
127
146
|
if (isCodex) {
|
|
128
|
-
// Codex: copy skill
|
|
147
|
+
// Codex: copy skill + write config
|
|
129
148
|
const dest = join(cwd, ".agents", "skills", "patchcord");
|
|
130
149
|
mkdirSync(dest, { recursive: true });
|
|
131
150
|
cpSync(join(pluginRoot, "codex", "SKILL.md"), join(dest, "SKILL.md"));
|
|
132
|
-
console.log(`✓ Codex skill installed: ${dest}/SKILL.md
|
|
133
|
-
|
|
134
|
-
Add to .codex/config.toml in this project:
|
|
135
151
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
const codexDir = join(cwd, ".codex");
|
|
153
|
+
mkdirSync(codexDir, { recursive: true });
|
|
154
|
+
const configPath = join(codexDir, "config.toml");
|
|
155
|
+
let existing = existsSync(configPath) ? readFileSync(configPath, "utf-8") : "";
|
|
156
|
+
if (!existing.includes("[mcp_servers.patchcord]")) {
|
|
157
|
+
existing = existing.trimEnd() + `\n\n[mcp_servers.patchcord]\nurl = "${serverUrl}/mcp/bearer"\nhttp_headers = { "Authorization" = "Bearer ${token}", "X-Patchcord-Client-Type" = "codex" }\n`;
|
|
158
|
+
writeFileSync(configPath, existing);
|
|
159
|
+
}
|
|
160
|
+
console.log(`✓ Codex configured: ${configPath}\n✓ Skill installed: ${dest}/SKILL.md`);
|
|
139
161
|
} else {
|
|
140
|
-
// Claude Code:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
162
|
+
// Claude Code: write .mcp.json
|
|
163
|
+
const mcpPath = join(cwd, ".mcp.json");
|
|
164
|
+
const mcpConfig = {
|
|
165
|
+
mcpServers: {
|
|
166
|
+
patchcord: {
|
|
167
|
+
type: "http",
|
|
168
|
+
url: `${serverUrl}/mcp`,
|
|
169
|
+
headers: {
|
|
170
|
+
Authorization: `Bearer ${token}`,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
if (existsSync(mcpPath)) {
|
|
177
|
+
try {
|
|
178
|
+
const existing = JSON.parse(readFileSync(mcpPath, "utf-8"));
|
|
179
|
+
existing.mcpServers = existing.mcpServers || {};
|
|
180
|
+
existing.mcpServers.patchcord = mcpConfig.mcpServers.patchcord;
|
|
181
|
+
writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + "\n");
|
|
182
|
+
} catch {
|
|
183
|
+
writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
151
184
|
}
|
|
185
|
+
} else {
|
|
186
|
+
writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
152
187
|
}
|
|
188
|
+
console.log(`✓ Claude Code configured: ${mcpPath}`);
|
|
153
189
|
}
|
|
154
190
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
claude mcp add patchcord "https://YOUR_SERVER/mcp" \\
|
|
158
|
-
--transport http -s project \\
|
|
159
|
-
-H "Authorization: Bearer YOUR_TOKEN"`);
|
|
160
|
-
}
|
|
191
|
+
console.log("\nRestart your session, then run: inbox()");
|
|
161
192
|
process.exit(0);
|
|
162
193
|
}
|
|
163
194
|
|