pushwork 2.0.0-a.sub.1 → 2.0.0-preview

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 (251) hide show
  1. package/dist/branches.d.ts +19 -0
  2. package/dist/branches.d.ts.map +1 -0
  3. package/dist/branches.js +111 -0
  4. package/dist/branches.js.map +1 -0
  5. package/dist/cli.d.ts +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +238 -272
  8. package/dist/cli.js.map +1 -1
  9. package/dist/config.d.ts +17 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +84 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/fs-tree.d.ts +6 -0
  14. package/dist/fs-tree.d.ts.map +1 -0
  15. package/dist/fs-tree.js +99 -0
  16. package/dist/fs-tree.js.map +1 -0
  17. package/dist/ignore.d.ts +6 -0
  18. package/dist/ignore.d.ts.map +1 -0
  19. package/dist/ignore.js +74 -0
  20. package/dist/ignore.js.map +1 -0
  21. package/dist/index.d.ts +8 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +34 -4
  24. package/dist/index.js.map +1 -1
  25. package/dist/log.d.ts +3 -0
  26. package/dist/log.d.ts.map +1 -0
  27. package/dist/log.js +14 -0
  28. package/dist/log.js.map +1 -0
  29. package/dist/pushwork.d.ts +115 -0
  30. package/dist/pushwork.d.ts.map +1 -0
  31. package/dist/pushwork.js +918 -0
  32. package/dist/pushwork.js.map +1 -0
  33. package/dist/repo.d.ts +14 -0
  34. package/dist/repo.d.ts.map +1 -0
  35. package/dist/repo.js +60 -0
  36. package/dist/repo.js.map +1 -0
  37. package/dist/shapes/custom.d.ts +3 -0
  38. package/dist/shapes/custom.d.ts.map +1 -0
  39. package/dist/shapes/custom.js +57 -0
  40. package/dist/shapes/custom.js.map +1 -0
  41. package/dist/shapes/file.d.ts +20 -0
  42. package/dist/shapes/file.d.ts.map +1 -0
  43. package/dist/shapes/file.js +140 -0
  44. package/dist/shapes/file.js.map +1 -0
  45. package/dist/shapes/index.d.ts +10 -0
  46. package/dist/shapes/index.d.ts.map +1 -0
  47. package/dist/shapes/index.js +35 -0
  48. package/dist/shapes/index.js.map +1 -0
  49. package/dist/shapes/patchwork-folder.d.ts +3 -0
  50. package/dist/shapes/patchwork-folder.d.ts.map +1 -0
  51. package/dist/shapes/patchwork-folder.js +160 -0
  52. package/dist/shapes/patchwork-folder.js.map +1 -0
  53. package/dist/shapes/types.d.ts +37 -0
  54. package/dist/shapes/types.d.ts.map +1 -0
  55. package/dist/shapes/types.js +52 -0
  56. package/dist/shapes/types.js.map +1 -0
  57. package/dist/shapes/vfs.d.ts +3 -0
  58. package/dist/shapes/vfs.d.ts.map +1 -0
  59. package/dist/shapes/vfs.js +88 -0
  60. package/dist/shapes/vfs.js.map +1 -0
  61. package/dist/stash.d.ts +23 -0
  62. package/dist/stash.d.ts.map +1 -0
  63. package/dist/stash.js +118 -0
  64. package/dist/stash.js.map +1 -0
  65. package/flake.lock +128 -0
  66. package/flake.nix +66 -0
  67. package/package.json +15 -48
  68. package/patches/@automerge__automerge-repo@2.6.0-subduction.15.patch +26 -0
  69. package/pnpm-workspace.yaml +5 -0
  70. package/src/branches.ts +93 -0
  71. package/src/cli.ts +258 -408
  72. package/src/config.ts +64 -0
  73. package/src/fs-tree.ts +70 -0
  74. package/src/ignore.ts +33 -0
  75. package/src/index.ts +38 -4
  76. package/src/log.ts +8 -0
  77. package/src/pushwork.ts +1055 -0
  78. package/src/repo.ts +76 -0
  79. package/src/shapes/custom.ts +29 -0
  80. package/src/shapes/file.ts +115 -0
  81. package/src/shapes/index.ts +19 -0
  82. package/src/shapes/patchwork-folder.ts +156 -0
  83. package/src/shapes/types.ts +79 -0
  84. package/src/shapes/vfs.ts +93 -0
  85. package/src/stash.ts +106 -0
  86. package/test/integration/branches.test.ts +389 -0
  87. package/test/integration/pushwork.test.ts +547 -0
  88. package/test/setup.ts +29 -0
  89. package/test/unit/doc-shape.test.ts +612 -0
  90. package/tsconfig.json +2 -3
  91. package/vitest.config.ts +14 -0
  92. package/ARCHITECTURE-ACCORDING-TO-CLAUDE.md +0 -248
  93. package/CLAUDE.md +0 -141
  94. package/README.md +0 -221
  95. package/babel.config.js +0 -5
  96. package/dist/cli/commands.d.ts +0 -71
  97. package/dist/cli/commands.d.ts.map +0 -1
  98. package/dist/cli/commands.js +0 -794
  99. package/dist/cli/commands.js.map +0 -1
  100. package/dist/cli/index.d.ts +0 -2
  101. package/dist/cli/index.d.ts.map +0 -1
  102. package/dist/cli/index.js +0 -19
  103. package/dist/cli/index.js.map +0 -1
  104. package/dist/commands.d.ts +0 -61
  105. package/dist/commands.d.ts.map +0 -1
  106. package/dist/commands.js +0 -861
  107. package/dist/commands.js.map +0 -1
  108. package/dist/config/index.d.ts +0 -71
  109. package/dist/config/index.d.ts.map +0 -1
  110. package/dist/config/index.js +0 -314
  111. package/dist/config/index.js.map +0 -1
  112. package/dist/core/change-detection.d.ts +0 -80
  113. package/dist/core/change-detection.d.ts.map +0 -1
  114. package/dist/core/change-detection.js +0 -523
  115. package/dist/core/change-detection.js.map +0 -1
  116. package/dist/core/config.d.ts +0 -81
  117. package/dist/core/config.d.ts.map +0 -1
  118. package/dist/core/config.js +0 -258
  119. package/dist/core/config.js.map +0 -1
  120. package/dist/core/index.d.ts +0 -6
  121. package/dist/core/index.d.ts.map +0 -1
  122. package/dist/core/index.js +0 -6
  123. package/dist/core/index.js.map +0 -1
  124. package/dist/core/move-detection.d.ts +0 -34
  125. package/dist/core/move-detection.d.ts.map +0 -1
  126. package/dist/core/move-detection.js +0 -121
  127. package/dist/core/move-detection.js.map +0 -1
  128. package/dist/core/snapshot.d.ts +0 -105
  129. package/dist/core/snapshot.d.ts.map +0 -1
  130. package/dist/core/snapshot.js +0 -217
  131. package/dist/core/snapshot.js.map +0 -1
  132. package/dist/core/sync-engine.d.ts +0 -157
  133. package/dist/core/sync-engine.d.ts.map +0 -1
  134. package/dist/core/sync-engine.js +0 -1379
  135. package/dist/core/sync-engine.js.map +0 -1
  136. package/dist/types/config.d.ts +0 -99
  137. package/dist/types/config.d.ts.map +0 -1
  138. package/dist/types/config.js +0 -5
  139. package/dist/types/config.js.map +0 -1
  140. package/dist/types/documents.d.ts +0 -88
  141. package/dist/types/documents.d.ts.map +0 -1
  142. package/dist/types/documents.js +0 -20
  143. package/dist/types/documents.js.map +0 -1
  144. package/dist/types/index.d.ts +0 -4
  145. package/dist/types/index.d.ts.map +0 -1
  146. package/dist/types/index.js +0 -4
  147. package/dist/types/index.js.map +0 -1
  148. package/dist/types/snapshot.d.ts +0 -64
  149. package/dist/types/snapshot.d.ts.map +0 -1
  150. package/dist/types/snapshot.js +0 -2
  151. package/dist/types/snapshot.js.map +0 -1
  152. package/dist/utils/content-similarity.d.ts +0 -53
  153. package/dist/utils/content-similarity.d.ts.map +0 -1
  154. package/dist/utils/content-similarity.js +0 -155
  155. package/dist/utils/content-similarity.js.map +0 -1
  156. package/dist/utils/content.d.ts +0 -10
  157. package/dist/utils/content.d.ts.map +0 -1
  158. package/dist/utils/content.js +0 -31
  159. package/dist/utils/content.js.map +0 -1
  160. package/dist/utils/directory.d.ts +0 -24
  161. package/dist/utils/directory.d.ts.map +0 -1
  162. package/dist/utils/directory.js +0 -52
  163. package/dist/utils/directory.js.map +0 -1
  164. package/dist/utils/fs.d.ts +0 -74
  165. package/dist/utils/fs.d.ts.map +0 -1
  166. package/dist/utils/fs.js +0 -248
  167. package/dist/utils/fs.js.map +0 -1
  168. package/dist/utils/index.d.ts +0 -5
  169. package/dist/utils/index.d.ts.map +0 -1
  170. package/dist/utils/index.js +0 -5
  171. package/dist/utils/index.js.map +0 -1
  172. package/dist/utils/mime-types.d.ts +0 -13
  173. package/dist/utils/mime-types.d.ts.map +0 -1
  174. package/dist/utils/mime-types.js +0 -209
  175. package/dist/utils/mime-types.js.map +0 -1
  176. package/dist/utils/network-sync.d.ts +0 -36
  177. package/dist/utils/network-sync.d.ts.map +0 -1
  178. package/dist/utils/network-sync.js +0 -250
  179. package/dist/utils/network-sync.js.map +0 -1
  180. package/dist/utils/node-polyfills.d.ts +0 -9
  181. package/dist/utils/node-polyfills.d.ts.map +0 -1
  182. package/dist/utils/node-polyfills.js +0 -9
  183. package/dist/utils/node-polyfills.js.map +0 -1
  184. package/dist/utils/output.d.ts +0 -129
  185. package/dist/utils/output.d.ts.map +0 -1
  186. package/dist/utils/output.js +0 -368
  187. package/dist/utils/output.js.map +0 -1
  188. package/dist/utils/repo-factory.d.ts +0 -13
  189. package/dist/utils/repo-factory.d.ts.map +0 -1
  190. package/dist/utils/repo-factory.js +0 -46
  191. package/dist/utils/repo-factory.js.map +0 -1
  192. package/dist/utils/string-similarity.d.ts +0 -14
  193. package/dist/utils/string-similarity.d.ts.map +0 -1
  194. package/dist/utils/string-similarity.js +0 -39
  195. package/dist/utils/string-similarity.js.map +0 -1
  196. package/dist/utils/text-diff.d.ts +0 -37
  197. package/dist/utils/text-diff.d.ts.map +0 -1
  198. package/dist/utils/text-diff.js +0 -93
  199. package/dist/utils/text-diff.js.map +0 -1
  200. package/dist/utils/trace.d.ts +0 -19
  201. package/dist/utils/trace.d.ts.map +0 -1
  202. package/dist/utils/trace.js +0 -63
  203. package/dist/utils/trace.js.map +0 -1
  204. package/src/commands.ts +0 -1134
  205. package/src/core/change-detection.ts +0 -712
  206. package/src/core/config.ts +0 -313
  207. package/src/core/index.ts +0 -5
  208. package/src/core/move-detection.ts +0 -169
  209. package/src/core/snapshot.ts +0 -275
  210. package/src/core/sync-engine.ts +0 -1795
  211. package/src/types/config.ts +0 -111
  212. package/src/types/documents.ts +0 -91
  213. package/src/types/index.ts +0 -3
  214. package/src/types/snapshot.ts +0 -67
  215. package/src/utils/content.ts +0 -34
  216. package/src/utils/directory.ts +0 -73
  217. package/src/utils/fs.ts +0 -297
  218. package/src/utils/index.ts +0 -4
  219. package/src/utils/mime-types.ts +0 -244
  220. package/src/utils/network-sync.ts +0 -319
  221. package/src/utils/node-polyfills.ts +0 -8
  222. package/src/utils/output.ts +0 -450
  223. package/src/utils/repo-factory.ts +0 -73
  224. package/src/utils/string-similarity.ts +0 -54
  225. package/src/utils/text-diff.ts +0 -101
  226. package/src/utils/trace.ts +0 -70
  227. package/test/integration/README.md +0 -328
  228. package/test/integration/clone-test.sh +0 -310
  229. package/test/integration/conflict-resolution-test.sh +0 -309
  230. package/test/integration/debug-both-nested.sh +0 -74
  231. package/test/integration/debug-concurrent-nested.sh +0 -87
  232. package/test/integration/debug-nested.sh +0 -73
  233. package/test/integration/deletion-behavior-test.sh +0 -487
  234. package/test/integration/deletion-sync-test-simple.sh +0 -193
  235. package/test/integration/deletion-sync-test.sh +0 -297
  236. package/test/integration/exclude-patterns.test.ts +0 -144
  237. package/test/integration/full-integration-test.sh +0 -363
  238. package/test/integration/fuzzer.test.ts +0 -818
  239. package/test/integration/in-memory-sync.test.ts +0 -830
  240. package/test/integration/init-sync.test.ts +0 -89
  241. package/test/integration/manual-sync-test.sh +0 -84
  242. package/test/integration/sync-deletion.test.ts +0 -280
  243. package/test/integration/sync-flow.test.ts +0 -291
  244. package/test/jest.setup.ts +0 -34
  245. package/test/run-tests.sh +0 -225
  246. package/test/unit/deletion-behavior.test.ts +0 -249
  247. package/test/unit/enhanced-mime-detection.test.ts +0 -244
  248. package/test/unit/snapshot.test.ts +0 -404
  249. package/test/unit/sync-convergence.test.ts +0 -298
  250. package/test/unit/sync-timing.test.ts +0 -134
  251. package/test/unit/utils.test.ts +0 -366
@@ -1,275 +0,0 @@
1
- /**
2
- * pvh TODO: the files & directories could be unified into a single map of entries with a type field
3
- */
4
-
5
- import * as fs from "fs/promises";
6
- import * as path from "path";
7
- import {
8
- SyncSnapshot,
9
- SerializableSyncSnapshot,
10
- SnapshotFileEntry,
11
- SnapshotDirectoryEntry,
12
- } from "../types/index.js";
13
- import { pathExists, ensureDirectoryExists } from "../utils/index.js";
14
- import { out } from "../utils/output.js";
15
-
16
- /**
17
- * Manages sync snapshots for local state tracking
18
- */
19
- export class SnapshotManager {
20
- private static readonly SNAPSHOT_FILENAME = "snapshot.json";
21
- private static readonly SYNC_TOOL_DIR = ".pushwork";
22
-
23
- constructor(private rootPath: string) {}
24
-
25
- /**
26
- * Get path to sync tool directory
27
- */
28
- private getSyncToolDir(): string {
29
- return path.join(this.rootPath, SnapshotManager.SYNC_TOOL_DIR);
30
- }
31
-
32
- /**
33
- * Get path to snapshot file
34
- */
35
- private getSnapshotPath(): string {
36
- return path.join(this.getSyncToolDir(), SnapshotManager.SNAPSHOT_FILENAME);
37
- }
38
-
39
- /**
40
- * Check if snapshot exists
41
- */
42
- async exists(): Promise<boolean> {
43
- return await pathExists(this.getSnapshotPath());
44
- }
45
-
46
- /**
47
- * Load snapshot from disk
48
- */
49
- async load(): Promise<SyncSnapshot | null> {
50
- try {
51
- const snapshotPath = this.getSnapshotPath();
52
- if (!(await pathExists(snapshotPath))) {
53
- return null;
54
- }
55
-
56
- const content = await fs.readFile(snapshotPath, "utf8");
57
- const serializable: SerializableSyncSnapshot = JSON.parse(content);
58
-
59
- return this.deserializeSnapshot(serializable);
60
- } catch (error) {
61
- out.taskLine(`Failed to load snapshot: ${error}`);
62
- return null;
63
- }
64
- }
65
-
66
- /**
67
- * Save snapshot to disk
68
- */
69
- async save(snapshot: SyncSnapshot): Promise<void> {
70
- try {
71
- await ensureDirectoryExists(this.getSyncToolDir());
72
-
73
- const serializable = this.serializeSnapshot(snapshot);
74
- const content = JSON.stringify(serializable, null, 2);
75
-
76
- await fs.writeFile(this.getSnapshotPath(), content, "utf8");
77
- } catch (error) {
78
- throw new Error(`Failed to save snapshot: ${error}`);
79
- }
80
- }
81
-
82
- /**
83
- * Create empty snapshot
84
- */
85
- createEmpty(): SyncSnapshot {
86
- return {
87
- timestamp: Date.now(),
88
- rootPath: this.rootPath,
89
- rootDirectoryUrl: undefined,
90
- files: new Map(),
91
- directories: new Map(),
92
- };
93
- }
94
-
95
- /**
96
- * Update file entry in snapshot
97
- */
98
- updateFileEntry(
99
- snapshot: SyncSnapshot,
100
- relativePath: string,
101
- entry: SnapshotFileEntry
102
- ): void {
103
- snapshot.files.set(relativePath, entry);
104
- snapshot.timestamp = Date.now();
105
- }
106
-
107
- /**
108
- * Update directory entry in snapshot
109
- */
110
- updateDirectoryEntry(
111
- snapshot: SyncSnapshot,
112
- relativePath: string,
113
- entry: SnapshotDirectoryEntry
114
- ): void {
115
- snapshot.directories.set(relativePath, entry);
116
- snapshot.timestamp = Date.now();
117
- }
118
-
119
- /**
120
- * Remove file entry from snapshot
121
- */
122
- removeFileEntry(snapshot: SyncSnapshot, relativePath: string): void {
123
- snapshot.files.delete(relativePath);
124
- snapshot.timestamp = Date.now();
125
- }
126
-
127
- /**
128
- * Remove directory entry from snapshot
129
- */
130
- removeDirectoryEntry(snapshot: SyncSnapshot, relativePath: string): void {
131
- snapshot.directories.delete(relativePath);
132
- snapshot.timestamp = Date.now();
133
- }
134
-
135
- /**
136
- * Get all file paths in snapshot
137
- */
138
- getFilePaths(snapshot: SyncSnapshot): string[] {
139
- return Array.from(snapshot.files.keys());
140
- }
141
-
142
- /**
143
- * Get all directory paths in snapshot
144
- */
145
- getDirectoryPaths(snapshot: SyncSnapshot): string[] {
146
- return Array.from(snapshot.directories.keys());
147
- }
148
-
149
- /**
150
- * Get file entry by path
151
- */
152
- getFileEntry(
153
- snapshot: SyncSnapshot,
154
- relativePath: string
155
- ): SnapshotFileEntry | undefined {
156
- return snapshot.files.get(relativePath);
157
- }
158
-
159
- /**
160
- * Get directory entry by path
161
- */
162
- getDirectoryEntry(
163
- snapshot: SyncSnapshot,
164
- relativePath: string
165
- ): SnapshotDirectoryEntry | undefined {
166
- return snapshot.directories.get(relativePath);
167
- }
168
-
169
- /**
170
- * Check if path is tracked in snapshot
171
- */
172
- isTracked(snapshot: SyncSnapshot, relativePath: string): boolean {
173
- return (
174
- snapshot.files.has(relativePath) || snapshot.directories.has(relativePath)
175
- );
176
- }
177
-
178
- /**
179
- * Get snapshot statistics
180
- */
181
- getStats(snapshot: SyncSnapshot): {
182
- files: number;
183
- directories: number;
184
- timestamp: Date;
185
- } {
186
- return {
187
- files: snapshot.files.size,
188
- directories: snapshot.directories.size,
189
- timestamp: new Date(snapshot.timestamp),
190
- };
191
- }
192
-
193
- /**
194
- * Validate snapshot integrity
195
- */
196
- validate(snapshot: SyncSnapshot): { valid: boolean; errors: string[] } {
197
- const errors: string[] = [];
198
-
199
- if (!snapshot.timestamp || snapshot.timestamp <= 0) {
200
- errors.push("Invalid timestamp");
201
- }
202
-
203
- if (!snapshot.rootPath) {
204
- errors.push("Missing root path");
205
- }
206
-
207
- if (!snapshot.files || !snapshot.directories) {
208
- errors.push("Missing files or directories map");
209
- }
210
-
211
- // Check for path conflicts (file and directory with same path)
212
- for (const filePath of snapshot.files.keys()) {
213
- if (snapshot.directories.has(filePath)) {
214
- errors.push(
215
- `Path conflict: ${filePath} exists as both file and directory`
216
- );
217
- }
218
- }
219
-
220
- return {
221
- valid: errors.length === 0,
222
- errors,
223
- };
224
- }
225
-
226
- /**
227
- * Convert snapshot to serializable format
228
- */
229
- private serializeSnapshot(snapshot: SyncSnapshot): SerializableSyncSnapshot {
230
- return {
231
- timestamp: snapshot.timestamp,
232
- rootPath: snapshot.rootPath,
233
- rootDirectoryUrl: snapshot.rootDirectoryUrl,
234
- files: Array.from(snapshot.files.entries()),
235
- directories: Array.from(snapshot.directories.entries()),
236
- };
237
- }
238
-
239
- /**
240
- * Convert serializable format back to snapshot
241
- */
242
- private deserializeSnapshot(
243
- serializable: SerializableSyncSnapshot
244
- ): SyncSnapshot {
245
- return {
246
- timestamp: serializable.timestamp,
247
- rootPath: serializable.rootPath,
248
- rootDirectoryUrl: serializable.rootDirectoryUrl,
249
- files: new Map(serializable.files),
250
- directories: new Map(serializable.directories),
251
- };
252
- }
253
-
254
- /**
255
- * Clear all snapshot data
256
- */
257
- clear(snapshot: SyncSnapshot): void {
258
- snapshot.files.clear();
259
- snapshot.directories.clear();
260
- snapshot.timestamp = Date.now();
261
- }
262
-
263
- /**
264
- * Clone snapshot for safe manipulation
265
- */
266
- clone(snapshot: SyncSnapshot): SyncSnapshot {
267
- return {
268
- timestamp: snapshot.timestamp,
269
- rootPath: snapshot.rootPath,
270
- rootDirectoryUrl: snapshot.rootDirectoryUrl,
271
- files: new Map(snapshot.files),
272
- directories: new Map(snapshot.directories),
273
- };
274
- }
275
- }