@indigoai-us/hq-cloud 6.1.0 → 6.2.0
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/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js +18 -0
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/reindex.d.ts +4 -11
- package/dist/cli/reindex.d.ts.map +1 -1
- package/dist/cli/reindex.js +336 -30
- package/dist/cli/reindex.js.map +1 -1
- package/dist/cli/reindex.test.d.ts +3 -3
- package/dist/cli/reindex.test.js +36 -11
- package/dist/cli/reindex.test.js.map +1 -1
- package/dist/cli/rescue-core.d.ts +36 -0
- package/dist/cli/rescue-core.d.ts.map +1 -0
- package/dist/cli/rescue-core.js +1536 -0
- package/dist/cli/rescue-core.js.map +1 -0
- package/dist/cli/rescue-drift-reconcile.test.js +33 -10
- package/dist/cli/rescue-drift-reconcile.test.js.map +1 -1
- package/dist/cli/rescue-mtime-preserve.test.js +36 -12
- package/dist/cli/rescue-mtime-preserve.test.js.map +1 -1
- package/dist/cli/rescue.d.ts +4 -10
- package/dist/cli/rescue.d.ts.map +1 -1
- package/dist/cli/rescue.js +14 -37
- package/dist/cli/rescue.js.map +1 -1
- package/dist/cli/rescue.reindex.test.js +9 -8
- package/dist/cli/rescue.reindex.test.js.map +1 -1
- package/dist/cli/rescue.test.js +1 -10
- package/dist/cli/rescue.test.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/conflict-index.d.ts +40 -0
- package/dist/lib/conflict-index.d.ts.map +1 -1
- package/dist/lib/conflict-index.js +121 -0
- package/dist/lib/conflict-index.js.map +1 -1
- package/dist/lib/conflict.test.js +145 -1
- package/dist/lib/conflict.test.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/sync-runner.ts +18 -0
- package/src/cli/index.ts +2 -2
- package/src/cli/reindex.test.ts +45 -12
- package/src/cli/reindex.ts +345 -36
- package/src/cli/rescue-core.ts +1650 -0
- package/src/cli/rescue-drift-reconcile.test.ts +33 -12
- package/src/cli/rescue-mtime-preserve.test.ts +36 -15
- package/src/cli/rescue.reindex.test.ts +9 -8
- package/src/cli/rescue.test.ts +1 -11
- package/src/cli/rescue.ts +15 -40
- package/src/index.ts +2 -2
- package/src/lib/conflict-index.ts +146 -0
- package/src/lib/conflict.test.ts +171 -0
- package/scripts/reindex.sh +0 -318
- package/scripts/replace-rescue.sh +0 -1522
package/dist/index.js
CHANGED
|
@@ -42,9 +42,9 @@ export { invite, listInvites, revokeInvite } from "./cli/index.js";
|
|
|
42
42
|
export { accept, parseToken } from "./cli/index.js";
|
|
43
43
|
export { promote } from "./cli/index.js";
|
|
44
44
|
// Skill/personal-overlay mirroring + workers-registry regen (`hq reindex`).
|
|
45
|
-
export { reindex
|
|
45
|
+
export { reindex } from "./cli/index.js";
|
|
46
46
|
// Drift-preserving HQ-core re-sync — shared by the HQ Sync app and `hq rescue`.
|
|
47
|
-
export { rescue,
|
|
47
|
+
export { rescue, buildRescueArgs } from "./cli/index.js";
|
|
48
48
|
// Client identification — every first-party caller should construct one of
|
|
49
49
|
// these once at startup and pass it in via VaultServiceConfig.clientInfo.
|
|
50
50
|
export { buildClientHeaders, clientInfoFromPackage, detectHqCoreVersion, HEADER_CLIENT_NAME, HEADER_CLIENT_VERSION, HEADER_HQ_CORE_VERSION, } from "./client-info.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,UAAU,GACX,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc;AACd,sBAAsB;AACtB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAEtB,oCAAoC;AACpC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,gDAAgD;AAChD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAS3B,qDAAqD;AACrD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAY1B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,gCAAgC;AAChC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,6EAA6E;AAC7E,OAAO,EACL,iCAAiC,EACjC,qCAAqC,EACrC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAG7B,2EAA2E;AAC3E,kEAAkE;AAClE,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,2BAA2B,EAC3B,mCAAmC,GACpC,MAAM,gCAAgC,CAAC;AAGxC,0BAA0B;AAC1B,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAyB3B,8EAA8E;AAC9E,4EAA4E;AAC5E,2DAA2D;AAC3D,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOtE,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AA0B9B,eAAe;AACf,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG3D,kCAAkC;AAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,4EAA4E;AAC5E,OAAO,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,UAAU,GACX,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc;AACd,sBAAsB;AACtB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAEtB,oCAAoC;AACpC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,gDAAgD;AAChD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAS3B,qDAAqD;AACrD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAY1B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,gCAAgC;AAChC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,6EAA6E;AAC7E,OAAO,EACL,iCAAiC,EACjC,qCAAqC,EACrC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAG7B,2EAA2E;AAC3E,kEAAkE;AAClE,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,2BAA2B,EAC3B,mCAAmC,GACpC,MAAM,gCAAgC,CAAC;AAGxC,0BAA0B;AAC1B,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAyB3B,8EAA8E;AAC9E,4EAA4E;AAC5E,2DAA2D;AAC3D,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOtE,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AA0B9B,eAAe;AACf,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG3D,kCAAkC;AAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,4EAA4E;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,gFAAgF;AAChF,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAmBzD,2EAA2E;AAC3E,0EAA0E;AAC1E,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,6CAA6C;AAC7C,OAAO,EACL,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAGnC,yDAAyD;AACzD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AASlE,oEAAoE;AACpE,sDAAsD;AACtD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AASlE,oEAAoE;AACpE,sDAAsD;AACtD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,4EAA4E;AAC5E,6EAA6E;AAC7E,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,kCAAkC,EAClC,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAazB,2EAA2E;AAC3E,6BAA6B;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -63,4 +63,44 @@ export declare function appendConflictEntry(hqRoot: string, entry: ConflictIndex
|
|
|
63
63
|
* skill — we want that to be a clean exit, not an error).
|
|
64
64
|
*/
|
|
65
65
|
export declare function removeConflictEntry(hqRoot: string, id: string): void;
|
|
66
|
+
/** Summary of what a {@link pruneConflictIndex} pass reclaimed. */
|
|
67
|
+
export interface PruneConflictIndexResult {
|
|
68
|
+
/** Rows dropped because their `.conflict-*` mirror no longer exists. */
|
|
69
|
+
prunedOrphans: number;
|
|
70
|
+
/** Rows dropped because the original file and its mirror are byte-identical. */
|
|
71
|
+
prunedIdentical: number;
|
|
72
|
+
/** Byte-identical mirror files deleted from disk during the pass. */
|
|
73
|
+
removedMirrors: number;
|
|
74
|
+
/** Rows kept (genuine divergence, or unprovable — fail-safe retained). */
|
|
75
|
+
kept: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Garbage-collect the conflict index so it self-heals instead of growing
|
|
79
|
+
* without bound. Before this pass existed the ledger only ever shrank when a
|
|
80
|
+
* human resolved a conflict via `/resolve-conflicts`; every false positive and
|
|
81
|
+
* every orphaned row lingered forever, so the index over-reported the real
|
|
82
|
+
* pending-conflict count (the menubar's journal-derived count stayed correct,
|
|
83
|
+
* but `.hq-conflicts/index.json` did not).
|
|
84
|
+
*
|
|
85
|
+
* Two classes of entry are dropped — both provably not a pending conflict:
|
|
86
|
+
*
|
|
87
|
+
* 1. **Orphaned** — the `.conflict-*` mirror file is gone from disk. The
|
|
88
|
+
* mirror is the only artifact a human resolves against; once it's missing
|
|
89
|
+
* the row can never be acted on, so it's pure litter (the "missing-cloud"
|
|
90
|
+
* rows operators reported climbing into the dozens).
|
|
91
|
+
*
|
|
92
|
+
* 2. **Byte-identical false positives** — the original file and its conflict
|
|
93
|
+
* mirror both still exist and are byte-for-byte identical. The mirror
|
|
94
|
+
* holds the remote bytes captured at detection time, so identical bytes
|
|
95
|
+
* mean there was never a real divergence (this is exactly the manual
|
|
96
|
+
* safe-purge operators have been doing by hand). The stale mirror file is
|
|
97
|
+
* deleted and the row dropped.
|
|
98
|
+
*
|
|
99
|
+
* Conservative by construction — an entry is kept whenever it might be a real
|
|
100
|
+
* conflict: the original file is missing (a genuine local-delete-vs-remote
|
|
101
|
+
* divergence), the bytes differ, or either side can't be read. The index file
|
|
102
|
+
* is only rewritten when at least one row is actually dropped, so a clean
|
|
103
|
+
* ledger keeps its mtime untouched.
|
|
104
|
+
*/
|
|
105
|
+
export declare function pruneConflictIndex(hqRoot: string): PruneConflictIndexResult;
|
|
66
106
|
//# sourceMappingURL=conflict-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-index.d.ts","sourceRoot":"","sources":["../../src/lib/conflict-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKrE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAY/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,GACnB,IAAI,CAgBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,GACxB,IAAI,CASN;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAKpE"}
|
|
1
|
+
{"version":3,"file":"conflict-index.d.ts","sourceRoot":"","sources":["../../src/lib/conflict-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKrE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAY/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,GACnB,IAAI,CAgBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,GACxB,IAAI,CASN;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAKpE;AAED,mEAAmE;AACnE,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;CACd;AA4BD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,wBAAwB,CA8E3E"}
|
|
@@ -109,4 +109,125 @@ export function removeConflictEntry(hqRoot, id) {
|
|
|
109
109
|
return;
|
|
110
110
|
writeConflictIndex(hqRoot, { version: index.version, conflicts: filtered });
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Byte-identity check used by the prune pass. Symlink-aware: two symlinks are
|
|
114
|
+
* identical iff their link targets match (mirroring how the detector hashes a
|
|
115
|
+
* symlink record — `hashSymlinkTarget`, not the followed content). A symlink
|
|
116
|
+
* compared against a regular file is never identical. Regular files reject on a
|
|
117
|
+
* size mismatch first (cheap), then compare full bytes.
|
|
118
|
+
*
|
|
119
|
+
* Throws if either side can't be read — callers treat that as "unprovable" and
|
|
120
|
+
* keep the entry rather than risk dropping a real conflict.
|
|
121
|
+
*/
|
|
122
|
+
function entryFilesAreIdentical(aPath, aStat, bPath, bStat) {
|
|
123
|
+
const aLink = aStat.isSymbolicLink();
|
|
124
|
+
const bLink = bStat.isSymbolicLink();
|
|
125
|
+
if (aLink || bLink) {
|
|
126
|
+
if (aLink !== bLink)
|
|
127
|
+
return false;
|
|
128
|
+
return fs.readlinkSync(aPath) === fs.readlinkSync(bPath);
|
|
129
|
+
}
|
|
130
|
+
if (aStat.size !== bStat.size)
|
|
131
|
+
return false;
|
|
132
|
+
return fs.readFileSync(aPath).equals(fs.readFileSync(bPath));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Garbage-collect the conflict index so it self-heals instead of growing
|
|
136
|
+
* without bound. Before this pass existed the ledger only ever shrank when a
|
|
137
|
+
* human resolved a conflict via `/resolve-conflicts`; every false positive and
|
|
138
|
+
* every orphaned row lingered forever, so the index over-reported the real
|
|
139
|
+
* pending-conflict count (the menubar's journal-derived count stayed correct,
|
|
140
|
+
* but `.hq-conflicts/index.json` did not).
|
|
141
|
+
*
|
|
142
|
+
* Two classes of entry are dropped — both provably not a pending conflict:
|
|
143
|
+
*
|
|
144
|
+
* 1. **Orphaned** — the `.conflict-*` mirror file is gone from disk. The
|
|
145
|
+
* mirror is the only artifact a human resolves against; once it's missing
|
|
146
|
+
* the row can never be acted on, so it's pure litter (the "missing-cloud"
|
|
147
|
+
* rows operators reported climbing into the dozens).
|
|
148
|
+
*
|
|
149
|
+
* 2. **Byte-identical false positives** — the original file and its conflict
|
|
150
|
+
* mirror both still exist and are byte-for-byte identical. The mirror
|
|
151
|
+
* holds the remote bytes captured at detection time, so identical bytes
|
|
152
|
+
* mean there was never a real divergence (this is exactly the manual
|
|
153
|
+
* safe-purge operators have been doing by hand). The stale mirror file is
|
|
154
|
+
* deleted and the row dropped.
|
|
155
|
+
*
|
|
156
|
+
* Conservative by construction — an entry is kept whenever it might be a real
|
|
157
|
+
* conflict: the original file is missing (a genuine local-delete-vs-remote
|
|
158
|
+
* divergence), the bytes differ, or either side can't be read. The index file
|
|
159
|
+
* is only rewritten when at least one row is actually dropped, so a clean
|
|
160
|
+
* ledger keeps its mtime untouched.
|
|
161
|
+
*/
|
|
162
|
+
export function pruneConflictIndex(hqRoot) {
|
|
163
|
+
const result = {
|
|
164
|
+
prunedOrphans: 0,
|
|
165
|
+
prunedIdentical: 0,
|
|
166
|
+
removedMirrors: 0,
|
|
167
|
+
kept: 0,
|
|
168
|
+
};
|
|
169
|
+
const index = readConflictIndex(hqRoot);
|
|
170
|
+
if (index.conflicts.length === 0)
|
|
171
|
+
return result;
|
|
172
|
+
const kept = [];
|
|
173
|
+
const mirrorsToRemove = [];
|
|
174
|
+
for (const entry of index.conflicts) {
|
|
175
|
+
const mirrorAbs = path.join(hqRoot, entry.conflictPath);
|
|
176
|
+
const originalAbs = path.join(hqRoot, entry.originalPath);
|
|
177
|
+
let mirrorStat;
|
|
178
|
+
try {
|
|
179
|
+
mirrorStat = fs.lstatSync(mirrorAbs);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Mirror is gone — orphaned row, drop it. Nothing on disk to clean up.
|
|
183
|
+
result.prunedOrphans++;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
// Both sides must exist to compare. A missing original is a real
|
|
187
|
+
// local-delete divergence — keep it for the human to resolve.
|
|
188
|
+
let originalStat;
|
|
189
|
+
try {
|
|
190
|
+
originalStat = fs.lstatSync(originalAbs);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
kept.push(entry);
|
|
194
|
+
result.kept++;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
let identical;
|
|
198
|
+
try {
|
|
199
|
+
identical = entryFilesAreIdentical(originalAbs, originalStat, mirrorAbs, mirrorStat);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// Couldn't read one side — fail safe, keep the row.
|
|
203
|
+
kept.push(entry);
|
|
204
|
+
result.kept++;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (identical) {
|
|
208
|
+
result.prunedIdentical++;
|
|
209
|
+
mirrorsToRemove.push(mirrorAbs);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
kept.push(entry);
|
|
213
|
+
result.kept++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// No row dropped → leave the file (and its mtime) untouched.
|
|
217
|
+
if (kept.length === index.conflicts.length)
|
|
218
|
+
return result;
|
|
219
|
+
// Delete the byte-identical mirror litter. Best-effort: a leftover identical
|
|
220
|
+
// mirror is cosmetic, never corrupting, so a failed unlink doesn't abort.
|
|
221
|
+
for (const mirrorAbs of mirrorsToRemove) {
|
|
222
|
+
try {
|
|
223
|
+
fs.rmSync(mirrorAbs, { force: true });
|
|
224
|
+
result.removedMirrors++;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
/* best-effort cleanup */
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
writeConflictIndex(hqRoot, { version: index.version, conflicts: kept });
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
112
233
|
//# sourceMappingURL=conflict-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-index.js","sourceRoot":"","sources":["../../src/lib/conflict-index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conflict-index.js","sourceRoot":"","sources":["../../src/lib/conflict-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import * as fs from "fs";
|
|
|
9
9
|
import * as os from "os";
|
|
10
10
|
import * as path from "path";
|
|
11
11
|
import { buildConflictPath, buildConflictId, } from "./conflict-file.js";
|
|
12
|
-
import { appendConflictEntry, getConflictIndexPath, readConflictIndex, removeConflictEntry, writeConflictIndex, } from "./conflict-index.js";
|
|
12
|
+
import { appendConflictEntry, getConflictIndexPath, pruneConflictIndex, readConflictIndex, removeConflictEntry, writeConflictIndex, } from "./conflict-index.js";
|
|
13
13
|
describe("buildConflictPath", () => {
|
|
14
14
|
it("inserts the conflict marker before the original extension", () => {
|
|
15
15
|
expect(buildConflictPath("knowledge/notes.md", "2026-04-27T22:05:14Z", "abc123")).toBe("knowledge/notes.md.conflict-2026-04-27T22-05-14Z-abc123.md");
|
|
@@ -105,4 +105,148 @@ describe("conflict index", () => {
|
|
|
105
105
|
expect(idx.conflicts).toEqual([]);
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
|
+
describe("pruneConflictIndex", () => {
|
|
109
|
+
let tmpHq;
|
|
110
|
+
beforeEach(() => {
|
|
111
|
+
tmpHq = fs.mkdtempSync(path.join(os.tmpdir(), "hq-cprune-"));
|
|
112
|
+
});
|
|
113
|
+
afterEach(() => {
|
|
114
|
+
fs.rmSync(tmpHq, { recursive: true, force: true });
|
|
115
|
+
});
|
|
116
|
+
/** Write a file at a hq-relative path, creating parent dirs. */
|
|
117
|
+
function put(rel, content) {
|
|
118
|
+
const abs = path.join(tmpHq, rel);
|
|
119
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
120
|
+
fs.writeFileSync(abs, content);
|
|
121
|
+
}
|
|
122
|
+
/** Write a symlink at a hq-relative path pointing at `target` (verbatim). */
|
|
123
|
+
function putLink(rel, target) {
|
|
124
|
+
const abs = path.join(tmpHq, rel);
|
|
125
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
126
|
+
fs.symlinkSync(target, abs);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build an entry whose original/conflict paths are derived from `id` so each
|
|
130
|
+
* row addresses distinct files on disk (the shared `entry()` helper above
|
|
131
|
+
* reuses one fixed path pair, which would collide across rows here).
|
|
132
|
+
*/
|
|
133
|
+
function rowFor(id) {
|
|
134
|
+
return {
|
|
135
|
+
id,
|
|
136
|
+
originalPath: `dir/${id}.md`,
|
|
137
|
+
conflictPath: `dir/${id}.md.conflict-2026-04-27T22-05-14Z-abc123.md`,
|
|
138
|
+
detectedAt: "2026-04-27T22:05:14Z",
|
|
139
|
+
side: "pull",
|
|
140
|
+
machineId: "abc123",
|
|
141
|
+
localHash: "local",
|
|
142
|
+
remoteHash: "remote",
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
it("returns a zeroed result and writes nothing for an empty/absent index", () => {
|
|
146
|
+
const res = pruneConflictIndex(tmpHq);
|
|
147
|
+
expect(res).toEqual({
|
|
148
|
+
prunedOrphans: 0,
|
|
149
|
+
prunedIdentical: 0,
|
|
150
|
+
removedMirrors: 0,
|
|
151
|
+
kept: 0,
|
|
152
|
+
});
|
|
153
|
+
expect(fs.existsSync(getConflictIndexPath(tmpHq))).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
it("drops a row whose .conflict-* mirror no longer exists (orphan)", () => {
|
|
156
|
+
const row = rowFor("orphan");
|
|
157
|
+
put(row.originalPath, "still here");
|
|
158
|
+
// No mirror file on disk.
|
|
159
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [row] });
|
|
160
|
+
const res = pruneConflictIndex(tmpHq);
|
|
161
|
+
expect(res.prunedOrphans).toBe(1);
|
|
162
|
+
expect(res.kept).toBe(0);
|
|
163
|
+
expect(readConflictIndex(tmpHq).conflicts).toHaveLength(0);
|
|
164
|
+
});
|
|
165
|
+
it("drops a byte-identical row and deletes its mirror file", () => {
|
|
166
|
+
const row = rowFor("identical");
|
|
167
|
+
put(row.originalPath, "same bytes");
|
|
168
|
+
put(row.conflictPath, "same bytes");
|
|
169
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [row] });
|
|
170
|
+
const res = pruneConflictIndex(tmpHq);
|
|
171
|
+
expect(res.prunedIdentical).toBe(1);
|
|
172
|
+
expect(res.removedMirrors).toBe(1);
|
|
173
|
+
expect(readConflictIndex(tmpHq).conflicts).toHaveLength(0);
|
|
174
|
+
expect(fs.existsSync(path.join(tmpHq, row.conflictPath))).toBe(false);
|
|
175
|
+
// The user's original is never touched.
|
|
176
|
+
expect(fs.existsSync(path.join(tmpHq, row.originalPath))).toBe(true);
|
|
177
|
+
});
|
|
178
|
+
it("keeps a genuinely divergent row and leaves both files in place", () => {
|
|
179
|
+
const row = rowFor("real");
|
|
180
|
+
put(row.originalPath, "local edit");
|
|
181
|
+
put(row.conflictPath, "remote edit");
|
|
182
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [row] });
|
|
183
|
+
const res = pruneConflictIndex(tmpHq);
|
|
184
|
+
expect(res.kept).toBe(1);
|
|
185
|
+
expect(res.prunedIdentical).toBe(0);
|
|
186
|
+
expect(res.prunedOrphans).toBe(0);
|
|
187
|
+
expect(readConflictIndex(tmpHq).conflicts.map((c) => c.id)).toEqual(["real"]);
|
|
188
|
+
expect(fs.existsSync(path.join(tmpHq, row.conflictPath))).toBe(true);
|
|
189
|
+
});
|
|
190
|
+
it("keeps a row whose original is missing (local-delete divergence)", () => {
|
|
191
|
+
const row = rowFor("deleted-local");
|
|
192
|
+
// No original; mirror present.
|
|
193
|
+
put(row.conflictPath, "remote bytes");
|
|
194
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [row] });
|
|
195
|
+
const res = pruneConflictIndex(tmpHq);
|
|
196
|
+
expect(res.kept).toBe(1);
|
|
197
|
+
expect(readConflictIndex(tmpHq).conflicts).toHaveLength(1);
|
|
198
|
+
});
|
|
199
|
+
it("treats two symlinks with the same target as identical, differing targets as a conflict", () => {
|
|
200
|
+
const same = rowFor("link-same");
|
|
201
|
+
putLink(same.originalPath, "../target/a");
|
|
202
|
+
putLink(same.conflictPath, "../target/a");
|
|
203
|
+
const diff = rowFor("link-diff");
|
|
204
|
+
putLink(diff.originalPath, "../target/a");
|
|
205
|
+
putLink(diff.conflictPath, "../target/b");
|
|
206
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [same, diff] });
|
|
207
|
+
const res = pruneConflictIndex(tmpHq);
|
|
208
|
+
expect(res.prunedIdentical).toBe(1);
|
|
209
|
+
expect(res.kept).toBe(1);
|
|
210
|
+
expect(readConflictIndex(tmpHq).conflicts.map((c) => c.id)).toEqual([
|
|
211
|
+
"link-diff",
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
it("partitions a mixed batch and preserves only the real conflicts", () => {
|
|
215
|
+
const orphan = rowFor("orphan");
|
|
216
|
+
put(orphan.originalPath, "x"); // mirror missing
|
|
217
|
+
const identical = rowFor("identical");
|
|
218
|
+
put(identical.originalPath, "dup");
|
|
219
|
+
put(identical.conflictPath, "dup");
|
|
220
|
+
const real = rowFor("real");
|
|
221
|
+
put(real.originalPath, "L");
|
|
222
|
+
put(real.conflictPath, "R");
|
|
223
|
+
writeConflictIndex(tmpHq, {
|
|
224
|
+
version: 1,
|
|
225
|
+
conflicts: [orphan, identical, real],
|
|
226
|
+
});
|
|
227
|
+
const res = pruneConflictIndex(tmpHq);
|
|
228
|
+
expect(res).toEqual({
|
|
229
|
+
prunedOrphans: 1,
|
|
230
|
+
prunedIdentical: 1,
|
|
231
|
+
removedMirrors: 1,
|
|
232
|
+
kept: 1,
|
|
233
|
+
});
|
|
234
|
+
expect(readConflictIndex(tmpHq).conflicts.map((c) => c.id)).toEqual(["real"]);
|
|
235
|
+
});
|
|
236
|
+
it("does not rewrite the index file when nothing is pruned", () => {
|
|
237
|
+
const real = rowFor("real");
|
|
238
|
+
put(real.originalPath, "L");
|
|
239
|
+
put(real.conflictPath, "R");
|
|
240
|
+
writeConflictIndex(tmpHq, { version: 1, conflicts: [real] });
|
|
241
|
+
const indexPath = getConflictIndexPath(tmpHq);
|
|
242
|
+
const before = fs.statSync(indexPath).mtimeMs;
|
|
243
|
+
// Advance the clock past filesystem mtime granularity, then prune.
|
|
244
|
+
const spin = Date.now() + 20;
|
|
245
|
+
while (Date.now() < spin) {
|
|
246
|
+
/* busy-wait ~20ms so a rewrite would move mtime */
|
|
247
|
+
}
|
|
248
|
+
pruneConflictIndex(tmpHq);
|
|
249
|
+
expect(fs.statSync(indexPath).mtimeMs).toBe(before);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
108
252
|
//# sourceMappingURL=conflict.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict.test.js","sourceRoot":"","sources":["../../src/lib/conflict.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conflict.test.js","sourceRoot":"","sources":["../../src/lib/conflict.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/bin/sync-runner.ts
CHANGED
|
@@ -99,6 +99,7 @@ import {
|
|
|
99
99
|
import { collectAndSendTelemetry } from "../telemetry.js";
|
|
100
100
|
import { collectAndSendSkillTelemetry } from "../skill-telemetry.js";
|
|
101
101
|
import { reindexAfterSync } from "../qmd-reindex.js";
|
|
102
|
+
import { pruneConflictIndex } from "../lib/conflict-index.js";
|
|
102
103
|
import { describeError } from "../lib/describe-error.js";
|
|
103
104
|
import { getOrCreateMachineId } from "../lib/machine-id.js";
|
|
104
105
|
import {
|
|
@@ -1639,6 +1640,23 @@ export async function runRunner(
|
|
|
1639
1640
|
}
|
|
1640
1641
|
}
|
|
1641
1642
|
|
|
1643
|
+
// Post-sync conflict-ledger prune — also a best-effort tail step (runs AFTER
|
|
1644
|
+
// `all-complete`, never touches the exit code). The producers only append a
|
|
1645
|
+
// conflict row after proving real divergence, but the ledger has no other
|
|
1646
|
+
// self-healing path: rows for byte-identical false positives (legacy or
|
|
1647
|
+
// since-reverted) and orphaned `.conflict-*` mirrors otherwise linger
|
|
1648
|
+
// forever and make `.hq-conflicts/index.json` over-report. One GC pass per
|
|
1649
|
+
// run keeps it converged. Idempotent and cheap on a clean ledger (a no-row
|
|
1650
|
+
// index returns immediately and never rewrites the file). Opt-out via
|
|
1651
|
+
// HQ_CONFLICT_PRUNE_ON_SYNC=0.
|
|
1652
|
+
if (process.env.HQ_CONFLICT_PRUNE_ON_SYNC !== "0") {
|
|
1653
|
+
try {
|
|
1654
|
+
pruneConflictIndex(parsed.hqRoot);
|
|
1655
|
+
} catch {
|
|
1656
|
+
// Defensive: a prune failure must never affect the sync outcome.
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1642
1660
|
// Exit 2 only when something actually threw (`errors.length > 0`). A clean
|
|
1643
1661
|
// conflict-abort sets `partial: true` in the JSON but exits 0 — the Tauri
|
|
1644
1662
|
// menubar's non-zero-exit Sentry capture would otherwise fire for normal
|
package/src/cli/index.ts
CHANGED
|
@@ -26,10 +26,10 @@ export type { PromoteOptions, PromoteResult } from "./promote.js";
|
|
|
26
26
|
|
|
27
27
|
// Skill/personal-overlay mirroring + workers-registry regen (formerly the
|
|
28
28
|
// hq-core master-sync.sh hook; `hq reindex`).
|
|
29
|
-
export { reindex
|
|
29
|
+
export { reindex } from "./reindex.js";
|
|
30
30
|
export type { ReindexOptions, ReindexResult } from "./reindex.js";
|
|
31
31
|
|
|
32
32
|
// Drift-preserving HQ-core re-sync (formerly bundled only inside the HQ Sync
|
|
33
33
|
// menubar app). Now shared between the app and `hq rescue`.
|
|
34
|
-
export { rescue,
|
|
34
|
+
export { rescue, buildRescueArgs } from "./rescue.js";
|
|
35
35
|
export type { RescueOptions, RescueResult } from "./rescue.js";
|
package/src/cli/reindex.test.ts
CHANGED
|
@@ -2,25 +2,17 @@
|
|
|
2
2
|
* Unit tests for `hq reindex` (the formerly-bash hq-core hook, now shipped
|
|
3
3
|
* in this package and invoked via the CLI).
|
|
4
4
|
*
|
|
5
|
-
* The logic
|
|
6
|
-
*
|
|
5
|
+
* The logic is implemented natively in TypeScript in ./reindex.ts; these tests
|
|
6
|
+
* exercise reindex() directly against a temp HQ tree, asserting the observable
|
|
7
7
|
* filesystem outcomes (skill wrappers, personal-overlay mirroring) rather than
|
|
8
|
-
* re-deriving the
|
|
8
|
+
* re-deriving the implementation internals.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
12
12
|
import * as fs from "fs";
|
|
13
13
|
import * as path from "path";
|
|
14
14
|
import * as os from "os";
|
|
15
|
-
import { reindex
|
|
16
|
-
|
|
17
|
-
describe("reindexScriptPath", () => {
|
|
18
|
-
it("resolves to the bundled script and the file exists", () => {
|
|
19
|
-
const p = reindexScriptPath();
|
|
20
|
-
expect(p.endsWith(path.join("scripts", "reindex.sh"))).toBe(true);
|
|
21
|
-
expect(fs.existsSync(p)).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
15
|
+
import { reindex } from "./reindex.js";
|
|
24
16
|
|
|
25
17
|
describe("reindex", () => {
|
|
26
18
|
let root: string;
|
|
@@ -91,4 +83,45 @@ describe("reindex", () => {
|
|
|
91
83
|
fs.readlinkSync(path.join(root, ".claude/skills/core:demo/SKILL.md")),
|
|
92
84
|
).toBe("../../../core/skills/demo/SKILL.md");
|
|
93
85
|
});
|
|
86
|
+
|
|
87
|
+
it("skips `_`-prefixed and dotfile skill folders", () => {
|
|
88
|
+
writeSkill("core/skills/_template");
|
|
89
|
+
fs.mkdirSync(path.join(root, "core/skills/.hidden"), { recursive: true });
|
|
90
|
+
fs.writeFileSync(path.join(root, "core/skills/.hidden/SKILL.md"), "x\n");
|
|
91
|
+
writeSkill("core/skills/real");
|
|
92
|
+
|
|
93
|
+
reindex({ repoRoot: root });
|
|
94
|
+
|
|
95
|
+
expect(fs.existsSync(path.join(root, ".claude/skills/core:real"))).toBe(true);
|
|
96
|
+
expect(fs.existsSync(path.join(root, ".claude/skills/core:_template"))).toBe(false);
|
|
97
|
+
expect(fs.existsSync(path.join(root, ".claude/skills/core:.hidden"))).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("removes legacy .claude/commands/<ns>/<skill>.md bridge symlinks", () => {
|
|
101
|
+
const cmdDir = path.join(root, ".claude/commands/core");
|
|
102
|
+
fs.mkdirSync(cmdDir, { recursive: true });
|
|
103
|
+
// Legacy bridge symlink (matches the cleanup pattern) → removed.
|
|
104
|
+
fs.symlinkSync("../../../core/skills/demo/SKILL.md", path.join(cmdDir, "demo.md"));
|
|
105
|
+
// A real file (non-symlink) → preserved.
|
|
106
|
+
fs.writeFileSync(path.join(cmdDir, "keep.md"), "manual\n");
|
|
107
|
+
|
|
108
|
+
reindex({ repoRoot: root });
|
|
109
|
+
|
|
110
|
+
expect(fs.existsSync(path.join(cmdDir, "demo.md"))).toBe(false);
|
|
111
|
+
expect(fs.existsSync(path.join(cmdDir, "keep.md"))).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("leaves hand-authored composite wrappers (unmanaged namespace) alone", () => {
|
|
115
|
+
// A wrapper whose namespace ('vendor') is not a managed namespace and
|
|
116
|
+
// whose target points into core/skills/<other> — must not be pruned.
|
|
117
|
+
const wrapper = path.join(root, ".claude/skills/vendor:tool");
|
|
118
|
+
fs.mkdirSync(wrapper, { recursive: true });
|
|
119
|
+
writeSkill("core/skills/helper");
|
|
120
|
+
fs.symlinkSync("../../../core/skills/helper/SKILL.md", path.join(wrapper, "SKILL.md"));
|
|
121
|
+
|
|
122
|
+
reindex({ repoRoot: root });
|
|
123
|
+
|
|
124
|
+
expect(fs.existsSync(wrapper)).toBe(true);
|
|
125
|
+
expect(fs.lstatSync(path.join(wrapper, "SKILL.md")).isSymbolicLink()).toBe(true);
|
|
126
|
+
});
|
|
94
127
|
});
|