@yefengr/remote-pi 0.7.4 → 0.7.6

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 +0,0 @@
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"}
@@ -1,9 +0,0 @@
1
- import type { PeerInfo } from "./broker.js";
2
- /** Shared wire limits measured in JavaScript UTF-16 code units (`.length`). */
3
- export declare const MAX_PEERS_UPDATE_ENTRIES = 1024;
4
- export declare const MAX_CWD_LENGTH = 4096;
5
- export declare const MAX_NAME_LENGTH = 256;
6
- export declare const MAX_ADDRESS_LENGTH = 4352;
7
- export declare function isBoundedPeerInfo(value: unknown): value is PeerInfo;
8
- export declare function isBoundedPeerRoster(infos: readonly PeerInfo[]): boolean;
9
- export declare function isBoundedPeerAddresses(addresses: readonly unknown[]): boolean;
@@ -1,21 +0,0 @@
1
- /** Shared wire limits measured in JavaScript UTF-16 code units (`.length`). */
2
- export const MAX_PEERS_UPDATE_ENTRIES = 1024;
3
- export const MAX_CWD_LENGTH = 4096;
4
- export const MAX_NAME_LENGTH = 256;
5
- export const MAX_ADDRESS_LENGTH = 4352;
6
- export function isBoundedPeerInfo(value) {
7
- if (!value || typeof value !== "object")
8
- return false;
9
- const { cwd, name, address } = value;
10
- return typeof cwd === "string" && cwd.length <= MAX_CWD_LENGTH &&
11
- typeof name === "string" && name.length <= MAX_NAME_LENGTH &&
12
- typeof address === "string" && address.length <= MAX_ADDRESS_LENGTH;
13
- }
14
- export function isBoundedPeerRoster(infos) {
15
- return infos.length <= MAX_PEERS_UPDATE_ENTRIES && infos.every(isBoundedPeerInfo);
16
- }
17
- export function isBoundedPeerAddresses(addresses) {
18
- return addresses.length <= MAX_PEERS_UPDATE_ENTRIES &&
19
- addresses.every((address) => typeof address === "string" && address.length <= MAX_ADDRESS_LENGTH);
20
- }
21
- //# sourceMappingURL=peer_limits.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"peer_limits.js","sourceRoot":"","sources":["../../src/session/peer_limits.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AACnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAiB,CAAC;IACjD,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,IAAI,cAAc;QAC5D,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe;QAC1D,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAA0B;IAE1B,OAAO,KAAK,CAAC,MAAM,IAAI,wBAAwB,IAAI,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,SAA6B;IAClE,OAAO,SAAS,CAAC,MAAM,IAAI,wBAAwB;QACjD,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,IAAI,kBAAkB,CACpE,CAAC;AACN,CAAC"}
@@ -1,39 +0,0 @@
1
- import type { LocalConfig } from "./local_config.js";
2
- /**
3
- * Pi SDK UI surface needed by the wizard. Subset of `ExtensionUIContext` —
4
- * declared inline so tests can mock cleanly without dragging the full
5
- * ExtensionContext shape.
6
- */
7
- export interface WizardUI {
8
- /** Free-text prompt. Returns the entered string, or undefined if cancelled. */
9
- input?: (title: string, options?: {
10
- defaultValue?: string;
11
- }) => Promise<string | undefined>;
12
- /** Picker. Returns the picked option, or undefined if cancelled. */
13
- select: (title: string, options: string[]) => Promise<string | undefined>;
14
- /** Non-blocking notification. Used for inline validation feedback. */
15
- notify?: (msg: string, kind: "info" | "warning" | "error") => void;
16
- }
17
- export interface WizardDefaults {
18
- agent_name: string;
19
- use_relay: boolean;
20
- }
21
- /**
22
- * Runs the 2-question setup wizard. Returns the chosen config on confirm, or
23
- * null when the user cancels any prompt.
24
- *
25
- * Prompts:
26
- * 1. Agent name (default: parent/folder of cwd)
27
- * 2. Use the relay on this terminal? (yes/no) — gates connection to the
28
- * remote mesh (browser PWA + other PCs over the relay). "No" means
29
- * local-only: this Pi joins the UDS mesh but doesn't open WSS.
30
- * Final: review + confirm "Save and activate?" yes/no
31
- *
32
- * Daemon mode (run agents 24/7 via systemd/launchd) is intentionally NOT in
33
- * the wizard — it's an explicit, separate opt-in via `/remote-pi install`.
34
- *
35
- * The local UDS mesh is always single per machine ("local" session) — no
36
- * session question. All Pis on the same machine see each other through
37
- * the same broker.
38
- */
39
- export declare function runSetupWizard(ui: WizardUI, defaults: WizardDefaults): Promise<LocalConfig | null>;
@@ -1,63 +0,0 @@
1
- const YES = "Yes";
2
- const NO = "No";
3
- const CANCEL_TOKEN = "__cancel__";
4
- /**
5
- * Runs the 2-question setup wizard. Returns the chosen config on confirm, or
6
- * null when the user cancels any prompt.
7
- *
8
- * Prompts:
9
- * 1. Agent name (default: parent/folder of cwd)
10
- * 2. Use the relay on this terminal? (yes/no) — gates connection to the
11
- * remote mesh (browser PWA + other PCs over the relay). "No" means
12
- * local-only: this Pi joins the UDS mesh but doesn't open WSS.
13
- * Final: review + confirm "Save and activate?" yes/no
14
- *
15
- * Daemon mode (run agents 24/7 via systemd/launchd) is intentionally NOT in
16
- * the wizard — it's an explicit, separate opt-in via `/remote-pi install`.
17
- *
18
- * The local UDS mesh is always single per machine ("local" session) — no
19
- * session question. All Pis on the same machine see each other through
20
- * the same broker.
21
- */
22
- export async function runSetupWizard(ui, defaults) {
23
- const agent_name = await _askText(ui, "Agent name:", defaults.agent_name);
24
- if (agent_name === null)
25
- return null;
26
- ui.notify?.("The relay forwards encrypted messages to the Remote Pi browser PWA and other PCs in your mesh. Skip this if you only want a local-only mesh on this machine.", "info");
27
- const useRelayChoice = await ui.select("Use the relay on this terminal to connect to the remote mesh (PWA + PCs)?", defaults.use_relay ? [YES, NO] : [NO, YES]);
28
- if (!useRelayChoice)
29
- return null;
30
- const auto_start_relay = useRelayChoice === YES;
31
- // Review + confirm
32
- const summary = [
33
- ` Agent name: ${agent_name}`,
34
- ` Use relay: ${auto_start_relay ? YES : NO}`,
35
- ].join("\n");
36
- ui.notify?.(`Summary:\n${summary}`, "info");
37
- const confirm = await ui.select("Save and activate?", [YES, NO]);
38
- if (confirm !== YES)
39
- return null;
40
- return { agent_name, auto_start_relay };
41
- }
42
- /**
43
- * Asks the user for free text. The Pi SDK's `ui.input` does not pre-fill the
44
- * field with `defaultValue` (the SDK ignores that option), so we surface the
45
- * default in the prompt label and treat an empty submission as "accept the
46
- * default" — the standard CLI convention. Falls back to `select` when the
47
- * SDK doesn't expose `input` at all.
48
- */
49
- async function _askText(ui, title, defaultValue) {
50
- const titleWithHint = `${title} (default: ${defaultValue})`;
51
- const raw = ui.input
52
- ? await ui.input(titleWithHint, { defaultValue })
53
- : await ui.select(titleWithHint, [defaultValue, CANCEL_TOKEN]);
54
- if (raw === undefined)
55
- return null;
56
- if (raw === CANCEL_TOKEN)
57
- return null;
58
- const trimmed = raw.trim();
59
- // Empty submission = accept the default. No re-prompt, no warning — the
60
- // user explicitly asked for the default by hitting enter.
61
- return trimmed.length > 0 ? trimmed : defaultValue;
62
- }
63
- //# sourceMappingURL=setup_wizard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup_wizard.js","sourceRoot":"","sources":["../../src/session/setup_wizard.ts"],"names":[],"mappings":"AAqBA,MAAM,GAAG,GAAG,KAAK,CAAC;AAClB,MAAM,EAAE,GAAG,IAAI,CAAC;AAChB,MAAM,YAAY,GAAG,YAAY,CAAC;AAElC;;;;;;;;;;;;;;;;;GAiBG;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,EAAE,CAAC,MAAM,EAAE,CACT,8JAA8J,EAC9J,MAAM,CACP,CAAC;IACF,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,MAAM,CACpC,2EAA2E,EAC3E,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAC3C,CAAC;IACF,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,gBAAgB,GAAG,cAAc,KAAK,GAAG,CAAC;IAEhD,mBAAmB;IACnB,MAAM,OAAO,GAAG;QACd,oBAAoB,UAAU,EAAE;QAChC,oBAAoB,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KAClD,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,gBAAgB,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,QAAQ,CACrB,EAAY,EACZ,KAAa,EACb,YAAoB;IAEpB,MAAM,aAAa,GAAG,GAAG,KAAK,cAAc,YAAY,GAAG,CAAC;IAC5D,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK;QAClB,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,YAAY,EAAE,CAAC;QACjD,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IACjE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,GAAG,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,wEAAwE;IACxE,0DAA0D;IAC1D,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;AACrD,CAAC"}
@@ -1,24 +0,0 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import type { SessionPeer } from "./peer.js";
3
- /**
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):
6
- *
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.
20
- *
21
- * `getSessionPeer` is a getter (not a captured value) so changes to the
22
- * underlying `_sessionPeer` module variable are observed live.
23
- */
24
- export declare function registerAgentTools(pi: ExtensionAPI, getSessionPeer: () => SessionPeer | null): void;
@@ -1,252 +0,0 @@
1
- import { Type } from "typebox";
2
- const NOT_IN_SESSION = "Not in a session. Run /remote-pi join first";
3
- const ACK_TIMEOUT_MS = 5_000;
4
- const LEGACY_REQUEST_TIMEOUT_MS = 30_000;
5
- const LIST_PEERS_TIMEOUT_MS = 2_000;
6
- /**
7
- * Registers the native tools the Pi LLM uses to talk to other agents in the
8
- * same UDS session (plano 19 transport + plan/25 Wave 0 ACK protocol):
9
- *
10
- * - `agent_send` — unified delivery with broker-level ACK. Returns
11
- * a status so the LLM can decide whether to retry.
12
- * For unicast targets the broker auto-replies with
13
- * `received | busy | denied`. For broadcast/multicast
14
- * the tool is fire-and-forget (status `sent`).
15
- * - `agent_request` — **deprecated**. Still works (send + block on reply
16
- * via `re` correlation) but the LLM should migrate
17
- * to the event-driven send+inbox pattern. Each call
18
- * emits a one-shot warning to stderr.
19
- *
20
- * Reply pattern (new world): when you receive a message you want to answer,
21
- * send back another envelope with `re=<original-id>`. The original sender
22
- * sees that reply in its inbox during a future turn.
23
- *
24
- * `getSessionPeer` is a getter (not a captured value) so changes to the
25
- * underlying `_sessionPeer` module variable are observed live.
26
- */
27
- export function registerAgentTools(pi, getSessionPeer) {
28
- const SendParams = Type.Object({
29
- to: Type.String({
30
- description: "Recipient agent name (e.g. 'backend'), 'broadcast', or array of names. " +
31
- "Broadcast/multicast are fire-and-forget; unicast returns an ACK status.",
32
- }),
33
- body: Type.Unknown({ description: "Free-form JSON payload. String or object — your choice." }),
34
- re: Type.Optional(Type.String({
35
- description: "Set this to the `id` of an incoming message when you are REPLYING to it. " +
36
- "The peer correlates your answer with their original send via this field.",
37
- })),
38
- });
39
- const RequestParams = Type.Object({
40
- to: Type.String({ description: "Recipient agent name. Must be a single peer (not broadcast)." }),
41
- body: Type.Unknown({ description: "Free-form JSON payload to send." }),
42
- timeout_ms: Type.Optional(Type.Number({
43
- description: "Optional override of the default 30s reply timeout. Per-request.",
44
- })),
45
- });
46
- pi.registerTool({
47
- name: "agent_send",
48
- label: "Agent Send",
49
- description: "Send a message to another Pi agent in the current local session and " +
50
- "wait for the broker's delivery ACK. Delivery is reliable: a peer that " +
51
- "is mid-turn still receives the message (its harness enqueues it for " +
52
- "the next turn), so you never need to retry. Returns one of: `received` " +
53
- "(delivered; peer will process it in an upcoming turn), `denied` (peer " +
54
- "refused), `timeout` (no ACK in 5s — peer offline / transport error), " +
55
- "`sent` (broadcast/multicast — no ACK semantics). Use `re` to mark this " +
56
- "message as a reply to an incoming envelope's `id` (correlation only).",
57
- promptSnippet: "agent_send({to, body, re?}): unicast → returns {status: received|denied|timeout} (delivery is reliable; no retry-on-busy). Broadcast/multicast → fire-and-forget ({status:'sent'}).",
58
- parameters: SendParams,
59
- execute: async (_toolCallId, params) => {
60
- const peer = getSessionPeer();
61
- if (!peer) {
62
- const details = { status: "refused", ok: false, error: NOT_IN_SESSION };
63
- return {
64
- content: [{ type: "text", text: NOT_IN_SESSION }],
65
- details,
66
- };
67
- }
68
- const { to, body, re } = params;
69
- if (to === peer.address() || to === peer.name()) {
70
- const msg = `Refused: cannot agent_send to yourself ("${to}"). Just do the work directly.`;
71
- const details = { status: "refused", ok: false, error: msg };
72
- return {
73
- content: [{ type: "text", text: msg }],
74
- details,
75
- };
76
- }
77
- const isUnicast = to !== "broadcast";
78
- // Broadcast: fire-and-forget. Broker doesn't ACK multi-target sends.
79
- if (!isUnicast) {
80
- try {
81
- await peer.send(to, body, re ?? null);
82
- const details = { status: "sent", ok: true };
83
- return {
84
- content: [{ type: "text", text: `Broadcast sent.` }],
85
- details,
86
- };
87
- }
88
- catch (err) {
89
- const msg = err instanceof Error ? err.message : String(err);
90
- const details = { status: "timeout", ok: false, error: msg };
91
- return {
92
- content: [{ type: "text", text: `Broadcast failed: ${msg}` }],
93
- details,
94
- };
95
- }
96
- }
97
- // Unicast: wait for broker ACK.
98
- try {
99
- const ack = await peer.sendWithAck(to, body, re ?? null, ACK_TIMEOUT_MS);
100
- const ok = ack.status === "received";
101
- const details = {
102
- status: ack.status,
103
- ok,
104
- ...(ack.target !== undefined ? { target: ack.target } : {}),
105
- ...(ack.error !== undefined ? { error: ack.error } : {}),
106
- ...(ack.reason !== undefined ? { reason: ack.reason } : {}),
107
- };
108
- const text = _formatAck(to, ack, re);
109
- return { content: [{ type: "text", text }], details };
110
- }
111
- catch (err) {
112
- const msg = err instanceof Error ? err.message : String(err);
113
- const details = { status: "timeout", ok: false, error: msg };
114
- return {
115
- content: [{ type: "text", text: `Failed to send: ${msg}` }],
116
- details,
117
- };
118
- }
119
- },
120
- });
121
- const ListPeersParams = Type.Object({});
122
- pi.registerTool({
123
- name: "list_peers",
124
- label: "List Peers",
125
- description: "Returns the current peer inventory in this session as ADDRESSES of the " +
126
- "form `<cwd>@<name>` (cross-PC peers prefixed `<pc>:`). An address is an " +
127
- "opaque routing key — pass it to `agent_send`/`agent_request` VERBATIM, " +
128
- "never build one by hand. Use BEFORE sending whenever you're unsure who's " +
129
- "available, or after a `peer_joined` / `peer_left` notification to refresh " +
130
- "your mental model. Resolves in milliseconds — a metadata query to the " +
131
- "broker, not a turn of another agent.",
132
- promptSnippet: "list_peers(): returns {peers: string[]} of addresses `<cwd>@<name>` (`<pc>:` prefix cross-PC). Echo an address verbatim to agent_send; never compose one. Cheap; call freely.",
133
- parameters: ListPeersParams,
134
- execute: async (_toolCallId) => {
135
- const peer = getSessionPeer();
136
- if (!peer) {
137
- return {
138
- content: [{ type: "text", text: NOT_IN_SESSION }],
139
- details: { peers: [] },
140
- };
141
- }
142
- try {
143
- // Internal use of the request/reply primitive is fine — broker
144
- // replies are synthesised in-process (`_handleBrokerMessage`)
145
- // without going through `_route`, so they bypass the ACK path.
146
- const reply = await peer.request("broker", { type: "list_peers" }, LIST_PEERS_TIMEOUT_MS);
147
- const body = reply.body;
148
- const peers = Array.isArray(body?.peers)
149
- ? body.peers.filter((p) => typeof p === "string")
150
- : [];
151
- // Drop self from the list — the caller is the only one who can't
152
- // address itself anyway, so listing it is noise. Peers are ADDRESSES
153
- // (plan/38), so filter by address.
154
- const selfAddress = peer.address();
155
- const filtered = peers.filter((p) => p !== selfAddress);
156
- const text = filtered.length === 0 ? "(no peers)" : filtered.join("\n");
157
- return {
158
- content: [{ type: "text", text }],
159
- details: { peers: filtered },
160
- };
161
- }
162
- catch (err) {
163
- const msg = err instanceof Error ? err.message : String(err);
164
- return {
165
- content: [{ type: "text", text: `list_peers failed: ${msg}` }],
166
- details: { peers: [] },
167
- };
168
- }
169
- },
170
- });
171
- pi.registerTool({
172
- name: "agent_request",
173
- label: "Agent Request (deprecated)",
174
- description: "DEPRECATED — prefer `agent_send` + observing your inbox for the " +
175
- "reply (correlated by `re=<your-send-id>`). This tool still works: " +
176
- "it sends a message and synchronously blocks until the peer replies " +
177
- "or the timeout fires. Default 30s. Will be removed in a future " +
178
- "release; migrate to the event-driven pattern in the agent-network skill.",
179
- promptSnippet: "agent_request({to, body, timeout_ms?}): DEPRECATED synchronous request/reply (blocks current turn). Prefer agent_send + inbox observation.",
180
- parameters: RequestParams,
181
- execute: async (_toolCallId, params) => {
182
- const peer = getSessionPeer();
183
- if (!peer) {
184
- return {
185
- content: [{ type: "text", text: NOT_IN_SESSION }],
186
- details: { error: NOT_IN_SESSION },
187
- };
188
- }
189
- const { to, body, timeout_ms } = params;
190
- if (to === peer.address() || to === peer.name()) {
191
- const msg = `Refused: cannot agent_request to yourself ("${to}"). Just do the work directly.`;
192
- return {
193
- content: [{ type: "text", text: msg }],
194
- details: { error: msg },
195
- };
196
- }
197
- const timeout = typeof timeout_ms === "number" && timeout_ms > 0
198
- ? timeout_ms
199
- : LEGACY_REQUEST_TIMEOUT_MS;
200
- try {
201
- const reply = await peer.request(to, body, timeout);
202
- const text = typeof reply.body === "string"
203
- ? reply.body
204
- : JSON.stringify(reply.body);
205
- return {
206
- content: [{ type: "text", text }],
207
- details: reply.body,
208
- };
209
- }
210
- catch (err) {
211
- const msg = err instanceof Error ? err.message : String(err);
212
- return {
213
- content: [{ type: "text", text: `Request failed: ${msg}` }],
214
- details: { error: msg },
215
- };
216
- }
217
- },
218
- });
219
- }
220
- function _formatAck(to, ack, re) {
221
- const reSuffix = re ? ` (re=${re})` : "";
222
- const errorSuffix = ack.error ? ` (${ack.error})` : "";
223
- switch (ack.status) {
224
- case "received":
225
- return `Delivered to "${to}"${reSuffix} — peer will process it in an upcoming turn.`;
226
- case "busy":
227
- // plan/34 removed busy-drop: the current broker never returns `busy`. If
228
- // we still see it, an OUT-OF-DATE broker leader dropped the message — so
229
- // be honest that it was NOT delivered, and point at the fix.
230
- return `NOT delivered — "${to}"${reSuffix} came back BUSY, which only ` +
231
- `happens when an out-of-date broker leader dropped the message. ` +
232
- `Restart the agent leading the local broker (oldest Pi/remote-pi process) ` +
233
- `to pick up the new build, then resend.`;
234
- case "denied":
235
- if (ack.reason === "not_authorized") {
236
- return `Relay did not authorize delivery to "${to}"${reSuffix}${errorSuffix}. ` +
237
- `Do not blindly retry; verify authorization first.`;
238
- }
239
- if (ack.reason === "bad_envelope") {
240
- return `Relay rejected the envelope for "${to}"${reSuffix}${errorSuffix}. ` +
241
- `Do not blindly retry; correct the envelope first.`;
242
- }
243
- return `"${to}" denied the message${reSuffix}. Do not retry; report to user.`;
244
- case "timeout":
245
- if (ack.reason === "offline") {
246
- return `Immediate Relay offline transport error for "${to}"${reSuffix}${errorSuffix}; ` +
247
- `reported as timeout without waiting for the ACK deadline.`;
248
- }
249
- return `No ACK from "${to}" within ${ACK_TIMEOUT_MS}ms${reSuffix} — transport error. Investigate or retry later.`;
250
- }
251
- }
252
- //# sourceMappingURL=tools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/session/tools.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * Minimal wizard for `/remote-pi join` with no argument.
3
- *
4
- * The Pi SDK `ExtensionUIContext.select` accepts a title and string options
5
- * and returns the chosen option. Wizard offers existing sessions + an "explicit
6
- * create" sentinel. If user picks the sentinel, prompts for a fresh name via
7
- * `select`-with-option-other (Pi's "Other" escape hatch). Returns the picked
8
- * session name, or null if user cancelled.
9
- */
10
- export interface WizardUI {
11
- select(title: string, options: string[]): Promise<string | undefined>;
12
- }
13
- export declare function joinWizard(ui: WizardUI, defaultName: string): Promise<string | null>;
@@ -1,20 +0,0 @@
1
- import { listSessions, sessionHasSock } from "./global_config.js";
2
- const CREATE_SENTINEL = "━━━ Create new session ━━━";
3
- export async function joinWizard(ui, defaultName) {
4
- const sessions = listSessions();
5
- const liveSessions = sessions.filter(sessionHasSock);
6
- const options = [...liveSessions, CREATE_SENTINEL];
7
- const picked = await ui.select(liveSessions.length
8
- ? "Choose a session to join, or create a new one"
9
- : "No active sessions. Create one?", options);
10
- if (!picked)
11
- return null;
12
- if (picked === CREATE_SENTINEL) {
13
- // Caller is expected to follow up with a name prompt via ctx.ui.select
14
- // (the Pi SDK input dialog). For non-interactive contexts we return the
15
- // default name.
16
- return defaultName;
17
- }
18
- return picked;
19
- }
20
- //# sourceMappingURL=wizard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/session/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAelE,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAY,EACZ,WAAmB;IAEnB,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,CAAC,GAAG,YAAY,EAAE,eAAe,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAC5B,YAAY,CAAC,MAAM;QACjB,CAAC,CAAC,+CAA+C;QACjD,CAAC,CAAC,iCAAiC,EACrC,OAAO,CACR,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;QAC/B,uEAAuE;QACvE,wEAAwE;QACxE,gBAAgB;QAChB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,29 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import type { RelayClient } from "./relay_client.js";
3
- import type { Envelope } from "../session/envelope.js";
4
- /** Outbound API + inbound listener for Pi↔Pi envelope forwarding via relay. */
5
- export interface PiForwardClientEvents {
6
- /**
7
- * Emitted whenever the relay delivers a `pi_envelope_in` frame addressed
8
- * to this Pi. `fromPc` is the verified Pi-pubkey of the sender (relay
9
- * authoritative — defense against spoofed `envelope.from`).
10
- */
11
- envelope: [env: Envelope, fromPc: string];
12
- }
13
- export declare class PiForwardClient extends EventEmitter {
14
- private readonly relay;
15
- private readonly onRelayMessage;
16
- private detached;
17
- constructor(relay: RelayClient);
18
- /**
19
- * Pack `env` in a `pi_envelope` frame addressed to `toPc` and send via
20
- * the relay WS. Best-effort: if the relay is not connected, the call is
21
- * silently dropped. The caller (broker_remote) handles the timeout via
22
- * its outstanding-ACK map — a missing ACK from the destination wrapper
23
- * surfaces as `status: "timeout"` upstream regardless.
24
- */
25
- sendEnvelopeToPi(toPc: string, env: Envelope): void;
26
- /** Stop listening to the relay. Call from `_goIdle` / shutdown. */
27
- detach(): void;
28
- private _handleLine;
29
- }
@@ -1,62 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- export class PiForwardClient extends EventEmitter {
3
- relay;
4
- onRelayMessage;
5
- detached = false;
6
- constructor(relay) {
7
- super();
8
- this.relay = relay;
9
- this.onRelayMessage = (line) => this._handleLine(line);
10
- this.relay.on("message", this.onRelayMessage);
11
- }
12
- /**
13
- * Pack `env` in a `pi_envelope` frame addressed to `toPc` and send via
14
- * the relay WS. Best-effort: if the relay is not connected, the call is
15
- * silently dropped. The caller (broker_remote) handles the timeout via
16
- * its outstanding-ACK map — a missing ACK from the destination wrapper
17
- * surfaces as `status: "timeout"` upstream regardless.
18
- */
19
- sendEnvelopeToPi(toPc, env) {
20
- if (this.detached)
21
- return;
22
- const frame = { type: "pi_envelope", to_pc: toPc, envelope: env };
23
- try {
24
- this.relay.send(JSON.stringify(frame));
25
- }
26
- catch {
27
- // relay not connected; broker_remote's pending logic will time out
28
- }
29
- }
30
- /** Stop listening to the relay. Call from `_goIdle` / shutdown. */
31
- detach() {
32
- if (this.detached)
33
- return;
34
- this.detached = true;
35
- this.relay.off("message", this.onRelayMessage);
36
- }
37
- _handleLine(line) {
38
- // The relay multiplexes several frame types over the same WS; we only
39
- // care about `pi_envelope_in`. Other frames (outer-encrypted owner
40
- // envelopes, control replies) are silently ignored.
41
- let parsed;
42
- try {
43
- parsed = JSON.parse(line);
44
- }
45
- catch {
46
- return;
47
- }
48
- if (!parsed || typeof parsed !== "object")
49
- return;
50
- const o = parsed;
51
- if (o.type !== "pi_envelope_in")
52
- return;
53
- if (typeof o.from_pc !== "string" || !o.envelope || typeof o.envelope !== "object")
54
- return;
55
- // Cheap shape check — full envelope parse happens downstream in broker_remote.
56
- const env = o.envelope;
57
- if (typeof env.from !== "string" || typeof env.id !== "string")
58
- return;
59
- this.emit("envelope", env, o.from_pc);
60
- }
61
- }
62
- //# sourceMappingURL=pi_forward_client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pi_forward_client.js","sourceRoot":"","sources":["../../src/transport/pi_forward_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2C3C,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAIlB;IAHZ,cAAc,CAAyB;IAChD,QAAQ,GAAG,KAAK,CAAC;IAEzB,YAA6B,KAAkB;QAC7C,KAAK,EAAE,CAAC;QADmB,UAAK,GAAL,KAAK,CAAa;QAE7C,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;OAMG;IACH,gBAAgB,CAAC,IAAY,EAAE,GAAa;QAC1C,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,KAAK,GAAoB,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACnF,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM;QACJ,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IAEO,WAAW,CAAC,IAAY;QAC9B,sEAAsE;QACtE,mEAAmE;QACnE,oDAAoD;QACpD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO;QAClD,MAAM,CAAC,GAAG,MAAoC,CAAC;QAC/C,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB;YAAE,OAAO;QACxC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO;QAE3F,+EAA+E;QAC/E,MAAM,GAAG,GAAG,CAAC,CAAC,QAAoB,CAAC;QACnC,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;YAAE,OAAO;QACvE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -1,32 +0,0 @@
1
- /**
2
- * Footer renderer for the Pi TUI. Three status slots + window title.
3
- *
4
- * Slot keys (intentionally namespaced so other extensions don't collide):
5
- * - remote-pi:session — current local session + peer count
6
- * - remote-pi:relay — relay state (off / on / paired)
7
- * - remote-pi:peer-active — active browser PWA profile, if paired
8
- */
9
- export interface FooterContext {
10
- ui: {
11
- setStatus(key: string, value: string | undefined): void;
12
- setTitle(title: string): void;
13
- };
14
- }
15
- export interface FooterState {
16
- session?: string;
17
- peerCount?: number;
18
- relayOn?: boolean;
19
- /** Active browser session right now (drives the 📱 slot).
20
- * Independent from `hasPairings` — a device may be paired globally
21
- * in peers.json without being actively connected to THIS Pi process. */
22
- devicePaired?: string;
23
- /** At least one device has been paired with this machine before
24
- * (peers.json is non-empty). Drives the 🟢/🟡 icon on the relay slot:
25
- * 🟢 when true (ready — devices can connect), 🟡 when false (first
26
- * pairing needed). Pairing is per-machine (global), not per-process. */
27
- hasPairings?: boolean;
28
- /** Assigned agent name in the current session. Becomes the title prefix
29
- * (e.g. "backend · foo · relay") when set. Falls back to "Pi" otherwise. */
30
- agentName?: string;
31
- }
32
- export declare function updateFooter(ctx: FooterContext, state: FooterState): void;