@indigoai-us/hq-cloud 6.11.10 → 6.11.11
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.test.js +65 -0
- package/dist/bin/sync-runner.test.js.map +1 -1
- package/dist/cli/reindex.d.ts.map +1 -1
- package/dist/cli/reindex.js +16 -1
- package/dist/cli/reindex.js.map +1 -1
- package/dist/cli/reindex.test.js +39 -1
- package/dist/cli/reindex.test.js.map +1 -1
- package/dist/cli/rescue-core.js +91 -0
- package/dist/cli/rescue-core.js.map +1 -1
- package/dist/cli/rescue-exec-bit-preserve.test.d.ts +2 -0
- package/dist/cli/rescue-exec-bit-preserve.test.d.ts.map +1 -0
- package/dist/cli/rescue-exec-bit-preserve.test.js +169 -0
- package/dist/cli/rescue-exec-bit-preserve.test.js.map +1 -0
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +10 -1
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/sync.test.js +125 -0
- package/dist/cli/sync.test.js.map +1 -1
- package/dist/personal-vault.d.ts +8 -0
- package/dist/personal-vault.d.ts.map +1 -1
- package/dist/personal-vault.js +9 -1
- package/dist/personal-vault.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/sync-runner.test.ts +98 -0
- package/src/cli/reindex.test.ts +47 -1
- package/src/cli/reindex.ts +17 -1
- package/src/cli/rescue-core.ts +87 -0
- package/src/cli/rescue-exec-bit-preserve.test.ts +187 -0
- package/src/cli/sync.test.ts +159 -0
- package/src/cli/sync.ts +12 -1
- package/src/personal-vault.ts +10 -1
|
@@ -1794,6 +1794,71 @@ describe("personal slot fanout", () => {
|
|
|
1794
1794
|
fs.rmSync(tmpHqRoot, { recursive: true, force: true });
|
|
1795
1795
|
}
|
|
1796
1796
|
});
|
|
1797
|
+
it("E2: personal slot pierces the workspace/ exclusion for the session-continuity pointer + active thread file, while the rest of workspace/ stays local (DEV-1778)", async () => {
|
|
1798
|
+
// Regression guard for the cross-machine session-handoff carve-out. Test
|
|
1799
|
+
// "E" proves `workspace/` is excluded wholesale; this proves the ONE
|
|
1800
|
+
// exception travels through the REAL runner push composition (not just the
|
|
1801
|
+
// pure computeContinuityPointerPaths helper): `/handoff` writes
|
|
1802
|
+
// workspace/threads/handoff.json + the thread file it points to, and both
|
|
1803
|
+
// must reach share() so a session handed off on machine A resumes on
|
|
1804
|
+
// machine B. Everything else under workspace/ (locks, other threads, the
|
|
1805
|
+
// INDEX) must remain machine-local.
|
|
1806
|
+
const shareSpy = vi.fn().mockResolvedValue(defaultShareResult());
|
|
1807
|
+
const tmpHqRoot = fs.mkdtempSync(path.join(os.tmpdir(), "hq-runner-test-"));
|
|
1808
|
+
try {
|
|
1809
|
+
// A normal included top-level dir, so the personal push is non-empty
|
|
1810
|
+
// regardless of the carve-out.
|
|
1811
|
+
fs.mkdirSync(path.join(tmpHqRoot, "knowledge"));
|
|
1812
|
+
// The session-continuity carve-out: handoff.json + the active thread it
|
|
1813
|
+
// references via `thread_path` (hq-root-relative, as handoff-finalize.sh
|
|
1814
|
+
// writes it).
|
|
1815
|
+
const threadsDir = path.join(tmpHqRoot, "workspace", "threads");
|
|
1816
|
+
fs.mkdirSync(threadsDir, { recursive: true });
|
|
1817
|
+
const activeThreadRel = "workspace/threads/T-20260619-1200-resume-me.json";
|
|
1818
|
+
fs.writeFileSync(path.join(tmpHqRoot, activeThreadRel), JSON.stringify({ conversation_summary: "pick up here" }));
|
|
1819
|
+
fs.writeFileSync(path.join(threadsDir, "handoff.json"), JSON.stringify({ thread_path: activeThreadRel }));
|
|
1820
|
+
// The rest of workspace/ that must NOT travel: a lock, an inactive
|
|
1821
|
+
// thread, and the regenerated index.
|
|
1822
|
+
fs.mkdirSync(path.join(tmpHqRoot, "workspace", "locks"), {
|
|
1823
|
+
recursive: true,
|
|
1824
|
+
});
|
|
1825
|
+
fs.writeFileSync(path.join(tmpHqRoot, "workspace", "locks", "sync.lock"), "1");
|
|
1826
|
+
fs.writeFileSync(path.join(threadsDir, "T-20260101-0000-stale.json"), "{}");
|
|
1827
|
+
fs.writeFileSync(path.join(threadsDir, "INDEX.md"), "# threads");
|
|
1828
|
+
const deps = makeDeps({
|
|
1829
|
+
createVaultClient: () => makeVaultStub({
|
|
1830
|
+
memberships: [{ companyUid: "cmp_a" }],
|
|
1831
|
+
entityGet: (uid) => Promise.resolve({ uid, slug: "acme" }),
|
|
1832
|
+
listPersons: () => Promise.resolve([olderPerson]),
|
|
1833
|
+
}),
|
|
1834
|
+
share: shareSpy,
|
|
1835
|
+
});
|
|
1836
|
+
const code = await runRunner(["--companies", "--direction", "push", "--hq-root", tmpHqRoot], deps);
|
|
1837
|
+
expect(code).toBe(0);
|
|
1838
|
+
const personalCall = shareSpy.mock.calls.find((c) => c[0].company?.startsWith("prs_"));
|
|
1839
|
+
expect(personalCall).toBeDefined();
|
|
1840
|
+
const personalArgs = personalCall[0];
|
|
1841
|
+
// Compare as hq-root-relative, forward-slash paths (the namespace the
|
|
1842
|
+
// continuity carve-out is specified in).
|
|
1843
|
+
const relPaths = personalArgs.paths.map((p) => path.relative(tmpHqRoot, p).split(path.sep).join("/"));
|
|
1844
|
+
// The two continuity files MUST be in the push set.
|
|
1845
|
+
expect(relPaths).toContain("workspace/threads/handoff.json");
|
|
1846
|
+
expect(relPaths).toContain(activeThreadRel);
|
|
1847
|
+
// The rest of workspace/ must NOT leak in — neither as the parent dir
|
|
1848
|
+
// nor as the individual machine-local files.
|
|
1849
|
+
expect(relPaths).not.toContain("workspace");
|
|
1850
|
+
expect(relPaths).not.toContain("workspace/locks");
|
|
1851
|
+
expect(relPaths.some((p) => p === "workspace/locks" || p.startsWith("workspace/locks/"))).toBe(false);
|
|
1852
|
+
expect(relPaths).not.toContain("workspace/threads/T-20260101-0000-stale.json");
|
|
1853
|
+
expect(relPaths).not.toContain("workspace/threads/INDEX.md");
|
|
1854
|
+
// The bare threads dir is never handed in wholesale — only the two
|
|
1855
|
+
// explicit files (otherwise share()'s walk would sweep stale threads).
|
|
1856
|
+
expect(relPaths).not.toContain("workspace/threads");
|
|
1857
|
+
}
|
|
1858
|
+
finally {
|
|
1859
|
+
fs.rmSync(tmpHqRoot, { recursive: true, force: true });
|
|
1860
|
+
}
|
|
1861
|
+
});
|
|
1797
1862
|
it("G: personal slot includes companies/{slug}/ subdirs when cloud:false marker is set AND HQ_SYNC_LOCAL_COMPANIES_TO_PERSONAL=1, excluding _template + team-synced slugs + missing/cloud:true markers", async () => {
|
|
1798
1863
|
// Gate the new behavior: without this env var the runner falls back to
|
|
1799
1864
|
// the legacy "companies/ never enumerated" personal vault. Test H below
|