patchcord 0.6.14 → 0.6.15
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 +66 -24
- package/package.json +1 -1
package/bin/patchcord.mjs
CHANGED
|
@@ -43,6 +43,59 @@ function isSafeId(s) {
|
|
|
43
43
|
return /^[A-Za-z0-9_\-]+$/.test(s) && s.length < 100;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Undo 0.6.14 mistake: Claude Code uses /mcp (not /mcp/bearer). */
|
|
47
|
+
function revertClaudeMcpBearerUrl(mcpPath) {
|
|
48
|
+
if (!existsSync(mcpPath)) return false;
|
|
49
|
+
try {
|
|
50
|
+
const obj = JSON.parse(readFileSync(mcpPath, "utf-8"));
|
|
51
|
+
const pt = obj?.mcpServers?.patchcord;
|
|
52
|
+
const url = pt?.url;
|
|
53
|
+
if (!url || !url.endsWith("/mcp/bearer")) return false;
|
|
54
|
+
pt.url = url.replace(/\/mcp\/bearer$/, "/mcp");
|
|
55
|
+
writeFileSync(mcpPath, JSON.stringify(obj, null, 2) + "\n");
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Patchcord uses project .mcp.json only — drop stale local-scope duplicates. */
|
|
63
|
+
function dedupeClaudePatchcordMcp(cwd) {
|
|
64
|
+
if (run("which claude")) {
|
|
65
|
+
run("claude mcp remove patchcord -s local");
|
|
66
|
+
}
|
|
67
|
+
const claudeJson = join(HOME, ".claude.json");
|
|
68
|
+
if (!existsSync(claudeJson)) return false;
|
|
69
|
+
try {
|
|
70
|
+
const obj = JSON.parse(readFileSync(claudeJson, "utf-8"));
|
|
71
|
+
let changed = false;
|
|
72
|
+
if (obj.mcpServers?.patchcord) {
|
|
73
|
+
delete obj.mcpServers.patchcord;
|
|
74
|
+
if (Object.keys(obj.mcpServers).length === 0) delete obj.mcpServers;
|
|
75
|
+
changed = true;
|
|
76
|
+
}
|
|
77
|
+
const proj = obj.projects?.[cwd];
|
|
78
|
+
if (proj?.mcpServers?.patchcord) {
|
|
79
|
+
delete proj.mcpServers.patchcord;
|
|
80
|
+
if (Object.keys(proj.mcpServers).length === 0) delete proj.mcpServers;
|
|
81
|
+
changed = true;
|
|
82
|
+
}
|
|
83
|
+
if (changed) {
|
|
84
|
+
writeFileSync(claudeJson, JSON.stringify(obj, null, 2) + "\n");
|
|
85
|
+
}
|
|
86
|
+
return changed;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function fixClaudePatchcordMcp(cwd) {
|
|
93
|
+
const mcpPath = join(cwd, ".mcp.json");
|
|
94
|
+
const reverted = revertClaudeMcpBearerUrl(mcpPath);
|
|
95
|
+
const deduped = dedupeClaudePatchcordMcp(cwd);
|
|
96
|
+
return { reverted, deduped };
|
|
97
|
+
}
|
|
98
|
+
|
|
46
99
|
// A trailing --help/-h on ANY subcommand must show help and exit — never run the
|
|
47
100
|
// command. (patchcord orchestrator --help used to PROVISION an orchestrator;
|
|
48
101
|
// patchcord login --help hung on the browser login. Side-effecting --help is a
|
|
@@ -708,6 +761,8 @@ if (cmd === "subscribe") {
|
|
|
708
761
|
const forceKimi = args.includes("--kimi");
|
|
709
762
|
const intervalArg = args.find((a) => a !== "--kimi") || "30";
|
|
710
763
|
|
|
764
|
+
fixClaudePatchcordMcp(process.cwd());
|
|
765
|
+
|
|
711
766
|
// Kimi Code uses polling instead of WebSocket realtime.
|
|
712
767
|
// Force Kimi mode with --kimi flag, or auto-detect from bearer config.
|
|
713
768
|
let isKimi = forceKimi;
|
|
@@ -1172,13 +1227,9 @@ if (cmd === "login" || cmd === "orchestrator" || cmd === "teamlead" || cmd === "
|
|
|
1172
1227
|
// default: claude_code. type:"http" is REQUIRED — without it Claude Code
|
|
1173
1228
|
// defaults to stdio transport and rejects the entry ("command: expected
|
|
1174
1229
|
// string, received undefined").
|
|
1175
|
-
// Use /mcp/bearer (not /mcp): Claude Code v2.1.113+ follows RFC 9728 OAuth
|
|
1176
|
-
// discovery on /mcp, drops the static bearer header, and stalls on "Needs
|
|
1177
|
-
// authentication". /mcp/bearer serves bearer-only resource metadata — same
|
|
1178
|
-
// path Cursor and Kimi Code already use.
|
|
1179
1230
|
return writeJson(join(dir, ".mcp.json"), (o) => {
|
|
1180
1231
|
o.mcpServers = o.mcpServers || {};
|
|
1181
|
-
o.mcpServers.patchcord = { type: "http", url: `${baseUrl}/mcp
|
|
1232
|
+
o.mcpServers.patchcord = { type: "http", url: `${baseUrl}/mcp`, headers: hdr };
|
|
1182
1233
|
});
|
|
1183
1234
|
};
|
|
1184
1235
|
|
|
@@ -1665,22 +1716,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1665
1716
|
return out.replace(/,(\s*[}\]])/g, "$1");
|
|
1666
1717
|
}
|
|
1667
1718
|
|
|
1668
|
-
//
|
|
1669
|
-
// Rewrite legacy project configs to /mcp/bearer (Cursor/Kimi already use it).
|
|
1670
|
-
function _migrateClaudeMcpBearerUrl(mcpPath) {
|
|
1671
|
-
if (!existsSync(mcpPath)) return false;
|
|
1672
|
-
try {
|
|
1673
|
-
const obj = JSON.parse(readFileSync(mcpPath, "utf-8"));
|
|
1674
|
-
const pt = obj?.mcpServers?.patchcord;
|
|
1675
|
-
const url = pt?.url;
|
|
1676
|
-
if (!url || !/\/mcp$/.test(url) || url.endsWith("/mcp/bearer")) return false;
|
|
1677
|
-
pt.url = url.replace(/\/mcp$/, "/mcp/bearer");
|
|
1678
|
-
writeFileSync(mcpPath, JSON.stringify(obj, null, 2) + "\n");
|
|
1679
|
-
return true;
|
|
1680
|
-
} catch {
|
|
1681
|
-
return false;
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1719
|
+
// dedupeClaudePatchcordMcp + revertClaudeMcpBearerUrl live at module scope.
|
|
1684
1720
|
|
|
1685
1721
|
// Read+merge+write a JSON config file. If the file exists but its contents
|
|
1686
1722
|
// can't be parsed, REFUSE to write — silently overwriting would erase
|
|
@@ -1740,8 +1776,13 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1740
1776
|
const bold = "\x1b[1m";
|
|
1741
1777
|
const r = "\x1b[0m";
|
|
1742
1778
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1779
|
+
const _installCwd = process.cwd();
|
|
1780
|
+
const _mcpFix = fixClaudePatchcordMcp(_installCwd);
|
|
1781
|
+
if (_mcpFix.reverted) {
|
|
1782
|
+
console.log(` ${green}✓${r} Claude Code MCP URL reverted to /mcp (0.6.14 /mcp/bearer was wrong for CC)`);
|
|
1783
|
+
}
|
|
1784
|
+
if (_mcpFix.deduped) {
|
|
1785
|
+
console.log(` ${green}✓${r} Removed stale local-scope patchcord MCP (use project .mcp.json only)`);
|
|
1745
1786
|
}
|
|
1746
1787
|
|
|
1747
1788
|
// ── Purge stale npx cache entries ────────────────────────────
|
|
@@ -3276,7 +3317,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
3276
3317
|
mcpServers: {
|
|
3277
3318
|
patchcord: {
|
|
3278
3319
|
type: "http",
|
|
3279
|
-
url: `${serverUrl}/mcp
|
|
3320
|
+
url: `${serverUrl}/mcp`,
|
|
3280
3321
|
headers: {
|
|
3281
3322
|
Authorization: `Bearer ${token}`,
|
|
3282
3323
|
"X-Patchcord-Machine": hostname,
|
|
@@ -3295,6 +3336,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
3295
3336
|
// their JSON and re-runs.
|
|
3296
3337
|
process.exit(1);
|
|
3297
3338
|
}
|
|
3339
|
+
dedupeClaudePatchcordMcp(cwd);
|
|
3298
3340
|
console.log(`\n ${green}✓${r} Claude Code configured: ${dim}${mcpPath}${r}`);
|
|
3299
3341
|
|
|
3300
3342
|
// Statusline: ask whether to enable full mode (unless --full flag passed or already configured).
|
package/package.json
CHANGED