@indigoai-us/hq-cloud 6.13.3 → 6.13.4

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.
Files changed (37) hide show
  1. package/dist/bin/sync-runner-company.d.ts.map +1 -1
  2. package/dist/bin/sync-runner-company.js +15 -0
  3. package/dist/bin/sync-runner-company.js.map +1 -1
  4. package/dist/bin/sync-runner-rollup.d.ts +7 -0
  5. package/dist/bin/sync-runner-rollup.d.ts.map +1 -1
  6. package/dist/bin/sync-runner-rollup.js +15 -0
  7. package/dist/bin/sync-runner-rollup.js.map +1 -1
  8. package/dist/bin/sync-runner.d.ts +7 -0
  9. package/dist/bin/sync-runner.d.ts.map +1 -1
  10. package/dist/bin/sync-runner.js +27 -3
  11. package/dist/bin/sync-runner.js.map +1 -1
  12. package/dist/bin/sync-runner.test.js +73 -0
  13. package/dist/bin/sync-runner.test.js.map +1 -1
  14. package/dist/cli/share.js +15 -2
  15. package/dist/cli/share.js.map +1 -1
  16. package/dist/cli/share.test.js +39 -0
  17. package/dist/cli/share.test.js.map +1 -1
  18. package/dist/cli/sync.d.ts +22 -0
  19. package/dist/cli/sync.d.ts.map +1 -1
  20. package/dist/cli/sync.js +14 -0
  21. package/dist/cli/sync.js.map +1 -1
  22. package/dist/qmd-reindex.d.ts +14 -0
  23. package/dist/qmd-reindex.d.ts.map +1 -1
  24. package/dist/qmd-reindex.js +93 -19
  25. package/dist/qmd-reindex.js.map +1 -1
  26. package/dist/qmd-reindex.test.js +47 -0
  27. package/dist/qmd-reindex.test.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/bin/sync-runner-company.ts +21 -0
  30. package/src/bin/sync-runner-rollup.ts +23 -0
  31. package/src/bin/sync-runner.test.ts +90 -0
  32. package/src/bin/sync-runner.ts +37 -5
  33. package/src/cli/share.test.ts +46 -0
  34. package/src/cli/share.ts +14 -2
  35. package/src/cli/sync.ts +40 -0
  36. package/src/qmd-reindex.test.ts +50 -0
  37. package/src/qmd-reindex.ts +124 -18
@@ -1 +1 @@
1
- {"version":3,"file":"qmd-reindex.test.js","sourceRoot":"","sources":["../src/qmd-reindex.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qmd-reindex.test.js","sourceRoot":"","sources":["../src/qmd-reindex.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cloud",
3
- "version": "6.13.3",
3
+ "version": "6.13.4",
4
4
  "description": "HQ by Indigo cloud sync engine — bidirectional S3 sync for mobile access",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -168,6 +168,7 @@ export async function executeCompanyFanout(options: {
168
168
  filesOutOfScope: 0,
169
169
  scopeOrphansRemoved: 0,
170
170
  scopeOrphansBlocked: 0,
171
+ changedPaths: [],
171
172
  };
172
173
 
173
174
  // Local (non-cloud) companies always sync to the personal vault. The
@@ -255,6 +256,7 @@ export async function executeCompanyFanout(options: {
255
256
  ...(options.operationLockAlreadyHeld
256
257
  ? { operationLockAlreadyHeld: true }
257
258
  : {}),
259
+ skipReindex: true,
258
260
  onEvent: tagAndEmit,
259
261
  });
260
262
  }
@@ -273,6 +275,12 @@ export async function executeCompanyFanout(options: {
273
275
 
274
276
  state.filesDownloaded = pullResult.filesDownloaded;
275
277
  state.bytesDownloaded = pullResult.bytesDownloaded;
278
+ state.filesTombstoned = pullResult.filesTombstoned;
279
+ state.scopeOrphansRemoved = pullResult.scopeOrphansRemoved;
280
+ state.changedPaths = normalizePullChangedPaths(
281
+ target,
282
+ pullResult.changedPaths,
283
+ );
276
284
  state.filesUploaded = pushResult.filesUploaded;
277
285
  state.bytesUploaded = pushResult.bytesUploaded;
278
286
  state.status = companyHadTransferError
@@ -342,6 +350,7 @@ export async function executeCompanyFanout(options: {
342
350
  filesOutOfScope: 0,
343
351
  scopeOrphansRemoved: 0,
344
352
  scopeOrphansBlocked: 0,
353
+ changedPaths: [],
345
354
  });
346
355
  options.emit({
347
356
  type: "error",
@@ -354,3 +363,15 @@ export async function executeCompanyFanout(options: {
354
363
 
355
364
  return { stateByCompany, errors, allConflicts };
356
365
  }
366
+
367
+ function normalizePullChangedPaths(
368
+ target: RunnerTarget,
369
+ changedPaths: string[] | undefined,
370
+ ): string[] {
371
+ const paths = changedPaths ?? [];
372
+ return paths.map((p) => {
373
+ const normalized = p.split(path.sep).join("/");
374
+ if (target.personalMode === true) return normalized;
375
+ return `companies/${target.slug}/${normalized}`;
376
+ });
377
+ }
@@ -8,6 +8,9 @@ export interface CompanyState {
8
8
  status: CompanyStatus;
9
9
  filesDownloaded: number;
10
10
  bytesDownloaded: number;
11
+ filesTombstoned: number;
12
+ scopeOrphansRemoved: number;
13
+ changedPaths: string[];
11
14
  filesUploaded: number;
12
15
  bytesUploaded: number;
13
16
  }
@@ -15,8 +18,12 @@ export interface CompanyState {
15
18
  export interface AllCompleteRollup {
16
19
  totalDownloaded: number;
17
20
  totalDownloadedBytes: number;
21
+ totalTombstoned: number;
22
+ totalScopeOrphansRemoved: number;
18
23
  totalUploaded: number;
19
24
  totalUploadedBytes: number;
25
+ changedPaths: string[];
26
+ needsReindex: boolean;
20
27
  partial: boolean;
21
28
  companies: Extract<RunnerEvent, { type: "all-complete" }>["companies"];
22
29
  }
@@ -27,6 +34,9 @@ export function createCompanyState(company: string): CompanyState {
27
34
  status: "errored",
28
35
  filesDownloaded: 0,
29
36
  bytesDownloaded: 0,
37
+ filesTombstoned: 0,
38
+ scopeOrphansRemoved: 0,
39
+ changedPaths: [],
30
40
  filesUploaded: 0,
31
41
  bytesUploaded: 0,
32
42
  };
@@ -38,8 +48,11 @@ export function rollupAllComplete(
38
48
  ): AllCompleteRollup {
39
49
  let totalDownloaded = 0;
40
50
  let totalDownloadedBytes = 0;
51
+ let totalTombstoned = 0;
52
+ let totalScopeOrphansRemoved = 0;
41
53
  let totalUploaded = 0;
42
54
  let totalUploadedBytes = 0;
55
+ const changedPaths: string[] = [];
43
56
  let partial = false;
44
57
  const companies: AllCompleteRollup["companies"] = [];
45
58
 
@@ -48,8 +61,11 @@ export function rollupAllComplete(
48
61
  if (!s) continue;
49
62
  totalDownloaded += s.filesDownloaded;
50
63
  totalDownloadedBytes += s.bytesDownloaded;
64
+ totalTombstoned += s.filesTombstoned;
65
+ totalScopeOrphansRemoved += s.scopeOrphansRemoved;
51
66
  totalUploaded += s.filesUploaded;
52
67
  totalUploadedBytes += s.bytesUploaded;
68
+ changedPaths.push(...s.changedPaths);
53
69
  if (s.status !== "complete") partial = true;
54
70
  companies.push({
55
71
  company: s.company,
@@ -64,8 +80,15 @@ export function rollupAllComplete(
64
80
  return {
65
81
  totalDownloaded,
66
82
  totalDownloadedBytes,
83
+ totalTombstoned,
84
+ totalScopeOrphansRemoved,
67
85
  totalUploaded,
68
86
  totalUploadedBytes,
87
+ changedPaths,
88
+ needsReindex:
89
+ totalDownloaded > 0 ||
90
+ totalTombstoned > 0 ||
91
+ totalScopeOrphansRemoved > 0,
69
92
  partial,
70
93
  companies,
71
94
  };
@@ -112,6 +112,7 @@ function defaultSyncResult(overrides: Partial<SyncResult> = {}): SyncResult {
112
112
  filesOutOfScope: 0,
113
113
  scopeOrphansRemoved: 0,
114
114
  scopeOrphansBlocked: 0,
115
+ changedPaths: [],
115
116
  ...overrides,
116
117
  };
117
118
  }
@@ -205,6 +206,14 @@ function makeDeps(overrides: Partial<RunnerDeps> = {}): TestDeps {
205
206
  getAccessToken: vi.fn().mockResolvedValue("test-access-token"),
206
207
  createVaultClient: vi.fn().mockImplementation(() => makeVaultStub()),
207
208
  sync: vi.fn().mockResolvedValue(defaultSyncResult()),
209
+ reindex: vi.fn(() => ({ status: 0 })),
210
+ qmdReindex: vi.fn(() => ({
211
+ qmdAvailable: true,
212
+ collectionsAdded: [],
213
+ updated: true,
214
+ embedded: false,
215
+ pendingDirty: false,
216
+ })),
208
217
  ...overrides,
209
218
  stdout,
210
219
  stderr,
@@ -1602,6 +1611,87 @@ describe("all-complete aggregate", () => {
1602
1611
  });
1603
1612
  });
1604
1613
 
1614
+ it("skips per-target native reindex and runs one final reindex for tombstones or scope orphans", async () => {
1615
+ const slugs: Record<string, string> = { cmp_a: "acme", cmp_b: "beta" };
1616
+ const reindex = vi.fn(() => ({ status: 0 }));
1617
+ const syncSpy = vi
1618
+ .fn<(opts: SyncOptions) => Promise<SyncResult>>()
1619
+ .mockResolvedValueOnce(defaultSyncResult({ filesTombstoned: 1 }))
1620
+ .mockResolvedValueOnce(defaultSyncResult({ scopeOrphansRemoved: 1 }));
1621
+ const deps = makeDeps({
1622
+ operationLockAlreadyHeld: true,
1623
+ createVaultClient: () =>
1624
+ makeVaultStub({
1625
+ memberships: [{ companyUid: "cmp_a" }, { companyUid: "cmp_b" }],
1626
+ entityGet: (uid: string) =>
1627
+ Promise.resolve({ uid, slug: slugs[uid] ?? uid } as unknown as EntityInfo),
1628
+ }),
1629
+ sync: syncSpy,
1630
+ reindex,
1631
+ } as Partial<RunnerDeps>);
1632
+
1633
+ const code = await runRunner(["--companies", "--hq-root", "/tmp/fake-hq"], deps);
1634
+
1635
+ expect(code).toBe(0);
1636
+ expect(syncSpy).toHaveBeenCalledTimes(2);
1637
+ expect(syncSpy.mock.calls.map(([opts]) => opts.skipReindex)).toEqual([
1638
+ true,
1639
+ true,
1640
+ ]);
1641
+ expect(reindex).toHaveBeenCalledTimes(1);
1642
+ expect(reindex).toHaveBeenCalledWith({
1643
+ repoRoot: "/tmp/fake-hq",
1644
+ skipLock: true,
1645
+ });
1646
+ });
1647
+
1648
+ it("gates qmd to knowledge markdown changes and propagates hq-relative changed paths", async () => {
1649
+ const slugs: Record<string, string> = { cmp_a: "acme", cmp_b: "beta" };
1650
+ const qmdReindex = vi.fn(() => ({
1651
+ qmdAvailable: true,
1652
+ collectionsAdded: [],
1653
+ updated: true,
1654
+ embedded: false,
1655
+ pendingDirty: false,
1656
+ }));
1657
+ const deps = makeDeps({
1658
+ createVaultClient: () =>
1659
+ makeVaultStub({
1660
+ memberships: [{ companyUid: "cmp_a" }, { companyUid: "cmp_b" }],
1661
+ entityGet: (uid: string) =>
1662
+ Promise.resolve({ uid, slug: slugs[uid] ?? uid } as unknown as EntityInfo),
1663
+ }),
1664
+ sync: vi
1665
+ .fn<(opts: SyncOptions) => Promise<SyncResult>>()
1666
+ .mockResolvedValueOnce(
1667
+ defaultSyncResult({
1668
+ filesDownloaded: 1,
1669
+ changedPaths: ["docs/readme.txt"],
1670
+ } as Partial<SyncResult>),
1671
+ )
1672
+ .mockResolvedValueOnce(
1673
+ defaultSyncResult({
1674
+ filesTombstoned: 1,
1675
+ changedPaths: ["knowledge/old.md"],
1676
+ } as Partial<SyncResult>),
1677
+ ),
1678
+ reindex: vi.fn(() => ({ status: 0 })),
1679
+ qmdReindex,
1680
+ } as Partial<RunnerDeps>);
1681
+
1682
+ const code = await runRunner(["--companies", "--hq-root", "/tmp/fake-hq"], deps);
1683
+
1684
+ expect(code).toBe(0);
1685
+ expect(qmdReindex).toHaveBeenCalledTimes(1);
1686
+ expect(qmdReindex).toHaveBeenCalledWith(
1687
+ "/tmp/fake-hq",
1688
+ expect.objectContaining({
1689
+ changedPaths: ["companies/beta/knowledge/old.md"],
1690
+ forceCollectionRefresh: true,
1691
+ }),
1692
+ );
1693
+ });
1694
+
1605
1695
  it("collects company-level errors into the all-complete errors array", async () => {
1606
1696
  const slugs: Record<string, string> = { cmp_a: "acme", cmp_b: "beta" };
1607
1697
  const deps = makeDeps({
@@ -104,6 +104,9 @@ import { HQ_CLOUD_VERSION } from "../version.js";
104
104
  import { collectAndSendTelemetry } from "../telemetry.js";
105
105
  import { collectAndSendSkillTelemetry } from "../skill-telemetry.js";
106
106
  import { reindexAfterSync } from "../qmd-reindex.js";
107
+ import type { ReindexOptions as QmdReindexOptions } from "../qmd-reindex.js";
108
+ import { reindex as defaultReindex } from "../cli/reindex.js";
109
+ import type { ReindexOptions, ReindexResult } from "../cli/reindex.js";
107
110
  import { pruneConflictIndex } from "../lib/conflict-index.js";
108
111
  import { materializeCodexAgents } from "../agent-codex-instructions.js";
109
112
  import { getOrCreateMachineId } from "../lib/machine-id.js";
@@ -577,6 +580,13 @@ export interface RunnerDeps {
577
580
  createVaultClient?: (config: VaultServiceConfig) => VaultClientSurface;
578
581
  /** Sync function. Defaults to `cli/sync.sync`. */
579
582
  sync?: (options: SyncOptions) => Promise<SyncResult>;
583
+ /** Native post-fanout reindex function. Defaults to `cli/reindex.reindex`. */
584
+ reindex?: (options: ReindexOptions) => ReindexResult;
585
+ /** QMD post-sync reindex function. Defaults to `qmd-reindex.reindexAfterSync`. */
586
+ qmdReindex?: (
587
+ hqRoot: string,
588
+ options: QmdReindexOptions,
589
+ ) => ReturnType<typeof reindexAfterSync>;
580
590
  /** Internal: set when runRunner is invoked under the per-root operation lock. */
581
591
  operationLockAlreadyHeld?: boolean;
582
592
  /** Share function (push phase). Defaults to `cli/share.share`. */
@@ -622,6 +632,11 @@ function defaultGetIdTokenClaims(): IdTokenClaims | null {
622
632
  return decodeJwtClaims(tokens.idToken);
623
633
  }
624
634
 
635
+ function isKnowledgeMarkdownPath(relPath: string): boolean {
636
+ const normalized = relPath.split(path.sep).join("/");
637
+ return /^companies\/[^/]+\/knowledge\/.+\.md$/i.test(normalized);
638
+ }
639
+
625
640
  /**
626
641
  * Best-effort: claim any email-keyed pending invites that were sent before
627
642
  * this user had a person entity. Mirrors the installer's vault-handoff flow.
@@ -1200,6 +1215,23 @@ export async function runRunner(
1200
1215
  const { errors, allConflicts } = fanout;
1201
1216
  const rollup = rollupAllComplete(plan, fanout.stateByCompany);
1202
1217
 
1218
+ if (rollup.needsReindex) {
1219
+ try {
1220
+ (deps.reindex ?? defaultReindex)({
1221
+ repoRoot: parsed.hqRoot,
1222
+ ...(deps.operationLockAlreadyHeld === true ? { skipLock: true } : {}),
1223
+ });
1224
+ } catch (err) {
1225
+ reportDiagnostic({
1226
+ component: "native-reindex",
1227
+ event: "runner.native_reindex.failed",
1228
+ message: "post-fanout native reindex failed",
1229
+ err,
1230
+ context: { hqRoot: parsed.hqRoot },
1231
+ });
1232
+ }
1233
+ }
1234
+
1203
1235
  // Fire telemetry collector before the all-complete emit so the cursor at
1204
1236
  // `~/.hq/telemetry-cursor.json` is consistent with what the menubar sees.
1205
1237
  await awaitTelemetryWithTimeout(
@@ -1250,12 +1282,12 @@ export async function runRunner(
1250
1282
  // pulled in (nothing to reindex otherwise) and not explicitly disabled.
1251
1283
  // Self-contained: shells out to the global `qmd` binary, no dependency on
1252
1284
  // any (possibly stale) script inside the synced HQ tree. See qmd-reindex.ts.
1253
- if (
1254
- rollup.totalDownloaded > 0 &&
1255
- process.env.HQ_QMD_REINDEX_ON_SYNC !== "0"
1256
- ) {
1285
+ const qmdChangedPaths = rollup.changedPaths.filter(isKnowledgeMarkdownPath);
1286
+ if (qmdChangedPaths.length > 0 && process.env.HQ_QMD_REINDEX_ON_SYNC !== "0") {
1257
1287
  try {
1258
- reindexAfterSync(parsed.hqRoot, {
1288
+ (deps.qmdReindex ?? reindexAfterSync)(parsed.hqRoot, {
1289
+ changedPaths: qmdChangedPaths,
1290
+ forceCollectionRefresh: true,
1259
1291
  log: ({ event, message, err, context }) =>
1260
1292
  reportDiagnostic({
1261
1293
  component: "qmd-reindex",
@@ -1264,6 +1264,52 @@ describe("share", () => {
1264
1264
  expect(events.some((e) => e.type === "error")).toBe(false);
1265
1265
  });
1266
1266
 
1267
+ it("a file over the size limit is a benign skip-size-limit event, NEVER an error (HQ-SYNC-4 exit-2 flood)", async () => {
1268
+ // Regression for the fleet-wide "auto-sync watcher exited unexpectedly
1269
+ // (code=Some(2))" flood (HQ-SYNC-4, ~93k events across 60+ machines). An
1270
+ // oversized file is a permanent, benign skip — it exceeds the 50 MB cap on
1271
+ // EVERY pass, forever. Emitting it as `type: "error"` pushed it into the
1272
+ // runner's `errors[]`, so the pass returned exit 2, which the menubar
1273
+ // supervisor reported as an unexpected watcher crash on every single tick.
1274
+ // A too-big file must surface for visibility but must NOT count as an error.
1275
+ const companyRoot = path.join(tmpDir, "companies", "acme");
1276
+ fs.mkdirSync(companyRoot, { recursive: true });
1277
+ const bigFile = path.join(companyRoot, "huge.mp4");
1278
+ // Sparse 51 MB file: statSync (isWithinSizeLimit) reports 51 MB while the
1279
+ // file occupies ~0 bytes on disk, so the test stays fast.
1280
+ const fd = fs.openSync(bigFile, "w");
1281
+ fs.ftruncateSync(fd, 51 * 1024 * 1024);
1282
+ fs.closeSync(fd);
1283
+
1284
+ const events: Array<{ type?: string; path?: string; bytes?: number }> = [];
1285
+ const result = await share({
1286
+ paths: [bigFile],
1287
+ company: "acme",
1288
+ vaultConfig: mockConfig,
1289
+ hqRoot: tmpDir,
1290
+ onEvent: (e) => events.push(e as { type?: string }),
1291
+ });
1292
+
1293
+ // Not uploaded, counted as a skip, company did not abort.
1294
+ expect(result.aborted).toBe(false);
1295
+ expect(result.filesUploaded).toBe(0);
1296
+ expect(result.filesSkipped).toBe(1);
1297
+ expect(uploadFile).not.toHaveBeenCalled();
1298
+
1299
+ // The oversized file surfaces as a benign skip-size-limit event for
1300
+ // visibility (path + byte size)…
1301
+ const skipEv = events.find((e) => e.type === "skip-size-limit") as
1302
+ | { path: string; bytes: number }
1303
+ | undefined;
1304
+ expect(skipEv).toBeDefined();
1305
+ expect(skipEv!.path).toBe("huge.mp4");
1306
+ expect(skipEv!.bytes).toBe(51 * 1024 * 1024);
1307
+
1308
+ // …and CRUCIALLY never as an error — an error event is what flipped the
1309
+ // pass to exit 2 and drove the watcher-crash flood.
1310
+ expect(events.some((e) => e.type === "error")).toBe(false);
1311
+ });
1312
+
1267
1313
  it("uploads (no conflict) when only the local side changed since last sync", async () => {
1268
1314
  // Regression for hq-cloud#<conflict-detection>: a local edit to a file
1269
1315
  // that exists on S3 used to trigger a push conflict because the
package/src/cli/share.ts CHANGED
@@ -1135,10 +1135,22 @@ async function executeUploads(
1135
1135
  const uploadItems: UploadPlanItem[] = [];
1136
1136
  for (const item of pushPlan.items) {
1137
1137
  if (item.action === "skip-size-limit") {
1138
+ // A file over the size cap is a permanent, benign skip — NOT an error.
1139
+ // Emitting it as `type: "error"` pushed it into the runner's `errors[]`,
1140
+ // so every watch pass returned exit 2 and the menubar reported an
1141
+ // "auto-sync watcher exited unexpectedly (code=Some(2))" crash on every
1142
+ // tick (the fleet-wide HQ-SYNC-4 flood). Surface it for visibility, but
1143
+ // do not let it flip the pass to a non-zero exit.
1144
+ let bytes = 0;
1145
+ try {
1146
+ bytes = fs.statSync(item.absolutePath).size;
1147
+ } catch {
1148
+ // Best-effort size for display only; a stat race must not break the sync.
1149
+ }
1138
1150
  run.emit({
1139
- type: "error",
1151
+ type: "skip-size-limit",
1140
1152
  path: item.relativePath,
1141
- message: "file exceeds size limit",
1153
+ bytes,
1142
1154
  });
1143
1155
  counters.filesSkipped++;
1144
1156
  continue;
package/src/cli/sync.ts CHANGED
@@ -322,6 +322,24 @@ export type SyncProgressEvent =
322
322
  type: "upload-suppressed-tombstone";
323
323
  path: string;
324
324
  deletedAt: string;
325
+ }
326
+ | {
327
+ /**
328
+ * Emitted by the PUSH leg (`share()`) once per local file skipped because
329
+ * it exceeds the max sync size (`isWithinSizeLimit`, 50 MB default). This
330
+ * is a permanent, benign, user-policy outcome — the file is too big to
331
+ * sync and will be over the cap on every pass — so it is NOT an error and
332
+ * the run exits 0. It was previously emitted as `type: "error"`, which
333
+ * pushed it into the runner's `errors[]` and made every watch pass return
334
+ * exit 2; the menubar supervisor then reported that as
335
+ * "auto-sync watcher exited unexpectedly (code=Some(2))" on every tick —
336
+ * the fleet-wide HQ-SYNC-4 flood. Surfaced here purely for visibility
337
+ * (`bytes` is the offending file's size) so a UI/CLI can tell the user
338
+ * which file was too big without treating it as a failure.
339
+ */
340
+ type: "skip-size-limit";
341
+ path: string;
342
+ bytes: number;
325
343
  };
326
344
 
327
345
  export interface SyncOptions {
@@ -503,6 +521,11 @@ export interface SyncResult {
503
521
  * true they are left on disk and tombstoned, and counted here.
504
522
  */
505
523
  scopeOrphansBlocked: number;
524
+ /**
525
+ * Remote keys whose local on-disk counterpart changed during this pull.
526
+ * Includes downloads, tombstone deletes, and clean scope-orphan removals.
527
+ */
528
+ changedPaths?: string[];
506
529
  }
507
530
 
508
531
  type SyncEventEmitter = (event: SyncProgressEvent) => void;
@@ -535,6 +558,7 @@ interface PullCounters {
535
558
  filesTombstoned: number;
536
559
  filesOutOfScope: number;
537
560
  conflictPaths: string[];
561
+ changedPaths: string[];
538
562
  }
539
563
 
540
564
  interface ScopeShrinkPlanState {
@@ -549,6 +573,7 @@ interface ScopeShrinkRun {
549
573
  shrinkPlan: ReturnType<typeof buildScopeShrinkPlan>;
550
574
  shrinkResult: ReturnType<typeof applyScopeShrink>;
551
575
  scopeOrphansRemoved: number;
576
+ changedPaths: string[];
552
577
  }
553
578
 
554
579
  /**
@@ -831,6 +856,7 @@ function createPullCounters(): PullCounters {
831
856
  filesTombstoned: 0,
832
857
  filesOutOfScope: 0,
833
858
  conflictPaths: [],
859
+ changedPaths: [],
834
860
  };
835
861
  }
836
862
 
@@ -943,6 +969,10 @@ function executeScopeShrink(
943
969
  shrinkResult,
944
970
  scopeOrphansRemoved:
945
971
  shrinkResult.cleanRemoved + shrinkResult.cleanQuarantined,
972
+ changedPaths: [
973
+ ...shrinkResult.quarantinedPaths,
974
+ ...shrinkResult.removedPaths,
975
+ ],
946
976
  };
947
977
  }
948
978
 
@@ -1039,6 +1069,7 @@ function executeFileTombstoneDelete(
1039
1069
  }
1040
1070
  removeEntry(run.journal, tombstoneKey);
1041
1071
  counters.filesTombstoned++;
1072
+ counters.changedPaths.push(tombstoneKey);
1042
1073
  run.emit({ type: "progress", path: tombstoneKey, bytes: 0 });
1043
1074
  }
1044
1075
 
@@ -1198,6 +1229,7 @@ async function executeConflictItem(
1198
1229
  filesOutOfScope: counters.filesOutOfScope,
1199
1230
  scopeOrphansRemoved: scopeRun.scopeOrphansRemoved,
1200
1231
  scopeOrphansBlocked: scopeRun.shrinkResult.dirtyTombstoned,
1232
+ changedPaths: [...counters.changedPaths, ...scopeRun.changedPaths],
1201
1233
  };
1202
1234
  }
1203
1235
 
@@ -1335,6 +1367,7 @@ async function downloadOne(
1335
1367
 
1336
1368
  counters.filesDownloaded++;
1337
1369
  counters.bytesDownloaded += size;
1370
+ counters.changedPaths.push(remoteFile.key);
1338
1371
  } catch (err) {
1339
1372
  if (isAccessDenied(err)) {
1340
1373
  counters.filesSkipped++;
@@ -1474,6 +1507,7 @@ function executeJournalTombstoneDeletes(
1474
1507
  }
1475
1508
  removeEntry(run.journal, key);
1476
1509
  counters.filesTombstoned++;
1510
+ counters.changedPaths.push(key);
1477
1511
  run.emit({
1478
1512
  type: "progress",
1479
1513
  path: key,
@@ -1532,6 +1566,7 @@ function finalizePullRun(
1532
1566
  filesOutOfScope: counters.filesOutOfScope,
1533
1567
  scopeOrphansRemoved: scopeRun.scopeOrphansRemoved,
1534
1568
  scopeOrphansBlocked: scopeRun.shrinkResult.dirtyTombstoned,
1569
+ changedPaths: [...counters.changedPaths, ...scopeRun.changedPaths],
1535
1570
  };
1536
1571
  }
1537
1572
 
@@ -2462,5 +2497,10 @@ function defaultConsoleLogger(event: SyncProgressEvent): void {
2462
2497
  if (event.count > event.samplePaths.length) {
2463
2498
  console.warn(` ... and ${event.count - event.samplePaths.length} more`);
2464
2499
  }
2500
+ } else if (event.type === "skip-size-limit") {
2501
+ const mb = (event.bytes / (1024 * 1024)).toFixed(1);
2502
+ console.warn(
2503
+ ` ! ${event.path} skipped — ${mb} MB exceeds the 50 MB sync size limit`,
2504
+ );
2465
2505
  }
2466
2506
  }
@@ -100,6 +100,56 @@ describe("reindexAfterSync", () => {
100
100
  expect(calls).toEqual([["collection", "list"], ["update"]]);
101
101
  });
102
102
 
103
+ it("skips qmd entirely when provided changed paths do not touch knowledge markdown", () => {
104
+ const { exec, calls } = fakeExec({ listStdout: "" });
105
+ const r = reindexAfterSync("/hq", {
106
+ exec,
107
+ existsSync: () => true,
108
+ changedPaths: ["companies/acme/docs/readme.txt"],
109
+ });
110
+ expect(r.qmdAvailable).toBe(false);
111
+ expect(r.updated).toBe(false);
112
+ expect(calls).toEqual([]);
113
+ });
114
+
115
+ it("debounces dirty updates with a pending marker and flushes the final update later", () => {
116
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "hq-qmd-debounce-"));
117
+ try {
118
+ const statePath = path.join(dir, "qmd-state.json");
119
+ const { exec, calls } = fakeExec({ listStdout: "acme (qmd://acme/)\n" });
120
+
121
+ const first = reindexAfterSync("/hq", {
122
+ exec,
123
+ existsSync: () => true,
124
+ changedPaths: ["companies/acme/knowledge/note.md"],
125
+ debounceMs: 60_000,
126
+ nowMs: 100_000,
127
+ statePath,
128
+ });
129
+ expect(first.updated).toBe(false);
130
+ expect(first.pendingDirty).toBe(true);
131
+ expect(calls).toEqual([["collection", "list"]]);
132
+
133
+ const second = reindexAfterSync("/hq", {
134
+ exec,
135
+ existsSync: () => true,
136
+ changedPaths: [],
137
+ debounceMs: 60_000,
138
+ nowMs: 161_000,
139
+ statePath,
140
+ });
141
+ expect(second.updated).toBe(true);
142
+ expect(second.pendingDirty).toBe(false);
143
+ expect(calls).toEqual([
144
+ ["collection", "list"],
145
+ ["collection", "list"],
146
+ ["update"],
147
+ ]);
148
+ } finally {
149
+ fs.rmSync(dir, { recursive: true, force: true });
150
+ }
151
+ });
152
+
103
153
  it("runs embed only when embed:true", () => {
104
154
  const { exec, calls } = fakeExec({ listStdout: "" });
105
155
  const r = reindexAfterSync("/hq", {