remote-pi 0.1.3 → 0.2.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.
Files changed (99) hide show
  1. package/README.md +160 -40
  2. package/dist/bin/supervisord.d.ts +2 -0
  3. package/dist/bin/supervisord.js +44 -0
  4. package/dist/bin/supervisord.js.map +1 -0
  5. package/dist/config.d.ts +44 -13
  6. package/dist/config.js +61 -22
  7. package/dist/config.js.map +1 -1
  8. package/dist/daemon/client.d.ts +20 -0
  9. package/dist/daemon/client.js +128 -0
  10. package/dist/daemon/client.js.map +1 -0
  11. package/dist/daemon/control_protocol.d.ts +100 -0
  12. package/dist/daemon/control_protocol.js +63 -0
  13. package/dist/daemon/control_protocol.js.map +1 -0
  14. package/dist/daemon/id.d.ts +18 -0
  15. package/dist/daemon/id.js +30 -0
  16. package/dist/daemon/id.js.map +1 -0
  17. package/dist/daemon/install.d.ts +132 -0
  18. package/dist/daemon/install.js +312 -0
  19. package/dist/daemon/install.js.map +1 -0
  20. package/dist/daemon/registry.d.ts +47 -0
  21. package/dist/daemon/registry.js +123 -0
  22. package/dist/daemon/registry.js.map +1 -0
  23. package/dist/daemon/rpc_child.d.ts +76 -0
  24. package/dist/daemon/rpc_child.js +130 -0
  25. package/dist/daemon/rpc_child.js.map +1 -0
  26. package/dist/daemon/supervisor.d.ts +38 -0
  27. package/dist/daemon/supervisor.js +301 -0
  28. package/dist/daemon/supervisor.js.map +1 -0
  29. package/dist/index.d.ts +62 -8
  30. package/dist/index.js +1231 -303
  31. package/dist/index.js.map +1 -1
  32. package/dist/mesh/canonical.d.ts +30 -0
  33. package/dist/mesh/canonical.js +61 -0
  34. package/dist/mesh/canonical.js.map +1 -0
  35. package/dist/mesh/client.d.ts +31 -0
  36. package/dist/mesh/client.js +56 -0
  37. package/dist/mesh/client.js.map +1 -0
  38. package/dist/mesh/encoding.d.ts +36 -0
  39. package/dist/mesh/encoding.js +53 -0
  40. package/dist/mesh/encoding.js.map +1 -0
  41. package/dist/mesh/self_revoke.d.ts +111 -0
  42. package/dist/mesh/self_revoke.js +182 -0
  43. package/dist/mesh/self_revoke.js.map +1 -0
  44. package/dist/mesh/siblings.d.ts +62 -0
  45. package/dist/mesh/siblings.js +95 -0
  46. package/dist/mesh/siblings.js.map +1 -0
  47. package/dist/mesh/types.d.ts +34 -0
  48. package/dist/mesh/types.js +11 -0
  49. package/dist/mesh/types.js.map +1 -0
  50. package/dist/mesh/verify.d.ts +17 -0
  51. package/dist/mesh/verify.js +77 -0
  52. package/dist/mesh/verify.js.map +1 -0
  53. package/dist/pairing/qr.d.ts +16 -5
  54. package/dist/pairing/qr.js +27 -8
  55. package/dist/pairing/qr.js.map +1 -1
  56. package/dist/pairing/storage.d.ts +41 -0
  57. package/dist/pairing/storage.js +160 -21
  58. package/dist/pairing/storage.js.map +1 -1
  59. package/dist/protocol/types.d.ts +23 -0
  60. package/dist/session/broker.d.ts +74 -0
  61. package/dist/session/broker.js +142 -4
  62. package/dist/session/broker.js.map +1 -1
  63. package/dist/session/broker_remote.d.ts +110 -0
  64. package/dist/session/broker_remote.js +397 -0
  65. package/dist/session/broker_remote.js.map +1 -0
  66. package/dist/session/cwd_lock.d.ts +28 -0
  67. package/dist/session/cwd_lock.js +89 -0
  68. package/dist/session/cwd_lock.js.map +1 -0
  69. package/dist/session/global_config.d.ts +9 -0
  70. package/dist/session/global_config.js +9 -0
  71. package/dist/session/global_config.js.map +1 -1
  72. package/dist/session/leader_election.d.ts +16 -0
  73. package/dist/session/leader_election.js +22 -0
  74. package/dist/session/leader_election.js.map +1 -1
  75. package/dist/session/local_config.d.ts +12 -5
  76. package/dist/session/local_config.js +24 -3
  77. package/dist/session/local_config.js.map +1 -1
  78. package/dist/session/peer.d.ts +28 -1
  79. package/dist/session/peer.js +69 -2
  80. package/dist/session/peer.js.map +1 -1
  81. package/dist/session/peer_inventory.d.ts +13 -0
  82. package/dist/session/peer_inventory.js +48 -0
  83. package/dist/session/peer_inventory.js.map +1 -0
  84. package/dist/session/setup_wizard.d.ts +32 -8
  85. package/dist/session/setup_wizard.js +45 -33
  86. package/dist/session/setup_wizard.js.map +1 -1
  87. package/dist/session/tools.d.ts +15 -7
  88. package/dist/session/tools.js +139 -31
  89. package/dist/session/tools.js.map +1 -1
  90. package/dist/transport/pi_forward_client.d.ts +29 -0
  91. package/dist/transport/pi_forward_client.js +62 -0
  92. package/dist/transport/pi_forward_client.js.map +1 -0
  93. package/dist/ui/footer.js +8 -6
  94. package/dist/ui/footer.js.map +1 -1
  95. package/docs/daemon.md +289 -0
  96. package/package.json +8 -2
  97. package/service-templates/launchd.plist.template +35 -0
  98. package/service-templates/systemd.service.template +19 -0
  99. package/skills/agent-network/SKILL.md +273 -294
package/docs/daemon.md ADDED
@@ -0,0 +1,289 @@
1
+ # Daemon mode — troubleshooting
2
+
3
+ Companion to the README's [Daemon mode](../README.md#daemon-mode) section.
4
+ Each scenario starts with the symptom you'd actually observe, followed by
5
+ likely causes and how to fix.
6
+
7
+ ---
8
+
9
+ ## 1. `remote-pi install` fails
10
+
11
+ ### "supervisor script not found"
12
+
13
+ ```
14
+ [remote-pi] install failed: Error: supervisor script not found at
15
+ /Users/x/dist/bin/supervisord.js. Run `pnpm build` (dev) or
16
+ `npm install -g remote-pi` (prod) first.
17
+ ```
18
+
19
+ You're running `remote-pi install` from a dev clone where `dist/` doesn't
20
+ exist yet, or from a partial install.
21
+
22
+ ```bash
23
+ # Dev clone:
24
+ cd pi-extension && pnpm build
25
+
26
+ # Production install:
27
+ npm install -g remote-pi # or pnpm install -g remote-pi
28
+ which pi-supervisord # confirm bin is on PATH
29
+ remote-pi install
30
+ ```
31
+
32
+ ### "launchctl: bootstrap … already running"
33
+
34
+ A previous install left a stale entry. The fix is built into `install` —
35
+ re-run it and the supervisor unloads the old entry before bootstrapping
36
+ the new one. If it still fails:
37
+
38
+ ```bash
39
+ launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/dev.remotepi.supervisord.plist
40
+ launchctl unload ~/Library/LaunchAgents/dev.remotepi.supervisord.plist 2>/dev/null
41
+ rm ~/Library/LaunchAgents/dev.remotepi.supervisord.plist
42
+ remote-pi install
43
+ ```
44
+
45
+ ### "systemctl --user … No such file or directory"
46
+
47
+ Linux without a logged-in graphical session (headless server). On most
48
+ distros `systemctl --user` requires `loginctl enable-linger <user>` so
49
+ the unit survives logout:
50
+
51
+ ```bash
52
+ loginctl enable-linger $USER
53
+ systemctl --user daemon-reload
54
+ remote-pi install
55
+ ```
56
+
57
+ ---
58
+
59
+ ## 2. Supervisor doesn't start at login
60
+
61
+ ### Check the service status
62
+
63
+ ```bash
64
+ # Linux
65
+ systemctl --user status remote-pi-supervisord
66
+ journalctl --user -u remote-pi-supervisord -n 50
67
+
68
+ # macOS
69
+ launchctl list | grep remotepi
70
+ tail -100 ~/.pi/remote/supervisord.log
71
+ ```
72
+
73
+ ### Common failures
74
+
75
+ - **`pi: command not found`** in the log — Pi's binary isn't on the
76
+ PATH that the unit inherited. `remote-pi install` captures
77
+ `process.env.PATH` at install time; if you installed Pi *after*
78
+ running install, re-run `remote-pi install` to refresh.
79
+ - **`Cannot find module …`** — the path baked into the unit doesn't
80
+ match where `dist/bin/supervisord.js` actually lives. Happens if you
81
+ uninstalled then reinstalled the package to a different location.
82
+ Fix: `remote-pi uninstall && remote-pi install`.
83
+ - **Permission denied on UDS** — `~/.pi/remote/` exists with wrong
84
+ perms (rare; only happens if you ran `pi` as `sudo` once). Delete
85
+ the dir and let it re-create: `rm -rf ~/.pi/remote && remote-pi install`.
86
+
87
+ ### Run the supervisor in the foreground for debugging
88
+
89
+ Bypass systemd/launchd and run it directly so you can see startup
90
+ errors live:
91
+
92
+ ```bash
93
+ pi-supervisord
94
+ # or: node /path/to/remote-pi/dist/bin/supervisord.js
95
+ ```
96
+
97
+ Ctrl-C to stop. If that works but the service doesn't, the problem is
98
+ in the unit/plist environment (PATH, HOME) — re-run `remote-pi install`.
99
+
100
+ ---
101
+
102
+ ## 3. A specific daemon stays `crashed`
103
+
104
+ `remote-pi daemon status` shows one row with `state=crashed` and a
105
+ restart count near 4 (the supervisor gives up after exponential
106
+ backoff: 1s, 5s, 30s, 5min).
107
+
108
+ ### Step 1 — read the daemon's stderr
109
+
110
+ The supervisor forwards each daemon's stderr with a `[<cwd>]` prefix:
111
+
112
+ ```bash
113
+ # Linux
114
+ journalctl --user -u remote-pi-supervisord -f | grep '\[/Users/x/Movies\]'
115
+
116
+ # macOS
117
+ tail -f ~/.pi/remote/supervisord.log | grep '\[/Users/x/Movies\]'
118
+ ```
119
+
120
+ ### Step 2 — run that daemon manually
121
+
122
+ Reproduce the failure with full visibility:
123
+
124
+ ```bash
125
+ cd /Users/x/Movies
126
+ REMOTE_PI_DAEMON=1 pi --mode rpc -e $(npm root -g)/remote-pi/dist/index.js
127
+ ```
128
+
129
+ Common reasons a daemon won't start:
130
+
131
+ - **Local config missing.** `cd` into the daemon's folder and check
132
+ `.pi/remote-pi/config.json` exists with `auto_start_relay: true`.
133
+ Recreate via `remote-pi create <cwd>` (it provisions a default config
134
+ when missing).
135
+ - **Pi extension config drift.** Pi's own settings (model, API keys)
136
+ reset → daemon fails to authenticate to the provider. Run
137
+ `cd <cwd> && pi` interactively to fix.
138
+ - **Port/UDS collision.** Another Pi process is already running in
139
+ that cwd. The cwd-lock should reject the second one, but stale UDS
140
+ sockets sometimes linger; check `lsof ~/.pi/remote/locks/<roomId>.sock`.
141
+
142
+ ### Step 3 — force a re-spawn
143
+
144
+ After fixing the underlying problem, kick the supervisor:
145
+
146
+ ```bash
147
+ remote-pi daemon restart # bounces every daemon
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 4. `daemon send` says "daemon not running"
153
+
154
+ The supervisor has the registry entry but no live child for that id.
155
+ Most common cause: the daemon never started OR it crashed past the
156
+ retry budget.
157
+
158
+ ```bash
159
+ remote-pi daemon status # is state running?
160
+ remote-pi daemon start # spawn any that aren't running
161
+ # Then retry send.
162
+ ```
163
+
164
+ If `daemon start` shows `started=0, already_running=N`, the supervisor
165
+ isn't actually spawning. Possible reasons:
166
+ - Registry empty: `remote-pi daemons` to verify.
167
+ - Child crashes faster than the status check: `daemon status` immediately
168
+ after start may still show `running` for a few seconds before the
169
+ exit event marks it crashed. Re-check 2-3 seconds later.
170
+
171
+ ---
172
+
173
+ ## 5. Mobile app doesn't connect to a daemon
174
+
175
+ The daemon is up but the app doesn't see it.
176
+
177
+ ### Confirm the daemon is paired
178
+
179
+ `pair_request` must have happened **before** the folder became a daemon
180
+ (daemons don't show QRs themselves):
181
+
182
+ ```bash
183
+ cd <daemon-cwd>
184
+ pi
185
+ > /remote-pi devices # confirm the device is listed
186
+ > /remote-pi stop # stop interactive session — daemon takes over
187
+ remote-pi daemon restart
188
+ ```
189
+
190
+ ### Confirm the relay URL matches
191
+
192
+ The daemon uses the cwd's local config (`<cwd>/.pi/remote-pi/config.json`
193
+ agent_name + `~/.pi/remote/config.json` relay). Verify with:
194
+
195
+ ```bash
196
+ cd <daemon-cwd>
197
+ pi
198
+ > /remote-pi status
199
+ ```
200
+
201
+ The relay line should match what the mobile app is connecting to. If
202
+ not, update the relay URL and bounce the daemon:
203
+
204
+ ```bash
205
+ remote-pi set-relay https://relay.example.tld
206
+ remote-pi daemon restart
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 6. Registry corrupted / partial
212
+
213
+ Symptom: `remote-pi daemons` errors out or shows nothing despite
214
+ having created entries.
215
+
216
+ ```bash
217
+ cat ~/.pi/remote/daemons.json # inspect
218
+ ```
219
+
220
+ The file should be:
221
+
222
+ ```json
223
+ {
224
+ "daemons": [
225
+ { "cwd": "/Users/x/Movies" },
226
+ { "cwd": "/Users/x/Projects/backend" }
227
+ ]
228
+ }
229
+ ```
230
+
231
+ Fix manually if needed (it's a JSON list of `{cwd}` entries), or wipe
232
+ and re-create:
233
+
234
+ ```bash
235
+ rm ~/.pi/remote/daemons.json
236
+ remote-pi create ~/Movies --name "Video Editor"
237
+ remote-pi create ~/Projects/backend --name "Backend"
238
+ remote-pi daemon restart
239
+ ```
240
+
241
+ ---
242
+
243
+ ## 7. Uninstall cleanly + re-install from scratch
244
+
245
+ When you suspect everything is misconfigured:
246
+
247
+ ```bash
248
+ remote-pi uninstall # removes service, keeps registry
249
+ rm -rf ~/.pi/remote # nukes registry + paired devices + keys
250
+ npm uninstall -g remote-pi
251
+ npm install -g remote-pi
252
+ remote-pi install
253
+ # Then re-pair + re-create daemons from scratch.
254
+ ```
255
+
256
+ This is the "nuke everything" path. After this, the only state left is
257
+ each cwd's `<cwd>/.pi/remote-pi/config.json` — which you can either
258
+ keep (re-create restores the daemon) or delete (full reset).
259
+
260
+ ---
261
+
262
+ ## 8. Diagnostic commands cheat-sheet
263
+
264
+ ```bash
265
+ # Where is the supervisor's UDS?
266
+ ls -la ~/.pi/remote/supervisor.sock
267
+
268
+ # Talk to the supervisor manually (raw JSONL):
269
+ echo '{"op":"list"}' | nc -U ~/.pi/remote/supervisor.sock
270
+
271
+ # Where are the daemon configs?
272
+ find ~/Projects -name "config.json" -path "*/.pi/remote-pi/*" 2>/dev/null
273
+
274
+ # Where are the cwd locks?
275
+ ls ~/.pi/remote/locks/
276
+
277
+ # Where are the paired devices?
278
+ cat ~/.pi/remote/peers.json
279
+
280
+ # What Pi binary is the supervisor about to spawn?
281
+ remote-pi install --dry-run # (not implemented; check ~/Library/LaunchAgents or systemd unit manually)
282
+
283
+ # Quick liveness check
284
+ remote-pi daemon status
285
+ ```
286
+
287
+ If after walking the list you're still stuck, file an issue with the
288
+ output of `remote-pi daemon status`, the recent supervisor log, and
289
+ the contents of `~/.pi/remote/daemons.json`.
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "remote-pi",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "Mobile remote control and local agent mesh for the Pi coding agent. Pair your phone via QR over a relay, watch tool calls in real time, run multi-Pi sessions over a local Unix Domain Socket broker, and let agents talk to each other through structured request/reply.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "remote-pi": "dist/index.js",
10
+ "pi-supervisord": "dist/bin/supervisord.js"
11
+ },
8
12
  "scripts": {
9
13
  "build": "tsc",
10
14
  "typecheck": "tsc --noEmit",
@@ -47,6 +51,8 @@
47
51
  "files": [
48
52
  "dist",
49
53
  "skills",
54
+ "service-templates",
55
+ "docs",
50
56
  "README.md",
51
57
  "LICENSE"
52
58
  ],
@@ -70,8 +76,8 @@
70
76
  },
71
77
  "dependencies": {
72
78
  "@mariozechner/pi-coding-agent": "^0.73.1",
79
+ "@napi-rs/keyring": "^1.3.0",
73
80
  "@noble/ed25519": "^3.1.0",
74
- "keytar": "^7.9.0",
75
81
  "qrcode-terminal": "^0.12.0",
76
82
  "typebox": "^1.1.38",
77
83
  "ws": "^8.20.1"
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <!-- Remote Pi daemon supervisor (plan/26). Generated by `remote-pi install`. -->
4
+ <plist version="1.0">
5
+ <dict>
6
+ <key>Label</key>
7
+ <string>dev.remotepi.supervisord</string>
8
+
9
+ <key>ProgramArguments</key>
10
+ <array>
11
+ <string>{NODE}</string>
12
+ <string>{SUPERVISOR}</string>
13
+ </array>
14
+
15
+ <key>RunAtLoad</key>
16
+ <true/>
17
+ <key>KeepAlive</key>
18
+ <true/>
19
+
20
+ <key>StandardOutPath</key>
21
+ <string>{HOME}/.pi/remote/supervisord.log</string>
22
+ <key>StandardErrorPath</key>
23
+ <string>{HOME}/.pi/remote/supervisord.log</string>
24
+
25
+ <key>EnvironmentVariables</key>
26
+ <dict>
27
+ <!-- Inherit the user's shell PATH so `pi --mode rpc` resolves to the
28
+ same binary it would in Terminal.app (Homebrew / npm-global / etc.). -->
29
+ <key>PATH</key>
30
+ <string>{PATH}</string>
31
+ <key>HOME</key>
32
+ <string>{HOME}</string>
33
+ </dict>
34
+ </dict>
35
+ </plist>
@@ -0,0 +1,19 @@
1
+ [Unit]
2
+ Description=Remote Pi daemon supervisor (plan/26)
3
+ Documentation=https://remote-pi.jacobmoura.work
4
+ After=default.target
5
+
6
+ [Service]
7
+ Type=simple
8
+ ExecStart={NODE} {SUPERVISOR}
9
+ Restart=on-failure
10
+ RestartSec=5s
11
+ StandardOutput=journal
12
+ StandardError=journal
13
+ # Inherit the user's shell PATH so `pi --mode rpc` resolves to the same
14
+ # binary it would in an interactive shell (npm-global / Homebrew / etc.).
15
+ Environment="PATH={PATH}"
16
+ Environment="HOME={HOME}"
17
+
18
+ [Install]
19
+ WantedBy=default.target