patchcord 0.6.24 → 0.6.26
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 +54 -14
- package/package.json +1 -1
package/bin/patchcord.mjs
CHANGED
|
@@ -257,11 +257,14 @@ function _purgeLegacyKimiProjectConfig(dir) {
|
|
|
257
257
|
} catch {}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
// Cursor slash menu duplicates come from
|
|
261
|
-
//
|
|
262
|
-
// cursor-agent's node_modules/patchcord
|
|
263
|
-
//
|
|
264
|
-
//
|
|
260
|
+
// Cursor slash menu duplicates come from multiple trees Cursor CLI indexes:
|
|
261
|
+
// (a) stale no-hyphen / colon dirs under skills-cursor
|
|
262
|
+
// (b) cursor-agent's bundled node_modules/patchcord — both skills/ (Claude
|
|
263
|
+
// colon names → /patchcordinbox) AND per-project-skills/cursor (exact
|
|
264
|
+
// dupes of skills-cursor /patchcord-inbox)
|
|
265
|
+
// (c) ~/.agents/skills Codex copies (/patchcord) — Cursor indexes Agent Skills
|
|
266
|
+
// NEVER delete ~/.agents/skills content (Codex owns that tree). We only strip
|
|
267
|
+
// the cursor-agent-bundled copies Cursor should not show.
|
|
265
268
|
function _purgeCursorSkillDuplicates() {
|
|
266
269
|
const staleCursorOnly = [
|
|
267
270
|
"patchcord",
|
|
@@ -278,8 +281,22 @@ function _purgeCursorSkillDuplicates() {
|
|
|
278
281
|
if (!existsSync(d)) continue;
|
|
279
282
|
try { rmSync(d, { recursive: true, force: true }); } catch {}
|
|
280
283
|
}
|
|
281
|
-
//
|
|
282
|
-
//
|
|
284
|
+
// Keep ONLY the three hyphenated Cursor skills under skills-cursor.
|
|
285
|
+
// Anything else named patchcord* there is leftover junk.
|
|
286
|
+
if (existsSync(cursorSkillsRoot)) {
|
|
287
|
+
const keep = new Set(["patchcord-inbox", "patchcord-wait", "patchcord-subscribe"]);
|
|
288
|
+
try {
|
|
289
|
+
for (const ent of readdirSync(cursorSkillsRoot, { withFileTypes: true })) {
|
|
290
|
+
if (!ent.isDirectory()) continue;
|
|
291
|
+
if (!/^patchcord/i.test(ent.name)) continue;
|
|
292
|
+
if (keep.has(ent.name)) continue;
|
|
293
|
+
try { rmSync(join(cursorSkillsRoot, ent.name), { recursive: true, force: true }); } catch {}
|
|
294
|
+
}
|
|
295
|
+
} catch {}
|
|
296
|
+
}
|
|
297
|
+
// cursor-agent ships the full npm package. Cursor indexes SKILL.md under it,
|
|
298
|
+
// so strip BOTH skills/ and per-project-skills/ from every bundled copy.
|
|
299
|
+
// Canonical Cursor skills live only in ~/.cursor/skills-cursor/.
|
|
283
300
|
const cursorAgentRoot = join(HOME, ".local", "share", "cursor-agent");
|
|
284
301
|
if (existsSync(cursorAgentRoot)) {
|
|
285
302
|
const walk = (dir, depth = 0) => {
|
|
@@ -290,8 +307,8 @@ function _purgeCursorSkillDuplicates() {
|
|
|
290
307
|
const p = join(dir, ent.name);
|
|
291
308
|
if (ent.isDirectory()) {
|
|
292
309
|
if (ent.name === "patchcord" && dir.endsWith("node_modules")) {
|
|
293
|
-
for (const
|
|
294
|
-
const sd = join(p,
|
|
310
|
+
for (const sub of ["skills", "per-project-skills"]) {
|
|
311
|
+
const sd = join(p, sub);
|
|
295
312
|
if (existsSync(sd)) {
|
|
296
313
|
try { rmSync(sd, { recursive: true, force: true }); } catch {}
|
|
297
314
|
}
|
|
@@ -318,8 +335,10 @@ function _purgeCursorSkillDuplicates() {
|
|
|
318
335
|
}
|
|
319
336
|
}
|
|
320
337
|
|
|
321
|
-
// Codex global skills live at ~/.agents/skills
|
|
322
|
-
//
|
|
338
|
+
// Codex global skills live at ~/.agents/skills/. Cursor CLI also indexes that
|
|
339
|
+
// tree (no exclude setting — see cursor.com/docs/skills). Use ONE hyphenated
|
|
340
|
+
// wait skill here so Cursor does not also show /patchcordwait (colon) +
|
|
341
|
+
// /patchcord-wait (skills-cursor). Claude plugin skills keep colon names.
|
|
323
342
|
function _restoreCodexGlobalSkills() {
|
|
324
343
|
const codexConfig = join(HOME, ".codex", "config.toml");
|
|
325
344
|
if (!existsSync(codexConfig)) return;
|
|
@@ -330,11 +349,20 @@ function _restoreCodexGlobalSkills() {
|
|
|
330
349
|
writeFileSync(join(globalSkillDir, "SKILL.md"),
|
|
331
350
|
readFileSync(join(pluginRoot, "per-project-skills", "codex", "SKILL.md"), "utf-8"));
|
|
332
351
|
mkdirSync(globalWaitDir, { recursive: true });
|
|
352
|
+
// Shared hyphenated wait (same MCP wait_for_message flow as Cursor).
|
|
333
353
|
writeFileSync(join(globalWaitDir, "SKILL.md"),
|
|
334
|
-
readFileSync(join(pluginRoot, "skills", "wait", "SKILL.md"), "utf-8"));
|
|
354
|
+
readFileSync(join(pluginRoot, "per-project-skills", "cursor", "wait", "SKILL.md"), "utf-8"));
|
|
335
355
|
} catch {}
|
|
336
356
|
}
|
|
337
357
|
|
|
358
|
+
/** True when Codex is on this machine (agents skills would be indexed by Cursor). */
|
|
359
|
+
function _hasCodexAgentsSkills() {
|
|
360
|
+
if (existsSync(join(HOME, ".codex", "config.toml"))) return true;
|
|
361
|
+
if (existsSync(join(HOME, ".agents", "skills", "patchcord"))) return true;
|
|
362
|
+
if (existsSync(join(HOME, ".agents", "skills", "patchcord-wait"))) return true;
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
|
|
338
366
|
// preserving the rest of the user's YAML. Block-style only (what Hermes writes).
|
|
339
367
|
function upsertHermesConfig(existing, url, token) {
|
|
340
368
|
const block = [
|
|
@@ -1949,16 +1977,28 @@ if (!cmd || cmd === "install" || cmd === "agent" || cmd?.startsWith("--")) {
|
|
|
1949
1977
|
if (existsSync(staleCursorSkillDir)) {
|
|
1950
1978
|
try { rmSync(staleCursorSkillDir, { recursive: true, force: true }); cursorChanged = true; } catch {}
|
|
1951
1979
|
}
|
|
1980
|
+
// Always install Cursor-specific inbox + subscribe (not in ~/.agents).
|
|
1952
1981
|
mkdirSync(cursorInboxDir, { recursive: true });
|
|
1953
1982
|
cpSync(join(pluginRoot, "per-project-skills", "cursor", "inbox", "SKILL.md"), join(cursorInboxDir, "SKILL.md"));
|
|
1954
1983
|
cursorChanged = true;
|
|
1955
|
-
mkdirSync(cursorWaitDir, { recursive: true });
|
|
1956
|
-
cpSync(join(pluginRoot, "per-project-skills", "cursor", "wait", "SKILL.md"), join(cursorWaitDir, "SKILL.md"));
|
|
1957
1984
|
mkdirSync(cursorSubscribeDir, { recursive: true });
|
|
1958
1985
|
cpSync(
|
|
1959
1986
|
join(pluginRoot, "per-project-skills", "cursor", "subscribe", "SKILL.md"),
|
|
1960
1987
|
join(cursorSubscribeDir, "SKILL.md")
|
|
1961
1988
|
);
|
|
1989
|
+
// Wait is shared MCP flow. If Codex/agents already owns patchcord-wait,
|
|
1990
|
+
// keep ONE copy under ~/.agents (Cursor indexes it) — do NOT also install
|
|
1991
|
+
// skills-cursor/patchcord-wait (duplicate slash). Cursor-only machines
|
|
1992
|
+
// still get wait under skills-cursor.
|
|
1993
|
+
if (_hasCodexAgentsSkills()) {
|
|
1994
|
+
_restoreCodexGlobalSkills();
|
|
1995
|
+
if (existsSync(cursorWaitDir)) {
|
|
1996
|
+
try { rmSync(cursorWaitDir, { recursive: true, force: true }); cursorChanged = true; } catch {}
|
|
1997
|
+
}
|
|
1998
|
+
} else {
|
|
1999
|
+
mkdirSync(cursorWaitDir, { recursive: true });
|
|
2000
|
+
cpSync(join(pluginRoot, "per-project-skills", "cursor", "wait", "SKILL.md"), join(cursorWaitDir, "SKILL.md"));
|
|
2001
|
+
}
|
|
1962
2002
|
if (cursorChanged) globalChanges.push("Cursor skills installed");
|
|
1963
2003
|
|
|
1964
2004
|
if (hasCursorAgent) {
|
package/package.json
CHANGED