patchcord 0.5.64 → 0.5.65
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/README.md +2 -1
- package/bin/patchcord.mjs +61 -16
- package/package.json +1 -1
- package/scripts/subscribe.mjs +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Cross-machine messaging between AI coding agents.
|
|
|
8
8
|
npx patchcord@latest
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
One command. Opens browser, configures everything. Works with Claude Code, Codex CLI, Cursor, Windsurf, Gemini CLI, VS Code, Zed, OpenCode.
|
|
11
|
+
One command. Opens browser, configures everything. Works with Claude Code, Codex CLI, Cursor, Windsurf, Gemini CLI, VS Code, Zed, OpenCode, Kimi CLI.
|
|
12
12
|
|
|
13
13
|
Self-hosted:
|
|
14
14
|
|
|
@@ -23,6 +23,7 @@ npx patchcord@latest --token <token> --server https://patchcord.yourdomain.com
|
|
|
23
23
|
- **Stop hook** — checks inbox between turns, notifies of pending messages
|
|
24
24
|
- **Slash commands** — `/patchcord` and `/patchcord-wait` for Codex and Gemini CLI
|
|
25
25
|
- **MCP config** — per-project or global config depending on tool
|
|
26
|
+
- **Kimi CLI** — global MCP config plus skills in `~/.kimi/skills/`
|
|
26
27
|
|
|
27
28
|
## How it works
|
|
28
29
|
|
package/bin/patchcord.mjs
CHANGED
|
@@ -94,9 +94,9 @@ if (cmd === "plugin-path") {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// Shared bearer/base-url resolver. Project-local configs win over globals.
|
|
97
|
-
// Supports all
|
|
97
|
+
// Supports all 12 installer targets: claude_code, codex, cursor, vscode,
|
|
98
98
|
// opencode (per-project) + windsurf, gemini, zed, openclaw, antigravity,
|
|
99
|
-
// cline (global). Each tool stores the bearer in its own shape.
|
|
99
|
+
// cline, kimi (global). Each tool stores the bearer in its own shape.
|
|
100
100
|
async function _resolveBearer() {
|
|
101
101
|
const { readFileSync } = await import("fs");
|
|
102
102
|
|
|
@@ -240,6 +240,7 @@ async function _resolveBearer() {
|
|
|
240
240
|
() => readJsonAt(join(HOME, ".openclaw", "openclaw.json"), ["mcp", "servers", "patchcord"], "openclaw"),
|
|
241
241
|
() => readJsonAt(join(HOME, ".gemini", "antigravity", "mcp_config.json"), ["mcpServers", "patchcord"], "antigravity"),
|
|
242
242
|
...clinePaths.map((p) => () => readJsonAt(p, ["mcpServers", "patchcord"], "cline")),
|
|
243
|
+
() => readJsonAt(join(HOME, ".kimi", "mcp.json"), ["mcpServers", "patchcord"], "kimi"),
|
|
243
244
|
];
|
|
244
245
|
for (const r of globalCandidates) {
|
|
245
246
|
const found = r();
|
|
@@ -458,7 +459,7 @@ if (cmd === "upload") {
|
|
|
458
459
|
// (exits with code 2 + "already running" if another listener is up),
|
|
459
460
|
// so this command needs zero pre-checks.
|
|
460
461
|
//
|
|
461
|
-
// We resolve the bearer here (all
|
|
462
|
+
// We resolve the bearer here (all 12 tool configs) and inject it as
|
|
462
463
|
// env vars so subscribe.mjs works regardless of which MCP client is
|
|
463
464
|
// running — OpenCode, Codex, Cursor, etc. — not just Claude Code.
|
|
464
465
|
if (cmd === "subscribe") {
|
|
@@ -946,6 +947,25 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
946
947
|
if (geminiChanged) globalChanges.push("Gemini CLI skills + commands installed");
|
|
947
948
|
}
|
|
948
949
|
|
|
950
|
+
// Kimi CLI
|
|
951
|
+
const hasKimi = run("which kimi");
|
|
952
|
+
if (hasKimi) {
|
|
953
|
+
const kimiSkillDir = join(HOME, ".kimi", "skills", "patchcord");
|
|
954
|
+
const kimiWaitDir = join(HOME, ".kimi", "skills", "patchcord-wait");
|
|
955
|
+
let kimiChanged = false;
|
|
956
|
+
if (!existsSync(kimiSkillDir)) {
|
|
957
|
+
mkdirSync(kimiSkillDir, { recursive: true });
|
|
958
|
+
cpSync(join(pluginRoot, "skills", "inbox", "SKILL.md"), join(kimiSkillDir, "SKILL.md"));
|
|
959
|
+
kimiChanged = true;
|
|
960
|
+
}
|
|
961
|
+
if (!existsSync(kimiWaitDir)) {
|
|
962
|
+
mkdirSync(kimiWaitDir, { recursive: true });
|
|
963
|
+
cpSync(join(pluginRoot, "skills", "wait", "SKILL.md"), join(kimiWaitDir, "SKILL.md"));
|
|
964
|
+
kimiChanged = true;
|
|
965
|
+
}
|
|
966
|
+
if (kimiChanged) globalChanges.push("Kimi CLI skills installed");
|
|
967
|
+
}
|
|
968
|
+
|
|
949
969
|
// Codex CLI — clean up old settings and install stop hook
|
|
950
970
|
const codexConfig = join(HOME, ".codex", "config.toml");
|
|
951
971
|
if (existsSync(codexConfig)) {
|
|
@@ -1006,8 +1026,8 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1006
1026
|
}
|
|
1007
1027
|
}
|
|
1008
1028
|
|
|
1009
|
-
if (!hasClaude && !existsSync(codexConfig)) {
|
|
1010
|
-
console.log(`${dim}No Claude Code or
|
|
1029
|
+
if (!hasClaude && !existsSync(codexConfig) && !hasKimi) {
|
|
1030
|
+
console.log(`${dim}No Claude Code, Codex CLI, or Kimi CLI detected — skipping global setup.${r}`);
|
|
1011
1031
|
}
|
|
1012
1032
|
|
|
1013
1033
|
if (updateOnly) process.exit(0);
|
|
@@ -1025,7 +1045,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1025
1045
|
const CLIENT_TYPE_MAP = {
|
|
1026
1046
|
"claude_code": "1", "codex": "2", "cursor": "3", "windsurf": "4",
|
|
1027
1047
|
"gemini": "5", "vscode": "6", "zed": "7", "opencode": "8", "openclaw": "9", "antigravity": "10",
|
|
1028
|
-
"cline": "11",
|
|
1048
|
+
"cline": "11", "kimi": "12",
|
|
1029
1049
|
};
|
|
1030
1050
|
|
|
1031
1051
|
|
|
@@ -1077,13 +1097,12 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1077
1097
|
// already pre-selected one for us.
|
|
1078
1098
|
if (!choice) {
|
|
1079
1099
|
console.log(`\n${bold}Which tool are you setting up?${r}\n`);
|
|
1080
|
-
console.log(` ${cyan}1.${r} Claude Code ${cyan}5.${r} Gemini CLI`);
|
|
1081
|
-
console.log(` ${cyan}2.${r} Codex CLI ${cyan}6.${r} VS Code`);
|
|
1082
|
-
console.log(` ${cyan}3.${r} Cursor ${cyan}7.${r} Zed`);
|
|
1083
|
-
console.log(` ${cyan}4.${r} Windsurf ${cyan}8.${r} OpenCode`);
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
if (!["1","2","3","4","5","6","7","8","9","11"].includes(choice)) {
|
|
1100
|
+
console.log(` ${cyan}1.${r} Claude Code ${cyan}5.${r} Gemini CLI ${cyan}9.${r} OpenClaw`);
|
|
1101
|
+
console.log(` ${cyan}2.${r} Codex CLI ${cyan}6.${r} VS Code ${cyan}10.${r} Antigravity`);
|
|
1102
|
+
console.log(` ${cyan}3.${r} Cursor ${cyan}7.${r} Zed ${cyan}11.${r} Cline`);
|
|
1103
|
+
console.log(` ${cyan}4.${r} Windsurf ${cyan}8.${r} OpenCode ${cyan}12.${r} Kimi CLI\n`);
|
|
1104
|
+
choice = (await ask(`${dim}Choose (1-12):${r} `)).trim();
|
|
1105
|
+
if (!["1","2","3","4","5","6","7","8","9","10","11","12"].includes(choice)) {
|
|
1087
1106
|
console.error("Invalid choice.");
|
|
1088
1107
|
rl.close();
|
|
1089
1108
|
process.exit(1);
|
|
@@ -1393,6 +1412,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1393
1412
|
const isOpenClaw = choice === "9";
|
|
1394
1413
|
const isAntigravity = choice === "10";
|
|
1395
1414
|
const isCline = choice === "11";
|
|
1415
|
+
const isKimi = choice === "12";
|
|
1396
1416
|
|
|
1397
1417
|
const hostname = run("hostname -s") || run("hostname") || "unknown";
|
|
1398
1418
|
|
|
@@ -1625,6 +1645,31 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1625
1645
|
console.log(`\n ${green}✓${r} Cline configured: ${dim}${clinePath}${r}`);
|
|
1626
1646
|
console.log(` ${yellow}Global config — all Cline projects share this agent.${r}`);
|
|
1627
1647
|
}
|
|
1648
|
+
} else if (isKimi) {
|
|
1649
|
+
// Kimi CLI: global ~/.kimi/mcp.json
|
|
1650
|
+
const kimiPath = join(HOME, ".kimi", "mcp.json");
|
|
1651
|
+
const kimiOk = updateJsonConfig(kimiPath, (obj) => {
|
|
1652
|
+
obj.mcpServers = obj.mcpServers || {};
|
|
1653
|
+
obj.mcpServers.patchcord = {
|
|
1654
|
+
url: `${serverUrl}/mcp`,
|
|
1655
|
+
headers: {
|
|
1656
|
+
Authorization: `Bearer ${token}`,
|
|
1657
|
+
"X-Patchcord-Machine": hostname,
|
|
1658
|
+
},
|
|
1659
|
+
};
|
|
1660
|
+
});
|
|
1661
|
+
if (kimiOk) {
|
|
1662
|
+
console.log(`\n ${green}✓${r} Kimi CLI configured: ${dim}${kimiPath}${r}`);
|
|
1663
|
+
console.log(` ${yellow}Global config — all Kimi CLI projects share this agent.${r}`);
|
|
1664
|
+
}
|
|
1665
|
+
// Install/update global skills
|
|
1666
|
+
const kimiSkillDir = join(HOME, ".kimi", "skills", "patchcord");
|
|
1667
|
+
const kimiWaitDir = join(HOME, ".kimi", "skills", "patchcord-wait");
|
|
1668
|
+
mkdirSync(kimiSkillDir, { recursive: true });
|
|
1669
|
+
mkdirSync(kimiWaitDir, { recursive: true });
|
|
1670
|
+
cpSync(join(pluginRoot, "skills", "inbox", "SKILL.md"), join(kimiSkillDir, "SKILL.md"));
|
|
1671
|
+
cpSync(join(pluginRoot, "skills", "wait", "SKILL.md"), join(kimiWaitDir, "SKILL.md"));
|
|
1672
|
+
console.log(` ${green}✓${r} Skills installed: ${dim}patchcord${r}, ${dim}patchcord-wait${r}`);
|
|
1628
1673
|
} else if (isVSCode) {
|
|
1629
1674
|
// VS Code: write .vscode/mcp.json (per-project)
|
|
1630
1675
|
const vscodeDir = join(cwd, ".vscode");
|
|
@@ -1851,7 +1896,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1851
1896
|
}
|
|
1852
1897
|
|
|
1853
1898
|
// Warn about gitignore for per-project configs with tokens
|
|
1854
|
-
if (!isWindsurf && !isGemini && !isZed && !isOpenClaw && !isAntigravity && !isCline) {
|
|
1899
|
+
if (!isWindsurf && !isGemini && !isZed && !isOpenClaw && !isAntigravity && !isCline && !isKimi) {
|
|
1855
1900
|
const gitignorePath = join(cwd, ".gitignore");
|
|
1856
1901
|
const configFile = isCodex ? ".codex/config.toml" : isCursor ? ".cursor/mcp.json" : isVSCode ? ".vscode/mcp.json" : isOpenCode ? "opencode.json" : ".mcp.json";
|
|
1857
1902
|
let needsWarning = true;
|
|
@@ -1869,9 +1914,9 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1869
1914
|
}
|
|
1870
1915
|
}
|
|
1871
1916
|
|
|
1872
|
-
const toolName = isAntigravity ? "Antigravity" : isCline ? "Cline" : isOpenClaw ? "OpenClaw" : isOpenCode ? "OpenCode" : isZed ? "Zed" : isVSCode ? "VS Code" : isGemini ? "Gemini CLI" : isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
|
|
1917
|
+
const toolName = isKimi ? "Kimi CLI" : isAntigravity ? "Antigravity" : isCline ? "Cline" : isOpenClaw ? "OpenClaw" : isOpenCode ? "OpenCode" : isZed ? "Zed" : isVSCode ? "VS Code" : isGemini ? "Gemini CLI" : isWindsurf ? "Windsurf" : isCursor ? "Cursor" : isCodex ? "Codex" : "Claude Code";
|
|
1873
1918
|
|
|
1874
|
-
if (!isWindsurf && !isGemini && !isZed && !isOpenClaw && !isAntigravity && !isCline) {
|
|
1919
|
+
if (!isWindsurf && !isGemini && !isZed && !isOpenClaw && !isAntigravity && !isCline && !isKimi) {
|
|
1875
1920
|
console.log(`\n ${dim}To connect a second agent:${r}`);
|
|
1876
1921
|
console.log(` ${dim}cd into another project and run${r} ${bold}npx patchcord@latest${r} ${dim}there.${r}`);
|
|
1877
1922
|
}
|
package/package.json
CHANGED
package/scripts/subscribe.mjs
CHANGED
|
@@ -55,7 +55,7 @@ function die(msg, code = 1) {
|
|
|
55
55
|
|
|
56
56
|
function readMcpConfig(cwd) {
|
|
57
57
|
// Prefer env vars injected by patchcord.mjs, which already ran _resolveBearer()
|
|
58
|
-
// and supports all
|
|
58
|
+
// and supports all 12 tool configs (Claude Code, OpenCode, Codex, Cursor, Kimi, etc.).
|
|
59
59
|
if (process.env.PATCHCORD_BASE_URL && process.env.PATCHCORD_BEARER_TOKEN) {
|
|
60
60
|
return { baseUrl: process.env.PATCHCORD_BASE_URL, token: process.env.PATCHCORD_BEARER_TOKEN };
|
|
61
61
|
}
|