patchcord 0.5.124 → 0.5.125

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. Messages from other agents land in the inbox and wake the agent to reply.",
4
- "version": "0.5.124",
4
+ "version": "0.5.125",
5
5
  "author": {
6
6
  "name": "ppravdin"
7
7
  },
package/bin/patchcord.mjs CHANGED
@@ -1786,6 +1786,33 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
1786
1786
  // Kimi Code (Node) reads ~/.kimi-code/skills. The legacy Python kimi-cli
1787
1787
  // (~/.kimi) is deprecated — install only into Kimi Code's home.
1788
1788
  const kimiSkillRoots = [join(kimiCodeHome, "skills")];
1789
+
1790
+ // Remove [[hooks]] array-of-tables blocks whose body matches `predicate`,
1791
+ // preserving everything else. A block runs from a `[[hooks]]` header line
1792
+ // until the next TOML table / array-of-tables header (`[...]` / `[[...]]`)
1793
+ // or EOF — so trailing sections like [providers.*] and [models.*] are NOT
1794
+ // swallowed. (The old split("[[hooks]]")+filter approach dropped the whole
1795
+ // segment after the patchcord hook, deleting kimi's model/provider defs and
1796
+ // leaving "Model not configured" on every host on the next install.)
1797
+ const removeHookBlocks = (toml, predicate) => {
1798
+ const lines = toml.split("\n");
1799
+ const out = [];
1800
+ let i = 0;
1801
+ while (i < lines.length) {
1802
+ if (/^\s*\[\[hooks\]\]\s*$/.test(lines[i])) {
1803
+ const block = [lines[i]];
1804
+ let j = i + 1;
1805
+ while (j < lines.length && !/^\s*\[/.test(lines[j])) { block.push(lines[j]); j++; }
1806
+ if (!predicate(block.join("\n"))) out.push(...block);
1807
+ i = j;
1808
+ } else {
1809
+ out.push(lines[i]); i++;
1810
+ }
1811
+ }
1812
+ return out.join("\n");
1813
+ };
1814
+ const isPatchcordHook = (b) => /patchcord-(stop-hook|session-start|prompt-hook)/.test(b);
1815
+
1789
1816
  for (const root of kimiSkillRoots) {
1790
1817
  for (const stale of ["patchcord", "patchcord-wait", "patchcord:inbox", "patchcord:wait", "patchcord:subscribe"]) {
1791
1818
  const d = join(root, stale);
@@ -1815,11 +1842,6 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
1815
1842
  // Remove old inline hooks = [] (conflicts with [[hooks]] array-of-tables)
1816
1843
  kimiConfig = kimiConfig.replace(/^hooks\s*=\s*\[\]\n?/gm, "");
1817
1844
 
1818
- // Remove existing patchcord stop hook blocks
1819
- const segments = kimiConfig.split("[[hooks]]");
1820
- const kept = segments.filter((seg, idx) => idx === 0 || !seg.includes("patchcord-stop-hook"));
1821
- kimiConfig = kept.join("[[hooks]]").replace(/\n{3,}/g, "\n\n").trim();
1822
-
1823
1845
  // Install session-start hook
1824
1846
  const kimiSessionSrc = join(pluginRoot, "scripts", "kimi-session-start.sh");
1825
1847
  const kimiSessionDest = join(kimiCodeHome, "patchcord-session-start.sh");
@@ -1828,10 +1850,9 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
1828
1850
  chmodSync(kimiSessionDest, 0o755);
1829
1851
  }
1830
1852
 
1831
- // Remove existing patchcord session-start hook blocks
1832
- const segments2 = kimiConfig.split("[[hooks]]");
1833
- const kept2 = segments2.filter((seg, idx) => idx === 0 || !seg.includes("patchcord-session-start") && !seg.includes("patchcord-prompt-hook"));
1834
- kimiConfig = kept2.join("[[hooks]]").replace(/\n{3,}/g, "\n\n").trim();
1853
+ // Remove any existing patchcord hook blocks (stop / session-start /
1854
+ // legacy prompt) in one pass, preserving all other tables.
1855
+ kimiConfig = removeHookBlocks(kimiConfig, isPatchcordHook).replace(/\n{3,}/g, "\n\n").trim();
1835
1856
 
1836
1857
  // Append new hooks
1837
1858
  kimiConfig = kimiConfig.trimEnd() + `\n\n[[hooks]]\nevent = "SessionStart"\ncommand = "${kimiSessionDest}"\ntimeout = 10\n\n[[hooks]]\nevent = "Stop"\ncommand = "${kimiHookDest}"\ntimeout = 10\n`;
@@ -1853,9 +1874,7 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
1853
1874
  if (existsSync(legacyConfigPath)) {
1854
1875
  try {
1855
1876
  let lc = readFileSync(legacyConfigPath, "utf-8");
1856
- const segs = lc.split("[[hooks]]");
1857
- const keptLegacy = segs.filter((seg, idx) => idx === 0 || !seg.includes("patchcord-"));
1858
- lc = keptLegacy.join("[[hooks]]").replace(/\n{3,}/g, "\n\n").trim();
1877
+ lc = removeHookBlocks(lc, (b) => /patchcord-/.test(b)).replace(/\n{3,}/g, "\n\n").trim();
1859
1878
  writeFileSync(legacyConfigPath, lc ? lc + "\n" : "");
1860
1879
  } catch {}
1861
1880
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.5.124",
3
+ "version": "0.5.125",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "scripts": {
6
6
  "version": "node scripts/sync-plugin-version.mjs && git add .claude-plugin/plugin.json"