@yefengr/remote-pi 0.7.16 → 0.9.0
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 +44 -95
- package/dist/actions/handlers.js +1 -1
- package/dist/actions/handlers.js.map +1 -1
- package/dist/actions/registry.d.ts +1 -1
- package/dist/actions/registry.js +1 -1
- package/dist/{daemon/commands.d.ts → commands.d.ts} +3 -4
- package/dist/{daemon/commands.js → commands.js} +8 -151
- package/dist/commands.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +20 -38
- package/dist/index.js.map +1 -1
- package/dist/pairing/storage.js +4 -4
- package/dist/pairing/storage.js.map +1 -1
- package/dist/protocol/v2/schemas.d.ts +64 -7
- package/dist/protocol/v2/schemas.js +6 -3
- package/dist/protocol/v2/schemas.js.map +1 -1
- package/dist/session/local_config.d.ts +0 -5
- package/dist/session/local_config.js +6 -29
- package/dist/session/local_config.js.map +1 -1
- package/dist/timeline/history.d.ts +3 -6
- package/dist/timeline/history.js +113 -249
- package/dist/timeline/history.js.map +1 -1
- package/dist/timeline/runtime.js +29 -37
- package/dist/timeline/runtime.js.map +1 -1
- package/dist/timeline/sequence.d.ts +7 -0
- package/dist/timeline/sequence.js +16 -0
- package/dist/timeline/sequence.js.map +1 -0
- package/dist/timeline/v2_service.js +3 -1
- package/dist/timeline/v2_service.js.map +1 -1
- package/dist/transport/relay_client.js.map +1 -1
- package/package.json +1 -8
- package/dist/bin/supervisord.d.ts +0 -2
- package/dist/bin/supervisord.js +0 -78
- package/dist/bin/supervisord.js.map +0 -1
- package/dist/daemon/cli-links.d.ts +0 -30
- package/dist/daemon/cli-links.js +0 -134
- package/dist/daemon/cli-links.js.map +0 -1
- package/dist/daemon/client.d.ts +0 -20
- package/dist/daemon/client.js +0 -131
- package/dist/daemon/client.js.map +0 -1
- package/dist/daemon/commands.js.map +0 -1
- package/dist/daemon/control_protocol.d.ts +0 -198
- package/dist/daemon/control_protocol.js +0 -40
- package/dist/daemon/control_protocol.js.map +0 -1
- package/dist/daemon/cron_log.d.ts +0 -24
- package/dist/daemon/cron_log.js +0 -57
- package/dist/daemon/cron_log.js.map +0 -1
- package/dist/daemon/cron_registry.d.ts +0 -43
- package/dist/daemon/cron_registry.js +0 -149
- package/dist/daemon/cron_registry.js.map +0 -1
- package/dist/daemon/install-runtime.d.ts +0 -10
- package/dist/daemon/install-runtime.js +0 -81
- package/dist/daemon/install-runtime.js.map +0 -1
- package/dist/daemon/install.d.ts +0 -110
- package/dist/daemon/install.js +0 -263
- package/dist/daemon/install.js.map +0 -1
- package/dist/daemon/registry.d.ts +0 -51
- package/dist/daemon/registry.js +0 -207
- package/dist/daemon/registry.js.map +0 -1
- package/dist/daemon/rpc_child.d.ts +0 -135
- package/dist/daemon/rpc_child.js +0 -472
- package/dist/daemon/rpc_child.js.map +0 -1
- package/dist/daemon/status.d.ts +0 -45
- package/dist/daemon/status.js +0 -87
- package/dist/daemon/status.js.map +0 -1
- package/dist/daemon/supervisor-ipc.d.ts +0 -2
- package/dist/daemon/supervisor-ipc.js +0 -20
- package/dist/daemon/supervisor-ipc.js.map +0 -1
- package/dist/daemon/supervisor.d.ts +0 -70
- package/dist/daemon/supervisor.js +0 -637
- package/dist/daemon/supervisor.js.map +0 -1
- package/dist/session/ipc.d.ts +0 -6
- package/dist/session/ipc.js +0 -15
- package/dist/session/ipc.js.map +0 -1
- package/docs/daemon.md +0 -175
- package/service-templates/launchd.plist.template +0 -35
- package/service-templates/systemd.service.template +0 -19
- package/service-templates/task-launcher.vbs.template +0 -10
- package/service-templates/task-scheduler.xml.template +0 -38
package/README.md
CHANGED
|
@@ -4,69 +4,57 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Remote Pi</h1>
|
|
6
6
|
|
|
7
|
-
> A Pi
|
|
7
|
+
> A Pi Extension for controlling the current Pi process from the browser through a Relay.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`/remote-pi` connects the current Pi endpoint to a Relay and provides pairing for the Remote Pi PWA. The browser selects endpoint cards, sends prompts, receives a live timeline, and can request a small set of typed session actions.
|
|
9
|
+
`/remote-pi` connects the current Pi process to a Relay, supports Owner pairing, and exposes the live timeline plus typed session actions to the Remote Pi PWA.
|
|
12
10
|
|
|
13
11
|
## Endpoint model
|
|
14
12
|
|
|
15
|
-
Remote Pi addresses process state as:
|
|
16
|
-
|
|
17
13
|
```text
|
|
18
|
-
device
|
|
14
|
+
device -> endpoint -> runtime -> session / history generation
|
|
19
15
|
```
|
|
20
16
|
|
|
21
|
-
- **Device**:
|
|
22
|
-
- **Endpoint**: a
|
|
23
|
-
- **
|
|
24
|
-
- **Session / generation**: the currently live Pi conversation and its history branch. The PWA does not list or resume historical Pi sessions.
|
|
17
|
+
- **Device**: the computer's Ed25519 identity.
|
|
18
|
+
- **Endpoint and runtime**: generated randomly when a Pi process loads the Extension. They remain stable across Extension reloads in that process and are regenerated for the next Pi process.
|
|
19
|
+
- **Session / generation**: the active Pi conversation and its current history branch. Remote Pi does not list or resume historical sessions.
|
|
25
20
|
|
|
26
|
-
The
|
|
21
|
+
The endpoint never derives from the working directory. Pairing QR codes target the current endpoint and runtime, while the resulting Owner authorization is stored at device scope. Later Pi processes on that computer are discovered without pairing again.
|
|
27
22
|
|
|
28
23
|
## Quick start
|
|
29
24
|
|
|
30
|
-
Install
|
|
25
|
+
Install the Extension once:
|
|
31
26
|
|
|
32
27
|
```bash
|
|
33
28
|
pi install npm:@yefengr/remote-pi
|
|
34
29
|
```
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
Open Pi in the project you want to control. When the session starts, the Extension automatically connects to the configured Relay. Pair the browser device from Pi:
|
|
37
32
|
|
|
38
33
|
```text
|
|
39
|
-
/remote-pi
|
|
40
34
|
/remote-pi pair
|
|
41
35
|
```
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Pairings are local to the computer that creates them:
|
|
37
|
+
Scan the code in the [Remote Pi PWA](https://remote-pi.jacobmoura.work/app), select the endpoint card, and send a prompt. Pairings are local to the computer that creates them:
|
|
46
38
|
|
|
47
39
|
```text
|
|
48
40
|
/remote-pi devices
|
|
49
41
|
/remote-pi revoke <shortid>
|
|
50
42
|
```
|
|
51
43
|
|
|
52
|
-
##
|
|
53
|
-
|
|
54
|
-
The PWA supports normal chat plus typed actions that Pi can apply directly:
|
|
44
|
+
## Commands
|
|
55
45
|
|
|
56
|
-
|
|
|
46
|
+
| Command | Description |
|
|
57
47
|
|---|---|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
| `/remote-pi` | Connect the current Pi endpoint after it was stopped |
|
|
49
|
+
| `/remote-pi start` / `/remote-pi stop` | Connect or disconnect this endpoint |
|
|
50
|
+
| `/remote-pi status` | Show Relay, endpoint, runtime, and Owner state |
|
|
51
|
+
| `/remote-pi pair` | Show an endpoint-aware pairing QR |
|
|
52
|
+
| `/remote-pi devices` | List locally paired Owners |
|
|
53
|
+
| `/remote-pi revoke <shortid>` | Revoke one locally stored Owner |
|
|
54
|
+
| `/remote-pi set-relay <url>` | Persist the Relay URL |
|
|
55
|
+
| `/remote-pi config` | Show the resolved Relay URL |
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
pi install npm:@eko24ive/pi-ask
|
|
69
|
-
```
|
|
57
|
+
The Extension handles remote `session_new` requests in-process through Pi's session API. There is no standalone `remote-pi` CLI, background process, scheduler, or service installation command.
|
|
70
58
|
|
|
71
59
|
## Relay configuration
|
|
72
60
|
|
|
@@ -83,75 +71,36 @@ Set and inspect it from Pi:
|
|
|
83
71
|
/remote-pi config
|
|
84
72
|
```
|
|
85
73
|
|
|
86
|
-
Only `http://` and `https://` are accepted at the command boundary; WebSocket conversion happens
|
|
87
|
-
|
|
88
|
-
## Commands
|
|
89
|
-
|
|
90
|
-
| Command | Description |
|
|
91
|
-
|---|---|
|
|
92
|
-
| `/remote-pi` | Connect the current endpoint; first use creates local configuration |
|
|
93
|
-
| `/remote-pi start` / `/remote-pi stop` | Connect or disconnect this endpoint |
|
|
94
|
-
| `/remote-pi status` | Show Relay, endpoint, and runtime state |
|
|
95
|
-
| `/remote-pi pair` | Show an endpoint- and runtime-aware pairing QR |
|
|
96
|
-
| `/remote-pi devices` | List pairings stored on this computer |
|
|
97
|
-
| `/remote-pi revoke <shortid>` | Revoke one locally stored pairing |
|
|
98
|
-
| `/remote-pi set-relay <url>` | Persist the Relay URL |
|
|
99
|
-
| `/remote-pi config` | Show the resolved Relay URL |
|
|
100
|
-
| `/remote-pi create <cwd>` | Explicitly register a daemon with desired state `running` |
|
|
101
|
-
| `/remote-pi remove <id>` | Unregister a daemon by identifier |
|
|
102
|
-
| `/remote-pi remove-cwd <cwd>` | Idempotently unregister a daemon by working directory |
|
|
103
|
-
| `/remote-pi daemons` | List registered daemons |
|
|
104
|
-
| `/remote-pi daemon start\|stop\|restart [id]` | Change the desired lifecycle for one daemon or the fleet |
|
|
105
|
-
| `/remote-pi daemon status` | Show orthogonal daemon lifecycle state |
|
|
106
|
-
| `/remote-pi install` / `/remote-pi uninstall` | Install or remove the user-level supervisor service |
|
|
107
|
-
|
|
108
|
-
The global `remote-pi` CLI exposes the same lifecycle commands after installation. The cwd-based removal command is intended for external worktree managers as well as manual cleanup.
|
|
109
|
-
|
|
110
|
-
## Daemon mode
|
|
111
|
-
|
|
112
|
-
Daemon mode is an explicit opt-in:
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
npm install -g @yefengr/remote-pi
|
|
116
|
-
remote-pi install
|
|
117
|
-
remote-pi create ~/Projects/backend
|
|
118
|
-
remote-pi daemon status
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
The v2 registry at `~/.pi/remote/daemons.json` stores an opaque daemon identifier, canonical cwd, display name, creation time, and desired lifecycle (`running` or `stopped`). Registration starts in `running`; a live supervisor starts it immediately. On supervisor startup, only registrations whose desired lifecycle is `running` are restored.
|
|
122
|
-
|
|
123
|
-
The supervisor starts Pi in RPC mode without an extra extension argument. Pi's own settings determine extension loading and model/provider configuration. A daemon runtime inherits its registered endpoint identity, while every spawn receives a fresh runtime identity.
|
|
124
|
-
|
|
125
|
-
### Lifecycle and health
|
|
74
|
+
Only `http://` and `https://` are accepted at the command boundary; WebSocket conversion happens inside the Extension. The Relay forwards opaque payloads and retains endpoint routing state in memory.
|
|
126
75
|
|
|
127
|
-
|
|
76
|
+
## Pairing and security
|
|
128
77
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
| runtime | RPC pending, ready, or failed |
|
|
135
|
-
| relay | Disconnected, connecting, connected, or reconnecting |
|
|
136
|
-
| health | Stopped, starting, healthy, degraded, failed, or blocked |
|
|
137
|
-
|
|
138
|
-
A ready daemon reconnecting to the Relay is **degraded**, not restarted. Non-retryable configuration and startup failures become deterministic **blocked** errors. If a cwd disappears, dispatch is denied immediately and the supervisor reconciles the stale registration after confirmation.
|
|
78
|
+
- `device_id` is the Host Ed25519 public key in canonical Base64 form.
|
|
79
|
+
- Owner messages are trusted only through the Relay-injected `source_owner_id`.
|
|
80
|
+
- Pairing and revocation update the Relay endpoint ACL with `authorized_owner_ids`.
|
|
81
|
+
- Relay loss enters reconnecting state; the Extension does not restart Pi to recover.
|
|
82
|
+
- Device private keys, pairing tokens, encrypted payloads, and message bodies are not logged.
|
|
139
83
|
|
|
140
|
-
|
|
84
|
+
## Migration from older releases
|
|
141
85
|
|
|
142
|
-
|
|
86
|
+
Older releases could have installed a standalone command and a per-user supervisor. This package does not start, stop, alter, or uninstall those leftovers. After confirming they belong to an older Remote Pi installation, remove them manually:
|
|
143
87
|
|
|
144
88
|
```bash
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
89
|
+
# macOS
|
|
90
|
+
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/dev.remotepi.supervisord.plist" 2>/dev/null || launchctl unload "$HOME/Library/LaunchAgents/dev.remotepi.supervisord.plist"
|
|
91
|
+
rm -f "$HOME/Library/LaunchAgents/dev.remotepi.supervisord.plist"
|
|
92
|
+
|
|
93
|
+
# Linux
|
|
94
|
+
systemctl --user disable --now remote-pi-supervisord.service
|
|
95
|
+
rm -f "$HOME/.config/systemd/user/remote-pi-supervisord.service"
|
|
96
|
+
systemctl --user daemon-reload
|
|
97
|
+
|
|
98
|
+
# Windows PowerShell or Command Prompt
|
|
99
|
+
schtasks /End /TN RemotePiSupervisor
|
|
100
|
+
schtasks /Delete /TN RemotePiSupervisor /F
|
|
148
101
|
```
|
|
149
102
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
## Troubleshooting
|
|
153
|
-
|
|
154
|
-
For daemon service installation, status interpretation, stale cwd cleanup, and recovery steps, see [`docs/daemon.md`](./docs/daemon.md).
|
|
103
|
+
Do not remove `~/.pi/remote/identity.json` or `peers.json`: they retain the existing device identity and pairings.
|
|
155
104
|
|
|
156
105
|
## Development
|
|
157
106
|
|
|
@@ -162,7 +111,7 @@ pnpm test
|
|
|
162
111
|
pnpm build
|
|
163
112
|
```
|
|
164
113
|
|
|
165
|
-
Node 20+ and TypeScript ESM are required.
|
|
114
|
+
Node 20+ and TypeScript ESM are required. TypeScript imports must use `.js` extensions.
|
|
166
115
|
|
|
167
116
|
## License
|
|
168
117
|
|
package/dist/actions/handlers.js
CHANGED
|
@@ -124,7 +124,7 @@ export async function handleModelSet(pi, ctx, reg, sender, msg, onPersist) {
|
|
|
124
124
|
throw new Error("no auth configured for this model");
|
|
125
125
|
// `pi.setModel` only sets the LIVE model — it does NOT persist. Without
|
|
126
126
|
// this, a model picked from the app reverts to the saved default on the
|
|
127
|
-
// next Pi
|
|
127
|
+
// next Pi restart (the TUI persists because AgentSession.setModel
|
|
128
128
|
// writes the default; this path doesn't). `onPersist` writes the new
|
|
129
129
|
// default so the app's choice survives. Best-effort — the caller's writer
|
|
130
130
|
// must not throw, so a failed settings write never fails the model change.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/actions/handlers.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/actions/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* 1. A ctx captured before a session replacement/reload is **stale**, and even
|
|
20
20
|
* *reading* `.modelRegistry` on it throws (`assertActive`). Every read is
|
|
21
21
|
* wrapped.
|
|
22
|
-
* 2. There may be no live ctx at all
|
|
22
|
+
* 2. There may be no live ctx at all while an Extension callback runs. Rather
|
|
23
23
|
* than throw from a WS callback — an uncaught exception that exits pi — we
|
|
24
24
|
* fall back to the last registry that worked, then to a stub whose methods
|
|
25
25
|
* never throw and report an empty catalog.
|
package/dist/actions/registry.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* 1. A ctx captured before a session replacement/reload is **stale**, and even
|
|
20
20
|
* *reading* `.modelRegistry` on it throws (`assertActive`). Every read is
|
|
21
21
|
* wrapped.
|
|
22
|
-
* 2. There may be no live ctx at all
|
|
22
|
+
* 2. There may be no live ctx at all while an Extension callback runs. Rather
|
|
23
23
|
* than throw from a WS callback — an uncaught exception that exits pi — we
|
|
24
24
|
* fall back to the last registry that worked, then to a stub whose methods
|
|
25
25
|
* never throw and report an empty catalog.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { type Ed25519Keypair } from "
|
|
3
|
-
import type { InitialRelayResult } from "
|
|
4
|
-
export type { InitialRelayResult } from "
|
|
2
|
+
import { type Ed25519Keypair } from "./pairing/crypto.js";
|
|
3
|
+
import type { InitialRelayResult } from "./runtime/relay_lifecycle.js";
|
|
4
|
+
export type { InitialRelayResult } from "./runtime/relay_lifecycle.js";
|
|
5
5
|
type CommandStartContext = Pick<ExtensionContext, "ui" | "cwd">;
|
|
6
6
|
export interface RemoteCommandDependencies {
|
|
7
7
|
start(ctx: CommandStartContext): Promise<InitialRelayResult>;
|
|
@@ -27,4 +27,3 @@ export interface RemoteCommandDependencies {
|
|
|
27
27
|
}
|
|
28
28
|
export declare function persistModelDefault(provider: string, modelId: string): void;
|
|
29
29
|
export declare function registerCommands(pi: ExtensionAPI, deps: RemoteCommandDependencies): void;
|
|
30
|
-
export declare function runDirectCli(deps: RemoteCommandDependencies, directRun: boolean): void;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
1
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
2
|
import { dirname, join } from "node:path";
|
|
4
|
-
import { canonicalizeEd25519PublicKey } from "
|
|
5
|
-
import { clampPairTtlMs, qrSession, renderQRAscii, PAIRING_INVITE_TTL_MS } from "
|
|
6
|
-
import { listPeers, removePeer } from "
|
|
7
|
-
import { isValidRelayUrl, isWebSocketScheme, resolveRelayUrl, saveConfig } from "
|
|
8
|
-
import { addDaemon, findDaemonByCwd, listDaemons, removeDaemon } from "./registry.js";
|
|
9
|
-
import { callSupervisor, supervisorOnline, SupervisorOfflineError } from "./client.js";
|
|
10
|
-
import { installService, uninstallService, linkCliBinaries, unlinkCliBinaries, LAUNCHD_LABEL, SYSTEMD_UNIT, } from "./install.js";
|
|
3
|
+
import { canonicalizeEd25519PublicKey } from "./pairing/crypto.js";
|
|
4
|
+
import { clampPairTtlMs, qrSession, renderQRAscii, PAIRING_INVITE_TTL_MS } from "./pairing/qr.js";
|
|
5
|
+
import { listPeers, removePeer } from "./pairing/storage.js";
|
|
6
|
+
import { isValidRelayUrl, isWebSocketScheme, resolveRelayUrl, saveConfig } from "./config.js";
|
|
11
7
|
const PAIR_WIDGET_KEY = "remote-pi-pair-code";
|
|
12
8
|
function notify(ctx, text, kind = "info") {
|
|
13
9
|
try {
|
|
14
10
|
ctx.ui.notify(text, kind);
|
|
15
11
|
}
|
|
16
|
-
catch { /* headless
|
|
12
|
+
catch { /* headless or stale context */ }
|
|
17
13
|
}
|
|
18
14
|
async function pair(ctx, args, deps) {
|
|
19
15
|
const result = deps.state() === "idle" ? await deps.start(ctx) : await deps.waitForInitialRelay();
|
|
@@ -27,8 +23,7 @@ async function pair(ctx, args, deps) {
|
|
|
27
23
|
return;
|
|
28
24
|
}
|
|
29
25
|
if (!deps.hasRelay()) {
|
|
30
|
-
|
|
31
|
-
notify(ctx, `[remote-pi] Pair requires a Relay connection; current state: ${status}.`, "warning");
|
|
26
|
+
notify(ctx, `[remote-pi] Pair requires a Relay connection; current state: ${deps.relayStatus()}.`, "warning");
|
|
32
27
|
return;
|
|
33
28
|
}
|
|
34
29
|
const ttl = /--ttl\s+(\d+)/.exec(args);
|
|
@@ -58,7 +53,7 @@ async function listDevices(ctx, deps) {
|
|
|
58
53
|
notify(ctx, "[remote-pi] No paired devices.");
|
|
59
54
|
return;
|
|
60
55
|
}
|
|
61
|
-
notify(ctx, `[remote-pi] Paired devices:\n${peers.map((peer) =>
|
|
56
|
+
notify(ctx, `[remote-pi] Paired devices:\n${peers.map((peer) => `* ${peer.remote_epk.slice(0, 8)} - ${peer.name}${deps.isOwnerActive(peer.remote_epk) ? " online" : ""}`).join("\n")}`);
|
|
62
57
|
}
|
|
63
58
|
async function revoke(args, ctx, deps) {
|
|
64
59
|
const shortId = args.trim();
|
|
@@ -77,7 +72,7 @@ async function revoke(args, ctx, deps) {
|
|
|
77
72
|
try {
|
|
78
73
|
ownerId = canonicalizeEd25519PublicKey(peer.remote_epk, "Owner public key");
|
|
79
74
|
}
|
|
80
|
-
catch { /*
|
|
75
|
+
catch { /* retain cleanup for corrupt legacy records */ }
|
|
81
76
|
deps.closeOwner(ownerId, "peer_stop");
|
|
82
77
|
await deps.updateEndpoint();
|
|
83
78
|
notify(ctx, `[remote-pi] Revoked: ${peer.name}`);
|
|
@@ -118,70 +113,6 @@ export function persistModelDefault(provider, modelId) {
|
|
|
118
113
|
}
|
|
119
114
|
catch { /* a live model switch must not fail because persistence failed */ }
|
|
120
115
|
}
|
|
121
|
-
function daemonLines(daemons) {
|
|
122
|
-
return daemons.map((daemon) => `${daemon.id.slice(0, 8)} ${daemon.name} ${daemon.health} ${daemon.relay}`).join("\n") || "(none)";
|
|
123
|
-
}
|
|
124
|
-
async function daemonList(ctx) {
|
|
125
|
-
if (await supervisorOnline()) {
|
|
126
|
-
const data = await callSupervisor({ op: "list" });
|
|
127
|
-
notify(ctx, `[remote-pi] Daemons:\n${daemonLines(data.daemons)}`);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const entries = listDaemons();
|
|
131
|
-
notify(ctx, `[remote-pi] Daemons (supervisor offline):\n${entries.map((entry) => `${entry.id.slice(0, 8)} ${entry.name} ${entry.desired_state}`).join("\n") || "(none)"}`);
|
|
132
|
-
}
|
|
133
|
-
async function daemonControl(op, id, ctx) {
|
|
134
|
-
const data = await callSupervisor(id ? { op, id } : { op: `${op}_all` });
|
|
135
|
-
notify(ctx, `[remote-pi] ${op}: ${JSON.stringify(data)}`);
|
|
136
|
-
}
|
|
137
|
-
async function daemonCreate(arg, ctx) {
|
|
138
|
-
const cwd = arg.trim() || process.cwd();
|
|
139
|
-
const entry = addDaemon(cwd);
|
|
140
|
-
try {
|
|
141
|
-
await callSupervisor({ op: "start", id: entry.id });
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (!(error instanceof SupervisorOfflineError))
|
|
145
|
-
throw error;
|
|
146
|
-
}
|
|
147
|
-
notify(ctx, `[remote-pi] Registered daemon ${entry.id} for ${entry.cwd}.`);
|
|
148
|
-
}
|
|
149
|
-
async function daemonRemove(arg, ctx) {
|
|
150
|
-
const id = arg.trim();
|
|
151
|
-
if (!id) {
|
|
152
|
-
notify(ctx, "[remote-pi] Usage: remove <daemon-id>", "warning");
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const removed = await supervisorOnline() ? await callSupervisor({ op: "unregister", id }) : removeDaemon(id);
|
|
156
|
-
notify(ctx, removed.removed ? "[remote-pi] Daemon removed." : "[remote-pi] No daemon matched.", removed.removed ? "info" : "warning");
|
|
157
|
-
}
|
|
158
|
-
async function daemonRemoveCwd(cwd, ctx) {
|
|
159
|
-
const target = cwd.trim() || process.cwd();
|
|
160
|
-
const removed = await supervisorOnline()
|
|
161
|
-
? await callSupervisor({ op: "unregister_cwd", cwd: target })
|
|
162
|
-
: (() => { const entry = findDaemonByCwd(target); return entry ? removeDaemon(entry.id) : { removed: false }; })();
|
|
163
|
-
notify(ctx, removed.removed ? "[remote-pi] Daemon removed." : "[remote-pi] No daemon matched.", removed.removed ? "info" : "warning");
|
|
164
|
-
}
|
|
165
|
-
function install(ctx) {
|
|
166
|
-
try {
|
|
167
|
-
installService();
|
|
168
|
-
linkCliBinaries();
|
|
169
|
-
notify(ctx, "[remote-pi] Supervisor service installed.");
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
notify(ctx, `[remote-pi] install failed: ${String(error)}`, "error");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
function uninstall(ctx) {
|
|
176
|
-
try {
|
|
177
|
-
uninstallService();
|
|
178
|
-
unlinkCliBinaries();
|
|
179
|
-
notify(ctx, "[remote-pi] Supervisor service removed.");
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
notify(ctx, `[remote-pi] uninstall failed: ${String(error)}`, "error");
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
116
|
async function command(args, ctx, deps) {
|
|
186
117
|
deps.setCommandContext(ctx);
|
|
187
118
|
const [verb, ...rest] = args.trim().split(/\s+/);
|
|
@@ -213,34 +144,6 @@ async function command(args, ctx, deps) {
|
|
|
213
144
|
case "config":
|
|
214
145
|
notify(ctx, `[remote-pi] ${resolveRelayUrl().url}`);
|
|
215
146
|
return;
|
|
216
|
-
case "daemons":
|
|
217
|
-
await daemonList(ctx);
|
|
218
|
-
return;
|
|
219
|
-
case "create":
|
|
220
|
-
await daemonCreate(value, ctx);
|
|
221
|
-
return;
|
|
222
|
-
case "remove":
|
|
223
|
-
await daemonRemove(value, ctx);
|
|
224
|
-
return;
|
|
225
|
-
case "remove-cwd":
|
|
226
|
-
await daemonRemoveCwd(value, ctx);
|
|
227
|
-
return;
|
|
228
|
-
case "install":
|
|
229
|
-
install(ctx);
|
|
230
|
-
return;
|
|
231
|
-
case "uninstall":
|
|
232
|
-
uninstall(ctx);
|
|
233
|
-
return;
|
|
234
|
-
case "daemon": {
|
|
235
|
-
const [operation, id] = value.split(/\s+/, 2);
|
|
236
|
-
if (operation === "start" || operation === "stop" || operation === "restart")
|
|
237
|
-
await daemonControl(operation, id, ctx);
|
|
238
|
-
else if (operation === "status")
|
|
239
|
-
await daemonList(ctx);
|
|
240
|
-
else
|
|
241
|
-
notify(ctx, "[remote-pi] Usage: daemon <start|stop|restart|status> [id]", "warning");
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
147
|
case "internal-session-new":
|
|
245
148
|
await deps.runInternalSessionNew(value, ctx);
|
|
246
149
|
return;
|
|
@@ -261,52 +164,6 @@ export function registerCommands(pi, deps) {
|
|
|
261
164
|
pi.registerCommand("remote-pi pair", { description: "Show an endpoint pairing QR", handler: async (args, ctx) => handler(`pair ${args}`, ctx) });
|
|
262
165
|
pi.registerCommand("remote-pi devices", { description: "List locally paired Owners", handler: async (_, ctx) => handler("devices", ctx) });
|
|
263
166
|
pi.registerCommand("remote-pi revoke", { description: "Revoke a locally paired Owner", handler: async (args, ctx) => handler(`revoke ${args}`, ctx) });
|
|
264
|
-
pi.registerCommand("remote-pi remove-cwd", { description: "Unregister the daemon for a cwd", handler: async (args, ctx) => handler(`remove-cwd ${args}`, ctx) });
|
|
265
167
|
pi.registerCommand("remote-pi set-relay", { description: "Set Relay URL", handler: async (args, ctx) => handler(`set-relay ${args}`, ctx) });
|
|
266
168
|
}
|
|
267
|
-
function directCliContext() {
|
|
268
|
-
return { ui: { notify: (message) => console.log(message) } };
|
|
269
|
-
}
|
|
270
|
-
export function runDirectCli(deps, directRun) {
|
|
271
|
-
if (!directRun)
|
|
272
|
-
return;
|
|
273
|
-
const [, , commandName, ...args] = process.argv;
|
|
274
|
-
const ctx = directCliContext();
|
|
275
|
-
if (commandName === "devices" || commandName === "list")
|
|
276
|
-
void listDevices(ctx, deps);
|
|
277
|
-
else if (commandName === "revoke")
|
|
278
|
-
void revoke(args[0] ?? "", ctx, deps);
|
|
279
|
-
else if (commandName === "set-relay")
|
|
280
|
-
setRelay(args[0] ?? "", ctx);
|
|
281
|
-
else if (commandName === "daemons" || (commandName === "daemon" && args[0] === "status"))
|
|
282
|
-
void daemonList(ctx);
|
|
283
|
-
else if (commandName === "daemon" && ["start", "stop", "restart"].includes(args[0] ?? ""))
|
|
284
|
-
void daemonControl(args[0], args[1], ctx);
|
|
285
|
-
else if (commandName === "create")
|
|
286
|
-
void daemonCreate(args.join(" "), ctx);
|
|
287
|
-
else if (commandName === "remove")
|
|
288
|
-
void daemonRemove(args[0] ?? "", ctx);
|
|
289
|
-
else if (commandName === "remove-cwd")
|
|
290
|
-
void daemonRemoveCwd(args.join(" "), ctx);
|
|
291
|
-
else if (commandName === "install")
|
|
292
|
-
install(ctx);
|
|
293
|
-
else if (commandName === "uninstall")
|
|
294
|
-
uninstall(ctx);
|
|
295
|
-
else if (commandName === "restart-supervisor")
|
|
296
|
-
restartSupervisor();
|
|
297
|
-
else
|
|
298
|
-
console.log("Usage: remote-pi <devices|revoke|set-relay|daemons|daemon|create|remove|remove-cwd|install|uninstall>");
|
|
299
|
-
}
|
|
300
|
-
function restartSupervisor() {
|
|
301
|
-
const uid = process.getuid?.() ?? 0;
|
|
302
|
-
const step = process.platform === "darwin"
|
|
303
|
-
? ["launchctl", ["kickstart", "-k", `gui/${uid}/${LAUNCHD_LABEL}`]]
|
|
304
|
-
: process.platform === "linux"
|
|
305
|
-
? ["systemctl", ["--user", "restart", SYSTEMD_UNIT]]
|
|
306
|
-
: null;
|
|
307
|
-
if (!step)
|
|
308
|
-
process.exitCode = 1;
|
|
309
|
-
else
|
|
310
|
-
spawnSync(step[0], step[1], { stdio: "inherit" });
|
|
311
|
-
}
|
|
312
169
|
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ type ProcessIdentity = Readonly<{
|
|
|
5
5
|
endpointId: string;
|
|
6
6
|
runtimeInstanceId: string;
|
|
7
7
|
}>;
|
|
8
|
+
/** One Pi process owns a fresh endpoint identity; extension reloads reuse it. */
|
|
8
9
|
export declare function processEndpointIdentity(): ProcessIdentity;
|
|
9
10
|
export declare const _getState: () => "idle" | "started" | "paired";
|
|
10
11
|
export declare const _getCachedPublicKeyForTest: () => string | null;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** One local Pi process is one stable Relay endpoint with replaceable sessions. */
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { readFileSync
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
5
|
import { hostname } from "node:os";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -16,33 +16,24 @@ import { createExtensionUiBridge } from "./extension_ui_bridge.js";
|
|
|
16
16
|
import { handleModelSet, handleSessionCompact, handleThinkingSet, getModelsList } from "./actions/handlers.js";
|
|
17
17
|
import { ensureModelRegistry } from "./actions/registry.js";
|
|
18
18
|
import { SessionNewBridge } from "./actions/session_new_bridge.js";
|
|
19
|
-
import { RPC_CONTROL_STATUS_KEY } from "./daemon/rpc_child.js";
|
|
20
19
|
import { defaultAgentName, loadLocalConfig } from "./session/local_config.js";
|
|
21
20
|
import { resolveRelayUrl, toWebSocketUrl } from "./config.js";
|
|
22
|
-
import { persistModelDefault, registerCommands
|
|
21
|
+
import { persistModelDefault, registerCommands } from "./commands.js";
|
|
23
22
|
import { installOwnerRouter } from "./runtime/owner_router.js";
|
|
24
23
|
import { RelayLifecycle } from "./runtime/relay_lifecycle.js";
|
|
25
24
|
import { PairingCoordinator } from "./runtime/pairing_coordinator.js";
|
|
26
25
|
import { ExtensionOwner } from "./runtime/extension_owner.js";
|
|
27
|
-
const CONTROL_PROTOCOL_VERSION = 2;
|
|
28
|
-
const ENDPOINT_ID_ENV = "REMOTE_PI_ENDPOINT_ID", RUNTIME_INSTANCE_ID_ENV = "REMOTE_PI_RUNTIME_INSTANCE_ID";
|
|
29
26
|
const CTRL_PREFIX = "\x00remote-pi-ctrl:";
|
|
27
|
+
const CONTROL_PROTOCOL_VERSION = 2;
|
|
28
|
+
const RUNTIME_CONTROL_STATUS_KEY = "remote-pi:control";
|
|
30
29
|
const PROCESS_IDENTITY_KEY = Symbol.for("remote-pi.endpoint-process-identity");
|
|
31
|
-
|
|
32
|
-
const value = process.env[name];
|
|
33
|
-
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)
|
|
34
|
-
? value
|
|
35
|
-
: undefined;
|
|
36
|
-
}
|
|
30
|
+
/** One Pi process owns a fresh endpoint identity; extension reloads reuse it. */
|
|
37
31
|
export function processEndpointIdentity() {
|
|
38
32
|
const global = globalThis;
|
|
39
33
|
const existing = global[PROCESS_IDENTITY_KEY];
|
|
40
34
|
if (existing)
|
|
41
35
|
return existing;
|
|
42
|
-
const identity = Object.freeze({
|
|
43
|
-
endpointId: opaqueUuidFromEnv(ENDPOINT_ID_ENV) ?? randomUUID(),
|
|
44
|
-
runtimeInstanceId: opaqueUuidFromEnv(RUNTIME_INSTANCE_ID_ENV) ?? randomUUID(),
|
|
45
|
-
});
|
|
36
|
+
const identity = Object.freeze({ endpointId: randomUUID(), runtimeInstanceId: randomUUID() });
|
|
46
37
|
global[PROCESS_IDENTITY_KEY] = identity;
|
|
47
38
|
return identity;
|
|
48
39
|
}
|
|
@@ -79,7 +70,7 @@ export const _setSessionNewBridgeTimeoutForTest = (timeoutMs) => sessionNewBridg
|
|
|
79
70
|
function displayName(cwd = process.cwd()) { return loadLocalConfig(cwd).agent_name ?? defaultAgentName(cwd); }
|
|
80
71
|
function endpointMetadata(cwd = process.cwd()) {
|
|
81
72
|
return {
|
|
82
|
-
kind:
|
|
73
|
+
kind: "interactive",
|
|
83
74
|
name: displayName(cwd),
|
|
84
75
|
cwd,
|
|
85
76
|
pid: process.pid,
|
|
@@ -107,14 +98,6 @@ async function authorizedOwnerIds() {
|
|
|
107
98
|
}
|
|
108
99
|
function relayStatus() { return relayLifecycle.status; }
|
|
109
100
|
function emitRuntimeEvent(type, details) {
|
|
110
|
-
if (process.env.REMOTE_PI_DAEMON === "1") {
|
|
111
|
-
const ui = lastEventCtx?.ui ?? lastCommandCtx?.ui;
|
|
112
|
-
try {
|
|
113
|
-
ui?.setStatus(RPC_CONTROL_STATUS_KEY, JSON.stringify({ type: type.replace(/-/g, "_"), ...details }));
|
|
114
|
-
}
|
|
115
|
-
catch { /* a stale RPC UI context must not take down the process */ }
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
101
|
try {
|
|
119
102
|
piApi?.sendMessage({ customType: `remote-pi:${type}`, content: "", details, display: false });
|
|
120
103
|
}
|
|
@@ -124,11 +107,19 @@ function emitRelayState() {
|
|
|
124
107
|
emitRuntimeEvent("relay-state", { state: relayStatus(), endpoint_id: endpointIdentity.endpointId, runtime_instance_id: endpointIdentity.runtimeInstanceId });
|
|
125
108
|
}
|
|
126
109
|
function emitRuntimeReady() {
|
|
127
|
-
|
|
128
|
-
control_protocol_version: CONTROL_PROTOCOL_VERSION,
|
|
129
|
-
|
|
110
|
+
const details = {
|
|
111
|
+
control_protocol_version: CONTROL_PROTOCOL_VERSION,
|
|
112
|
+
extension_version: extensionVersion(),
|
|
113
|
+
endpoint_id: endpointIdentity.endpointId,
|
|
114
|
+
runtime_instance_id: endpointIdentity.runtimeInstanceId,
|
|
130
115
|
...(currentSessionManager ? { session_id: currentSessionManager.getSessionId() } : {}),
|
|
131
|
-
}
|
|
116
|
+
};
|
|
117
|
+
emitRuntimeEvent("runtime-ready", details);
|
|
118
|
+
const ui = lastEventCtx?.ui ?? lastCommandCtx?.ui;
|
|
119
|
+
try {
|
|
120
|
+
ui?.setStatus(RUNTIME_CONTROL_STATUS_KEY, JSON.stringify({ type: "runtime_ready", ...details }));
|
|
121
|
+
}
|
|
122
|
+
catch { /* stale RPC UI context */ }
|
|
132
123
|
}
|
|
133
124
|
function emitRuntimeFailed(stage, code, message, retryable) {
|
|
134
125
|
emitRuntimeEvent("runtime-failed", { stage, code, message, retryable });
|
|
@@ -593,9 +584,8 @@ const extension = (api) => {
|
|
|
593
584
|
currentThinking = pi.getThinkingLevel();
|
|
594
585
|
}
|
|
595
586
|
catch { /* optional SDK capability */ }
|
|
596
|
-
if (
|
|
587
|
+
if (relayLifecycle.state === "idle")
|
|
597
588
|
void start(ctx);
|
|
598
|
-
}
|
|
599
589
|
});
|
|
600
590
|
pi.on("session_tree", () => rotateGeneration("branch_changed"));
|
|
601
591
|
api.on("session_shutdown", (event) => {
|
|
@@ -619,12 +609,4 @@ export default extension;
|
|
|
619
609
|
export async function _startRelayForTest(ctx) { await start(ctx); }
|
|
620
610
|
export async function _stopForTest(_ctx) { closeRelay("peer_stop"); }
|
|
621
611
|
export async function _connectForTest(ctx) { await start(ctx); }
|
|
622
|
-
runDirectCli(commandDependencies, (() => {
|
|
623
|
-
try {
|
|
624
|
-
return fileURLToPath(import.meta.url) === realpathSync(process.argv[1] ?? "");
|
|
625
|
-
}
|
|
626
|
-
catch {
|
|
627
|
-
return false;
|
|
628
|
-
}
|
|
629
|
-
})());
|
|
630
612
|
//# sourceMappingURL=index.js.map
|