remote-pi 0.1.2 → 0.2.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 (99) hide show
  1. package/README.md +195 -36
  2. package/dist/bin/supervisord.d.ts +2 -0
  3. package/dist/bin/supervisord.js +44 -0
  4. package/dist/bin/supervisord.js.map +1 -0
  5. package/dist/config.d.ts +49 -5
  6. package/dist/config.js +73 -9
  7. package/dist/config.js.map +1 -1
  8. package/dist/daemon/client.d.ts +20 -0
  9. package/dist/daemon/client.js +128 -0
  10. package/dist/daemon/client.js.map +1 -0
  11. package/dist/daemon/control_protocol.d.ts +100 -0
  12. package/dist/daemon/control_protocol.js +63 -0
  13. package/dist/daemon/control_protocol.js.map +1 -0
  14. package/dist/daemon/id.d.ts +18 -0
  15. package/dist/daemon/id.js +30 -0
  16. package/dist/daemon/id.js.map +1 -0
  17. package/dist/daemon/install.d.ts +132 -0
  18. package/dist/daemon/install.js +312 -0
  19. package/dist/daemon/install.js.map +1 -0
  20. package/dist/daemon/registry.d.ts +47 -0
  21. package/dist/daemon/registry.js +123 -0
  22. package/dist/daemon/registry.js.map +1 -0
  23. package/dist/daemon/rpc_child.d.ts +76 -0
  24. package/dist/daemon/rpc_child.js +130 -0
  25. package/dist/daemon/rpc_child.js.map +1 -0
  26. package/dist/daemon/supervisor.d.ts +38 -0
  27. package/dist/daemon/supervisor.js +301 -0
  28. package/dist/daemon/supervisor.js.map +1 -0
  29. package/dist/index.d.ts +62 -8
  30. package/dist/index.js +1232 -304
  31. package/dist/index.js.map +1 -1
  32. package/dist/mesh/canonical.d.ts +30 -0
  33. package/dist/mesh/canonical.js +61 -0
  34. package/dist/mesh/canonical.js.map +1 -0
  35. package/dist/mesh/client.d.ts +31 -0
  36. package/dist/mesh/client.js +56 -0
  37. package/dist/mesh/client.js.map +1 -0
  38. package/dist/mesh/encoding.d.ts +36 -0
  39. package/dist/mesh/encoding.js +53 -0
  40. package/dist/mesh/encoding.js.map +1 -0
  41. package/dist/mesh/self_revoke.d.ts +111 -0
  42. package/dist/mesh/self_revoke.js +182 -0
  43. package/dist/mesh/self_revoke.js.map +1 -0
  44. package/dist/mesh/siblings.d.ts +62 -0
  45. package/dist/mesh/siblings.js +95 -0
  46. package/dist/mesh/siblings.js.map +1 -0
  47. package/dist/mesh/types.d.ts +34 -0
  48. package/dist/mesh/types.js +11 -0
  49. package/dist/mesh/types.js.map +1 -0
  50. package/dist/mesh/verify.d.ts +17 -0
  51. package/dist/mesh/verify.js +77 -0
  52. package/dist/mesh/verify.js.map +1 -0
  53. package/dist/pairing/qr.d.ts +16 -5
  54. package/dist/pairing/qr.js +27 -8
  55. package/dist/pairing/qr.js.map +1 -1
  56. package/dist/pairing/storage.d.ts +41 -0
  57. package/dist/pairing/storage.js +158 -21
  58. package/dist/pairing/storage.js.map +1 -1
  59. package/dist/protocol/types.d.ts +23 -0
  60. package/dist/session/broker.d.ts +74 -0
  61. package/dist/session/broker.js +142 -4
  62. package/dist/session/broker.js.map +1 -1
  63. package/dist/session/broker_remote.d.ts +110 -0
  64. package/dist/session/broker_remote.js +397 -0
  65. package/dist/session/broker_remote.js.map +1 -0
  66. package/dist/session/cwd_lock.d.ts +28 -0
  67. package/dist/session/cwd_lock.js +89 -0
  68. package/dist/session/cwd_lock.js.map +1 -0
  69. package/dist/session/global_config.d.ts +9 -0
  70. package/dist/session/global_config.js +9 -0
  71. package/dist/session/global_config.js.map +1 -1
  72. package/dist/session/leader_election.d.ts +16 -0
  73. package/dist/session/leader_election.js +22 -0
  74. package/dist/session/leader_election.js.map +1 -1
  75. package/dist/session/local_config.d.ts +12 -5
  76. package/dist/session/local_config.js +24 -3
  77. package/dist/session/local_config.js.map +1 -1
  78. package/dist/session/peer.d.ts +28 -1
  79. package/dist/session/peer.js +69 -2
  80. package/dist/session/peer.js.map +1 -1
  81. package/dist/session/peer_inventory.d.ts +13 -0
  82. package/dist/session/peer_inventory.js +48 -0
  83. package/dist/session/peer_inventory.js.map +1 -0
  84. package/dist/session/setup_wizard.d.ts +32 -8
  85. package/dist/session/setup_wizard.js +45 -33
  86. package/dist/session/setup_wizard.js.map +1 -1
  87. package/dist/session/tools.d.ts +15 -7
  88. package/dist/session/tools.js +145 -31
  89. package/dist/session/tools.js.map +1 -1
  90. package/dist/transport/pi_forward_client.d.ts +29 -0
  91. package/dist/transport/pi_forward_client.js +62 -0
  92. package/dist/transport/pi_forward_client.js.map +1 -0
  93. package/dist/ui/footer.js +8 -6
  94. package/dist/ui/footer.js.map +1 -1
  95. package/docs/daemon.md +289 -0
  96. package/package.json +10 -3
  97. package/service-templates/launchd.plist.template +35 -0
  98. package/service-templates/systemd.service.template +19 -0
  99. package/skills/agent-network/SKILL.md +273 -294
@@ -1,10 +1,11 @@
1
1
  export interface LocalConfig {
2
2
  agent_name?: string;
3
- session_name?: string;
4
3
  /**
5
- * If true (default), `/remote-pi` with no args auto-joins the session and
6
- * starts the relay on a fresh terminal. Added in plano 21. Legacy configs
7
- * without this field are treated as `true` for backward compatibility.
4
+ * If true (default), `/remote-pi` with no args auto-joins the local UDS
5
+ * mesh and starts the relay on a fresh terminal. The field name is
6
+ * historical (plano 21); the UX wording was reworked to "use the relay
7
+ * on this terminal to connect to the remote mesh (mobile + PCs)". Legacy
8
+ * configs without this field are treated as `true` for backward compat.
8
9
  */
9
10
  auto_start_relay?: boolean;
10
11
  }
@@ -12,7 +13,13 @@ export interface LocalConfig {
12
13
  export declare function localConfigExists(cwd: string): boolean;
13
14
  export declare function loadLocalConfig(cwd: string): LocalConfig;
14
15
  export declare function saveLocalConfig(cwd: string, patch: Partial<LocalConfig>): void;
15
- /** Default agent name when none is configured: basename of cwd. */
16
+ /**
17
+ * Default agent name when none is configured: `<parent>/<folder>` of the
18
+ * given cwd. Falls back gracefully when the parent isn't meaningful
19
+ * (root, current dir, single-segment paths) — in those cases just the
20
+ * folder name. Purpose: surface a non-empty string the user can accept
21
+ * by pressing enter in the wizard.
22
+ */
16
23
  export declare function defaultAgentName(cwd: string): string;
17
24
  /** Resolves auto_start_relay with backward-compat (undefined → true). */
18
25
  export declare function effectiveAutoStartRelay(cfg: LocalConfig): boolean;
@@ -18,7 +18,16 @@ export function loadLocalConfig(cwd) {
18
18
  const parsed = JSON.parse(raw);
19
19
  if (!parsed || typeof parsed !== "object")
20
20
  return {};
21
- return parsed;
21
+ // Only surface known fields. Legacy `session_name` from pre-refactor
22
+ // configs is silently dropped — the local UDS mesh is now always a
23
+ // single fixed session, so the field has no meaning.
24
+ const src = parsed;
25
+ const cfg = {};
26
+ if (typeof src["agent_name"] === "string")
27
+ cfg.agent_name = src["agent_name"];
28
+ if (typeof src["auto_start_relay"] === "boolean")
29
+ cfg.auto_start_relay = src["auto_start_relay"];
30
+ return cfg;
22
31
  }
23
32
  catch {
24
33
  return {};
@@ -36,9 +45,21 @@ export function saveLocalConfig(cwd, patch) {
36
45
  next.auto_start_relay = true;
37
46
  writeFileSync(p, JSON.stringify(next, null, 2));
38
47
  }
39
- /** Default agent name when none is configured: basename of cwd. */
48
+ /**
49
+ * Default agent name when none is configured: `<parent>/<folder>` of the
50
+ * given cwd. Falls back gracefully when the parent isn't meaningful
51
+ * (root, current dir, single-segment paths) — in those cases just the
52
+ * folder name. Purpose: surface a non-empty string the user can accept
53
+ * by pressing enter in the wizard.
54
+ */
40
55
  export function defaultAgentName(cwd) {
41
- return basename(cwd) || "agent";
56
+ const folder = basename(cwd);
57
+ const parent = basename(dirname(cwd));
58
+ if (!folder)
59
+ return "agent";
60
+ if (!parent || parent === "/" || parent === folder || parent === ".")
61
+ return folder;
62
+ return `${parent}/${folder}`;
42
63
  }
43
64
  /** Resolves auto_start_relay with backward-compat (undefined → true). */
44
65
  export function effectiveAutoStartRelay(cfg) {
@@ -1 +1 @@
1
- {"version":3,"file":"local_config.js","sourceRoot":"","sources":["../../src/session/local_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,SAAS,GAAG,eAAe,CAAC;AAClC,MAAM,UAAU,GAAG,aAAa,CAAC;AAajC,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACrD,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,KAA2B;IACtE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,IAAI,GAAgB,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;IACnD,4EAA4E;IAC5E,uEAAuE;IACvE,qEAAqE;IACrE,IAAI,OAAO,IAAI,CAAC,gBAAgB,KAAK,SAAS;QAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC7E,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;AAClC,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,uBAAuB,CAAC,GAAgB;IACtD,OAAO,GAAG,CAAC,gBAAgB,KAAK,KAAK,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"local_config.js","sourceRoot":"","sources":["../../src/session/local_config.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type Envelope } from "./envelope.js";
2
+ import { Broker } from "./broker.js";
2
3
  /**
3
4
  * Symmetric peer-in-session API. Hides whether you are leader or follower;
4
5
  * `send`, `request`, `onMessage`, `rename`, `leave` all work the same.
@@ -17,6 +18,14 @@ export interface SessionPeerOptions {
17
18
  /** Per-request default timeout (ms). Override per call if needed. */
18
19
  defaultTimeoutMs?: number;
19
20
  }
21
+ export type AckStatus = "received" | "busy" | "denied" | "timeout";
22
+ export interface AckResult {
23
+ status: AckStatus;
24
+ /** The original envelope id that was awaiting ACK. */
25
+ id: string;
26
+ /** Target name reported by broker (when ACK arrived). Undefined on timeout. */
27
+ target?: string;
28
+ }
20
29
  export declare class SessionPeer {
21
30
  private readonly opts;
22
31
  /** Name actually assigned by the broker (may differ via #N collision suffix). */
@@ -25,8 +34,10 @@ export declare class SessionPeer {
25
34
  private broker;
26
35
  private socket;
27
36
  private buf;
28
- /** Map of in-flight request ids → resolver. */
37
+ /** Map of in-flight request ids → resolver. Used by `request()`. */
29
38
  private readonly pending;
39
+ /** Map of in-flight send ids → ACK resolver. Used by `sendWithAck()`. */
40
+ private readonly ackPending;
30
41
  private readonly handlers;
31
42
  private readonly reconnectHandlers;
32
43
  private leftFlag;
@@ -37,6 +48,10 @@ export declare class SessionPeer {
37
48
  name(): string;
38
49
  /** Returns "leader" or "follower" — current role. */
39
50
  currentRole(): "leader" | "follower";
51
+ /** Returns the locally-hosted Broker when this peer is the leader, or
52
+ * null when it's a follower. Wave 25C uses this to attach the
53
+ * cross-PC router. */
54
+ localBroker(): Broker | null;
40
55
  /**
41
56
  * Fire-and-forget send. Doesn't await a reply.
42
57
  *
@@ -47,6 +62,18 @@ export declare class SessionPeer {
47
62
  * new unsolicited message and its `request()` call times out.
48
63
  */
49
64
  send(to: string | string[], body: unknown, re?: string | null): Promise<void>;
65
+ /**
66
+ * Unicast send + await broker ACK. Returns the ACK status:
67
+ * - `received` — peer was idle, envelope delivered, will be processed soon
68
+ * - `busy` — peer mid-turn, envelope dropped; sender is owner of retry
69
+ * - `denied` — peer explicitly refused (reserved; no producer in MVP)
70
+ * - `timeout` — no ACK within `timeoutMs`; treat as transport error
71
+ *
72
+ * Only meaningful for unicast non-broadcast addresses. The peer's body-level
73
+ * reply (if any) is asynchronous and arrives as a normal inbound envelope
74
+ * carrying `re=<this-send-id>` in a future turn — handled by `onMessage`.
75
+ */
76
+ sendWithAck(to: string, body: unknown, re?: string | null, timeoutMs?: number): Promise<AckResult>;
50
77
  /**
51
78
  * Send + await reply. Resolves with the first inbound envelope whose `re`
52
79
  * matches the outbound `id`. Rejects on timeout.
@@ -3,6 +3,7 @@ import { envelope, parse, serialize, EnvelopeError } from "./envelope.js";
3
3
  import { joinOrLead } from "./leader_election.js";
4
4
  import { Broker } from "./broker.js";
5
5
  const DEFAULT_TIMEOUT_MS = 30_000;
6
+ const ACK_TIMEOUT_MS = 5_000;
6
7
  const FAILOVER_RETRY_MS = 100;
7
8
  export class SessionPeer {
8
9
  opts;
@@ -12,8 +13,10 @@ export class SessionPeer {
12
13
  broker = null;
13
14
  socket = null;
14
15
  buf = "";
15
- /** Map of in-flight request ids → resolver. */
16
+ /** Map of in-flight request ids → resolver. Used by `request()`. */
16
17
  pending = new Map();
18
+ /** Map of in-flight send ids → ACK resolver. Used by `sendWithAck()`. */
19
+ ackPending = new Map();
17
20
  handlers = new Set();
18
21
  reconnectHandlers = new Set();
19
22
  leftFlag = false;
@@ -34,6 +37,12 @@ export class SessionPeer {
34
37
  currentRole() {
35
38
  return this.role;
36
39
  }
40
+ /** Returns the locally-hosted Broker when this peer is the leader, or
41
+ * null when it's a follower. Wave 25C uses this to attach the
42
+ * cross-PC router. */
43
+ localBroker() {
44
+ return this.broker;
45
+ }
37
46
  /**
38
47
  * Fire-and-forget send. Doesn't await a reply.
39
48
  *
@@ -47,6 +56,35 @@ export class SessionPeer {
47
56
  const env = envelope(this.assignedName, to, body, re);
48
57
  await this._writeEnvelope(env);
49
58
  }
59
+ /**
60
+ * Unicast send + await broker ACK. Returns the ACK status:
61
+ * - `received` — peer was idle, envelope delivered, will be processed soon
62
+ * - `busy` — peer mid-turn, envelope dropped; sender is owner of retry
63
+ * - `denied` — peer explicitly refused (reserved; no producer in MVP)
64
+ * - `timeout` — no ACK within `timeoutMs`; treat as transport error
65
+ *
66
+ * Only meaningful for unicast non-broadcast addresses. The peer's body-level
67
+ * reply (if any) is asynchronous and arrives as a normal inbound envelope
68
+ * carrying `re=<this-send-id>` in a future turn — handled by `onMessage`.
69
+ */
70
+ async sendWithAck(to, body, re = null, timeoutMs = ACK_TIMEOUT_MS) {
71
+ const env = envelope(this.assignedName, to, body, re);
72
+ return new Promise((resolve) => {
73
+ const timer = setTimeout(() => {
74
+ this.ackPending.delete(env.id);
75
+ resolve({ status: "timeout", id: env.id });
76
+ }, timeoutMs);
77
+ this.ackPending.set(env.id, { resolve, timer });
78
+ this._writeEnvelope(env).catch(() => {
79
+ const slot = this.ackPending.get(env.id);
80
+ if (!slot)
81
+ return;
82
+ clearTimeout(slot.timer);
83
+ this.ackPending.delete(env.id);
84
+ resolve({ status: "timeout", id: env.id });
85
+ });
86
+ });
87
+ }
50
88
  /**
51
89
  * Send + await reply. Resolves with the first inbound envelope whose `re`
52
90
  * matches the outbound `id`. Rejects on timeout.
@@ -198,7 +236,31 @@ export class SessionPeer {
198
236
  return;
199
237
  throw e;
200
238
  }
201
- // Correlate replies first.
239
+ // Intercept broker ACKs first. Body shape `{type:"ack", status, target}`
240
+ // from broker correlates by `re` against pending `sendWithAck` ids. Even
241
+ // when no `sendWithAck` is waiting (e.g. message was sent via plain
242
+ // `send()` or legacy `request()`), the ACK envelope must be swallowed
243
+ // here — otherwise it would match `request()`'s pending map by `re` and
244
+ // resolve the request with the ACK body instead of the peer's real reply.
245
+ //
246
+ // Plan/25 Wave D: cross-PC ACKs arrive with prefixed sender
247
+ // (`<pcLabel>:broker`) since broker_remote rewrites `from` to include
248
+ // the source PC label. Accept both forms here so cross-PC senders
249
+ // resolve their `sendWithAck` Promise instead of timing out.
250
+ if (env.re && (env.from === "broker" || env.from.endsWith(":broker"))) {
251
+ const ackBody = env.body;
252
+ if (ackBody && ackBody.type === "ack" && typeof ackBody.status === "string") {
253
+ const slot = this.ackPending.get(env.re);
254
+ if (slot) {
255
+ clearTimeout(slot.timer);
256
+ this.ackPending.delete(env.re);
257
+ const status = ackBody.status;
258
+ slot.resolve({ status, id: env.re, target: ackBody.target });
259
+ }
260
+ return;
261
+ }
262
+ }
263
+ // Correlate replies for `request()`.
202
264
  if (env.re) {
203
265
  const slot = this.pending.get(env.re);
204
266
  if (slot) {
@@ -263,6 +325,11 @@ export class SessionPeer {
263
325
  slot.reject(new Error("peer leaving"));
264
326
  }
265
327
  this.pending.clear();
328
+ for (const slot of this.ackPending.values()) {
329
+ clearTimeout(slot.timer);
330
+ slot.resolve({ status: "timeout", id: "" });
331
+ }
332
+ this.ackPending.clear();
266
333
  }
267
334
  }
268
335
  //# sourceMappingURL=peer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"peer.js","sourceRoot":"","sources":["../../src/session/peer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../../src/session/peer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Plan/25 Wave D — pure formatter for the `/remote-pi peers` output.
3
+ *
4
+ * Lives in its own module so it can be unit-tested without booting the full
5
+ * extension (no keychain access, no relay client, no mocks needed). The
6
+ * extension imports the function and wraps it with the `_sessionPeer`
7
+ * `list_peers` request.
8
+ *
9
+ * Input shape: the broker's `list_peers_reply` body returns peer names as
10
+ * plain strings — local peers without a prefix (`sess-1`, `agent-2`),
11
+ * cross-PC peers with a `<pc_label>:<peer>` prefix (`casa:sess-3`).
12
+ */
13
+ export declare function formatPeerInventory(peers: string[], selfName?: string): string;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Plan/25 Wave D — pure formatter for the `/remote-pi peers` output.
3
+ *
4
+ * Lives in its own module so it can be unit-tested without booting the full
5
+ * extension (no keychain access, no relay client, no mocks needed). The
6
+ * extension imports the function and wraps it with the `_sessionPeer`
7
+ * `list_peers` request.
8
+ *
9
+ * Input shape: the broker's `list_peers_reply` body returns peer names as
10
+ * plain strings — local peers without a prefix (`sess-1`, `agent-2`),
11
+ * cross-PC peers with a `<pc_label>:<peer>` prefix (`casa:sess-3`).
12
+ */
13
+ export function formatPeerInventory(peers, selfName) {
14
+ const locals = [];
15
+ const remotes = new Map();
16
+ for (const p of peers) {
17
+ if (selfName && p === selfName)
18
+ continue;
19
+ const idx = p.indexOf(":");
20
+ if (idx > 0 && idx < p.length - 1) {
21
+ const label = p.slice(0, idx);
22
+ const name = p.slice(idx + 1);
23
+ const bucket = remotes.get(label) ?? [];
24
+ bucket.push(name);
25
+ remotes.set(label, bucket);
26
+ }
27
+ else {
28
+ locals.push(p);
29
+ }
30
+ }
31
+ const lines = [" local:"];
32
+ if (locals.length === 0) {
33
+ lines.push(" (none)");
34
+ }
35
+ else {
36
+ for (const n of locals.sort())
37
+ lines.push(` ${n}`);
38
+ }
39
+ const sortedLabels = [...remotes.keys()].sort();
40
+ for (const label of sortedLabels) {
41
+ lines.push("");
42
+ lines.push(` remote:${label}`);
43
+ for (const n of (remotes.get(label) ?? []).sort())
44
+ lines.push(` ${n}`);
45
+ }
46
+ return lines.join("\n");
47
+ }
48
+ //# sourceMappingURL=peer_inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer_inventory.js","sourceRoot":"","sources":["../../src/session/peer_inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,UAAU,mBAAmB,CAAC,KAAe,EAAE,QAAiB;IACpE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,QAAQ,IAAI,CAAC,KAAK,QAAQ;YAAE,SAAS;QACzC,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAa,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -16,17 +16,41 @@ export interface WizardUI {
16
16
  }
17
17
  export interface WizardDefaults {
18
18
  agent_name: string;
19
- session_name: string;
20
- auto_start_relay: boolean;
19
+ use_relay: boolean;
20
+ /**
21
+ * Default for the "Enable daemon mode?" prompt. Doesn't persist in
22
+ * `LocalConfig` — daemon enablement is OS-level state (service unit on
23
+ * disk), not config. The wizard surfaces it so first-time users get
24
+ * the option without having to discover `/remote-pi install` later.
25
+ */
26
+ enable_daemon?: boolean;
21
27
  }
22
28
  /**
23
- * Runs the 3-question setup wizard. Returns the chosen config on confirm,
24
- * or null when the user cancels any prompt.
29
+ * Result of `runSetupWizard`. Extends `LocalConfig` with an out-of-band
30
+ * `enable_daemon` flag the caller acts on (by invoking the install
31
+ * command) — NOT a persisted config field.
32
+ */
33
+ export interface WizardResult extends LocalConfig {
34
+ enable_daemon: boolean;
35
+ }
36
+ /**
37
+ * Runs the 3-question setup wizard. Returns the chosen config + a
38
+ * `enable_daemon` flag on confirm, or null when the user cancels any
39
+ * prompt.
25
40
  *
26
41
  * Prompts:
27
- * 1. Agent name (default: basename of cwd)
28
- * 2. Session name (default: basename of cwd)
29
- * 3. Auto-start relay? (yes/no) relay lets the mobile app connect to this Pi
42
+ * 1. Agent name (default: parent/folder of cwd)
43
+ * 2. Use the relay on this terminal? (yes/no) gates connection to the
44
+ * remote mesh (mobile devices + other PCs over the relay). "No" means
45
+ * local-only: this Pi joins the UDS mesh but doesn't open WSS.
46
+ * 3. Enable daemon mode? (yes/no) — installs the system service so
47
+ * agents you `/remote-pi create` keep running 24/7 in the background.
48
+ * Symlinks the `remote-pi` + `pi-supervisord` CLIs into
49
+ * `~/.local/bin/` so the shell can address daemons by id.
30
50
  * Final: review + confirm "Save and activate?" yes/no
51
+ *
52
+ * The local UDS mesh is always single per machine ("local" session) — no
53
+ * session question. All Pis on the same machine see each other through
54
+ * the same broker.
31
55
  */
32
- export declare function runSetupWizard(ui: WizardUI, defaults: WizardDefaults): Promise<LocalConfig | null>;
56
+ export declare function runSetupWizard(ui: WizardUI, defaults: WizardDefaults): Promise<WizardResult | null>;
@@ -2,59 +2,71 @@ const YES = "Yes";
2
2
  const NO = "No";
3
3
  const CANCEL_TOKEN = "__cancel__";
4
4
  /**
5
- * Runs the 3-question setup wizard. Returns the chosen config on confirm,
6
- * or null when the user cancels any prompt.
5
+ * Runs the 3-question setup wizard. Returns the chosen config + a
6
+ * `enable_daemon` flag on confirm, or null when the user cancels any
7
+ * prompt.
7
8
  *
8
9
  * Prompts:
9
- * 1. Agent name (default: basename of cwd)
10
- * 2. Session name (default: basename of cwd)
11
- * 3. Auto-start relay? (yes/no) relay lets the mobile app connect to this Pi
10
+ * 1. Agent name (default: parent/folder of cwd)
11
+ * 2. Use the relay on this terminal? (yes/no) gates connection to the
12
+ * remote mesh (mobile devices + other PCs over the relay). "No" means
13
+ * local-only: this Pi joins the UDS mesh but doesn't open WSS.
14
+ * 3. Enable daemon mode? (yes/no) — installs the system service so
15
+ * agents you `/remote-pi create` keep running 24/7 in the background.
16
+ * Symlinks the `remote-pi` + `pi-supervisord` CLIs into
17
+ * `~/.local/bin/` so the shell can address daemons by id.
12
18
  * Final: review + confirm "Save and activate?" yes/no
19
+ *
20
+ * The local UDS mesh is always single per machine ("local" session) — no
21
+ * session question. All Pis on the same machine see each other through
22
+ * the same broker.
13
23
  */
14
24
  export async function runSetupWizard(ui, defaults) {
15
25
  const agent_name = await _askText(ui, "Agent name:", defaults.agent_name);
16
26
  if (agent_name === null)
17
27
  return null;
18
- const session_name = await _askText(ui, "Default session:", defaults.session_name);
19
- if (session_name === null)
28
+ ui.notify?.("The relay forwards encrypted messages to the Remote Pi mobile app and other PCs in your mesh. Skip this if you only want a local-only mesh on this machine.", "info");
29
+ const useRelayChoice = await ui.select("Use the relay on this terminal to connect to the remote mesh (mobile + PCs)?", defaults.use_relay ? [YES, NO] : [NO, YES]);
30
+ if (!useRelayChoice)
20
31
  return null;
21
- ui.notify?.("The relay lets the Remote Pi mobile app connect to this Pi over the network. Enable it to allow the app to send prompts and receive responses; disable for local-only use.", "info");
22
- const autoChoice = await ui.select("Auto-start the relay (for mobile app access)?", defaults.auto_start_relay ? [YES, NO] : [NO, YES]);
23
- if (!autoChoice)
32
+ const auto_start_relay = useRelayChoice === YES;
33
+ ui.notify?.("Daemon mode runs Pi agents 24/7 in the background (systemd on Linux, launchd on macOS) so they can answer your phone or sibling PCs while your terminal is closed. Also adds `remote-pi` and `pi-supervisord` to your $PATH so you can drive them from any shell.", "info");
34
+ const enableDaemonDefault = defaults.enable_daemon ?? false;
35
+ const enableDaemonChoice = await ui.select("Enable daemon mode? (run agents 24/7 in background)", enableDaemonDefault ? [YES, NO] : [NO, YES]);
36
+ if (!enableDaemonChoice)
24
37
  return null;
25
- const auto_start_relay = autoChoice === YES;
38
+ const enable_daemon = enableDaemonChoice === YES;
26
39
  // Review + confirm
27
40
  const summary = [
28
- ` Agent name: ${agent_name}`,
29
- ` Default session: ${session_name}`,
30
- ` Auto-start relay: ${auto_start_relay ? YES : NO}`,
41
+ ` Agent name: ${agent_name}`,
42
+ ` Use relay: ${auto_start_relay ? YES : NO}`,
43
+ ` Daemon mode: ${enable_daemon ? YES : NO}`,
31
44
  ].join("\n");
32
45
  ui.notify?.(`Summary:\n${summary}`, "info");
33
46
  const confirm = await ui.select("Save and activate?", [YES, NO]);
34
47
  if (confirm !== YES)
35
48
  return null;
36
- return { agent_name, session_name, auto_start_relay };
49
+ return { agent_name, auto_start_relay, enable_daemon };
37
50
  }
38
51
  /**
39
- * Asks the user for free text. Falls back to `select` with the default as the
40
- * only option when the SDK doesn't expose `input` (some Pi modes). Re-prompts
41
- * once on empty/whitespace input; second blank counts as cancel.
52
+ * Asks the user for free text. The Pi SDK's `ui.input` does not pre-fill the
53
+ * field with `defaultValue` (the SDK ignores that option), so we surface the
54
+ * default in the prompt label and treat an empty submission as "accept the
55
+ * default" — the standard CLI convention. Falls back to `select` when the
56
+ * SDK doesn't expose `input` at all.
42
57
  */
43
58
  async function _askText(ui, title, defaultValue) {
44
- for (let attempt = 0; attempt < 2; attempt++) {
45
- const raw = ui.input
46
- ? await ui.input(title, { defaultValue })
47
- : await ui.select(`${title} (default: ${defaultValue})`, [defaultValue, CANCEL_TOKEN]);
48
- if (raw === undefined)
49
- return null;
50
- if (raw === CANCEL_TOKEN)
51
- return null;
52
- const trimmed = raw.trim();
53
- if (trimmed.length > 0)
54
- return trimmed;
55
- ui.notify?.("Value required cannot be empty.", "warning");
56
- }
57
- // 2 blanks in a row → treat as cancel
58
- return null;
59
+ const titleWithHint = `${title} (default: ${defaultValue})`;
60
+ const raw = ui.input
61
+ ? await ui.input(titleWithHint, { defaultValue })
62
+ : await ui.select(titleWithHint, [defaultValue, CANCEL_TOKEN]);
63
+ if (raw === undefined)
64
+ return null;
65
+ if (raw === CANCEL_TOKEN)
66
+ return null;
67
+ const trimmed = raw.trim();
68
+ // Empty submission = accept the default. No re-prompt, no warning — the
69
+ // user explicitly asked for the default by hitting enter.
70
+ return trimmed.length > 0 ? trimmed : defaultValue;
59
71
  }
60
72
  //# sourceMappingURL=setup_wizard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup_wizard.js","sourceRoot":"","sources":["../../src/session/setup_wizard.ts"],"names":[],"mappings":"AAsBA,MAAM,GAAG,GAAG,KAAK,CAAC;AAClB,MAAM,EAAE,GAAG,IAAI,CAAC;AAChB,MAAM,YAAY,GAAG,YAAY,CAAC;AAElC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAY,EACZ,QAAwB;IAExB,MAAM,UAAU,GAAG,MAAM,QAAQ,CAC/B,EAAE,EACF,aAAa,EACb,QAAQ,CAAC,UAAU,CACpB,CAAC;IACF,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,YAAY,GAAG,MAAM,QAAQ,CACjC,EAAE,EACF,kBAAkB,EAClB,QAAQ,CAAC,YAAY,CACtB,CAAC;IACF,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvC,EAAE,CAAC,MAAM,EAAE,CACT,4KAA4K,EAC5K,MAAM,CACP,CAAC;IACF,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,MAAM,CAChC,+CAA+C,EAC/C,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAClD,CAAC;IACF,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,gBAAgB,GAAG,UAAU,KAAK,GAAG,CAAC;IAE5C,mBAAmB;IACnB,MAAM,OAAO,GAAG;QACd,uBAAuB,UAAU,EAAE;QACnC,uBAAuB,YAAY,EAAE;QACrC,uBAAuB,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KACrD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,EAAE,CAAC,MAAM,EAAE,CAAC,aAAa,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,QAAQ,CACrB,EAAY,EACZ,KAAa,EACb,YAAoB;IAEpB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK;YAClB,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC;YACzC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,cAAc,YAAY,GAAG,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QACzF,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,GAAG,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC;QACvC,EAAE,CAAC,MAAM,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IACD,sCAAsC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"setup_wizard.js","sourceRoot":"","sources":["../../src/session/setup_wizard.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,22 @@
1
1
  import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
2
  import type { SessionPeer } from "./peer.js";
3
3
  /**
4
- * Registers two native tools the Pi LLM can invoke to talk to other agents
5
- * in the same UDS session (plano 19 transport):
6
- * - `agent_send` — fire-and-forget delivery
7
- * - `agent_request` — request/reply with `re` correlation + timeout
4
+ * Registers the native tools the Pi LLM uses to talk to other agents in the
5
+ * same UDS session (plano 19 transport + plan/25 Wave 0 ACK protocol):
8
6
  *
9
- * Both tools are registered unconditionally. When this Pi is not currently
10
- * joined to a session, the tool returns a structured error string instead
11
- * of throwing, so the LLM can react and tell the user.
7
+ * - `agent_send` — unified delivery with broker-level ACK. Returns
8
+ * a status so the LLM can decide whether to retry.
9
+ * For unicast targets the broker auto-replies with
10
+ * `received | busy | denied`. For broadcast/multicast
11
+ * the tool is fire-and-forget (status `sent`).
12
+ * - `agent_request` — **deprecated**. Still works (send + block on reply
13
+ * via `re` correlation) but the LLM should migrate
14
+ * to the event-driven send+inbox pattern. Each call
15
+ * emits a one-shot warning to stderr.
16
+ *
17
+ * Reply pattern (new world): when you receive a message you want to answer,
18
+ * send back another envelope with `re=<original-id>`. The original sender
19
+ * sees that reply in its inbox during a future turn.
12
20
  *
13
21
  * `getSessionPeer` is a getter (not a captured value) so changes to the
14
22
  * underlying `_sessionPeer` module variable are observed live.