@yefengr/remote-pi 0.7.4 → 0.7.5

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 (165) hide show
  1. package/README.md +81 -586
  2. package/dist/bin/supervisord.js +4 -5
  3. package/dist/bin/supervisord.js.map +1 -1
  4. package/dist/config.d.ts +1 -1
  5. package/dist/config.js +2 -2
  6. package/dist/daemon/cli-links.d.ts +30 -0
  7. package/dist/daemon/cli-links.js +134 -0
  8. package/dist/daemon/cli-links.js.map +1 -0
  9. package/dist/daemon/commands.d.ts +27 -0
  10. package/dist/daemon/commands.js +295 -0
  11. package/dist/daemon/commands.js.map +1 -0
  12. package/dist/daemon/control_protocol.d.ts +53 -31
  13. package/dist/daemon/control_protocol.js +8 -31
  14. package/dist/daemon/control_protocol.js.map +1 -1
  15. package/dist/daemon/cron_log.d.ts +2 -23
  16. package/dist/daemon/cron_log.js +10 -25
  17. package/dist/daemon/cron_log.js.map +1 -1
  18. package/dist/daemon/cron_registry.d.ts +3 -40
  19. package/dist/daemon/cron_registry.js +58 -103
  20. package/dist/daemon/cron_registry.js.map +1 -1
  21. package/dist/daemon/install-runtime.d.ts +10 -0
  22. package/dist/daemon/install-runtime.js +81 -0
  23. package/dist/daemon/install-runtime.js.map +1 -0
  24. package/dist/daemon/install.d.ts +3 -63
  25. package/dist/daemon/install.js +5 -289
  26. package/dist/daemon/install.js.map +1 -1
  27. package/dist/daemon/preflight.d.ts +51 -0
  28. package/dist/daemon/preflight.js +136 -0
  29. package/dist/daemon/preflight.js.map +1 -0
  30. package/dist/daemon/registry.d.ts +33 -45
  31. package/dist/daemon/registry.js +171 -117
  32. package/dist/daemon/registry.js.map +1 -1
  33. package/dist/daemon/rpc_child.d.ts +92 -146
  34. package/dist/daemon/rpc_child.js +336 -263
  35. package/dist/daemon/rpc_child.js.map +1 -1
  36. package/dist/daemon/status.d.ts +45 -0
  37. package/dist/daemon/status.js +87 -0
  38. package/dist/daemon/status.js.map +1 -0
  39. package/dist/daemon/supervisor-ipc.d.ts +2 -0
  40. package/dist/daemon/supervisor-ipc.js +20 -0
  41. package/dist/daemon/supervisor-ipc.js.map +1 -0
  42. package/dist/daemon/supervisor.d.ts +48 -71
  43. package/dist/daemon/supervisor.js +430 -420
  44. package/dist/daemon/supervisor.js.map +1 -1
  45. package/dist/extension_ui_bridge.d.ts +4 -3
  46. package/dist/extension_ui_bridge.js +10 -0
  47. package/dist/extension_ui_bridge.js.map +1 -1
  48. package/dist/index.d.ts +25 -230
  49. package/dist/index.js +515 -5553
  50. package/dist/index.js.map +1 -1
  51. package/dist/pairing/crypto.d.ts +8 -1
  52. package/dist/pairing/crypto.js +56 -6
  53. package/dist/pairing/crypto.js.map +1 -1
  54. package/dist/pairing/owner_storage.d.ts +42 -0
  55. package/dist/pairing/owner_storage.js +207 -0
  56. package/dist/pairing/owner_storage.js.map +1 -0
  57. package/dist/pairing/qr.d.ts +3 -42
  58. package/dist/pairing/qr.js +9 -59
  59. package/dist/pairing/qr.js.map +1 -1
  60. package/dist/pairing/storage.d.ts +3 -45
  61. package/dist/pairing/storage.js +10 -223
  62. package/dist/pairing/storage.js.map +1 -1
  63. package/dist/protocol/types.d.ts +1 -1
  64. package/dist/protocol/v2/schemas.d.ts +1 -1
  65. package/dist/protocol/v2/schemas.js +1 -1
  66. package/dist/protocol/v2/schemas.js.map +1 -1
  67. package/dist/runtime/owner_router.d.ts +16 -0
  68. package/dist/runtime/owner_router.js +37 -0
  69. package/dist/runtime/owner_router.js.map +1 -0
  70. package/dist/session/ipc.d.ts +1 -22
  71. package/dist/session/ipc.js +4 -11
  72. package/dist/session/ipc.js.map +1 -1
  73. package/dist/session/local_config.d.ts +4 -47
  74. package/dist/session/local_config.js +19 -101
  75. package/dist/session/local_config.js.map +1 -1
  76. package/dist/transport/peer_channel.d.ts +25 -39
  77. package/dist/transport/peer_channel.js +74 -131
  78. package/dist/transport/peer_channel.js.map +1 -1
  79. package/dist/transport/relay_client.d.ts +26 -70
  80. package/dist/transport/relay_client.js +37 -106
  81. package/dist/transport/relay_client.js.map +1 -1
  82. package/docs/daemon.md +91 -207
  83. package/package.json +21 -17
  84. package/dist/daemon/id.d.ts +0 -24
  85. package/dist/daemon/id.js +0 -36
  86. package/dist/daemon/id.js.map +0 -1
  87. package/dist/mcp/mesh_result.d.ts +0 -10
  88. package/dist/mcp/mesh_result.js +0 -42
  89. package/dist/mcp/mesh_result.js.map +0 -1
  90. package/dist/mcp/mesh_server.d.ts +0 -16
  91. package/dist/mcp/mesh_server.js +0 -327
  92. package/dist/mcp/mesh_server.js.map +0 -1
  93. package/dist/mesh/canonical.d.ts +0 -30
  94. package/dist/mesh/canonical.js +0 -61
  95. package/dist/mesh/canonical.js.map +0 -1
  96. package/dist/mesh/client.d.ts +0 -18
  97. package/dist/mesh/client.js +0 -125
  98. package/dist/mesh/client.js.map +0 -1
  99. package/dist/mesh/encoding.d.ts +0 -38
  100. package/dist/mesh/encoding.js +0 -216
  101. package/dist/mesh/encoding.js.map +0 -1
  102. package/dist/mesh/self_revoke.d.ts +0 -73
  103. package/dist/mesh/self_revoke.js +0 -401
  104. package/dist/mesh/self_revoke.js.map +0 -1
  105. package/dist/mesh/siblings.d.ts +0 -49
  106. package/dist/mesh/siblings.js +0 -159
  107. package/dist/mesh/siblings.js.map +0 -1
  108. package/dist/mesh/types.d.ts +0 -34
  109. package/dist/mesh/types.js +0 -11
  110. package/dist/mesh/types.js.map +0 -1
  111. package/dist/mesh/verify.d.ts +0 -17
  112. package/dist/mesh/verify.js +0 -86
  113. package/dist/mesh/verify.js.map +0 -1
  114. package/dist/rooms.d.ts +0 -29
  115. package/dist/rooms.js +0 -57
  116. package/dist/rooms.js.map +0 -1
  117. package/dist/session/bridge.d.ts +0 -37
  118. package/dist/session/bridge.js +0 -130
  119. package/dist/session/bridge.js.map +0 -1
  120. package/dist/session/broker.d.ts +0 -189
  121. package/dist/session/broker.js +0 -507
  122. package/dist/session/broker.js.map +0 -1
  123. package/dist/session/broker_remote.d.ts +0 -74
  124. package/dist/session/broker_remote.js +0 -583
  125. package/dist/session/broker_remote.js.map +0 -1
  126. package/dist/session/cwd_lock.d.ts +0 -33
  127. package/dist/session/cwd_lock.js +0 -126
  128. package/dist/session/cwd_lock.js.map +0 -1
  129. package/dist/session/envelope.d.ts +0 -33
  130. package/dist/session/envelope.js +0 -117
  131. package/dist/session/envelope.js.map +0 -1
  132. package/dist/session/global_config.d.ts +0 -33
  133. package/dist/session/global_config.js +0 -73
  134. package/dist/session/global_config.js.map +0 -1
  135. package/dist/session/leader_election.d.ts +0 -32
  136. package/dist/session/leader_election.js +0 -106
  137. package/dist/session/leader_election.js.map +0 -1
  138. package/dist/session/mesh_node.d.ts +0 -116
  139. package/dist/session/mesh_node.js +0 -573
  140. package/dist/session/mesh_node.js.map +0 -1
  141. package/dist/session/peer.d.ts +0 -139
  142. package/dist/session/peer.js +0 -451
  143. package/dist/session/peer.js.map +0 -1
  144. package/dist/session/peer_inventory.d.ts +0 -13
  145. package/dist/session/peer_inventory.js +0 -48
  146. package/dist/session/peer_inventory.js.map +0 -1
  147. package/dist/session/peer_limits.d.ts +0 -9
  148. package/dist/session/peer_limits.js +0 -21
  149. package/dist/session/peer_limits.js.map +0 -1
  150. package/dist/session/setup_wizard.d.ts +0 -39
  151. package/dist/session/setup_wizard.js +0 -63
  152. package/dist/session/setup_wizard.js.map +0 -1
  153. package/dist/session/tools.d.ts +0 -24
  154. package/dist/session/tools.js +0 -252
  155. package/dist/session/tools.js.map +0 -1
  156. package/dist/session/wizard.d.ts +0 -13
  157. package/dist/session/wizard.js +0 -20
  158. package/dist/session/wizard.js.map +0 -1
  159. package/dist/transport/pi_forward_client.d.ts +0 -29
  160. package/dist/transport/pi_forward_client.js +0 -62
  161. package/dist/transport/pi_forward_client.js.map +0 -1
  162. package/dist/ui/footer.d.ts +0 -32
  163. package/dist/ui/footer.js +0 -34
  164. package/dist/ui/footer.js.map +0 -1
  165. package/skills/agent-network/SKILL.md +0 -310
@@ -1,152 +1,206 @@
1
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync } from "node:fs";
2
+ import { randomUUID } from "node:crypto";
2
3
  import { homedir } from "node:os";
3
4
  import { dirname, isAbsolute, join, resolve as resolvePath } from "node:path";
4
- import { daemonIdForCwd } from "./id.js";
5
5
  import { defaultAgentName } from "../session/local_config.js";
6
6
  /**
7
- * The global daemon registry: which working directories are promoted to
8
- * always-on daemons under the supervisor.
9
- *
10
- * Schema rationale (decision Q in plan/26): the registry stores **only**
11
- * `cwd` per entry. Everything else (agent_name, auto_start_relay, etc.)
12
- * is the cwd's local config at `<cwd>/.pi/remote-pi/config.json` — single
13
- * source of truth, no duplication. The daemon `id` is *derived* from cwd
14
- * via `daemonIdForCwd`, never persisted.
15
- *
16
- * Cwds are always normalized to an **absolute realpath** before storage.
17
- * A user typing `/remote-pi create ~/Movies` or `/remote-pi create .`
18
- * results in the same entry as `/remote-pi create /Users/x/Movies` — no
19
- * surprise duplicates, symlinks collapse correctly.
7
+ * A malformed or old registry is an operator-visible error, not an empty
8
+ * registry. Treating it as empty could overwrite valid registrations on the
9
+ * next save, which is destructive.
20
10
  */
21
- /** Resolved at call time so tests can override via `REMOTE_PI_HOME`. The
22
- * prod path is always `~/.pi/remote/daemons.json`. */
11
+ export class RegistrySchemaError extends Error {
12
+ code;
13
+ constructor(code, message) {
14
+ super(message);
15
+ this.code = code;
16
+ this.name = "RegistrySchemaError";
17
+ }
18
+ }
23
19
  function registryPathInternal() {
24
20
  const root = process.env["REMOTE_PI_HOME"] || homedir();
25
21
  return join(root, ".pi", "remote", "daemons.json");
26
22
  }
27
- /**
28
- * Normalizes a user-provided path: expands `~`/`~/...`, resolves relative
29
- * components against `process.cwd()`, and runs `realpath` to canonicalize
30
- * symlinks. Throws if the resulting path doesn't exist on disk.
31
- *
32
- * `/remote-pi create` always stores normalized paths so two registrations
33
- * of the same logical folder via different aliases produce a single entry.
34
- */
23
+ function emptyRegistry() {
24
+ return { version: 2, daemons: [] };
25
+ }
26
+ /** Canonicalizes a supplied cwd and rejects nonexistent paths. */
35
27
  export function normalizeCwd(input) {
36
- if (!input || !input.trim()) {
28
+ if (!input || !input.trim())
37
29
  throw new Error("cwd is required");
30
+ let path = input.trim();
31
+ if (path === "~")
32
+ path = homedir();
33
+ else if (path.startsWith("~/"))
34
+ path = join(homedir(), path.slice(2));
35
+ if (!isAbsolute(path))
36
+ path = resolvePath(process.cwd(), path);
37
+ return realpathSync(path);
38
+ }
39
+ function registryError(message, code = "registry_schema_invalid") {
40
+ throw new RegistrySchemaError(code, message);
41
+ }
42
+ function isOpaqueId(value) {
43
+ // UUID is generated by this registry. Accept UUID variants to keep the
44
+ // persisted identifier opaque without coupling validation to a display form.
45
+ 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);
46
+ }
47
+ function parseEntry(value, index) {
48
+ if (!value || typeof value !== "object")
49
+ registryError(`registry daemon[${index}] must be an object`);
50
+ const entry = value;
51
+ if (!isOpaqueId(entry["id"]))
52
+ registryError(`registry daemon[${index}].id must be an opaque UUID`);
53
+ if (typeof entry["cwd"] !== "string" || !isAbsolute(entry["cwd"]) || entry["cwd"].length === 0) {
54
+ registryError(`registry daemon[${index}].cwd must be an absolute path`);
55
+ }
56
+ // A vanished cwd stays loadable long enough for supervisor reconcile to
57
+ // remove it. Existing paths must already be their canonical realpath.
58
+ if (existsSync(entry["cwd"]) && realpathSync(entry["cwd"]) !== entry["cwd"]) {
59
+ registryError(`registry daemon[${index}].cwd must be a filesystem realpath`);
38
60
  }
39
- let p = input.trim();
40
- // Expand `~` / `~/relative`. Shell wouldn't expand inside slash command args.
41
- if (p === "~")
42
- p = homedir();
43
- else if (p.startsWith("~/"))
44
- p = join(homedir(), p.slice(2));
45
- if (!isAbsolute(p))
46
- p = resolvePath(process.cwd(), p);
47
- // realpath canonicalizes symlinks + throws if path doesn't exist.
48
- return realpathSync(p);
49
- }
50
- /** Reads the registry, returning an empty one when the file is absent. */
61
+ if (typeof entry["name"] !== "string" || entry["name"].trim().length === 0) {
62
+ registryError(`registry daemon[${index}].name must be a non-empty string`);
63
+ }
64
+ if (entry["desired_state"] !== "running" && entry["desired_state"] !== "stopped") {
65
+ registryError(`registry daemon[${index}].desired_state must be running or stopped`);
66
+ }
67
+ if (typeof entry["created_at"] !== "number" || !Number.isFinite(entry["created_at"]) || entry["created_at"] < 0) {
68
+ registryError(`registry daemon[${index}].created_at must be an epoch timestamp`);
69
+ }
70
+ return {
71
+ id: entry["id"],
72
+ cwd: entry["cwd"],
73
+ name: entry["name"].trim(),
74
+ desired_state: entry["desired_state"],
75
+ created_at: entry["created_at"],
76
+ };
77
+ }
78
+ function validateRegistry(value) {
79
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
80
+ registryError("registry root must be an object");
81
+ }
82
+ const root = value;
83
+ if (root["version"] !== 2) {
84
+ const code = root["version"] === undefined || root["version"] === 1
85
+ ? "registry_schema_unsupported"
86
+ : "registry_schema_invalid";
87
+ registryError(`unsupported daemon registry version ${String(root["version"])}; remove or replace ~/.pi/remote/daemons.json before registering daemons`, code);
88
+ }
89
+ if (!Array.isArray(root["daemons"]))
90
+ registryError("registry.daemons must be an array");
91
+ const daemons = root["daemons"].map((entry, index) => parseEntry(entry, index));
92
+ const ids = new Set();
93
+ const cwds = new Set();
94
+ for (const entry of daemons) {
95
+ if (ids.has(entry.id))
96
+ registryError(`registry contains duplicate id ${entry.id}`);
97
+ if (cwds.has(entry.cwd))
98
+ registryError(`registry contains duplicate cwd ${entry.cwd}`);
99
+ ids.add(entry.id);
100
+ cwds.add(entry.cwd);
101
+ }
102
+ return { version: 2, daemons };
103
+ }
104
+ /** Missing file is empty v2; every existing file must be valid v2. */
51
105
  export function loadRegistry() {
52
- if (!existsSync(registryPathInternal()))
53
- return { daemons: [] };
106
+ const path = registryPathInternal();
107
+ if (!existsSync(path))
108
+ return emptyRegistry();
109
+ let raw;
54
110
  try {
55
- const raw = readFileSync(registryPathInternal(), "utf8");
56
- const parsed = JSON.parse(raw);
57
- if (!parsed || typeof parsed !== "object")
58
- return { daemons: [] };
59
- const arr = parsed.daemons;
60
- if (!Array.isArray(arr))
61
- return { daemons: [] };
62
- const daemons = [];
63
- for (const item of arr) {
64
- if (!item || typeof item !== "object")
65
- continue;
66
- const cwd = item.cwd;
67
- if (typeof cwd === "string" && cwd.length > 0) {
68
- const rawName = item.name;
69
- const entry = { cwd };
70
- if (typeof rawName === "string" && rawName.length > 0)
71
- entry.name = rawName;
72
- daemons.push(entry);
73
- }
74
- }
75
- return { daemons };
111
+ raw = readFileSync(path, "utf8");
76
112
  }
77
- catch {
78
- return { daemons: [] };
113
+ catch (error) {
114
+ throw new RegistrySchemaError("registry_schema_invalid", `cannot read daemon registry: ${String(error)}`);
79
115
  }
116
+ let parsed;
117
+ try {
118
+ parsed = JSON.parse(raw);
119
+ }
120
+ catch (error) {
121
+ throw new RegistrySchemaError("registry_schema_invalid", `invalid daemon registry JSON: ${String(error)}`);
122
+ }
123
+ return validateRegistry(parsed);
80
124
  }
81
- export function saveRegistry(reg) {
82
- mkdirSync(dirname(registryPathInternal()), { recursive: true });
83
- writeFileSync(registryPathInternal(), JSON.stringify(reg, null, 2) + "\n");
125
+ /** Validates before atomically replacing the on-disk registry. */
126
+ export function saveRegistry(registry) {
127
+ const valid = validateRegistry(registry);
128
+ const path = registryPathInternal();
129
+ mkdirSync(dirname(path), { recursive: true });
130
+ const temp = `${path}.${process.pid}.${randomUUID()}.tmp`;
131
+ try {
132
+ writeFileSync(temp, JSON.stringify(valid, null, 2) + "\n", "utf8");
133
+ renameSync(temp, path);
134
+ }
135
+ catch (error) {
136
+ throw new Error(`failed to save daemon registry: ${String(error)}`);
137
+ }
84
138
  }
85
- /**
86
- * Adds a daemon entry. Refuses duplicates (same normalized cwd already
87
- * present). Returns the derived id + normalized cwd so the caller can
88
- * report it back to the user.
89
- */
139
+ /** Explicit registration always starts in the desired running state. */
90
140
  export function addDaemon(rawCwd, name) {
91
141
  const cwd = normalizeCwd(rawCwd);
92
- const reg = loadRegistry();
93
- if (reg.daemons.some((d) => d.cwd === cwd)) {
142
+ const registry = loadRegistry();
143
+ if (registry.daemons.some((entry) => entry.cwd === cwd)) {
94
144
  throw new Error(`Daemon already registered for cwd: ${cwd}`);
95
145
  }
96
- // Always persist a name (the registry is the source of truth now that the
97
- // supervisor injects config via env instead of a local config file).
98
- const resolvedName = name?.trim() || defaultAgentName(cwd);
99
- reg.daemons.push({ cwd, name: resolvedName });
100
- saveRegistry(reg);
101
- return { id: daemonIdForCwd(cwd), cwd, name: resolvedName };
146
+ const entry = {
147
+ id: randomUUID(),
148
+ cwd,
149
+ name: name?.trim() || defaultAgentName(cwd),
150
+ desired_state: "running",
151
+ created_at: Date.now(),
152
+ };
153
+ registry.daemons.push(entry);
154
+ saveRegistry(registry);
155
+ return entry;
102
156
  }
103
- /**
104
- * Removes the daemon entry whose derived id matches `id`. Returns the
105
- * removed cwd (if any). Does NOT touch the cwd's local config — `create`
106
- * the same cwd later restores the registration idempotently.
107
- */
108
157
  export function removeDaemon(id) {
109
- const reg = loadRegistry();
110
- const idx = reg.daemons.findIndex((d) => daemonIdForCwd(d.cwd) === id);
111
- if (idx === -1)
158
+ const registry = loadRegistry();
159
+ const index = registry.daemons.findIndex((entry) => entry.id === id);
160
+ if (index === -1)
112
161
  return { removed: false };
113
- const [removed] = reg.daemons.splice(idx, 1);
114
- saveRegistry(reg);
162
+ const [removed] = registry.daemons.splice(index, 1);
163
+ saveRegistry(registry);
115
164
  return { removed: true, cwd: removed.cwd };
116
165
  }
117
- /** Snapshot of all registered daemons with derived ids. Order matches the
118
- * file's insertion order — first-registered first. */
166
+ /** Finds a registration by canonical cwd for external lifecycle integrations. */
167
+ export function findDaemonByCwd(rawCwd) {
168
+ let cwd;
169
+ try {
170
+ cwd = normalizeCwd(rawCwd);
171
+ }
172
+ catch {
173
+ let path = rawCwd.trim();
174
+ if (path === "~")
175
+ path = homedir();
176
+ else if (path.startsWith("~/"))
177
+ path = join(homedir(), path.slice(2));
178
+ cwd = isAbsolute(path) ? resolvePath(path) : resolvePath(process.cwd(), path);
179
+ }
180
+ return loadRegistry().daemons.find((entry) => entry.cwd === cwd);
181
+ }
182
+ /** Persists intended lifecycle independently from process state. */
183
+ export function setDaemonDesiredState(id, desiredState) {
184
+ const registry = loadRegistry();
185
+ const entry = registry.daemons.find((item) => item.id === id);
186
+ if (!entry)
187
+ return undefined;
188
+ entry.desired_state = desiredState;
189
+ saveRegistry(registry);
190
+ return entry;
191
+ }
192
+ /** Returns v2 entries in insertion order. */
119
193
  export function listDaemons() {
120
- return loadRegistry().daemons.map((d) => ({
121
- id: daemonIdForCwd(d.cwd),
122
- cwd: d.cwd,
123
- // Legacy entries (cwd only) fall back to the folder-derived name so a
124
- // daemon is never nameless. New entries already carry an explicit name.
125
- name: d.name ?? defaultAgentName(d.cwd),
126
- }));
194
+ return loadRegistry().daemons;
127
195
  }
128
196
  /**
129
- * One-shot migration: backfill `name` (folder-derived) into legacy entries
130
- * that predate the name field, persisting the change to `daemons.json`.
131
- * Idempotent — writes only when something was missing. Returns how many
132
- * entries were backfilled. The supervisor runs this on start.
197
+ * Backward compatible export name only. v2 deliberately has no in-place
198
+ * migration: an old registry must be explicitly replaced by its operator.
133
199
  */
134
200
  export function migrateRegistryNames() {
135
- const reg = loadRegistry();
136
- let changed = 0;
137
- for (const d of reg.daemons) {
138
- if (!d.name) {
139
- d.name = defaultAgentName(d.cwd);
140
- changed++;
141
- }
142
- }
143
- if (changed > 0)
144
- saveRegistry(reg);
145
- return changed;
146
- }
147
- /** Test/diag-only: returns the on-disk path. Exported so tests can poke
148
- * at it (e.g. tmpdir override is done via env, but for now the path is
149
- * hardcoded to ~/.pi/remote/daemons.json). */
201
+ loadRegistry();
202
+ return 0;
203
+ }
150
204
  export function registryPath() {
151
205
  return registryPathInternal();
152
206
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/daemon/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/daemon/registry.ts"],"names":[],"mappings":"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"}
@@ -1,194 +1,140 @@
1
1
  import { EventEmitter } from "node:events";
2
- import type { DaemonState } from "./control_protocol.js";
2
+ import type { DaemonState, ProcessState, RelayState, RuntimeState } from "./control_protocol.js";
3
3
  import { type LocalConfig } from "../session/local_config.js";
4
- /**
5
- * Wrapper around a `pi --mode rpc -e <extension>` child process for the
6
- * supervisor.
7
- *
8
- * Lifecycle:
9
- * - `spawn()` boots the child with the daemon's cwd + `REMOTE_PI_DAEMON=1`
10
- * env so the extension knows to skip the interactive wizard.
11
- * - `sendPrompt(text)` writes a Pi RPC `prompt` command to stdin.
12
- * - The child's stdout (Pi RPC events) is currently consumed line-by-line
13
- * and ignored — wave 2 only needs fire-and-forget. Later waves can
14
- * surface the events back through the supervisor's status op.
15
- * - Exit/crash fires `exit` event with `{code, signal, isCrash}` so the
16
- * supervisor can decide whether to auto-restart.
17
- *
18
- * Each `RpcChild` instance maps 1:1 to a registry entry (single cwd).
19
- * The supervisor owns the map of these and addresses them by `id`.
20
- */
4
+ /** RPC child wrapper. PID creation is not readiness: only structured stdout
5
+ * responses/events can move runtime from pending to ready. */
21
6
  export interface RpcChildOptions {
22
- /** Path to the `pi` binary. Defaults to "pi" (must be on PATH). */
23
7
  piBin?: string;
24
- /** Absolute path to the remote-pi `dist/index.js` to load as -e. */
8
+ /** Retained until bin/supervisor wiring is removed; daemon spawn deliberately
9
+ * does not pass it as `-e` because Pi's configured extension environment is
10
+ * the sole extension source. */
25
11
  extensionPath: string;
26
- /** Working directory for the spawned process. Determines which local
27
- * config the extension reads. */
28
12
  cwd: string;
29
- /** Additional env vars merged on top of `process.env` + the mandatory
30
- * `REMOTE_PI_DAEMON=1`. */
13
+ /** Stable daemon endpoint identity supplied by the supervisor. */
14
+ endpointId?: string;
31
15
  env?: NodeJS.ProcessEnv;
32
- /**
33
- * Daemon config injected into the child via `REMOTE_PI_DIRECT_CONFIG`
34
- * (JSON inline) instead of a per-cwd `.pi/remote-pi/config.json` file. The
35
- * supervisor builds this from the registry. When set, the child reads it
36
- * env-first (see `loadLocalConfig`) and no config file is needed. Also the
37
- * source of the `--name` for the session. Falls back to the on-disk config
38
- * when omitted.
39
- */
40
16
  config?: LocalConfig;
17
+ readinessTimeoutMs?: number;
18
+ promptTimeoutMs?: number;
41
19
  }
42
20
  export interface RpcChildExitEvent {
43
21
  code: number | null;
44
22
  signal: NodeJS.Signals | null;
45
- /** True when exit was not clean (non-zero or signal). */
23
+ /** True for every exit not initiated through stop(), including code 0. */
46
24
  isCrash: boolean;
47
25
  }
26
+ export interface PromptAcceptance {
27
+ accepted: boolean;
28
+ code?: string;
29
+ error?: string;
30
+ }
31
+ export interface RuntimeReadyEvent {
32
+ control_protocol_version?: number;
33
+ extension_version?: string;
34
+ endpoint_id?: string;
35
+ runtime_instance_id?: string;
36
+ session_id?: string;
37
+ }
38
+ export interface RuntimeFailedEvent {
39
+ stage?: string;
40
+ code: string;
41
+ message?: string;
42
+ retryable: boolean;
43
+ }
44
+ export interface RelayStateChangedEvent {
45
+ state: RelayState;
46
+ }
47
+ export interface SessionChangedEvent {
48
+ session_id?: string;
49
+ }
48
50
  export declare const EXIT_DAEMON_FRESH_SESSION = 42;
49
- /**
50
- * Resolve the `pi` executable for `spawn` (plan/40, decision C). On Windows a
51
- * bare `pi` is actually `pi.cmd`/`pi.ps1`, and `spawn` won't find it without an
52
- * extension → resolve the real path via `where` (rather than `shell:true`,
53
- * which risks shell injection). An explicit path or an already-suffixed name is
54
- * used as-is. POSIX returns the name unchanged. Best-effort: if `where` fails,
55
- * fall back to the bare name (spawn will surface ENOENT honestly).
56
- *
57
- * `where` lists every match in PATH order, which on pi-node installs puts the
58
- * extensionless `pi` (a shell script) BEFORE `pi.cmd`. Naively taking the first
59
- * line spawns the unrunnable script → ENOENT → "crashed". So we prefer a result
60
- * with a real Windows executable extension and only fall back to the first line.
61
- */
51
+ export declare const DEFAULT_READINESS_TIMEOUT_MS = 10000;
52
+ export declare const DEFAULT_PROMPT_TIMEOUT_MS = 5000;
62
53
  export declare function resolvePiBin(piBin: string, plat?: NodeJS.Platform): string;
63
- /** What to pass to `spawn`: the executable and any args to prepend before the
64
- * caller's args. On POSIX (and for `.exe`) `prefixArgs` is empty. */
65
54
  export interface PiSpawnTarget {
66
55
  command: string;
67
56
  prefixArgs: string[];
68
57
  }
69
- /**
70
- * Resolve `pi` to a directly-spawnable target (plan/40). On Windows `pi` is an
71
- * npm `.cmd` shim, which modern Node refuses to `spawn` without `shell:true`
72
- * (EINVAL, post CVE-2024-27980). Wrapping it in `cmd.exe` would (a) add a layer
73
- * that orphans the real `node` on kill and (b) complicate stdio — both fatal for
74
- * a long-lived RPC daemon the supervisor must stop/restart cleanly. Instead we
75
- * parse the shim to recover the underlying `node <cli.js>` and spawn that
76
- * directly: one process, clean signals, clean stdio.
77
- *
78
- * Falls back to the bare resolved path when not a parseable shim (e.g. a real
79
- * `pi.exe`, or POSIX) so `spawn` surfaces any real error honestly.
80
- */
81
58
  export declare function resolvePiSpawn(piBin: string, plat?: NodeJS.Platform, nodeExe?: string): PiSpawnTarget;
82
- /**
83
- * Extract the JS entry an npm `.cmd` shim launches. npm shims invoke
84
- * `"%_prog%" "%dp0%\<relative>\entry.js" %*`; we recover `<dir>\<relative>\entry.js`
85
- * (dir = the shim's own folder, i.e. `%dp0%`). Returns null when the shim
86
- * doesn't match the expected shape or the target is missing.
87
- */
88
59
  export declare function _npmShimTarget(cmdPath: string): string | null;
60
+ export declare function busyTransition(line: string): boolean | null;
89
61
  /**
90
- * Maps an RPC stdout line to a busy-state transition: `message_start` → true
91
- * (a message is streaming), `message_end` → false. Other lines → null (no
92
- * change). Pure + exported for tests.
93
- *
94
- * NOTE (plan/39 detail 1): the Pi RPC stream has NO turn-level event — only
95
- * per-message start/end (and `response{command:"prompt"}` is emitted at
96
- * PREFLIGHT, i.e. turn START, not end). So this passive flag reflects
97
- * "a message is being produced right now"; the authoritative turn-busy signal
98
- * is `get_state.isStreaming` (see `RpcChild.refreshBusy`).
62
+ * The installed Pi RPC starts configured extensions itself. In particular this
63
+ * must not attach Remote Pi with `-e`, which could load it a second time.
99
64
  */
100
- export declare function busyTransition(line: string): boolean | null;
65
+ export declare function rpcSpawnArgs(_extensionPath: string, sessionName?: string, useContinue?: boolean): string[];
66
+ type ParsedRuntimeEvent = {
67
+ type: "runtime_ready";
68
+ event: RuntimeReadyEvent;
69
+ } | {
70
+ type: "runtime_failed";
71
+ event: RuntimeFailedEvent;
72
+ } | {
73
+ type: "relay_state_changed";
74
+ event: RelayStateChangedEvent;
75
+ } | {
76
+ type: "session_changed";
77
+ event: SessionChangedEvent;
78
+ };
101
79
  /**
102
- * CLI args for the daemon's `pi --mode rpc` child.
103
- *
104
- * `--continue` is the key bit: it resumes the **most recent** session for the
105
- * cwd (`SessionManager.continueRecent`, non-interactive — unlike `--resume`
106
- * which opens a picker). Without it every supervisor restart spun up a brand
107
- * new session file, piling up thousands of JSONLs per folder. With it, a
108
- * restart REUSES the one session; the app's `/new` (session_new) still rolls
109
- * it over to a fresh one, which the next restart then continues. First boot
110
- * (no prior session) just creates the first one.
111
- *
112
- * `--name <sessionName>`, when given, pins the session's display name to the
113
- * daemon's identity (its `agent_name`) so every restart shows up under the
114
- * same stable name in the picker/app instead of an auto-generated one. The
115
- * daemon's name is set at registration (`remote-pi create <cwd> --name "…"`).
116
- * Omitted when no name resolves, so the arg list stays minimal.
117
- *
118
- * `--approve` is mandatory for a daemon (pi ≥0.79 project trust): RPC mode is
119
- * non-interactive, so without an override Pi resolves an untrusted project
120
- * folder (any folder with `.pi/` or CLAUDE.md/AGENTS.md) to NOT trusted and
121
- * silently skips its `.pi/settings.json` (model/provider/keys), instructions,
122
- * resources and project extensions — the daemon then comes up with no model
123
- * and fails on the first turn. The operator already authorized this folder by
124
- * registering/launching a daemon in it, so `--approve` (trust-for-this-run) is
125
- * the correct non-interactive stance. (Does NOT affect the separate "extension
126
- * loaded twice" conflict, which comes from the extension being BOTH installed
127
- * in ~/.pi/agent/extensions or cwd/.pi/extensions AND passed via `-e`.)
80
+ * Parses direct daemon-control events and the current extension's custom
81
+ * relay-state message shape. Natural-language stderr is intentionally absent.
128
82
  */
129
- export declare function rpcSpawnArgs(extensionPath: string, sessionName?: string, useContinue?: boolean): string[];
83
+ export declare function parseRuntimeEvent(line: string): ParsedRuntimeEvent | null;
130
84
  export declare class RpcChild extends EventEmitter {
131
85
  private readonly opts;
132
86
  private child;
133
87
  private _state;
88
+ private _process;
89
+ private _runtime;
90
+ private _relay;
134
91
  private _startedAt;
92
+ private _runtimeInstanceId;
93
+ private _sessionId;
135
94
  private _restartCount;
136
- /** True while a deliberate `stop()` is in flight. The process dies by
137
- * signal (SIGTERM/SIGKILL), which would otherwise look like a crash and
138
- * trip the supervisor's auto-restart — re-spawning a daemon the operator
139
- * just stopped/removed. Gating `isCrash` on this makes a deliberate stop a
140
- * clean exit (no restart). Reset on every `spawn()`. */
141
95
  private _stopping;
142
- /** Next spawn should create a fresh session instead of --continue. */
143
96
  private forceFreshSessionOnNextSpawn;
144
- /** Accumulates partial stdout lines while waiting for `\n`. */
145
97
  private stdoutBuf;
146
- /** Passive busy flag derived from the RPC stream (message_start/end). Hint
147
- * only; `refreshBusy` syncs it authoritatively via get_state.isStreaming. */
148
98
  private _busy;
149
- /** In-flight `get_state` requests, keyed by request id. */
150
- private readonly _statePending;
99
+ private rpcReady;
100
+ private extensionReady;
101
+ private extensionReadyEvent;
102
+ private readinessTimer;
103
+ private readyPromise;
104
+ private readyResolve;
105
+ private readonly statePending;
106
+ private readonly promptPending;
151
107
  constructor(opts: RpcChildOptions);
152
108
  get state(): DaemonState;
153
- /** Passive busy hint from the stream. Prefer `refreshBusy()` for an
154
- * authoritative check before acting on it (cron skip_if_busy). */
109
+ get processState(): ProcessState;
110
+ get runtimeState(): RuntimeState;
111
+ get relayState(): RelayState;
155
112
  get isBusy(): boolean;
156
113
  get pid(): number | undefined;
157
114
  get restartCount(): number;
115
+ get startedAt(): number | undefined;
116
+ get runtimeInstanceId(): string | undefined;
117
+ get sessionId(): string | undefined;
158
118
  get uptimeMs(): number | undefined;
159
- /**
160
- * Spawn the child process. Idempotent for the same instance: a second
161
- * call while already running is a no-op.
162
- */
119
+ /** Resolves true only after the readiness probe/event, false on timeout/exit. */
120
+ ready(): Promise<boolean>;
163
121
  spawn(): void;
164
- /**
165
- * Sends a Pi RPC `prompt` command to the child's stdin. Fire-and-forget
166
- * — we don't wait for the response (response would be the success ack;
167
- * the actual agent output streams via the relay/UDS, not back through
168
- * stdout).
169
- *
170
- * Returns false if the child isn't running (caller decides how to report).
171
- */
172
- sendPrompt(text: string, requestId?: string): boolean;
173
- /**
174
- * Asks the child to exit gracefully. Sends SIGTERM; if the child doesn't
175
- * exit within `timeoutMs`, escalates to SIGKILL. Resolves when the
176
- * `exit` event fires.
177
- */
122
+ /** Waits for Pi's correlated prompt preflight response, not merely stdin write. */
123
+ sendPrompt(text: string, requestId?: string, timeoutMs?: number): Promise<PromptAcceptance>;
178
124
  stop(timeoutMs?: number): Promise<void>;
179
- private _onStdout;
180
- private _handleStdoutLine;
181
- /**
182
- * Authoritative busy check: queries the child's `get_state` and syncs
183
- * `_busy` to `isStreaming`. Resolves the passive flag on timeout (no
184
- * response) or when the child isn't running. Used by the cron `skip_if_busy`
185
- * gate, where a false "not busy" would pile a prompt onto a live turn.
186
- */
187
125
  refreshBusy(timeoutMs?: number): Promise<boolean>;
188
- /** Test-only: feed a raw stdout line through the same handler. */
126
+ /** Test injection point for deterministic RPC event/response coverage. */
189
127
  _ingestStdoutForTest(line: string): void;
190
- private _onExit;
191
- /** Bumps the restart counter — called by the supervisor when it
192
- * decides to re-spawn after a crash. Exposed so tests can drive it. */
128
+ private startReadinessProbe;
129
+ private onStdout;
130
+ private handleStdoutLine;
131
+ private parseResponse;
132
+ private handleResponse;
133
+ private handleRuntimeEvent;
134
+ private acceptExtensionReady;
135
+ private maybeMarkReady;
136
+ private failRuntime;
137
+ private onExit;
193
138
  noteRestart(): void;
194
139
  }
140
+ export {};