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