pushwork 1.0.5 → 1.0.7
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/README.md +87 -335
- package/dist/.pushwork/automerge/3P/Dm3ekE2pmjGnWvDaG3vSR7ww98/snapshot/aa2349c94955ea561f698720142f9d884a6872d9f82dc332d578c216beb0df0e +0 -0
- package/dist/.pushwork/automerge/st/orage-adapter-id +1 -0
- package/dist/.pushwork/config.json +15 -0
- package/dist/.pushwork/snapshot.json +7 -0
- package/dist/cli.js +208 -213
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +51 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +799 -0
- package/dist/commands.js.map +1 -0
- package/dist/core/change-detection.d.ts +2 -23
- package/dist/core/change-detection.d.ts.map +1 -1
- package/dist/core/change-detection.js +73 -115
- package/dist/core/change-detection.js.map +1 -1
- package/dist/{config/index.d.ts → core/config.d.ts} +13 -3
- package/dist/core/config.d.ts.map +1 -0
- package/dist/{config/index.js → core/config.js} +55 -73
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/move-detection.d.ts +4 -3
- package/dist/core/move-detection.d.ts.map +1 -1
- package/dist/core/move-detection.js +8 -7
- package/dist/core/move-detection.js.map +1 -1
- package/dist/core/snapshot.d.ts +0 -4
- package/dist/core/snapshot.d.ts.map +1 -1
- package/dist/core/snapshot.js +2 -11
- package/dist/core/snapshot.js.map +1 -1
- package/dist/core/sync-engine.d.ts +5 -11
- package/dist/core/sync-engine.d.ts.map +1 -1
- package/dist/core/sync-engine.js +211 -308
- package/dist/core/sync-engine.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +1 -1
- package/dist/types/config.d.ts +24 -88
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/documents.d.ts +15 -2
- package/dist/types/documents.d.ts.map +1 -1
- package/dist/types/documents.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/snapshot.d.ts +0 -21
- package/dist/types/snapshot.d.ts.map +1 -1
- package/dist/types/snapshot.js +0 -14
- package/dist/types/snapshot.js.map +1 -1
- package/dist/utils/content.d.ts.map +1 -1
- package/dist/utils/content.js +2 -6
- package/dist/utils/content.js.map +1 -1
- package/dist/utils/directory.d.ts +10 -0
- package/dist/utils/directory.d.ts.map +1 -0
- package/dist/utils/directory.js +37 -0
- package/dist/utils/directory.js.map +1 -0
- package/dist/utils/fs.d.ts +15 -2
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +54 -20
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -3
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/mime-types.d.ts.map +1 -1
- package/dist/utils/mime-types.js +11 -4
- package/dist/utils/mime-types.js.map +1 -1
- package/dist/utils/network-sync.d.ts +0 -6
- package/dist/utils/network-sync.d.ts.map +1 -1
- package/dist/utils/network-sync.js +55 -99
- package/dist/utils/network-sync.js.map +1 -1
- package/dist/utils/output.d.ts +129 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +375 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/repo-factory.d.ts +2 -6
- package/dist/utils/repo-factory.d.ts.map +1 -1
- package/dist/utils/repo-factory.js +8 -31
- package/dist/utils/repo-factory.js.map +1 -1
- package/dist/utils/string-similarity.js +2 -2
- package/dist/utils/string-similarity.js.map +1 -1
- package/dist/utils/trace.d.ts +19 -0
- package/dist/utils/trace.d.ts.map +1 -0
- package/dist/utils/trace.js +68 -0
- package/dist/utils/trace.js.map +1 -0
- package/package.json +11 -11
- package/src/cli.ts +276 -308
- package/src/commands.ts +988 -0
- package/src/core/change-detection.ts +182 -240
- package/src/{config/index.ts → core/config.ts} +65 -82
- package/src/core/index.ts +1 -1
- package/src/core/move-detection.ts +10 -8
- package/src/core/snapshot.ts +2 -12
- package/src/core/sync-engine.ts +237 -427
- package/src/index.ts +0 -10
- package/src/types/config.ts +28 -93
- package/src/types/documents.ts +16 -2
- package/src/types/index.ts +0 -5
- package/src/types/snapshot.ts +0 -23
- package/src/utils/content.ts +2 -6
- package/src/utils/directory.ts +50 -0
- package/src/utils/fs.ts +58 -23
- package/src/utils/index.ts +1 -5
- package/src/utils/mime-types.ts +12 -4
- package/src/utils/network-sync.ts +79 -137
- package/src/utils/output.ts +450 -0
- package/src/utils/repo-factory.ts +13 -44
- package/src/utils/string-similarity.ts +2 -2
- package/src/utils/trace.ts +70 -0
- package/test/integration/exclude-patterns.test.ts +6 -15
- package/test/integration/fuzzer.test.ts +308 -391
- package/test/integration/init-sync.test.ts +89 -0
- package/test/integration/sync-deletion.test.ts +2 -61
- package/test/integration/sync-flow.test.ts +4 -24
- package/test/jest.setup.ts +34 -0
- package/test/unit/deletion-behavior.test.ts +3 -14
- package/test/unit/enhanced-mime-detection.test.ts +0 -22
- package/test/unit/snapshot.test.ts +2 -29
- package/test/unit/sync-convergence.test.ts +3 -198
- package/test/unit/sync-timing.test.ts +0 -44
- package/test/unit/utils.test.ts +0 -2
- package/tsconfig.json +3 -3
- package/bench/filesystem.bench.ts +0 -78
- package/bench/hashing.bench.ts +0 -60
- package/bench/move-detection.bench.ts +0 -130
- package/bench/runner.ts +0 -49
- package/dist/browser/browser-sync-engine.d.ts +0 -64
- package/dist/browser/browser-sync-engine.d.ts.map +0 -1
- package/dist/browser/browser-sync-engine.js +0 -303
- package/dist/browser/browser-sync-engine.js.map +0 -1
- package/dist/browser/filesystem-adapter.d.ts +0 -84
- package/dist/browser/filesystem-adapter.d.ts.map +0 -1
- package/dist/browser/filesystem-adapter.js +0 -413
- package/dist/browser/filesystem-adapter.js.map +0 -1
- package/dist/browser/index.d.ts +0 -36
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js +0 -90
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/types.d.ts +0 -70
- package/dist/browser/types.d.ts.map +0 -1
- package/dist/browser/types.js +0 -6
- package/dist/browser/types.js.map +0 -1
- package/dist/cli/commands.d.ts +0 -67
- package/dist/cli/commands.d.ts.map +0 -1
- package/dist/cli/commands.js +0 -794
- package/dist/cli/commands.js.map +0 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -19
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/output.d.ts +0 -75
- package/dist/cli/output.d.ts.map +0 -1
- package/dist/cli/output.js +0 -182
- package/dist/cli/output.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/remote-manager.d.ts +0 -65
- package/dist/config/remote-manager.d.ts.map +0 -1
- package/dist/config/remote-manager.js +0 -243
- package/dist/config/remote-manager.js.map +0 -1
- package/dist/core/isomorphic-snapshot.d.ts +0 -58
- package/dist/core/isomorphic-snapshot.d.ts.map +0 -1
- package/dist/core/isomorphic-snapshot.js +0 -204
- package/dist/core/isomorphic-snapshot.js.map +0 -1
- package/dist/platform/browser-filesystem.d.ts +0 -26
- package/dist/platform/browser-filesystem.d.ts.map +0 -1
- package/dist/platform/browser-filesystem.js +0 -91
- package/dist/platform/browser-filesystem.js.map +0 -1
- package/dist/platform/filesystem.d.ts +0 -29
- package/dist/platform/filesystem.d.ts.map +0 -1
- package/dist/platform/filesystem.js +0 -65
- package/dist/platform/filesystem.js.map +0 -1
- package/dist/platform/node-filesystem.d.ts +0 -21
- package/dist/platform/node-filesystem.d.ts.map +0 -1
- package/dist/platform/node-filesystem.js +0 -93
- package/dist/platform/node-filesystem.js.map +0 -1
- package/dist/utils/content-similarity.d.ts +0 -53
- package/dist/utils/content-similarity.d.ts.map +0 -1
- package/dist/utils/content-similarity.js +0 -155
- package/dist/utils/content-similarity.js.map +0 -1
- package/dist/utils/fs-browser.d.ts +0 -57
- package/dist/utils/fs-browser.d.ts.map +0 -1
- package/dist/utils/fs-browser.js +0 -311
- package/dist/utils/fs-browser.js.map +0 -1
- package/dist/utils/fs-node.d.ts +0 -53
- package/dist/utils/fs-node.d.ts.map +0 -1
- package/dist/utils/fs-node.js +0 -220
- package/dist/utils/fs-node.js.map +0 -1
- package/dist/utils/isomorphic.d.ts +0 -29
- package/dist/utils/isomorphic.d.ts.map +0 -1
- package/dist/utils/isomorphic.js +0 -139
- package/dist/utils/isomorphic.js.map +0 -1
- package/dist/utils/pure.d.ts +0 -25
- package/dist/utils/pure.d.ts.map +0 -1
- package/dist/utils/pure.js +0 -112
- package/dist/utils/pure.js.map +0 -1
- package/src/cli/commands.ts +0 -1030
- package/src/cli/index.ts +0 -2
- package/src/cli/output.ts +0 -244
- package/test/README-TESTING-GAPS.md +0 -174
package/README.md
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
# Pushwork
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Bidirectional file synchronization using Automerge CRDTs for conflict-free collaborative editing.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Key Features
|
|
10
|
-
|
|
11
|
-
- **Bidirectional Sync**: Keep local directories synchronized with remote Automerge repositories
|
|
12
|
-
- **Conflict-Free**: Automatic conflict resolution using Automerge CRDTs - no merge conflicts ever
|
|
7
|
+
- **Conflict-Free Sync**: Automatic conflict resolution using Automerge CRDTs
|
|
13
8
|
- **Real-time Collaboration**: Multiple users can edit the same files simultaneously
|
|
14
9
|
- **Intelligent Move Detection**: Detects file renames and moves based on content similarity
|
|
15
|
-
- **
|
|
16
|
-
- **Network Resilient**: Works offline and gracefully handles network interruptions
|
|
10
|
+
- **Offline Support**: Works offline and gracefully handles network interruptions
|
|
17
11
|
- **Cross-Platform**: Runs on Windows, macOS, and Linux
|
|
18
|
-
- **Rich CLI**: Full-featured command-line interface with comprehensive tooling
|
|
19
|
-
|
|
20
|
-
## Quick Start
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Currently, install from source:
|
|
13
|
+
## Installation
|
|
25
14
|
|
|
26
15
|
```bash
|
|
27
16
|
pnpm install
|
|
@@ -29,214 +18,89 @@ pnpm run build
|
|
|
29
18
|
pnpm link --global
|
|
30
19
|
```
|
|
31
20
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
export PNPM_HOME="/Users/username/Library/pnpm" # wherever you have pnpm installed
|
|
36
|
-
export PATH="$PATH:$PNPM_HOME"
|
|
37
|
-
```
|
|
21
|
+
Requires: Node.js 18+, pnpm 8.15.0+
|
|
38
22
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
### Basic Usage
|
|
42
|
-
|
|
43
|
-
1. **Initialize a new repository:**
|
|
23
|
+
## Quick Start
|
|
44
24
|
|
|
45
25
|
```bash
|
|
26
|
+
# Initialize a directory
|
|
46
27
|
pushwork init ./my-project
|
|
47
|
-
```
|
|
48
28
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pushwork clone <automerge-url> ./cloned-project
|
|
53
|
-
```
|
|
29
|
+
# Clone an existing repository
|
|
30
|
+
pushwork clone <automerge-url> ./project
|
|
54
31
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
32
|
+
# Sync changes
|
|
58
33
|
pushwork sync
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
4. **Check status:**
|
|
62
34
|
|
|
63
|
-
|
|
35
|
+
# Check status
|
|
64
36
|
pushwork status
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Commands
|
|
68
|
-
|
|
69
|
-
### `init <path> [options]`
|
|
70
|
-
|
|
71
|
-
Initialize sync in a directory, creating a new Automerge repository.
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
# Initialize with default sync server
|
|
75
|
-
pushwork init ./my-project
|
|
76
|
-
|
|
77
|
-
# Initialize with custom sync server
|
|
78
|
-
pushwork init ./my-project \
|
|
79
|
-
--sync-server ws://localhost:3030 \
|
|
80
|
-
--sync-server-storage-id your-storage-id
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**Options:**
|
|
84
|
-
|
|
85
|
-
- `--sync-server <url>`: Custom sync server URL (requires storage-id)
|
|
86
|
-
- `--sync-server-storage-id <id>`: Custom sync server storage ID (requires server)
|
|
87
|
-
|
|
88
|
-
### `clone <url> <path> [options]`
|
|
89
|
-
|
|
90
|
-
Clone an existing synced directory from an Automerge URL.
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
# Clone from default sync server
|
|
94
|
-
pushwork clone automerge:abc123... ./cloned-project
|
|
95
|
-
|
|
96
|
-
# Clone with custom sync server
|
|
97
|
-
pushwork clone automerge:abc123... ./cloned-project \
|
|
98
|
-
--sync-server ws://localhost:3030 \
|
|
99
|
-
--sync-server-storage-id your-storage-id
|
|
100
37
|
|
|
101
|
-
#
|
|
102
|
-
pushwork
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**Options:**
|
|
106
|
-
|
|
107
|
-
- `--force`: Overwrite existing directory
|
|
108
|
-
- `--sync-server <url>`: Custom sync server URL
|
|
109
|
-
- `--sync-server-storage-id <id>`: Custom sync server storage ID
|
|
110
|
-
|
|
111
|
-
### `sync [options]`
|
|
112
|
-
|
|
113
|
-
Run bidirectional synchronization between local files and remote repository.
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
# Preview changes without applying them
|
|
117
|
-
pushwork sync --dry-run
|
|
118
|
-
|
|
119
|
-
# Apply all changes
|
|
120
|
-
pushwork sync
|
|
121
|
-
|
|
122
|
-
# Verbose output
|
|
123
|
-
pushwork sync --verbose
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Options:**
|
|
127
|
-
|
|
128
|
-
- `--dry-run`: Preview changes without applying them
|
|
129
|
-
- `--verbose`: Show detailed progress information
|
|
130
|
-
|
|
131
|
-
### `diff [path] [options]`
|
|
132
|
-
|
|
133
|
-
Show differences between local and remote state.
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
# Show all changes
|
|
137
|
-
pushwork diff
|
|
138
|
-
|
|
139
|
-
# Show changes for specific path
|
|
140
|
-
pushwork diff src/
|
|
141
|
-
|
|
142
|
-
# Show only changed file names
|
|
143
|
-
pushwork diff --name-only
|
|
144
|
-
|
|
145
|
-
# Use external diff tool
|
|
146
|
-
pushwork diff --tool meld
|
|
38
|
+
# Get shareable URL
|
|
39
|
+
pushwork url
|
|
147
40
|
```
|
|
148
41
|
|
|
149
|
-
|
|
42
|
+
## Commands
|
|
150
43
|
|
|
151
|
-
|
|
152
|
-
- `--name-only`: Show only changed file names
|
|
44
|
+
### Core Commands
|
|
153
45
|
|
|
154
|
-
|
|
46
|
+
**`init [path]`** - Initialize sync in a directory
|
|
155
47
|
|
|
156
|
-
|
|
48
|
+
- `--sync-server <url>` - Custom sync server URL
|
|
49
|
+
- `--sync-server-storage-id <id>` - Custom storage ID
|
|
50
|
+
- `--debug` - Export performance flame graphs
|
|
157
51
|
|
|
158
|
-
|
|
159
|
-
pushwork status
|
|
160
|
-
```
|
|
52
|
+
**`clone <url> <path>`** - Clone an existing synced directory
|
|
161
53
|
|
|
162
|
-
|
|
54
|
+
- `--force` - Overwrite existing directory
|
|
55
|
+
- `--sync-server <url>` - Custom sync server URL
|
|
56
|
+
- `--sync-server-storage-id <id>` - Custom storage ID
|
|
163
57
|
|
|
164
|
-
|
|
58
|
+
**`sync [path]`** - Run bidirectional synchronization
|
|
165
59
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
60
|
+
- `--dry-run` - Preview changes without applying
|
|
61
|
+
- `--verbose` - Show detailed progress
|
|
62
|
+
- `--debug` - Export performance flame graphs
|
|
169
63
|
|
|
170
|
-
|
|
171
|
-
pushwork log --oneline
|
|
64
|
+
**`status [path]`** - Show sync status and repository info
|
|
172
65
|
|
|
173
|
-
|
|
174
|
-
pushwork log src/important-file.txt
|
|
175
|
-
```
|
|
66
|
+
- `--verbose` - Show detailed status including all tracked files
|
|
176
67
|
|
|
177
|
-
|
|
68
|
+
**`commit [path]`** - Commit local changes without network sync
|
|
178
69
|
|
|
179
|
-
- `--
|
|
180
|
-
- `--
|
|
181
|
-
- `--limit <n>`: Limit number of syncs shown (default: 10)
|
|
70
|
+
- `--dry-run` - Preview what would be committed
|
|
71
|
+
- `--debug` - Export performance flame graphs
|
|
182
72
|
|
|
183
|
-
###
|
|
73
|
+
### Utility Commands
|
|
184
74
|
|
|
185
|
-
|
|
75
|
+
**`diff [path]`** - Show differences between local and remote
|
|
186
76
|
|
|
187
|
-
|
|
188
|
-
# Get URL for current directory
|
|
189
|
-
pushwork url
|
|
77
|
+
- `--name-only` - Show only changed file names
|
|
190
78
|
|
|
191
|
-
|
|
192
|
-
pushwork url ./my-project
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### `commit [path] [options]`
|
|
79
|
+
**`url [path]`** - Show the Automerge root URL for sharing
|
|
196
80
|
|
|
197
|
-
|
|
81
|
+
**`ls [path]`** - List tracked files
|
|
198
82
|
|
|
199
|
-
|
|
200
|
-
# Commit all changes
|
|
201
|
-
pushwork commit
|
|
83
|
+
- `--long` - Show Automerge URLs
|
|
202
84
|
|
|
203
|
-
|
|
204
|
-
pushwork commit --dry-run
|
|
85
|
+
**`config [path]`** - View or edit configuration
|
|
205
86
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
```
|
|
87
|
+
- `--list` - Show full configuration
|
|
88
|
+
- `--get <key>` - Get specific config value (dot notation)
|
|
209
89
|
|
|
210
|
-
|
|
90
|
+
**`rm [path]`** - Remove local pushwork data
|
|
211
91
|
|
|
212
|
-
|
|
92
|
+
**`watch [path]`** - Watch directory, build, and sync automatically
|
|
213
93
|
|
|
214
|
-
|
|
94
|
+
- `--script <command>` - Build script (default: "pnpm build")
|
|
95
|
+
- `--dir <dir>` - Directory to watch (default: "src")
|
|
96
|
+
- `--verbose` - Show build output
|
|
215
97
|
|
|
216
|
-
|
|
98
|
+
**`log [path]`** - Show sync history _(experimental, limited functionality)_
|
|
217
99
|
|
|
218
|
-
|
|
219
|
-
# Restore entire directory
|
|
220
|
-
pushwork checkout sync-123
|
|
221
|
-
|
|
222
|
-
# Force checkout even with uncommitted changes
|
|
223
|
-
pushwork checkout sync-123 --force
|
|
224
|
-
```
|
|
100
|
+
**`checkout <sync-id> [path]`** - Restore to previous sync _(not yet implemented)_
|
|
225
101
|
|
|
226
102
|
## Configuration
|
|
227
103
|
|
|
228
|
-
### Default Configuration
|
|
229
|
-
|
|
230
|
-
Pushwork uses sensible defaults:
|
|
231
|
-
|
|
232
|
-
- **Sync Server**: `wss://sync3.automerge.org`
|
|
233
|
-
- **Storage ID**: `3760df37-a4c6-4f66-9ecd-732039a9385d`
|
|
234
|
-
- **Excluded Patterns**: `.git`, `node_modules`, `*.tmp`, `.pushwork`
|
|
235
|
-
- **Large File Threshold**: 100MB
|
|
236
|
-
- **Move Detection Threshold**: 80% similarity
|
|
237
|
-
|
|
238
|
-
### Directory Configuration
|
|
239
|
-
|
|
240
104
|
Configuration is stored in `.pushwork/config.json`:
|
|
241
105
|
|
|
242
106
|
```json
|
|
@@ -262,36 +126,23 @@ Configuration is stored in `.pushwork/config.json`:
|
|
|
262
126
|
|
|
263
127
|
## How It Works
|
|
264
128
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
Pushwork uses **Automerge CRDTs** to automatically resolve conflicts:
|
|
268
|
-
|
|
269
|
-
- **Text Files**: Character-level merging preserves all changes
|
|
270
|
-
- **Binary Files**: Last-writer-wins with automatic convergence
|
|
271
|
-
- **Directory Structure**: Additive merging supports simultaneous file creation
|
|
272
|
-
- **File Moves**: Intelligent detection prevents data loss during renames
|
|
273
|
-
|
|
274
|
-
### Two-Phase Sync Process
|
|
129
|
+
Pushwork uses Automerge CRDTs for automatic conflict resolution:
|
|
275
130
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
131
|
+
- **Text files**: Character-level merging preserves all changes
|
|
132
|
+
- **Binary files**: Last-writer-wins with automatic convergence
|
|
133
|
+
- **Directories**: Additive merging supports simultaneous file creation
|
|
279
134
|
|
|
280
|
-
|
|
135
|
+
Sync process:
|
|
281
136
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- **Resumable**: Interrupted syncs can be safely resumed
|
|
137
|
+
1. **Push**: Apply local changes to Automerge documents
|
|
138
|
+
2. **Pull**: Apply remote changes to local filesystem
|
|
139
|
+
3. **Convergence**: All repositories reach identical state
|
|
286
140
|
|
|
287
|
-
|
|
141
|
+
State tracking:
|
|
288
142
|
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
- **Ignore**: Moves with <50% similarity
|
|
293
|
-
|
|
294
|
-
## Architecture
|
|
143
|
+
- `.pushwork/snapshot.json` - Tracks sync state and file mappings
|
|
144
|
+
- `.pushwork/config.json` - Configuration settings
|
|
145
|
+
- Content-based change detection using Automerge document heads
|
|
295
146
|
|
|
296
147
|
### Document Schema
|
|
297
148
|
|
|
@@ -303,7 +154,10 @@ Pushwork uses **Automerge CRDTs** to automatically resolve conflicts:
|
|
|
303
154
|
name: string;
|
|
304
155
|
extension: string;
|
|
305
156
|
mimeType: string;
|
|
306
|
-
content:
|
|
157
|
+
content: ImmutableString | Uint8Array;
|
|
158
|
+
metadata: {
|
|
159
|
+
permissions: number;
|
|
160
|
+
};
|
|
307
161
|
}
|
|
308
162
|
```
|
|
309
163
|
|
|
@@ -317,153 +171,51 @@ Pushwork uses **Automerge CRDTs** to automatically resolve conflicts:
|
|
|
317
171
|
type: "file" | "folder";
|
|
318
172
|
url: AutomergeUrl;
|
|
319
173
|
}>;
|
|
174
|
+
lastSyncAt?: number;
|
|
320
175
|
}
|
|
321
176
|
```
|
|
322
177
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
- **Snapshot File**: `.pushwork/snapshot.json` tracks sync state
|
|
326
|
-
- **Path Mapping**: Links filesystem paths to Automerge document URLs
|
|
327
|
-
- **Head Tracking**: Enables efficient change detection
|
|
328
|
-
- **Configuration**: `.pushwork/config.json` stores sync settings
|
|
329
|
-
|
|
330
|
-
### Network Architecture
|
|
331
|
-
|
|
332
|
-
- **Sync Server**: Handles real-time synchronization between clients
|
|
333
|
-
- **Storage ID**: Isolates different collaboration groups
|
|
334
|
-
- **WebSocket Connection**: Provides real-time updates
|
|
335
|
-
- **Graceful Degradation**: Works offline with manual sync
|
|
178
|
+
## Development
|
|
336
179
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
### Running Tests
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
# Build the project
|
|
343
|
-
npm run build
|
|
344
|
-
|
|
345
|
-
# Run unit tests
|
|
346
|
-
npm test
|
|
347
|
-
|
|
348
|
-
# Run integration tests
|
|
349
|
-
./test/run-tests.sh
|
|
350
|
-
|
|
351
|
-
# Test conflict resolution
|
|
352
|
-
./test/integration/conflict-resolution-test.sh
|
|
353
|
-
|
|
354
|
-
# Test clone functionality
|
|
355
|
-
./test/integration/clone-test.sh
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
### Test Coverage
|
|
359
|
-
|
|
360
|
-
- **Unit Tests**: Core functionality and utilities
|
|
361
|
-
- **Integration Tests**: End-to-end sync scenarios
|
|
362
|
-
- **Conflict Resolution**: CRDT merging behavior
|
|
363
|
-
- **Clone Operations**: Repository sharing workflows
|
|
364
|
-
|
|
365
|
-
## 🛠️ Development
|
|
366
|
-
|
|
367
|
-
### Prerequisites
|
|
368
|
-
|
|
369
|
-
- Node.js 18+
|
|
370
|
-
- TypeScript 5+
|
|
371
|
-
- pnpm (recommended) or npm
|
|
372
|
-
|
|
373
|
-
### Development Setup
|
|
180
|
+
### Setup
|
|
374
181
|
|
|
375
182
|
```bash
|
|
376
183
|
git clone <repository-url>
|
|
377
184
|
cd pushwork
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
#
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
# Watch mode for testing
|
|
385
|
-
npm run test:watch
|
|
185
|
+
pnpm install
|
|
186
|
+
pnpm run build
|
|
187
|
+
pnpm run dev # Watch mode
|
|
188
|
+
pnpm test # Run tests
|
|
189
|
+
pnpm run test:watch # Watch mode for tests
|
|
386
190
|
```
|
|
387
191
|
|
|
388
192
|
### Project Structure
|
|
389
193
|
|
|
390
194
|
```
|
|
391
195
|
src/
|
|
392
|
-
├── cli/
|
|
393
|
-
├── core/
|
|
394
|
-
├── config/
|
|
395
|
-
├──
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
test/
|
|
399
|
-
├── unit/ # Unit tests
|
|
400
|
-
└── integration/ # Integration tests
|
|
196
|
+
├── cli/ # Command-line interface
|
|
197
|
+
├── core/ # Core sync engine
|
|
198
|
+
├── config/ # Configuration management
|
|
199
|
+
├── tracing/ # Performance tracing
|
|
200
|
+
├── types/ # TypeScript type definitions
|
|
201
|
+
└── utils/ # Shared utilities
|
|
401
202
|
```
|
|
402
203
|
|
|
403
|
-
|
|
204
|
+
### Testing
|
|
404
205
|
|
|
405
206
|
```bash
|
|
406
|
-
#
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
alice$ pushwork sync
|
|
410
|
-
alice$ pushwork url
|
|
411
|
-
# automerge:2V4w7zv8zkJYJxJsKaYhZ5NPjxA1
|
|
412
|
-
|
|
413
|
-
# Bob clones Alice's project
|
|
414
|
-
bob$ pushwork clone automerge:2V4w7zv8zkJYJxJsKaYhZ5NPjxA1 ./bobs-copy
|
|
415
|
-
|
|
416
|
-
# Both edit the same file simultaneously
|
|
417
|
-
alice$ echo "Alice's changes" >> shared-docs/readme.txt
|
|
418
|
-
bob$ echo "Bob's changes" >> bobs-copy/readme.txt
|
|
419
|
-
|
|
420
|
-
# Both sync - no conflicts!
|
|
421
|
-
alice$ pushwork sync
|
|
422
|
-
bob$ pushwork sync
|
|
423
|
-
alice$ pushwork sync # Gets Bob's changes
|
|
424
|
-
|
|
425
|
-
# Final result contains both changes merged automatically
|
|
426
|
-
alice$ cat shared-docs/readme.txt
|
|
427
|
-
Hello World
|
|
428
|
-
Alice's changes
|
|
429
|
-
Bob's changes
|
|
207
|
+
pnpm test # Unit tests
|
|
208
|
+
./test/run-tests.sh # All integration tests
|
|
209
|
+
./test/integration/conflict-resolution-test.sh # Specific test
|
|
430
210
|
```
|
|
431
211
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
### Common Issues
|
|
435
|
-
|
|
436
|
-
**WebSocket Connection Errors**: Usually safe to ignore during shutdown
|
|
437
|
-
|
|
438
|
-
**"Directory not initialized"**: Run `pushwork init .` first
|
|
439
|
-
|
|
440
|
-
**Network Sync Timeout**: Check internet connection and sync server status
|
|
441
|
-
|
|
442
|
-
**File Permission Errors**: Ensure write access to target directory
|
|
443
|
-
|
|
444
|
-
### Debug Mode
|
|
212
|
+
### Profiling
|
|
445
213
|
|
|
446
214
|
```bash
|
|
447
|
-
#
|
|
448
|
-
pushwork sync
|
|
449
|
-
|
|
450
|
-
# Preview changes without applying
|
|
451
|
-
pushwork sync --dry-run
|
|
452
|
-
|
|
453
|
-
# Check repository status
|
|
454
|
-
pushwork status
|
|
215
|
+
pushwork sync --debug # Export flame graphs
|
|
216
|
+
clinic flame --collect-only -- node --enable-source-maps --prof $(pnpm root -g)/pushwork/dist/cli.js sync
|
|
455
217
|
```
|
|
456
218
|
|
|
457
219
|
## License
|
|
458
220
|
|
|
459
|
-
MIT License
|
|
460
|
-
|
|
461
|
-
## Links
|
|
462
|
-
|
|
463
|
-
- **Issues**: Report bugs and request features
|
|
464
|
-
- **Documentation**: Additional guides and tutorials
|
|
465
|
-
- **Automerge**: Learn more about CRDT technology
|
|
466
|
-
|
|
467
|
-
---
|
|
468
|
-
|
|
469
|
-
** Ready to collaborate conflict-free? Get started with `pushwork init`!**
|
|
221
|
+
MIT License
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e43182b5-f406-4319-8bac-ee54d9dec4a9
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sync_enabled": true,
|
|
3
|
+
"sync_server": "wss://sync3.automerge.org",
|
|
4
|
+
"sync_server_storage_id": "3760df37-a4c6-4f66-9ecd-732039a9385d",
|
|
5
|
+
"exclude_patterns": [
|
|
6
|
+
".git",
|
|
7
|
+
"node_modules",
|
|
8
|
+
"*.tmp",
|
|
9
|
+
".pushwork",
|
|
10
|
+
".DS_Store"
|
|
11
|
+
],
|
|
12
|
+
"sync": {
|
|
13
|
+
"move_detection_threshold": 0.7
|
|
14
|
+
}
|
|
15
|
+
}
|