pushwork 1.0.21 → 1.0.25

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 (40) hide show
  1. package/CLAUDE.md +24 -2
  2. package/dist/cli.js +21 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands.d.ts +11 -1
  5. package/dist/commands.d.ts.map +1 -1
  6. package/dist/commands.js +81 -7
  7. package/dist/commands.js.map +1 -1
  8. package/dist/core/change-detection.d.ts +8 -1
  9. package/dist/core/change-detection.d.ts.map +1 -1
  10. package/dist/core/change-detection.js +69 -1
  11. package/dist/core/change-detection.js.map +1 -1
  12. package/dist/core/sync-engine.d.ts +11 -0
  13. package/dist/core/sync-engine.d.ts.map +1 -1
  14. package/dist/core/sync-engine.js +257 -42
  15. package/dist/core/sync-engine.js.map +1 -1
  16. package/dist/types/config.d.ts +5 -0
  17. package/dist/types/config.d.ts.map +1 -1
  18. package/dist/types/snapshot.d.ts +1 -0
  19. package/dist/types/snapshot.d.ts.map +1 -1
  20. package/dist/utils/content.d.ts +5 -0
  21. package/dist/utils/content.d.ts.map +1 -1
  22. package/dist/utils/content.js +9 -0
  23. package/dist/utils/content.js.map +1 -1
  24. package/dist/utils/network-sync.d.ts +12 -2
  25. package/dist/utils/network-sync.d.ts.map +1 -1
  26. package/dist/utils/network-sync.js +127 -77
  27. package/dist/utils/network-sync.js.map +1 -1
  28. package/dist/utils/repo-factory.d.ts.map +1 -1
  29. package/dist/utils/repo-factory.js +0 -1
  30. package/dist/utils/repo-factory.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/cli.ts +36 -0
  33. package/src/commands.ts +106 -6
  34. package/src/core/change-detection.ts +81 -2
  35. package/src/core/sync-engine.ts +319 -48
  36. package/src/types/config.ts +5 -0
  37. package/src/types/snapshot.ts +1 -0
  38. package/src/utils/content.ts +10 -0
  39. package/src/utils/network-sync.ts +162 -94
  40. package/src/utils/repo-factory.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/types/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC1C,WAAW,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/types/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC1C,WAAW,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Compute a SHA-256 hash of file content.
3
+ * Used to detect local changes for artifact files without reading remote docs.
4
+ */
5
+ export declare function contentHash(content: string | Uint8Array): string;
1
6
  /**
2
7
  * Compare two content pieces for equality
3
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,EACpC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,GACnC,OAAO,CAiBT"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,EACpC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,GACnC,OAAO,CAiBT"}
@@ -1,6 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.contentHash = contentHash;
3
4
  exports.isContentEqual = isContentEqual;
5
+ const crypto_1 = require("crypto");
6
+ /**
7
+ * Compute a SHA-256 hash of file content.
8
+ * Used to detect local changes for artifact files without reading remote docs.
9
+ */
10
+ function contentHash(content) {
11
+ return (0, crypto_1.createHash)("sha256").update(content).digest("hex");
12
+ }
4
13
  /**
5
14
  * Compare two content pieces for equality
6
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":";;AAGA,wCAoBC;AAvBD;;GAEG;AACH,SAAgB,cAAc,CAC5B,QAAoC,EACpC,QAAoC;IAEpC,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEzC,IAAI,OAAO,QAAQ,KAAK,OAAO,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEtD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,KAAK,QAAQ,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,yEAAyE;QACzE,MAAM,IAAI,GAAG,QAAsB,CAAC;QACpC,MAAM,IAAI,GAAG,QAAsB,CAAC;QAEpC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE9C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":";;AAMA,kCAEC;AAKD,wCAoBC;AAjCD,mCAAoC;AAEpC;;;GAGG;AACH,SAAgB,WAAW,CAAC,OAA4B;IACtD,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,QAAoC,EACpC,QAAoC;IAEpC,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEzC,IAAI,OAAO,QAAQ,KAAK,OAAO,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEtD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,KAAK,QAAQ,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,yEAAyE;QACzE,MAAM,IAAI,GAAG,QAAsB,CAAC;QACpC,MAAM,IAAI,GAAG,QAAsB,CAAC;QAEpC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE9C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}
@@ -13,9 +13,19 @@ export declare function waitForBidirectionalSync(repo: Repo, rootDirectoryUrl: A
13
13
  timeoutMs?: number;
14
14
  pollIntervalMs?: number;
15
15
  stableChecksRequired?: number;
16
+ handles?: DocHandle<unknown>[];
16
17
  }): Promise<void>;
17
18
  /**
18
- * Wait for documents to sync to the remote server
19
+ * Result of waitForSync lists which handles failed to sync.
19
20
  */
20
- export declare function waitForSync(handlesToWaitOn: DocHandle<unknown>[], syncServerStorageId?: StorageId, timeoutMs?: number): Promise<void>;
21
+ export interface SyncWaitResult {
22
+ failed: DocHandle<unknown>[];
23
+ }
24
+ /**
25
+ * Wait for documents to sync to the remote server.
26
+ * Processes handles in batches to avoid flooding the server.
27
+ * Returns a result with any failed handles instead of throwing,
28
+ * so callers can attempt recovery (e.g. recreating documents).
29
+ */
30
+ export declare function waitForSync(handlesToWaitOn: DocHandle<unknown>[], syncServerStorageId?: StorageId, timeoutMs?: number): Promise<SyncWaitResult>;
21
31
  //# sourceMappingURL=network-sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"network-sync.d.ts","sourceRoot":"","sources":["../../src/utils/network-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,IAAI,EACJ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAWnC;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,mBAAmB,EAAE,SAAS,GAAG,SAAS,EAC1C,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC1B,GACL,OAAO,CAAC,IAAI,CAAC,CAoEf;AA6ED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,EACrC,mBAAmB,CAAC,EAAE,SAAS,EAC/B,SAAS,GAAE,MAAc,GACxB,OAAO,CAAC,IAAI,CAAC,CAoHf"}
1
+ {"version":3,"file":"network-sync.d.ts","sourceRoot":"","sources":["../../src/utils/network-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,IAAI,EACJ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAWnC;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,mBAAmB,EAAE,SAAS,GAAG,SAAS,EAC1C,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3B,GACL,OAAO,CAAC,IAAI,CAAC,CAiFf;AA2FD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9B;AAuED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,EACrC,mBAAmB,CAAC,EAAE,SAAS,EAC/B,SAAS,GAAE,MAAc,GACxB,OAAO,CAAC,cAAc,CAAC,CA6EzB"}
@@ -54,7 +54,7 @@ function debug(...args) {
54
54
  * @param options - Configuration options
55
55
  */
56
56
  async function waitForBidirectionalSync(repo, rootDirectoryUrl, syncServerStorageId, options = {}) {
57
- const { timeoutMs = 10000, pollIntervalMs = 100, stableChecksRequired = 3, } = options;
57
+ const { timeoutMs = 10000, pollIntervalMs = 100, stableChecksRequired = 3, handles, } = options;
58
58
  if (!syncServerStorageId || !rootDirectoryUrl) {
59
59
  return;
60
60
  }
@@ -62,11 +62,22 @@ async function waitForBidirectionalSync(repo, rootDirectoryUrl, syncServerStorag
62
62
  let lastSeenHeads = new Map();
63
63
  let stableCount = 0;
64
64
  let pollCount = 0;
65
- debug(`waitForBidirectionalSync: starting (timeout=${timeoutMs}ms, stableChecks=${stableChecksRequired})`);
66
- while (Date.now() - startTime < timeoutMs) {
65
+ let dynamicTimeoutMs = timeoutMs;
66
+ debug(`waitForBidirectionalSync: starting (timeout=${timeoutMs}ms, stableChecks=${stableChecksRequired}${handles ? `, tracking ${handles.length} handles` : ', full tree scan'})`);
67
+ while (Date.now() - startTime < dynamicTimeoutMs) {
67
68
  pollCount++;
68
- // Get current heads for all documents in the directory hierarchy
69
- const currentHeads = await getAllDocumentHeads(repo, rootDirectoryUrl);
69
+ // Get current heads: use provided handles if available, otherwise full tree scan
70
+ const currentHeads = handles
71
+ ? getHandleHeads(handles)
72
+ : await getAllDocumentHeads(repo, rootDirectoryUrl);
73
+ // After first scan: scale timeout to tree size and reset the clock.
74
+ // The first scan is just establishing a baseline — its duration
75
+ // shouldn't count against the stability-wait timeout.
76
+ if (pollCount === 1) {
77
+ const scanDuration = Date.now() - startTime;
78
+ dynamicTimeoutMs = Math.max(timeoutMs, 5000 + currentHeads.size * 50) + scanDuration;
79
+ debug(`waitForBidirectionalSync: first scan took ${scanDuration}ms, timeout now ${dynamicTimeoutMs}ms for ${currentHeads.size} docs`);
80
+ }
70
81
  // Check if heads are stable (no changes since last check)
71
82
  const isStable = headsMapEqual(lastSeenHeads, currentHeads);
72
83
  if (isStable) {
@@ -113,6 +124,17 @@ async function waitForBidirectionalSync(repo, rootDirectoryUrl, syncServerStorag
113
124
  debug(`waitForBidirectionalSync: timed out after ${elapsed}ms (${pollCount} polls, ${lastSeenHeads.size} docs tracked, reached ${stableCount}/${stableChecksRequired} stable checks)`);
114
125
  output_1.out.taskLine(`Bidirectional sync timed out after ${(elapsed / 1000).toFixed(1)}s - document heads were still changing after ${pollCount} checks across ${lastSeenHeads.size} docs (reached ${stableCount}/${stableChecksRequired} stability checks). This may mean another peer is actively editing, or the sync server is slow to relay changes. The sync will continue but some remote changes may not be reflected yet.`, true);
115
126
  }
127
+ /**
128
+ * Get heads from a pre-collected set of handles (cheap, synchronous reads).
129
+ * Used for post-push stabilization where we already know which documents changed.
130
+ */
131
+ function getHandleHeads(handles) {
132
+ const heads = new Map();
133
+ for (const handle of handles) {
134
+ heads.set((0, directory_1.getPlainUrl)(handle.url), JSON.stringify(handle.heads()));
135
+ }
136
+ return heads;
137
+ }
116
138
  /**
117
139
  * Get all document heads in the directory hierarchy.
118
140
  * Returns a map of document URL -> serialized heads.
@@ -138,8 +160,8 @@ async function collectHeadsRecursive(repo, directoryUrl, heads) {
138
160
  if (!doc || !doc.docs) {
139
161
  return;
140
162
  }
141
- // Process all entries in the directory
142
- for (const entry of doc.docs) {
163
+ // Process all entries in the directory concurrently
164
+ await Promise.all(doc.docs.map(async (entry) => {
143
165
  if (entry.type === "folder") {
144
166
  // Recurse into subdirectory (entry.url may have stale heads)
145
167
  await collectHeadsRecursive(repo, entry.url, heads);
@@ -155,7 +177,7 @@ async function collectHeadsRecursive(repo, directoryUrl, heads) {
155
177
  // File document may not exist yet
156
178
  }
157
179
  }
158
- }
180
+ }));
159
181
  }
160
182
  catch {
161
183
  // Directory may not exist yet
@@ -175,98 +197,126 @@ function headsMapEqual(a, b) {
175
197
  }
176
198
  return true;
177
199
  }
200
+ /** Maximum documents to sync concurrently to avoid flooding the server */
201
+ const SYNC_BATCH_SIZE = 10;
202
+ /**
203
+ * Wait for a single document handle to sync to the server.
204
+ * Resolves with the handle on success, rejects with the handle on timeout.
205
+ */
206
+ function waitForHandleSync(handle, syncServerStorageId, timeoutMs, startTime) {
207
+ return new Promise((resolve, reject) => {
208
+ let pollInterval;
209
+ const cleanup = () => {
210
+ clearTimeout(timeout);
211
+ clearInterval(pollInterval);
212
+ handle.off("remote-heads", onRemoteHeads);
213
+ };
214
+ const onConverged = () => {
215
+ debug(`waitForSync: ${handle.url.slice(0, 20)}... converged in ${Date.now() - startTime}ms`);
216
+ cleanup();
217
+ resolve(handle);
218
+ };
219
+ const timeout = setTimeout(() => {
220
+ debug(`waitForSync: ${handle.url.slice(0, 20)}... timed out after ${timeoutMs}ms`);
221
+ cleanup();
222
+ reject(handle);
223
+ }, timeoutMs);
224
+ const isConverged = () => {
225
+ const localHeads = handle.heads();
226
+ const info = handle.getSyncInfo(syncServerStorageId);
227
+ return A.equals(localHeads, info?.lastHeads);
228
+ };
229
+ const onRemoteHeads = ({ storageId, }) => {
230
+ if (storageId === syncServerStorageId && isConverged()) {
231
+ onConverged();
232
+ }
233
+ };
234
+ // Initial check
235
+ if (isConverged()) {
236
+ cleanup();
237
+ resolve(handle);
238
+ return;
239
+ }
240
+ // Start polling and event listening
241
+ pollInterval = setInterval(() => {
242
+ if (isConverged()) {
243
+ onConverged();
244
+ }
245
+ }, 100);
246
+ handle.on("remote-heads", onRemoteHeads);
247
+ });
248
+ }
178
249
  /**
179
- * Wait for documents to sync to the remote server
250
+ * Wait for documents to sync to the remote server.
251
+ * Processes handles in batches to avoid flooding the server.
252
+ * Returns a result with any failed handles instead of throwing,
253
+ * so callers can attempt recovery (e.g. recreating documents).
180
254
  */
181
255
  async function waitForSync(handlesToWaitOn, syncServerStorageId, timeoutMs = 60000) {
182
256
  const startTime = Date.now();
183
257
  if (!syncServerStorageId) {
184
258
  debug("waitForSync: no sync server storage ID, skipping");
185
- return;
259
+ return { failed: [] };
186
260
  }
187
261
  if (handlesToWaitOn.length === 0) {
188
262
  debug("waitForSync: no documents to sync");
189
- return;
263
+ return { failed: [] };
190
264
  }
191
- debug(`waitForSync: waiting for ${handlesToWaitOn.length} documents (timeout=${timeoutMs}ms)`);
265
+ debug(`waitForSync: waiting for ${handlesToWaitOn.length} documents (timeout=${timeoutMs}ms, batchSize=${SYNC_BATCH_SIZE})`);
266
+ // Separate already-synced from needs-sync
267
+ const needsSync = [];
192
268
  let alreadySynced = 0;
193
- const promises = handlesToWaitOn.map((handle) => {
194
- // Check if already synced
269
+ for (const handle of handlesToWaitOn) {
195
270
  const heads = handle.heads();
196
271
  const syncInfo = handle.getSyncInfo(syncServerStorageId);
197
272
  const remoteHeads = syncInfo?.lastHeads;
198
- const wasAlreadySynced = A.equals(heads, remoteHeads);
199
- if (wasAlreadySynced) {
273
+ if (A.equals(heads, remoteHeads)) {
200
274
  alreadySynced++;
201
275
  debug(`waitForSync: ${handle.url.slice(0, 20)}... already synced`);
202
- return Promise.resolve();
203
276
  }
204
- debug(`waitForSync: ${handle.url.slice(0, 20)}... waiting for convergence (remoteHeads=${remoteHeads ? 'present' : 'missing'})`);
205
- // Wait for convergence
206
- return new Promise((resolve, reject) => {
207
- let pollInterval;
208
- const cleanup = () => {
209
- clearTimeout(timeout);
210
- clearInterval(pollInterval);
211
- handle.off("remote-heads", onRemoteHeads);
212
- };
213
- const onConverged = () => {
214
- debug(`waitForSync: ${handle.url.slice(0, 20)}... converged in ${Date.now() - startTime}ms`);
215
- cleanup();
216
- resolve();
217
- };
218
- const timeout = setTimeout(() => {
219
- debug(`waitForSync: ${handle.url.slice(0, 20)}... timed out after ${timeoutMs}ms`);
220
- cleanup();
221
- reject(new Error(`Sync timeout after ${timeoutMs}ms for document ${handle.url}`));
222
- }, timeoutMs);
223
- const isConverged = () => {
224
- const localHeads = handle.heads();
225
- const info = handle.getSyncInfo(syncServerStorageId);
226
- return A.equals(localHeads, info?.lastHeads);
227
- };
228
- const onRemoteHeads = ({ storageId, }) => {
229
- if (storageId === syncServerStorageId && isConverged()) {
230
- onConverged();
231
- }
232
- };
233
- const poll = () => {
234
- if (isConverged()) {
235
- onConverged();
236
- return true;
237
- }
238
- return false;
239
- };
240
- // Initial check
241
- if (poll()) {
242
- return;
243
- }
244
- // Start polling and event listening
245
- pollInterval = setInterval(() => {
246
- poll();
247
- }, 100);
248
- handle.on("remote-heads", onRemoteHeads);
249
- });
250
- });
251
- const needSync = handlesToWaitOn.length - alreadySynced;
252
- if (needSync > 0) {
253
- debug(`waitForSync: ${alreadySynced} already synced, waiting for ${needSync} remaining`);
254
- output_1.out.taskLine(`Uploading: ${alreadySynced}/${handlesToWaitOn.length} already synced, waiting for ${needSync} more`);
277
+ else {
278
+ debug(`waitForSync: ${handle.url.slice(0, 20)}... needs sync (remoteHeads=${remoteHeads ? 'present' : 'missing'})`);
279
+ needsSync.push(handle);
280
+ }
281
+ }
282
+ if (needsSync.length > 0) {
283
+ debug(`waitForSync: ${alreadySynced} already synced, ${needsSync.length} need sync`);
284
+ output_1.out.taskLine(`Uploading: ${alreadySynced}/${handlesToWaitOn.length} already synced, waiting for ${needsSync.length} more`);
255
285
  }
256
286
  else {
257
287
  debug(`waitForSync: all ${handlesToWaitOn.length} already synced`);
288
+ return { failed: [] };
258
289
  }
259
- try {
260
- await Promise.all(promises);
261
- const elapsed = Date.now() - startTime;
290
+ // Process in batches to avoid flooding the server
291
+ const failed = [];
292
+ let synced = alreadySynced;
293
+ for (let i = 0; i < needsSync.length; i += SYNC_BATCH_SIZE) {
294
+ const batch = needsSync.slice(i, i + SYNC_BATCH_SIZE);
295
+ const batchNum = Math.floor(i / SYNC_BATCH_SIZE) + 1;
296
+ const totalBatches = Math.ceil(needsSync.length / SYNC_BATCH_SIZE);
297
+ if (totalBatches > 1) {
298
+ debug(`waitForSync: batch ${batchNum}/${totalBatches} (${batch.length} docs)`);
299
+ output_1.out.update(`Uploading batch ${batchNum}/${totalBatches} (${synced}/${handlesToWaitOn.length} done)`);
300
+ }
301
+ const results = await Promise.allSettled(batch.map(handle => waitForHandleSync(handle, syncServerStorageId, timeoutMs, startTime)));
302
+ for (const result of results) {
303
+ if (result.status === "rejected") {
304
+ failed.push(result.reason);
305
+ }
306
+ else {
307
+ synced++;
308
+ }
309
+ }
310
+ }
311
+ const elapsed = Date.now() - startTime;
312
+ if (failed.length > 0) {
313
+ debug(`waitForSync: ${failed.length} documents failed after ${elapsed}ms`);
314
+ output_1.out.taskLine(`Upload: ${synced} synced, ${failed.length} failed after ${(elapsed / 1000).toFixed(1)}s`, true);
315
+ }
316
+ else {
262
317
  debug(`waitForSync: all ${handlesToWaitOn.length} documents synced in ${elapsed}ms (${alreadySynced} were already synced)`);
263
318
  output_1.out.taskLine(`All ${handlesToWaitOn.length} documents uploaded to server (${(elapsed / 1000).toFixed(1)}s)`);
264
319
  }
265
- catch (error) {
266
- const elapsed = Date.now() - startTime;
267
- debug(`waitForSync: failed after ${elapsed}ms: ${error}`);
268
- output_1.out.taskLine(`Upload to server failed after ${(elapsed / 1000).toFixed(1)}s: ${error}`, true);
269
- throw error;
270
- }
320
+ return { failed };
271
321
  }
272
322
  //# sourceMappingURL=network-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"network-sync.js","sourceRoot":"","sources":["../../src/utils/network-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"network-sync.js","sourceRoot":"","sources":["../../src/utils/network-sync.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"repo-factory.d.ts","sourceRoot":"","sources":["../../src/utils/repo-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAa,MAAM,2BAA2B,CAAC;AAI5D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
1
+ {"version":3,"file":"repo-factory.d.ts","sourceRoot":"","sources":["../../src/utils/repo-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAa,MAAM,2BAA2B,CAAC;AAI5D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
@@ -49,7 +49,6 @@ async function createRepo(workingDir, config) {
49
49
  if (config.sync_enabled && config.sync_server) {
50
50
  const networkAdapter = new automerge_repo_network_websocket_1.BrowserWebSocketClientAdapter(config.sync_server);
51
51
  repoConfig.network = [networkAdapter];
52
- repoConfig.enableRemoteHeadsGossiping = true;
53
52
  }
54
53
  const repo = new automerge_repo_1.Repo(repoConfig);
55
54
  // Subscribe to the sync server storage for network sync
@@ -1 +1 @@
1
- {"version":3,"file":"repo-factory.js","sourceRoot":"","sources":["../../src/utils/repo-factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,gCA8BC;AAvCD,8DAA4D;AAC5D,4FAAgF;AAChF,kGAA4F;AAC5F,2CAA6B;AAG7B;;GAEG;AACI,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,MAAuB;IAEvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,oDAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAE9E,MAAM,UAAU,GAAQ,EAAE,OAAO,EAAE,CAAC;IAEpC,uEAAuE;IACvE,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,gEAA6B,CACtD,MAAM,CAAC,WAAW,CACnB,CAAC;QACF,UAAU,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC;QACtC,UAAU,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAC/C,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,qBAAI,CAAC,UAAU,CAAC,CAAC;IAElC,wDAAwD;IACxD,IACE,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,WAAW;QAClB,MAAM,CAAC,sBAAsB,EAC7B,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,sBAAmC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"repo-factory.js","sourceRoot":"","sources":["../../src/utils/repo-factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,gCA6BC;AAtCD,8DAA4D;AAC5D,4FAAgF;AAChF,kGAA4F;AAC5F,2CAA6B;AAG7B;;GAEG;AACI,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,MAAuB;IAEvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,oDAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAE9E,MAAM,UAAU,GAAQ,EAAE,OAAO,EAAE,CAAC;IAEpC,uEAAuE;IACvE,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,gEAA6B,CACtD,MAAM,CAAC,WAAW,CACnB,CAAC;QACF,UAAU,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,qBAAI,CAAC,UAAU,CAAC,CAAC;IAElC,wDAAwD;IACxD,IACE,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,WAAW;QAClB,MAAM,CAAC,sBAAsB,EAC7B,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,sBAAmC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushwork",
3
- "version": "1.0.21",
3
+ "version": "1.0.25",
4
4
  "description": "Bidirectional directory synchronization using Automerge CRDTs",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
package/src/cli.ts CHANGED
@@ -7,6 +7,8 @@ import {
7
7
  init,
8
8
  clone,
9
9
  sync,
10
+ push,
11
+ root,
10
12
  diff,
11
13
  status,
12
14
  log,
@@ -45,6 +47,24 @@ program
45
47
  await init(path, { syncServer, syncServerStorageId });
46
48
  });
47
49
 
50
+ // Root command
51
+ program
52
+ .command("root")
53
+ .summary("Set root directory URL without full initialization")
54
+ .argument(
55
+ "<url>",
56
+ "AutomergeUrl of root directory (format: automerge:XXXXX)"
57
+ )
58
+ .argument(
59
+ "[path]",
60
+ "Directory path (default: current directory)",
61
+ "."
62
+ )
63
+ .option("-f, --force", "Overwrite existing pushwork setup", false)
64
+ .action(async (url, path, opts) => {
65
+ await root(url, path, { force: opts.force });
66
+ });
67
+
48
68
  // Clone command
49
69
  program
50
70
  .command("clone")
@@ -85,6 +105,22 @@ program
85
105
  await commit(path);
86
106
  });
87
107
 
108
+ // Push command
109
+ program
110
+ .command("push")
111
+ .summary("Push local changes to server without pulling remote changes")
112
+ .argument(
113
+ "[path]",
114
+ "Directory path to push (default: current directory)",
115
+ "."
116
+ )
117
+ .option("-v, --verbose", "Verbose output", false)
118
+ .action(async (path, opts) => {
119
+ await push(path, {
120
+ verbose: opts.verbose,
121
+ });
122
+ });
123
+
88
124
  // Sync command
89
125
  program
90
126
  .command("sync")
package/src/commands.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  DirectoryConfig,
18
18
  DirectoryDocument,
19
19
  CommandOptions,
20
+ PushOptions,
20
21
  } from "./types";
21
22
  import { SyncEngine } from "./core";
22
23
  import { pathExists, ensureDirectoryExists, formatRelativePath } from "./utils";
@@ -193,11 +194,10 @@ export async function init(
193
194
  // This ensures the document is uploaded before we exit
194
195
  // waitForSync() verifies the server has the document by comparing local and remote heads
195
196
  if (config.sync_enabled && config.sync_server_storage_id) {
196
- try {
197
- out.update("Syncing to server");
198
- await waitForSync([rootHandle], config.sync_server_storage_id);
199
- } catch (error) {
200
- out.taskLine(`Network sync failed: ${error}`, true);
197
+ out.update("Syncing to server");
198
+ const { failed } = await waitForSync([rootHandle], config.sync_server_storage_id);
199
+ if (failed.length > 0) {
200
+ out.taskLine("Root document failed to sync to server", true);
201
201
  // Continue anyway - the document is created locally and will sync later
202
202
  }
203
203
  }
@@ -1025,7 +1025,107 @@ async function runScript(
1025
1025
  });
1026
1026
  }
1027
1027
 
1028
- // TODO: Add push and pull commands later
1028
+ /**
1029
+ * Set root directory URL for an existing or new pushwork directory
1030
+ */
1031
+ export async function root(
1032
+ rootUrl: string,
1033
+ targetPath: string = ".",
1034
+ options: { force?: boolean } = {}
1035
+ ): Promise<void> {
1036
+ if (!rootUrl.startsWith("automerge:")) {
1037
+ out.error(
1038
+ `Invalid Automerge URL: ${rootUrl}\n` +
1039
+ `Expected format: automerge:XXXXX`
1040
+ );
1041
+ out.exit(1);
1042
+ }
1043
+
1044
+ const resolvedPath = path.resolve(targetPath);
1045
+ const syncToolDir = path.join(resolvedPath, ConfigManager.CONFIG_DIR);
1046
+
1047
+ if (await pathExists(syncToolDir)) {
1048
+ if (!options.force) {
1049
+ out.error("Directory already initialized for pushwork. Use --force to overwrite");
1050
+ out.exit(1);
1051
+ }
1052
+ }
1053
+
1054
+ await ensureDirectoryExists(syncToolDir);
1055
+ await ensureDirectoryExists(path.join(syncToolDir, "automerge"));
1056
+
1057
+ // Create minimal snapshot with just the root URL
1058
+ const snapshotPath = path.join(syncToolDir, "snapshot.json");
1059
+ const snapshot = {
1060
+ timestamp: Date.now(),
1061
+ rootPath: resolvedPath,
1062
+ rootDirectoryUrl: rootUrl,
1063
+ files: [],
1064
+ directories: [],
1065
+ };
1066
+ await fs.writeFile(snapshotPath, JSON.stringify(snapshot, null, 2), "utf-8");
1067
+
1068
+ // Ensure config exists
1069
+ const configManager = new ConfigManager(resolvedPath);
1070
+ await configManager.initializeWithOverrides({});
1071
+
1072
+ out.successBlock("ROOT SET", rootUrl);
1073
+ process.exit();
1074
+ }
1075
+
1076
+ /**
1077
+ * Push local changes to server without pulling remote changes
1078
+ */
1079
+ export async function push(
1080
+ targetPath: string = ".",
1081
+ _options: PushOptions = {}
1082
+ ): Promise<void> {
1083
+ out.task("Pushing local changes to server");
1084
+
1085
+ const { repo, syncEngine } = await setupCommandContext(targetPath);
1086
+
1087
+ const result = await syncEngine.pushToRemote();
1088
+
1089
+ out.taskLine("Writing to disk");
1090
+ await safeRepoShutdown(repo);
1091
+
1092
+ if (result.success) {
1093
+ out.done("Pushed");
1094
+ if (result.filesChanged === 0 && result.directoriesChanged === 0) {
1095
+ out.info("No local changes to push");
1096
+ } else {
1097
+ out.successBlock(
1098
+ "PUSHED",
1099
+ `${result.filesChanged} ${plural("file", result.filesChanged)}`
1100
+ );
1101
+ }
1102
+
1103
+ if (result.warnings.length > 0) {
1104
+ out.log("");
1105
+ out.warnBlock("WARNINGS", `${result.warnings.length} warnings`);
1106
+ for (const warning of result.warnings.slice(0, 5)) {
1107
+ out.log(` ${warning}`);
1108
+ }
1109
+ if (result.warnings.length > 5) {
1110
+ out.log(` ... and ${result.warnings.length - 5} more`);
1111
+ }
1112
+ }
1113
+ } else {
1114
+ out.done("partial", false);
1115
+ out.warnBlock(
1116
+ "PARTIAL",
1117
+ `${result.filesChanged} updated, ${result.errors.length} errors`
1118
+ );
1119
+ result.errors
1120
+ .slice(0, 5)
1121
+ .forEach((error) => out.error(`${error.path}: ${error.error.message}`));
1122
+ if (result.errors.length > 5) {
1123
+ out.warn(`... and ${result.errors.length - 5} more errors`);
1124
+ }
1125
+ }
1126
+
1127
+ process.exit();
1128
+ }
1029
1129
 
1030
1130
  function plural(word: string, count: number): string {
1031
1131
  return count === 1 ? word : `${word}s`;