@indigoai-us/hq-cloud 6.11.12 → 6.11.13

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 (107) hide show
  1. package/dist/bin/sync-runner-company.d.ts +35 -0
  2. package/dist/bin/sync-runner-company.d.ts.map +1 -0
  3. package/dist/bin/sync-runner-company.js +290 -0
  4. package/dist/bin/sync-runner-company.js.map +1 -0
  5. package/dist/bin/sync-runner-events.d.ts +12 -0
  6. package/dist/bin/sync-runner-events.d.ts.map +1 -0
  7. package/dist/bin/sync-runner-events.js +12 -0
  8. package/dist/bin/sync-runner-events.js.map +1 -0
  9. package/dist/bin/sync-runner-planning.d.ts +53 -0
  10. package/dist/bin/sync-runner-planning.d.ts.map +1 -0
  11. package/dist/bin/sync-runner-planning.js +59 -0
  12. package/dist/bin/sync-runner-planning.js.map +1 -0
  13. package/dist/bin/sync-runner-rollup.d.ts +24 -0
  14. package/dist/bin/sync-runner-rollup.d.ts.map +1 -0
  15. package/dist/bin/sync-runner-rollup.js +46 -0
  16. package/dist/bin/sync-runner-rollup.js.map +1 -0
  17. package/dist/bin/sync-runner-telemetry.d.ts +5 -0
  18. package/dist/bin/sync-runner-telemetry.d.ts.map +1 -0
  19. package/dist/bin/sync-runner-telemetry.js +5 -0
  20. package/dist/bin/sync-runner-telemetry.js.map +1 -0
  21. package/dist/bin/sync-runner-watch-loop.d.ts +17 -0
  22. package/dist/bin/sync-runner-watch-loop.d.ts.map +1 -0
  23. package/dist/bin/sync-runner-watch-loop.js +372 -0
  24. package/dist/bin/sync-runner-watch-loop.js.map +1 -0
  25. package/dist/bin/sync-runner-watch-routes.d.ts +25 -0
  26. package/dist/bin/sync-runner-watch-routes.d.ts.map +1 -0
  27. package/dist/bin/sync-runner-watch-routes.js +74 -0
  28. package/dist/bin/sync-runner-watch-routes.js.map +1 -0
  29. package/dist/bin/sync-runner.d.ts +3 -54
  30. package/dist/bin/sync-runner.d.ts.map +1 -1
  31. package/dist/bin/sync-runner.js +73 -1154
  32. package/dist/bin/sync-runner.js.map +1 -1
  33. package/dist/cli/reindex.d.ts.map +1 -1
  34. package/dist/cli/reindex.js +34 -17
  35. package/dist/cli/reindex.js.map +1 -1
  36. package/dist/cli/reindex.test.js +39 -5
  37. package/dist/cli/reindex.test.js.map +1 -1
  38. package/dist/cli/rescue-classify-ordering.test.js +17 -0
  39. package/dist/cli/rescue-classify-ordering.test.js.map +1 -1
  40. package/dist/cli/rescue-core.d.ts +45 -0
  41. package/dist/cli/rescue-core.d.ts.map +1 -1
  42. package/dist/cli/rescue-core.js +197 -170
  43. package/dist/cli/rescue-core.js.map +1 -1
  44. package/dist/cli/share.d.ts.map +1 -1
  45. package/dist/cli/share.js +224 -676
  46. package/dist/cli/share.js.map +1 -1
  47. package/dist/cli/sync.d.ts.map +1 -1
  48. package/dist/cli/sync.js +399 -726
  49. package/dist/cli/sync.js.map +1 -1
  50. package/dist/cli/sync.test.js +20 -0
  51. package/dist/cli/sync.test.js.map +1 -1
  52. package/dist/daemon-worker.d.ts +2 -2
  53. package/dist/daemon-worker.js +3 -3
  54. package/dist/daemon-worker.js.map +1 -1
  55. package/dist/object-io.js +1 -1
  56. package/dist/object-io.js.map +1 -1
  57. package/dist/remote-pull.d.ts +2 -2
  58. package/dist/remote-pull.d.ts.map +1 -1
  59. package/dist/remote-pull.js +23 -3
  60. package/dist/remote-pull.js.map +1 -1
  61. package/dist/remote-pull.test.js +24 -2
  62. package/dist/remote-pull.test.js.map +1 -1
  63. package/dist/sync/push-receiver.d.ts +6 -0
  64. package/dist/sync/push-receiver.d.ts.map +1 -1
  65. package/dist/sync/push-receiver.js +32 -2
  66. package/dist/sync/push-receiver.js.map +1 -1
  67. package/dist/sync/push-receiver.test.js +31 -0
  68. package/dist/sync/push-receiver.test.js.map +1 -1
  69. package/dist/sync-core.d.ts +27 -0
  70. package/dist/sync-core.d.ts.map +1 -0
  71. package/dist/sync-core.js +54 -0
  72. package/dist/sync-core.js.map +1 -0
  73. package/dist/vault-client.d.ts.map +1 -1
  74. package/dist/vault-client.js +284 -36
  75. package/dist/vault-client.js.map +1 -1
  76. package/dist/vault-client.test.js +59 -0
  77. package/dist/vault-client.test.js.map +1 -1
  78. package/dist/watcher.d.ts +2 -20
  79. package/dist/watcher.d.ts.map +1 -1
  80. package/dist/watcher.js +3 -113
  81. package/dist/watcher.js.map +1 -1
  82. package/package.json +1 -1
  83. package/src/bin/sync-runner-company.ts +350 -0
  84. package/src/bin/sync-runner-events.ts +25 -0
  85. package/src/bin/sync-runner-planning.ts +121 -0
  86. package/src/bin/sync-runner-rollup.ts +72 -0
  87. package/src/bin/sync-runner-telemetry.ts +8 -0
  88. package/src/bin/sync-runner-watch-loop.ts +443 -0
  89. package/src/bin/sync-runner-watch-routes.ts +86 -0
  90. package/src/bin/sync-runner.ts +96 -1253
  91. package/src/cli/reindex.test.ts +41 -3
  92. package/src/cli/reindex.ts +35 -19
  93. package/src/cli/rescue-classify-ordering.test.ts +20 -0
  94. package/src/cli/rescue-core.ts +252 -176
  95. package/src/cli/share.ts +363 -705
  96. package/src/cli/sync.test.ts +25 -0
  97. package/src/cli/sync.ts +612 -802
  98. package/src/daemon-worker.ts +3 -3
  99. package/src/object-io.ts +1 -1
  100. package/src/remote-pull.test.ts +30 -1
  101. package/src/remote-pull.ts +29 -4
  102. package/src/sync/push-receiver.test.ts +35 -0
  103. package/src/sync/push-receiver.ts +41 -2
  104. package/src/sync-core.ts +58 -0
  105. package/src/vault-client.test.ts +74 -0
  106. package/src/vault-client.ts +395 -43
  107. package/src/watcher.ts +6 -141
package/src/watcher.ts CHANGED
@@ -2,9 +2,8 @@
2
2
  * File watcher — monitors HQ directory for changes
3
3
  * Uses chokidar with debounced batching
4
4
  *
5
- * Day 1: not invoked by CLI surface; retained for future automatic-sync milestone.
6
- * When re-enabled, the constructor will need an EntityContext (or a context resolver)
7
- * to be passed in for entity-aware S3 operations.
5
+ * Active watcher path: TreeWatcher detects local changes, WatchPushDriver
6
+ * schedules pushes, and PushEventEmitter publishes typed push events.
8
7
  */
9
8
 
10
9
  import * as fs from "fs";
@@ -12,12 +11,7 @@ import { createHash } from "node:crypto";
12
11
  import { readFile, stat } from "node:fs/promises";
13
12
  import * as path from "path";
14
13
  import { watch } from "chokidar";
15
- import type { FSWatcher } from "chokidar";
16
- import type { EntityContext } from "./types.js";
17
- import { createIgnoreFilter, isWithinSizeLimit } from "./ignore.js";
18
- import { readJournal, writeJournal, hashFile, updateEntry } from "./journal.js";
19
- import { uploadFile, deleteRemoteFile, toPosixKey } from "./s3.js";
20
- import type { UploadAuthor } from "./s3.js";
14
+ import { createIgnoreFilter } from "./ignore.js";
21
15
  import { isPersonalVaultExcluded } from "./personal-vault-exclusions.js";
22
16
  import {
23
17
  CONTINUITY_POINTER_REL,
@@ -205,141 +199,12 @@ export class WatchPushDriver {
205
199
  }
206
200
  }
207
201
 
208
- interface PendingChange {
209
- type: "add" | "change" | "unlink";
210
- absolutePath: string;
211
- relativePath: string;
212
- }
213
-
214
- export class SyncWatcher {
215
- private watcher: FSWatcher | null = null;
216
- private hqRoot: string;
217
- private ctx: EntityContext;
218
- private author?: UploadAuthor;
219
- private shouldSync: (filePath: string, isDir?: boolean) => boolean;
220
- private pendingChanges = new Map<string, PendingChange>();
221
- private debounceTimer: ReturnType<typeof setTimeout> | null = null;
222
- private processing = false;
223
-
224
- constructor(hqRoot: string, ctx: EntityContext, author?: UploadAuthor) {
225
- this.hqRoot = hqRoot;
226
- this.ctx = ctx;
227
- this.author = author;
228
- this.shouldSync = createIgnoreFilter(hqRoot);
229
- }
230
-
231
- start(): void {
232
- if (this.watcher) return;
233
-
234
- this.watcher = watch(this.hqRoot, {
235
- // See toChokidarIgnored: chokidar's pre-stat descent probe has no stats
236
- // hint, so a naive file-verdict prunes intermediate allowlist dirs
237
- // before descending to their in-scope leaves. Keep a statless probe
238
- // when EITHER the file or directory reading would survive the filter.
239
- ignored: toChokidarIgnored(this.shouldSync, this.hqRoot),
240
- persistent: true,
241
- ignoreInitial: true,
242
- awaitWriteFinish: {
243
- stabilityThreshold: 500,
244
- pollInterval: 100,
245
- },
246
- });
247
-
248
- this.watcher
249
- .on("add", (p) => this.queueChange("add", p))
250
- .on("change", (p) => this.queueChange("change", p))
251
- .on("unlink", (p) => this.queueChange("unlink", p))
252
- .on("error", (err) => console.error("Watcher error:", err));
253
- }
254
-
255
- stop(): void {
256
- if (this.watcher) {
257
- this.watcher.close();
258
- this.watcher = null;
259
- }
260
- if (this.debounceTimer) {
261
- clearTimeout(this.debounceTimer);
262
- this.debounceTimer = null;
263
- }
264
- }
265
-
266
- private queueChange(type: "add" | "change" | "unlink", absolutePath: string): void {
267
- const relativePath = toPosixKey(path.relative(this.hqRoot, absolutePath));
268
-
269
- // Skip files that exceed size limit
270
- if (type !== "unlink" && !isWithinSizeLimit(absolutePath)) {
271
- return;
272
- }
273
-
274
- this.pendingChanges.set(relativePath, {
275
- type,
276
- absolutePath,
277
- relativePath,
278
- });
279
-
280
- // Debounce: wait for DEBOUNCE_MS of quiet before processing
281
- if (this.debounceTimer) {
282
- clearTimeout(this.debounceTimer);
283
- }
284
- this.debounceTimer = setTimeout(() => this.flush(), DEBOUNCE_MS);
285
- }
286
-
287
- private async flush(): Promise<void> {
288
- if (this.processing || this.pendingChanges.size === 0) return;
289
- this.processing = true;
290
-
291
- const batch = new Map(this.pendingChanges);
292
- this.pendingChanges.clear();
293
-
294
- const journal = readJournal(this.ctx.slug);
295
-
296
- for (const [relativePath, change] of batch) {
297
- try {
298
- if (change.type === "unlink") {
299
- await deleteRemoteFile(this.ctx, relativePath);
300
- delete journal.files[relativePath];
301
- } else {
302
- const hash = hashFile(change.absolutePath);
303
- const stat = fs.statSync(change.absolutePath);
304
-
305
- // Skip if unchanged from last sync
306
- const existing = journal.files[relativePath];
307
- if (existing && existing.hash === hash) continue;
308
-
309
- const { etag } = this.author
310
- ? await uploadFile(this.ctx, change.absolutePath, relativePath, this.author)
311
- : await uploadFile(this.ctx, change.absolutePath, relativePath);
312
- updateEntry(journal, relativePath, hash, stat.size, "up", etag);
313
- }
314
- } catch (err) {
315
- console.error(
316
- `Sync error [${relativePath}]:`,
317
- err instanceof Error ? err.message : err
318
- );
319
- // Re-queue failed changes
320
- this.pendingChanges.set(relativePath, change);
321
- }
322
- }
323
-
324
- // See cli/sync.ts: stamp lastSync on every flush so the indicator
325
- // ticks even when all changes were re-queued or no-op.
326
- journal.lastSync = new Date().toISOString();
327
- writeJournal(this.ctx.slug, journal);
328
- this.processing = false;
329
-
330
- // Process any changes that came in while we were flushing
331
- if (this.pendingChanges.size > 0) {
332
- this.debounceTimer = setTimeout(() => this.flush(), DEBOUNCE_MS);
333
- }
334
- }
335
- }
336
-
337
202
  // ---------------------------------------------------------------------------
338
203
  // US-002 — debounced, ignore-aware, exclusion-aware tree watcher.
339
204
  //
340
- // Unlike SyncWatcher (which does S3 work inline), TreeWatcher is a pure change
341
- // detector: it emits a single debounced `changed` callback after a quiet window
342
- // and never touches S3 itself. US-003 wires that callback to a targeted push.
205
+ // TreeWatcher is a pure change detector: it emits a single debounced `changed`
206
+ // callback after a quiet window and never touches S3 itself. US-003 wires that
207
+ // callback to a targeted push.
343
208
  //
344
209
  // The emit decision composes the SAME filter stack the push walk uses, so a
345
210
  // path that the push would skip never wakes the watcher: