@indigoai-us/hq-cloud 6.1.0 → 6.2.1
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 +1589 -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-journal-reconcile.test.d.ts +2 -0
- package/dist/cli/rescue-journal-reconcile.test.d.ts.map +1 -0
- package/dist/cli/rescue-journal-reconcile.test.js +135 -0
- package/dist/cli/rescue-journal-reconcile.test.js.map +1 -0
- 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 +1719 -0
- package/src/cli/rescue-drift-reconcile.test.ts +33 -12
- package/src/cli/rescue-journal-reconcile.test.ts +156 -0
- 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/cli/rescue.js
CHANGED
|
@@ -2,32 +2,18 @@
|
|
|
2
2
|
* hq rescue — re-sync a local HQ tree to an upstream hq-core release (or a
|
|
3
3
|
* staging branch) WITHOUT destroying the user's local edits ("drift").
|
|
4
4
|
*
|
|
5
|
-
* The implementation
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* command — drive the exact same rescue logic.
|
|
5
|
+
* The implementation is native TypeScript in ./rescue-core.ts (the former
|
|
6
|
+
* scripts/replace-rescue.sh, ported and removed). This module owns the public
|
|
7
|
+
* option surface + flag mapping and the post-rescue reindex wiring; the heavy
|
|
8
|
+
* classify/overlay/stamp algorithm lives in rescue-core. BOTH consumers — the
|
|
9
|
+
* HQ Sync menubar app (which spawns `hq-rescue` from this package) and
|
|
10
|
+
* `@indigoai-us/hq-cli`'s `hq rescue` command — drive the exact same logic.
|
|
12
11
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* See scripts/replace-rescue.sh for the full classify/overlay/stamp algorithm.
|
|
12
|
+
* Channel-agnostic: `--source <repo>` + `--ref <tag|branch>` select prod vs
|
|
13
|
+
* staging, and `--floor-sha` pins the three-way history floor.
|
|
16
14
|
*/
|
|
17
|
-
import { spawnSync } from "child_process";
|
|
18
|
-
import { fileURLToPath } from "url";
|
|
19
|
-
import path from "path";
|
|
20
15
|
import { reindex } from "./reindex.js";
|
|
21
|
-
|
|
22
|
-
const __dirname = path.dirname(__filename);
|
|
23
|
-
/**
|
|
24
|
-
* Absolute path to the bundled replace-rescue.sh. From the compiled module at
|
|
25
|
-
* dist/cli/rescue.js, the package root is two levels up; the script lives at
|
|
26
|
-
* <package-root>/scripts/replace-rescue.sh.
|
|
27
|
-
*/
|
|
28
|
-
export function rescueScriptPath() {
|
|
29
|
-
return path.resolve(__dirname, "..", "..", "scripts", "replace-rescue.sh");
|
|
30
|
-
}
|
|
16
|
+
import { runRescue } from "./rescue-core.js";
|
|
31
17
|
/**
|
|
32
18
|
* Build the argv passed to bash (after the script path itself). Pure +
|
|
33
19
|
* exported so callers and tests can assert the flag mapping without spawning.
|
|
@@ -65,26 +51,17 @@ export function buildRescueArgs(opts = {}) {
|
|
|
65
51
|
return args;
|
|
66
52
|
}
|
|
67
53
|
/**
|
|
68
|
-
* Run the rescue
|
|
69
|
-
*
|
|
70
|
-
* stdout/stderr
|
|
71
|
-
*
|
|
54
|
+
* Run the rescue against an HQ root. Synchronous — the work is long-running
|
|
55
|
+
* (clone + scan + overlay) and callers want the exit status + live output.
|
|
56
|
+
* stdout/stderr are written directly so the user sees the scan log and the
|
|
57
|
+
* confirmation prompt (unless `assumeYes` is set).
|
|
72
58
|
*/
|
|
73
59
|
export function rescue(opts = {}) {
|
|
74
|
-
const script = rescueScriptPath();
|
|
75
60
|
const args = buildRescueArgs(opts);
|
|
76
61
|
const env = { ...process.env };
|
|
77
62
|
if (opts.ghToken)
|
|
78
63
|
env.GH_TOKEN = opts.ghToken;
|
|
79
|
-
const
|
|
80
|
-
stdio: "inherit",
|
|
81
|
-
env,
|
|
82
|
-
});
|
|
83
|
-
if (res.error) {
|
|
84
|
-
process.stderr.write(`rescue: failed to run ${script}: ${res.error.message}\n`);
|
|
85
|
-
return { status: 1 };
|
|
86
|
-
}
|
|
87
|
-
const status = res.status ?? 1;
|
|
64
|
+
const { status } = runRescue(args, { env });
|
|
88
65
|
// A successful, non-dry-run rescue re-lays-down core/, so refresh the
|
|
89
66
|
// generated skill wrappers, personal-overlay mirrors, and workers registry.
|
|
90
67
|
// Best-effort + idempotent — never overrides the rescue's own exit status.
|
package/dist/cli/rescue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/cli/rescue.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/cli/rescue.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,23 +3,24 @@
|
|
|
3
3
|
* rescue so the generated skill wrappers / personal mirrors / workers registry
|
|
4
4
|
* are refreshed once core/ has been re-laid-down.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* ./reindex.js is mocked to a spy so we assert the call without
|
|
6
|
+
* The rescue algorithm (./rescue-core.js) is mocked so no real clone/overlay
|
|
7
|
+
* runs, and ./reindex.js is mocked to a spy so we assert the call without
|
|
8
|
+
* touching disk.
|
|
8
9
|
*/
|
|
9
10
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
10
|
-
vi.mock("
|
|
11
|
-
|
|
11
|
+
vi.mock("./rescue-core.js", () => ({
|
|
12
|
+
runRescue: vi.fn(() => ({ status: 0 })),
|
|
12
13
|
}));
|
|
13
14
|
vi.mock("./reindex.js", () => ({
|
|
14
15
|
reindex: vi.fn(() => ({ status: 0 })),
|
|
15
16
|
}));
|
|
16
|
-
import {
|
|
17
|
+
import { runRescue } from "./rescue-core.js";
|
|
17
18
|
import { reindex } from "./reindex.js";
|
|
18
19
|
import { rescue } from "./rescue.js";
|
|
19
20
|
describe("rescue → reindex", () => {
|
|
20
21
|
beforeEach(() => {
|
|
21
22
|
vi.clearAllMocks();
|
|
22
|
-
|
|
23
|
+
runRescue.mockReturnValue({ status: 0 });
|
|
23
24
|
});
|
|
24
25
|
it("refreshes via reindex after a successful rescue", () => {
|
|
25
26
|
const r = rescue({ hqRoot: "/tmp/hq", assumeYes: true });
|
|
@@ -31,8 +32,8 @@ describe("rescue → reindex", () => {
|
|
|
31
32
|
rescue({ hqRoot: "/tmp/hq", dryRun: true });
|
|
32
33
|
expect(reindex).not.toHaveBeenCalled();
|
|
33
34
|
});
|
|
34
|
-
it("does NOT run reindex when the rescue
|
|
35
|
-
|
|
35
|
+
it("does NOT run reindex when the rescue fails", () => {
|
|
36
|
+
runRescue.mockReturnValueOnce({ status: 1 });
|
|
36
37
|
const r = rescue({ hqRoot: "/tmp/hq", assumeYes: true });
|
|
37
38
|
expect(r.status).toBe(1);
|
|
38
39
|
expect(reindex).not.toHaveBeenCalled();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rescue.reindex.test.js","sourceRoot":"","sources":["../../src/cli/rescue.reindex.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rescue.reindex.test.js","sourceRoot":"","sources":["../../src/cli/rescue.reindex.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;CACxC,CAAC,CAAC,CAAC;AACJ,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7B,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;CACtC,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QAClB,SAAiD,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACnD,SAAiD,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/cli/rescue.test.js
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { buildRescueArgs
|
|
3
|
-
describe("rescueScriptPath", () => {
|
|
4
|
-
it("resolves to the bundled script at the package root", () => {
|
|
5
|
-
const p = rescueScriptPath();
|
|
6
|
-
expect(p.endsWith("scripts/replace-rescue.sh")).toBe(true);
|
|
7
|
-
// From dist/cli/rescue.js the package root is two levels up; ensure we
|
|
8
|
-
// don't accidentally point inside dist/.
|
|
9
|
-
expect(p).not.toContain("/dist/scripts/");
|
|
10
|
-
});
|
|
11
|
-
});
|
|
2
|
+
import { buildRescueArgs } from "./rescue.js";
|
|
12
3
|
describe("buildRescueArgs", () => {
|
|
13
4
|
it("emits no args for an empty option set (script defaults apply)", () => {
|
|
14
5
|
expect(buildRescueArgs()).toEqual([]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rescue.test.js","sourceRoot":"","sources":["../../src/cli/rescue.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"rescue.test.js","sourceRoot":"","sources":["../../src/cli/rescue.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,qBAAqB;YAC7B,GAAG,EAAE,SAAS;YACd,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,WAAW;YACX,aAAa;YACb,UAAU;YACV,qBAAqB;YACrB,OAAO;YACP,SAAS;YACT,aAAa;YACb,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACd,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;YAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;YACxB,gBAAgB,EAAE,CAAC,cAAc,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -39,9 +39,9 @@ export { accept, parseToken } from "./cli/index.js";
|
|
|
39
39
|
export type { AcceptOptions, AcceptResult } from "./cli/index.js";
|
|
40
40
|
export { promote } from "./cli/index.js";
|
|
41
41
|
export type { PromoteOptions, PromoteResult } from "./cli/index.js";
|
|
42
|
-
export { reindex
|
|
42
|
+
export { reindex } from "./cli/index.js";
|
|
43
43
|
export type { ReindexOptions, ReindexResult } from "./cli/index.js";
|
|
44
|
-
export { rescue,
|
|
44
|
+
export { rescue, buildRescueArgs } from "./cli/index.js";
|
|
45
45
|
export type { RescueOptions, RescueResult } from "./cli/index.js";
|
|
46
46
|
export type { EntityContext, VaultCredentials, VaultServiceConfig, ClientInfo, SyncConfig, Credentials, JournalEntry, SyncJournal, PullRecord, SyncStatus, PushResult, PullResult, DaemonState, } from "./types.js";
|
|
47
47
|
export { buildClientHeaders, clientInfoFromPackage, detectHqCoreVersion, HEADER_CLIENT_NAME, HEADER_CLIENT_VERSION, HEADER_HQ_CORE_VERSION, } from "./client-info.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
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
|