@yefengr/remote-pi 0.7.15 → 0.8.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.
Files changed (76) hide show
  1. package/README.md +44 -95
  2. package/dist/actions/handlers.js +1 -1
  3. package/dist/actions/handlers.js.map +1 -1
  4. package/dist/actions/registry.d.ts +1 -1
  5. package/dist/actions/registry.js +1 -1
  6. package/dist/{daemon/commands.d.ts → commands.d.ts} +4 -5
  7. package/dist/commands.js +169 -0
  8. package/dist/commands.js.map +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +44 -39
  11. package/dist/index.js.map +1 -1
  12. package/dist/pairing/qr.d.ts +22 -21
  13. package/dist/pairing/qr.js +40 -65
  14. package/dist/pairing/qr.js.map +1 -1
  15. package/dist/pairing/storage.js +4 -4
  16. package/dist/pairing/storage.js.map +1 -1
  17. package/dist/protocol/types.d.ts +1 -1
  18. package/dist/protocol/v2/schemas.d.ts +5 -5
  19. package/dist/protocol/v2/schemas.js +2 -1
  20. package/dist/protocol/v2/schemas.js.map +1 -1
  21. package/dist/runtime/pairing_coordinator.js +6 -6
  22. package/dist/runtime/pairing_coordinator.js.map +1 -1
  23. package/dist/session/local_config.d.ts +0 -5
  24. package/dist/session/local_config.js +6 -29
  25. package/dist/session/local_config.js.map +1 -1
  26. package/dist/transport/relay_client.js.map +1 -1
  27. package/package.json +1 -8
  28. package/dist/bin/supervisord.d.ts +0 -2
  29. package/dist/bin/supervisord.js +0 -78
  30. package/dist/bin/supervisord.js.map +0 -1
  31. package/dist/daemon/cli-links.d.ts +0 -30
  32. package/dist/daemon/cli-links.js +0 -134
  33. package/dist/daemon/cli-links.js.map +0 -1
  34. package/dist/daemon/client.d.ts +0 -20
  35. package/dist/daemon/client.js +0 -131
  36. package/dist/daemon/client.js.map +0 -1
  37. package/dist/daemon/commands.js +0 -311
  38. package/dist/daemon/commands.js.map +0 -1
  39. package/dist/daemon/control_protocol.d.ts +0 -198
  40. package/dist/daemon/control_protocol.js +0 -40
  41. package/dist/daemon/control_protocol.js.map +0 -1
  42. package/dist/daemon/cron_log.d.ts +0 -24
  43. package/dist/daemon/cron_log.js +0 -57
  44. package/dist/daemon/cron_log.js.map +0 -1
  45. package/dist/daemon/cron_registry.d.ts +0 -43
  46. package/dist/daemon/cron_registry.js +0 -149
  47. package/dist/daemon/cron_registry.js.map +0 -1
  48. package/dist/daemon/install-runtime.d.ts +0 -10
  49. package/dist/daemon/install-runtime.js +0 -81
  50. package/dist/daemon/install-runtime.js.map +0 -1
  51. package/dist/daemon/install.d.ts +0 -110
  52. package/dist/daemon/install.js +0 -263
  53. package/dist/daemon/install.js.map +0 -1
  54. package/dist/daemon/registry.d.ts +0 -51
  55. package/dist/daemon/registry.js +0 -207
  56. package/dist/daemon/registry.js.map +0 -1
  57. package/dist/daemon/rpc_child.d.ts +0 -135
  58. package/dist/daemon/rpc_child.js +0 -472
  59. package/dist/daemon/rpc_child.js.map +0 -1
  60. package/dist/daemon/status.d.ts +0 -45
  61. package/dist/daemon/status.js +0 -87
  62. package/dist/daemon/status.js.map +0 -1
  63. package/dist/daemon/supervisor-ipc.d.ts +0 -2
  64. package/dist/daemon/supervisor-ipc.js +0 -20
  65. package/dist/daemon/supervisor-ipc.js.map +0 -1
  66. package/dist/daemon/supervisor.d.ts +0 -70
  67. package/dist/daemon/supervisor.js +0 -637
  68. package/dist/daemon/supervisor.js.map +0 -1
  69. package/dist/session/ipc.d.ts +0 -6
  70. package/dist/session/ipc.js +0 -15
  71. package/dist/session/ipc.js.map +0 -1
  72. package/docs/daemon.md +0 -175
  73. package/service-templates/launchd.plist.template +0 -35
  74. package/service-templates/systemd.service.template +0 -19
  75. package/service-templates/task-launcher.vbs.template +0 -10
  76. 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 extension for browser control of local Pi endpoints, with an optional supervised daemon lifecycle.
7
+ > A Pi Extension for controlling the current Pi process from the browser through a Relay.
8
8
 
9
- **Homepage:** <https://remote-pi.jacobmoura.work>
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 endpoint runtime session / history generation
14
+ device -> endpoint -> runtime -> session / history generation
19
15
  ```
20
16
 
21
- - **Device**: a computer identity.
22
- - **Endpoint**: a stable interactive or daemon target. A working directory may host more than one endpoint.
23
- - **Runtime**: the current process instance for an endpoint. A daemon restart keeps the endpoint and starts a new runtime.
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 pairing QR is endpoint- and runtime-aware. Pair every computer independently, and revoke pairings independently on each computer. The PWA can retain multiple devices and multiple endpoint cards for each device.
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 once in any project where Pi runs:
25
+ Install the Extension once:
31
26
 
32
27
  ```bash
33
28
  pi install npm:@yefengr/remote-pi
34
29
  ```
35
30
 
36
- Then in Pi:
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
- The first run creates a per-folder endpoint configuration and connects to the configured Relay. The QR command prints a one-time URI. Scan it in the [Remote Pi PWA](https://remote-pi.jacobmoura.work/app), select the endpoint card, and send a prompt.
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
- ## Browser session actions
53
-
54
- The PWA supports normal chat plus typed actions that Pi can apply directly:
44
+ ## Commands
55
45
 
56
- | Action | Effect |
46
+ | Command | Description |
57
47
  |---|---|
58
- | Compact context | Calls `ctx.compact()` |
59
- | New session | Calls `ctx.newSession()` after confirmation |
60
- | Model | Uses `pi.setModel(model)` |
61
- | Thinking | Uses `pi.setThinkingLevel(level)` |
62
-
63
- The model picker reflects the providers configured on the host. Pi settings are the only extension source used by the supervisor and interactive Pi; Remote Pi does not inject an additional extension argument when starting Pi.
64
-
65
- An optional companion adds rich remote clarification prompts:
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
- ```bash
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 internally. The Relay keeps endpoint routing state in memory and forwards opaque `ct` payloads. See [`../relay/README.md`](../relay/README.md) for its operational and security boundary.
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
- `daemon status` keeps these dimensions separate:
76
+ ## Pairing and security
128
77
 
129
- | Dimension | Meaning |
130
- |---|---|
131
- | registration | Registered or missing working directory |
132
- | desired | Persisted `running` or `stopped` intent |
133
- | process | OS child absent, spawning, running, or exited |
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
- ### Scheduled prompts
84
+ ## Migration from older releases
141
85
 
142
- Cron owns no daemon lifecycle. A scheduled prompt is sent only when its daemon is desired `running` and its runtime is ready; otherwise it is skipped and audited. There is no wake behavior.
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
- remote-pi cron add <daemon-id> "0 9 * * 1-5" "Summarize the new PRs" --tz America/Sao_Paulo
146
- remote-pi cron list
147
- remote-pi cron log --tail 20
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
- Runs are at least 60 seconds apart. `--no-skip-busy` permits dispatch during a running turn; `--catchup` permits one missed run after supervisor startup. Audits distinguish accepted, rejected, busy, desired-stopped, starting, retrying, failed, blocked, missing, and disabled outcomes.
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. Use `.js` extensions in TypeScript imports.
114
+ Node 20+ and TypeScript ESM are required. TypeScript imports must use `.js` extensions.
166
115
 
167
116
  ## License
168
117
 
@@ -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/daemon restart (the TUI persists because AgentSession.setModel
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 (daemon boot, control channel). Rather
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.
@@ -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 (daemon boot, control channel). Rather
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 "../pairing/crypto.js";
3
- import type { InitialRelayResult } from "../runtime/relay_lifecycle.js";
4
- export type { InitialRelayResult } from "../runtime/relay_lifecycle.js";
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>;
@@ -21,10 +21,9 @@ export interface RemoteCommandDependencies {
21
21
  displayName(cwd?: string): string;
22
22
  keypair(): Ed25519Keypair | null;
23
23
  hasRelay(): boolean;
24
- piApi(): ExtensionAPI | null;
24
+ publishPairingOffer(code: string, expiresAt: number): boolean;
25
25
  setCommandContext(ctx: ExtensionCommandContext): void;
26
26
  runInternalSessionNew(token: string, ctx: ExtensionCommandContext): Promise<void>;
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;
@@ -0,0 +1,169 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
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";
7
+ const PAIR_WIDGET_KEY = "remote-pi-pair-code";
8
+ function notify(ctx, text, kind = "info") {
9
+ try {
10
+ ctx.ui.notify(text, kind);
11
+ }
12
+ catch { /* headless or stale context */ }
13
+ }
14
+ async function pair(ctx, args, deps) {
15
+ const result = deps.state() === "idle" ? await deps.start(ctx) : await deps.waitForInitialRelay();
16
+ if (result === "cancelled") {
17
+ notify(ctx, `[remote-pi] Pair requires a Relay connection; current state: ${deps.relayStatus()}.`, "warning");
18
+ return;
19
+ }
20
+ const keypair = deps.keypair();
21
+ if (!keypair) {
22
+ notify(ctx, "[remote-pi] Pair requires an available device identity.", "warning");
23
+ return;
24
+ }
25
+ if (!deps.hasRelay()) {
26
+ notify(ctx, `[remote-pi] Pair requires a Relay connection; current state: ${deps.relayStatus()}.`, "warning");
27
+ return;
28
+ }
29
+ const ttl = /--ttl\s+(\d+)/.exec(args);
30
+ const ttlMs = ttl ? clampPairTtlMs(Number(ttl[1]) * 1_000) : PAIRING_INVITE_TTL_MS;
31
+ const invite = qrSession.issueCode(ttlMs);
32
+ if (!deps.publishPairingOffer(invite.code, invite.expiresAt)) {
33
+ qrSession.clear();
34
+ notify(ctx, `[remote-pi] Pair requires a Relay connection; current state: ${deps.relayStatus()}.`, "warning");
35
+ return;
36
+ }
37
+ try {
38
+ ctx.ui.setWidget(PAIR_WIDGET_KEY, [
39
+ "Scan to pair:",
40
+ "",
41
+ renderQRAscii(invite.code),
42
+ "",
43
+ `Pairing code: ${invite.code}`,
44
+ `Expires at: ${new Date(invite.expiresAt).toLocaleTimeString()}`,
45
+ ]);
46
+ }
47
+ catch { /* headless pairing still has a status message */ }
48
+ notify(ctx, `[remote-pi] Pairing code ready until ${new Date(invite.expiresAt).toLocaleTimeString()}.`);
49
+ }
50
+ async function listDevices(ctx, deps) {
51
+ const peers = await listPeers();
52
+ if (!peers.length) {
53
+ notify(ctx, "[remote-pi] No paired devices.");
54
+ return;
55
+ }
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")}`);
57
+ }
58
+ async function revoke(args, ctx, deps) {
59
+ const shortId = args.trim();
60
+ if (!shortId) {
61
+ notify(ctx, "[remote-pi] Usage: /remote-pi revoke <shortid>", "warning");
62
+ return;
63
+ }
64
+ const matches = (await listPeers()).filter((peer) => peer.remote_epk.startsWith(shortId));
65
+ if (matches.length !== 1) {
66
+ notify(ctx, matches.length ? "[remote-pi] Ambiguous owner id." : "[remote-pi] No matching paired device.", "warning");
67
+ return;
68
+ }
69
+ const peer = matches[0];
70
+ await removePeer(peer.remote_epk);
71
+ let ownerId = peer.remote_epk;
72
+ try {
73
+ ownerId = canonicalizeEd25519PublicKey(peer.remote_epk, "Owner public key");
74
+ }
75
+ catch { /* retain cleanup for corrupt legacy records */ }
76
+ deps.closeOwner(ownerId, "peer_stop");
77
+ await deps.updateEndpoint();
78
+ notify(ctx, `[remote-pi] Revoked: ${peer.name}`);
79
+ }
80
+ function status(ctx, deps) {
81
+ const url = deps.relayUrl() ?? resolveRelayUrl().url;
82
+ const identity = deps.endpointIdentity();
83
+ const detail = deps.state() === "idle"
84
+ ? "off"
85
+ : `${deps.relayStatus()}, endpoint=${identity.endpointId}, runtime=${identity.runtimeInstanceId}, owners=${deps.activeOwnerCount()}`;
86
+ notify(ctx, `[remote-pi] Relay ${detail} (${url})`);
87
+ }
88
+ function setRelay(value, ctx) {
89
+ const url = value.trim();
90
+ if (isWebSocketScheme(url)) {
91
+ notify(ctx, "[remote-pi] Use http:// or https://; it is converted internally.", "warning");
92
+ return;
93
+ }
94
+ if (!isValidRelayUrl(url)) {
95
+ notify(ctx, "[remote-pi] Invalid Relay URL.", "warning");
96
+ return;
97
+ }
98
+ saveConfig({ relay: url });
99
+ notify(ctx, `[remote-pi] Relay set to ${url}.`);
100
+ }
101
+ export function persistModelDefault(provider, modelId) {
102
+ try {
103
+ const path = join(process.cwd(), ".pi", "settings.json");
104
+ let config = {};
105
+ try {
106
+ config = JSON.parse(readFileSync(path, "utf8"));
107
+ }
108
+ catch { /* fresh file */ }
109
+ config.defaultProvider = provider;
110
+ config.defaultModel = modelId;
111
+ mkdirSync(dirname(path), { recursive: true });
112
+ writeFileSync(path, JSON.stringify(config, null, 2));
113
+ }
114
+ catch { /* a live model switch must not fail because persistence failed */ }
115
+ }
116
+ async function command(args, ctx, deps) {
117
+ deps.setCommandContext(ctx);
118
+ const [verb, ...rest] = args.trim().split(/\s+/);
119
+ const value = rest.join(" ");
120
+ try {
121
+ switch (verb || "start") {
122
+ case "start":
123
+ await deps.start(ctx);
124
+ return;
125
+ case "stop":
126
+ deps.stop();
127
+ notify(ctx, "[remote-pi] Stopped.");
128
+ return;
129
+ case "status":
130
+ status(ctx, deps);
131
+ return;
132
+ case "pair":
133
+ await pair(ctx, value, deps);
134
+ return;
135
+ case "devices":
136
+ await listDevices(ctx, deps);
137
+ return;
138
+ case "revoke":
139
+ await revoke(value, ctx, deps);
140
+ return;
141
+ case "set-relay":
142
+ setRelay(value, ctx);
143
+ return;
144
+ case "config":
145
+ notify(ctx, `[remote-pi] ${resolveRelayUrl().url}`);
146
+ return;
147
+ case "internal-session-new":
148
+ await deps.runInternalSessionNew(value, ctx);
149
+ return;
150
+ default:
151
+ await deps.start(ctx);
152
+ return;
153
+ }
154
+ }
155
+ catch (error) {
156
+ notify(ctx, `[remote-pi] ${verb} failed: ${String(error)}`, "error");
157
+ }
158
+ }
159
+ export function registerCommands(pi, deps) {
160
+ const handler = (args, ctx) => command(args, ctx, deps);
161
+ pi.registerCommand("remote-pi", { description: "Connect this Pi endpoint to Remote Pi", handler });
162
+ pi.registerCommand("remote-pi start", { description: "Connect this endpoint to Relay", handler: async (_, ctx) => handler("start", ctx) });
163
+ pi.registerCommand("remote-pi stop", { description: "Disconnect this endpoint", handler: async (_, ctx) => handler("stop", ctx) });
164
+ pi.registerCommand("remote-pi pair", { description: "Show an endpoint pairing QR", handler: async (args, ctx) => handler(`pair ${args}`, ctx) });
165
+ pi.registerCommand("remote-pi devices", { description: "List locally paired Owners", handler: async (_, ctx) => handler("devices", ctx) });
166
+ pi.registerCommand("remote-pi revoke", { description: "Revoke a locally paired Owner", handler: async (args, ctx) => handler(`revoke ${args}`, ctx) });
167
+ pi.registerCommand("remote-pi set-relay", { description: "Set Relay URL", handler: async (args, ctx) => handler(`set-relay ${args}`, ctx) });
168
+ }
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;