@jbaehova/onthego 0.3.1 → 0.4.1

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 CHANGED
@@ -1,117 +1,218 @@
1
- # ONTHEGO
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/peerproblem/onthego/main/assets/onthego-hero.png" alt="Start on your desktop. Finish on your laptop. onthego moves your uncommitted work and your Codex and Claude Code sessions to your other machine." width="100%">
3
+ </p>
4
+
5
+ <h3 align="center">Start on your desktop. Finish on your laptop.</h3>
6
+
7
+ <p align="center">
8
+ onthego copies your uncommitted work and your Codex and Claude Code sessions<br>
9
+ to your other machine. Then you pick up the same session there.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/@jbaehova/onthego"><img alt="npm" src="https://img.shields.io/npm/v/%40jbaehova%2Fonthego?style=flat-square&color=1d1d1f&label=npm"></a>
14
+ <a href="https://github.com/peerproblem/onthego/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/peerproblem/onthego/ci.yml?branch=main&style=flat-square&label=ci"></a>
15
+ <img alt="macOS and Linux" src="https://img.shields.io/badge/macOS%20%2B%20Linux-1d1d1f?style=flat-square">
16
+ <img alt="No account, no server" src="https://img.shields.io/badge/no%20account%2C%20no%20server-0071e3?style=flat-square">
17
+ <a href="LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-1d1d1f?style=flat-square"></a>
18
+ </p>
19
+
20
+ <p align="center">
21
+ <a href="https://peerproblem.github.io/onthego/"><b>Website</b></a>
22
+ &nbsp;&nbsp;/&nbsp;&nbsp;
23
+ <a href="#quick-start"><b>Quick start</b></a>
24
+ &nbsp;&nbsp;/&nbsp;&nbsp;
25
+ <a href="docs/tailscale.md"><b>Tailscale</b></a>
26
+ &nbsp;&nbsp;/&nbsp;&nbsp;
27
+ <a href="docs/releases/0.4.1.md"><b>What's new</b></a>
28
+ </p>
29
+
30
+ <br>
2
31
 
3
- Continue your coding-agent conversation on another device, with your unfinished Git workspace intact.
32
+ ```sh
33
+ npm install -g @jbaehova/onthego
34
+ onthego sync laptop
35
+ ```
36
+
37
+ That's the whole idea. Staged, unstaged, and untracked work arrives exactly as you left it, together with this project's agent sessions. On the other device, run `codex resume` or `claude --resume` and keep talking.
4
38
 
5
- ONTHEGO is an MIT-licensed CLI for explicit handoffs between your own computers. It carries staged and unstaged work together with project-scoped Codex CLI and Claude Code histories. Each destination keeps its Git settings, hooks, local dependencies, and editor directory intact.
39
+ ## How it works
6
40
 
7
- No ONTHEGO account or central server is needed. SSH connects your devices. Install and authenticate the coding agent separately on each device. This project targets individual CLI users.
41
+ | | |
42
+ | :-- | :-- |
43
+ | **Capture** | Staged, unstaged, and untracked files, plus this project's recent agent sessions. Your `.env` stays put. |
44
+ | **Encrypt** | Each handoff is encrypted for the receiving device and signed by the sender. |
45
+ | **Send** | Over your own SSH. Same Wi-Fi, Tailscale, or a VPS. No account, no relay. |
46
+ | **Resume** | Run `codex resume` or `claude --resume` on the other machine. Same conversation. |
47
+
48
+ Your Git history stays clean, with no "wip" commits. `node_modules`, caches, Git config, hooks, and agent logins stay on each machine.
8
49
 
9
50
  ## Install
10
51
 
11
52
  ```sh
12
- npm install -g @jbaehova/onthego@^0.3.1
53
+ npm install -g @jbaehova/onthego
13
54
  ```
14
55
 
15
- The npm package includes binaries for macOS arm64/amd64 and Linux arm64/amd64. Git and OpenSSH are required. Node.js is needed only for the npm launcher. Install the same ONTHEGO version on both devices.
56
+ Ships native binaries for macOS and Linux (arm64 and amd64). Requires Git and OpenSSH.
57
+
58
+ <details>
59
+ <summary><b>Other ways to install</b></summary>
60
+ <br>
16
61
 
17
- You can also build from source with Go 1.26 or newer (the build selects Go 1.27.2):
62
+ **Without Node.js** (servers, minimal machines). Downloads the release binary, verifies its SHA-256 checksum, and installs to `~/.local/bin`:
18
63
 
19
64
  ```sh
20
- git clone https://github.com/peerproblem/onthego.git
21
- cd onthego
22
- make build
23
- mkdir -p ~/.local/bin
24
- install -m 755 dist/onthego ~/.local/bin/onthego
25
- # Or: go install github.com/peerproblem/onthego/cmd/onthego@latest
65
+ curl -fsSL https://raw.githubusercontent.com/peerproblem/onthego/main/install.sh | sh
26
66
  ```
27
67
 
28
- ## Desktop to laptop
68
+ **From source** with Go 1.26 or newer:
29
69
 
30
- Enable SSH on the destination and establish a trusted SSH connection first. An existing SSH alias can use a LAN address or your own VPS. Tailscale and other VPNs are optional ways to provide reachability. Both devices must be reachable during a direct transfer.
70
+ ```sh
71
+ git clone https://github.com/peerproblem/onthego.git && cd onthego
72
+ make build && install -m 755 dist/onthego ~/.local/bin/onthego
73
+ ```
31
74
 
32
- Inside the project on the desktop:
75
+ </details>
33
76
 
34
- ```sh
35
- onthego init
36
- onthego device add laptop --host me@my-laptop
37
- onthego remote set laptop /Users/me/projects/my-app
38
- onthego doctor laptop
39
- onthego push laptop --dry-run
77
+ You only install it once by hand. `onthego device add <name> --install` copies the exact same version to your other devices over SSH.
78
+
79
+ ## Quick start
40
80
 
41
- # Stop agents and other processes that write project files, then:
42
- onthego push laptop --verbose
81
+ **1. On your desktop**, inside a Git project:
82
+
83
+ ```sh
84
+ onthego init # once per project; commit .onthego.yaml
85
+ onthego device add laptop --host me@laptop.local --install
86
+ onthego sync laptop
43
87
  ```
44
88
 
45
- `device add` pairs both public identities through your trusted SSH connection. It discovers the remote executable using a login shell. Use `--binary /absolute/path/onthego` when needed. `--port` and `--identity-file` select an existing SSH connection; private SSH keys are never copied.
89
+ **2. On the laptop**, continue where you stopped. The handoff prints the exact commands:
46
90
 
47
- Devices store hosts and identities once. Project paths are separate mappings under `~/.onthego/projects/<id>/peers.yaml`. Without a mapping, the path relative to your home directory is used under the remote home. `device add ... --path ...` remains a shortcut for the current project's mapping.
91
+ ```sh
92
+ cd ~/projects/my-app
93
+ codex resume <session-id> # or: claude --resume <session-id>
94
+ ```
48
95
 
49
- For the first transfer, choose a destination directory that does not exist. On the laptop:
96
+ **3. Back at the desktop**, bring the work home:
50
97
 
51
98
  ```sh
52
- cd /Users/me/projects/my-app
53
- onthego status
54
- codex resume <session-id>
55
- # Or: claude --resume <session-id>
99
+ onthego sync laptop
56
100
  ```
57
101
 
58
- Use the session ID printed by the handoff. These commands resume a native history, not a running process. See the exact tested CLI versions and validation boundaries in [agent compatibility](docs/agent-compatibility.md).
102
+ > [!TIP]
103
+ > Run every command from the device that can reach the other one. A laptop that can reach a VPS can both send work to it and bring work back, so the VPS never needs to reach the laptop.
104
+
105
+ ## How `sync` decides
106
+
107
+ <p align="center">
108
+ <img src="https://raw.githubusercontent.com/peerproblem/onthego/main/assets/onthego-sync-decision.png" alt="sync pushes when only this side changed, pulls when only the other side changed, and stops when both changed" width="100%">
109
+ </p>
110
+
111
+ `sync` compares both sides with their last handoff and only moves work away from the side that has not changed.
59
112
 
60
- To bring laptop changes back, run this from the desktop project:
113
+ | Situation | `sync` does |
114
+ | :-- | :-- |
115
+ | The project is not on the other device yet | **push** |
116
+ | Only this device changed | **push** |
117
+ | Only the other device changed | **pull** |
118
+ | You handed the work off and have not touched it since | **pull**, to take it back |
119
+ | Nothing changed | nothing |
120
+ | Both sides changed | **stops** and asks you to pick `push --replace` or `pull --replace` |
121
+
122
+ Nothing is merged behind your back. Whenever work is replaced, the previous state is kept as a Git backup that `onthego undo` restores. Preview any decision with `onthego sync laptop --dry-run`, or choose the direction yourself with `push` and `pull`.
123
+
124
+ ## Connect your devices
125
+
126
+ onthego uses your normal SSH setup: `~/.ssh/config`, keys, and `known_hosts`. All it needs is one device that can `ssh` into the other without a password prompt. `onthego doctor <device>` checks the whole chain.
127
+
128
+ ### Same network
61
129
 
62
130
  ```sh
63
- onthego pull laptop --verbose
131
+ # On the laptop: turn on SSH
132
+ # macOS: System Settings > General > Sharing > Remote Login
133
+ # Linux: sudo systemctl enable --now ssh
134
+
135
+ # On the desktop:
136
+ ssh-copy-id me@laptop.local
137
+ onthego device add laptop --host me@laptop.local --install
64
138
  ```
65
139
 
66
- The destination is updated in place. Existing shells, editor watchers, and local dependency directories continue to refer to the same project directory. Stop writers during the transfer so they cannot race with capture or application.
140
+ An alias from `~/.ssh/config` also works (`--host laptop`), as do `--port` and `--identity-file`. Private keys are never copied.
67
141
 
68
- After a successful push, `status` warns that the project and sessions were handed to the other device. Pull before editing or resuming them on the original device.
142
+ ### Anywhere, with Tailscale
69
143
 
70
- ## What moves
144
+ When your devices are on different networks, Tailscale gives each one a stable name and onthego looks it up for you.
145
+
146
+ ```sh
147
+ onthego tailscale # checks Tailscale, lists your devices
148
+ onthego device add laptop --tailscale me@laptop --install
149
+ ```
150
+
151
+ Install Tailscale on each device and sign in with the same account. Each device you pair to still needs SSH turned on (or Tailscale SSH on Linux). onthego only reads `tailscale status` and never changes your settings. See the [Tailscale guide](docs/tailscale.md) for MagicDNS, Tailscale SSH, and troubleshooting.
71
152
 
72
- | Data | Behavior |
73
- | --- | --- |
74
- | Git history | Missing objects travel in a negotiated bundle. GitHub is optional. |
75
- | Staged and unstaged work | Temporary Git trees preserve their distinction, binary content, and executable bits. |
76
- | Untracked project files | Included subject to project exclusions and the secret policy. |
77
- | Ignored files | Include explicitly with `--include` or project policy. |
78
- | Secret candidates such as `.env` | Excluded and reported; eligible files require `--include-secret`. |
79
- | Codex and Claude histories | Recent project sessions by default; path values are remapped without rewriting conversation content. |
80
- | Destination Git configuration and hooks | Preserved in place, together with remotes, reflogs, and existing stashes. |
81
- | Destination caches and local dependencies | Left in place when they are outside the managed file set. |
82
- | Agent logins, global databases, and running processes | Not transferred. Authenticate and run the agent separately on each device. |
153
+ ### A VPS
83
154
 
84
- Native transcripts may contain sensitive prompts or tool output. ONTHEGO preserves them inside an encrypted package for resumability. All tracked Git content and history also travel as recorded, including anything previously committed. Supplemental secret-file rules cannot remove secrets from Git history.
155
+ ```sh
156
+ onthego device add vps --host me@vps.example.com --install
157
+ onthego sync vps
158
+ ```
159
+
160
+ `--install` detects the server's OS and CPU and copies the matching binary to `~/.local/bin/onthego`. The server needs neither Node.js nor internet access. After upgrading locally, `onthego device install vps` brings the server to the same version.
85
161
 
86
- ## Sessions and conflicts
162
+ ### Where the project lands
87
163
 
88
- The default selection is sessions active in the last seven days. Choose a narrower or broader set explicitly:
164
+ By default, the same path relative to your home directory: `~/projects/my-app` on macOS becomes `/home/me/projects/my-app` on Linux, and agent session paths are remapped to match.
89
165
 
90
166
  ```sh
91
- onthego push laptop --session <id>
92
- onthego push laptop --session-days 2
93
- onthego push laptop --all-sessions
94
- onthego pull laptop --no-sessions
95
- onthego pull laptop --session-conflict skip
167
+ onthego device path laptop /Users/me/code/my-app # choose another location
168
+ onthego device list # devices and this project's path on each
96
169
  ```
97
170
 
98
- Malformed completed JSONL lines exclude that session with a warning. An incomplete final line is discarded with a warning. These histories do not stop the workspace handoff. An explicitly requested ID that cannot be found fails before packaging. `--no-sessions` skips session discovery and leaves receiving agent homes untouched.
171
+ The first destination directory should not exist yet. To adopt an existing copy, use `push --replace` once; a Git backup of the destination is kept.
172
+
173
+ ## What moves
174
+
175
+ | | |
176
+ | :-- | :-- |
177
+ | **Git history** | Only the objects the other side is missing. No Git hosting needed. |
178
+ | **Staged and unstaged work** | Kept separate, including binary files and executable bits. |
179
+ | **Untracked files** | Included, subject to `exclude` rules and the secret policy. |
180
+ | **Ignored files** | Only when you add them with `--include` or project policy. |
181
+ | **Agent sessions** | This project's Codex and Claude sessions from the last 7 days. Paths are remapped; content is not rewritten. |
182
+ | **Secrets** such as `.env`, `.npmrc` | Excluded and reported. `--include-secret` carries a file encrypted, outside Git objects. |
183
+ | **Stays on each device** | `node_modules`, caches, build output, Git config, hooks, remotes, stashes, agent logins, and running processes. |
184
+
185
+ Each handoff is one package, encrypted for the receiving device with [age](https://age-encryption.org) and signed by the sender with Ed25519. Pairing pins both identities, so a device whose keys change is rejected.
99
186
 
100
- Identical sessions are skipped. Incoming extensions update an older destination, while a newer destination is kept. Divergent sessions keep the destination and save the incoming history in private `~/.onthego/conflicts/` storage by default. `--session-conflict keep-both`, `--session-conflict theirs`, and `--session-conflict skip` make the policy explicit. Conflict copies remain until you review and remove them. Plaintext staging copies are removed after import. If an adapter cannot write its destination, the workspace still arrives and its authenticated inbound histories are retained in a private `session-recovery-*` directory under ONTHEGO state. The warning prints its location. `status` reports pending recovery. Retry the same package or run `onthego sessions recover --session-conflict keep-both` to import only the saved sessions while preserving subsequent workspace edits. JSON reports `sessions.status: "recovery_needed"` until recovery succeeds. The deprecated `--sessions` alias still works and warns; it only chooses a conflict policy.
187
+ > [!NOTE]
188
+ > Stop agents and other processes that write to the project before a handoff. Agent transcripts can contain sensitive prompts or tool output; they are encrypted in transit and stored as the agent would store them. Anything already committed to Git travels as recorded.
101
189
 
102
- Concurrent workspace edits require a deliberate decision. ONTHEGO checks Git handoff ancestry and the destination's captured workspace state. `--replace` applies incoming managed files after retaining a Git backup; a different project ID is always rejected.
190
+ ## Everyday commands
103
191
 
104
192
  ```sh
105
- onthego backups list
106
- onthego undo
107
- onthego backups prune --keep 3
193
+ onthego status # changed since the last handoff? which device has the work?
194
+ onthego status laptop # the same, for the laptop's copy
195
+ onthego sync laptop --dry-run # show the decision without moving anything
196
+ onthego push laptop --dry-run # preview files and sessions
197
+ onthego push laptop --session-days 2 # or --session <id>, --all-sessions, --no-sessions
198
+ onthego push laptop --include scratch/notes.txt --include-secret .env
108
199
  ```
109
200
 
110
- The newest five Git backups are retained automatically. Explicitly included supplemental secrets stay outside Git objects; their backup contents are encrypted under the private ONTHEGO state directory. Unmanaged `node_modules`, caches, and local environment files are not copied into backups. Undo restores the backed-up managed state and clears the delivery baseline, since restoring old work does not prove that another device has received it. Backup listing, pruning and undo remain available even if `.onthego.yaml` is missing or invalid. Use Git to reconcile intentional concurrent development.
201
+ ### When something goes wrong
202
+
203
+ - **Both devices changed.** `sync`, `push`, and `pull` stop with exit code 6. `--replace` overwrites the other side after saving a Git backup there.
204
+ - **Undo a handoff.** `onthego backups list` shows backups and `onthego undo` restores the latest. The newest five are kept automatically; `onthego backups prune --keep 3` trims them.
205
+ - **Diverged agent session.** The destination keeps its copy and the incoming one is saved under `~/.onthego/conflicts/`. Change this with `--session-conflict keep-both|theirs|skip`.
206
+ - **Sessions could not be written.** The workspace still arrives, the sessions are kept privately, and `status` tells you. Fix the cause and run `onthego sessions recover`.
207
+ - **SSH trouble.** Errors name the problem and the fix: a missing key, an unknown host key, a refused or unreachable host, or onthego missing on the device.
111
208
 
112
- ## Configuration
209
+ ## Reference
113
210
 
114
- Commit the project policy `.onthego.yaml`:
211
+ <details>
212
+ <summary><b>Configuration</b></summary>
213
+ <br>
214
+
215
+ `onthego init` writes `.onthego.yaml`. Commit it so every device shares the same project ID.
115
216
 
116
217
  ```yaml
117
218
  schema_version: 2
@@ -127,92 +228,99 @@ exclude:
127
228
  - build
128
229
  - .cache
129
230
  - __pycache__
130
- agent: auto
231
+ agent: auto # auto, codex, claude, or none (workspace only)
131
232
  ```
132
233
 
133
- `agent` accepts `auto`, `codex`, `claude`, or `none`. `none` performs workspace-only handoffs.
234
+ Paths passed with `--include` or `--include-secret` stay managed in later handoffs, including deletions. Adding a managed file to `exclude` stops sending it and leaves the receiving copy in place with a warning.
235
+
236
+ Private state lives in `~/.onthego` (or `$ONTHEGO_HOME`) with `0700` directories and `0600` files: paired devices in `config.yaml`, keys in `identity/`, and per-project paths under `projects/`. onthego never loads `.env` files.
134
237
 
135
- Personal configuration and pinned identities live in `~/.onthego/config.yaml`. Private ONTHEGO keys live in `~/.onthego/identity/keys.json`. Private directories use mode `0700` and files use `0600`. `ONTHEGO_HOME` optionally selects a different state directory. ONTHEGO never automatically loads `.env` files.
238
+ Shell completion, including device names:
136
239
 
137
240
  ```sh
138
- onthego config path
139
- onthego device list
140
- onthego identity
141
- onthego push laptop --include scratch/notes.txt
142
- onthego push laptop --include-secret .env
241
+ onthego completion zsh > "${fpath[1]}/_onthego" # also: bash, fish
143
242
  ```
144
243
 
145
- Explicitly selected files remain managed across subsequent handoffs, including deletions. Do not opt in credentials that must stay device-local. Adding a managed supplemental file to `exclude` stops future transfer and leaves the receiving copy in place with a warning. Source deletions still propagate. Project exclusions override previously remembered secret selections; explicitly combining an excluded path with `--include-secret` fails.
244
+ </details>
146
245
 
147
- Credential filenames such as `.npmrc` and `.netrc` are excluded from automatic selection. `--include-secret .npmrc` carries an allowed file in the encrypted supplemental payload, outside Git objects. Names such as `tokenizer.ts`, `docs-secret-santa.md`, and `design.key` are ordinary project files, not secret candidates.
246
+ <details>
247
+ <summary><b>Offline handoff</b></summary>
248
+ <br>
148
249
 
149
- ## Portable snapshots
150
-
151
- For removable storage or another delivery channel, create an encrypted `.otg` file:
250
+ Without a network path, hand off through an encrypted file on a USB drive or any other channel.
152
251
 
153
252
  ```sh
154
- onthego snapshot pack --output /tmp/project.otg --recipient age1...
253
+ onthego identity # on the receiving device: prints its public keys
254
+ onthego snapshot pack --output /tmp/my-app.otg --recipient age1...
155
255
 
156
256
  # On the receiving device:
157
- onthego snapshot restore /tmp/project.otg \
158
- --output /path/to/project \
159
- --signing-public <trusted-source-public-key>
257
+ onthego snapshot restore /tmp/my-app.otg --output ~/projects/my-app --signing-public <sender-signing-key>
160
258
  ```
161
259
 
162
- Use the recipient and signing public keys printed by `onthego identity`. Without `--recipient`, packing targets the local device. SSH handoffs resolve both identities from pairing; offline restores require you to authenticate the source signing key.
163
-
164
- Offline exports retain pending receipts for up to 30 days, bounded to 64 per workspace. A returning descendant can acknowledge this lineage without `--replace`. Retrying an already applied snapshot succeeds without overwriting later local edits.
260
+ </details>
165
261
 
166
- ## Commands
262
+ <details>
263
+ <summary><b>All commands</b></summary>
264
+ <br>
167
265
 
168
266
  | Command | Purpose |
169
- | --- | --- |
170
- | `init` | Initialize project policy. |
171
- | `device add/list/remove` | Pair and manage devices. |
172
- | `remote set` | Manage project paths on those devices. |
173
- | `push`, `pull` | Hand off a workspace and selected histories. |
174
- | `status [device]` | Inspect changes and active-device guidance. |
175
- | `inspect` | Preview file selection and excluded secret candidates. |
176
- | `doctor [device]` | Check prerequisites, CLI versions, and optional peer access. |
177
- | `snapshot pack/restore` | Create or receive an offline package. |
178
- | `sessions recover` | Retry saved native histories without changing the workspace. |
179
- | `backups list/prune`, `undo` | Inspect, limit, or restore Git backups. |
180
- | `identity`, `config path`, `version` | Inspect public identity and installation. |
181
-
182
- Text output escapes control characters in filenames and session IDs. Suggested commands for these unusual names use Bash/Zsh quoting. `--json` emits structured results and errors. `--verbose` reports transfer phases on stderr. Dry-run validates local options and previews files plus selected sessions. Its `not_checked` field lists `peer` and `destination_conflict`.
183
-
184
- | Exit status | Public error codes |
185
- | --- | --- |
186
- | 0 | Success, including delivered workspaces with pending session recovery |
267
+ | :-- | :-- |
268
+ | `sync <device>` | Push or pull, whichever brings both devices up to date. |
269
+ | `push <device>`, `pull <device>` | Hand off in an explicit direction. |
270
+ | `status [device]` | Changes since the last handoff, and which device has the work. |
271
+ | `inspect` | Preview selected files, excluded secrets, and sessions. |
272
+ | `init` | Set up the current Git project. |
273
+ | `device add / list / path / install / remove` | Pair devices, map project paths, install or upgrade onthego on them. |
274
+ | `tailscale` | Check Tailscale and list tailnet devices to pair. |
275
+ | `doctor [device]` | Check Git, SSH, Tailscale, agents, and a device connection. |
276
+ | `undo`, `backups list / prune` | Restore or manage workspace backups. |
277
+ | `sessions recover` | Retry an agent session import after a partial handoff. |
278
+ | `snapshot pack / restore` | Offline handoff through an encrypted file. |
279
+ | `identity`, `config path`, `completion`, `version` | Keys, settings location, shell completion, build info. |
280
+
281
+ Every command accepts `--json` for structured output and errors, and `--verbose` for transfer phases on stderr.
282
+
283
+ </details>
284
+
285
+ <details>
286
+ <summary><b>Exit codes</b></summary>
287
+ <br>
288
+
289
+ | Exit | Meaning |
290
+ | :-: | :-- |
291
+ | 0 | Success, including a delivered workspace with pending session recovery |
187
292
  | 1 | `E_INTERNAL` |
188
293
  | 2 | `E_INPUT` |
189
294
  | 3 | `E_PRECONDITION`, `E_UNSUPPORTED_GIT`, `E_SECRET_POLICY`, `E_SESSION_FORMAT` |
190
- | 4 | `E_TARGET_AUTH`, `E_TARGET_UNAVAILABLE` |
295
+ | 4 | `E_TARGET_AUTH`, `E_TARGET_UNAVAILABLE` (SSH login, host key, or reachability) |
191
296
  | 5 | `E_PACKAGE_INVALID`, `E_RESTORE_FAILED` |
192
297
  | 6 | `E_GENERATION_CONFLICT`, `E_SOURCE_CHANGED` |
193
298
  | 130 | `E_CANCELED` |
194
299
 
195
- ## Upgrading to 0.3.1
196
-
197
- Upgrade both devices together. Snapshot schema 3 adds signed `retained_paths` and `payload_sizes`; 0.3.1 reads schema 2 and 3, while older receivers reject schema 3. Peer transfers require the `snapshot-v3` and `session-scope` capabilities. Project policy and handoff receipt schemas remain 2; session recovery uses a separate state file.
300
+ </details>
198
301
 
199
- If you transferred an untracked credential file such as `.npmrc` with 0.3.0 or earlier, rotate its tokens. Those bytes can remain in the source and receiving repositories' Git objects through retained WIP history. This update prevents new automatic capture but does not remove existing objects; Git garbage collection alone does not remove referenced history. See the [0.3.1 release notes](docs/releases/0.3.1.md).
302
+ ## Upgrading
200
303
 
201
- ## Development
304
+ 0.4 keeps the 0.3.1 wire protocol and file formats, so 0.4 and 0.3.1 devices can hand off to each other. Keeping every device on one version is still simplest:
202
305
 
203
306
  ```sh
204
- make check
205
- go test -race ./...
206
- make build
207
- ./scripts/demo.sh
208
- ./scripts/ssh-e2e.sh
209
- make package
307
+ npm update -g @jbaehova/onthego
308
+ onthego device install laptop # repeat for each SSH device
210
309
  ```
211
310
 
212
- The tests and demos isolate project and agent homes. The SSH script uses a real temporary OpenSSH server. See [validation and feedback coverage](docs/progress.md), [architecture](docs/architecture.md), and [migration](docs/migration.md).
311
+ `onthego remote set` still works but is replaced by `onthego device path`. See the [0.4.0 release notes](docs/releases/0.4.0.md) and the [migration notes](docs/migration.md).
312
+
313
+ ## Documentation
314
+
315
+ | | |
316
+ | :-- | :-- |
317
+ | [Tailscale guide](docs/tailscale.md) | Pairing across networks, Tailscale SSH, troubleshooting. |
318
+ | [Agent compatibility](docs/agent-compatibility.md) | Tested Codex and Claude Code versions, and how resume is verified. |
319
+ | [Architecture](docs/architecture.md) | Capture, encryption, in-place application, and receipts. |
320
+ | [Development](docs/development.md) | Tests, demos, end-to-end checks, benchmarks, and releasing. |
213
321
 
214
- This is an explicit handoff tool. Continuous synchronization and user-owned asynchronous storage adapters remain future work.
322
+ Handoffs are explicit on purpose: you always know which device has the work. Continuous background synchronization is out of scope.
215
323
 
216
324
  ## License
217
325
 
218
- [MIT](LICENSE).
326
+ [MIT](LICENSE)
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbaehova/onthego",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Open-source workspace and coding-agent session handoffs between your own devices",
5
5
  "license": "MIT",
6
6
  "repository": {