remote-pi-app 0.7.1

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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +675 -0
  3. package/dist/actions/handlers.d.ts +138 -0
  4. package/dist/actions/handlers.js +189 -0
  5. package/dist/actions/handlers.js.map +1 -0
  6. package/dist/actions/registry.d.ts +39 -0
  7. package/dist/actions/registry.js +58 -0
  8. package/dist/actions/registry.js.map +1 -0
  9. package/dist/bin/supervisord.d.ts +2 -0
  10. package/dist/bin/supervisord.js +86 -0
  11. package/dist/bin/supervisord.js.map +1 -0
  12. package/dist/config.d.ts +62 -0
  13. package/dist/config.js +115 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/daemon/client.d.ts +20 -0
  16. package/dist/daemon/client.js +131 -0
  17. package/dist/daemon/client.js.map +1 -0
  18. package/dist/daemon/control_protocol.d.ts +176 -0
  19. package/dist/daemon/control_protocol.js +63 -0
  20. package/dist/daemon/control_protocol.js.map +1 -0
  21. package/dist/daemon/cron_log.d.ts +45 -0
  22. package/dist/daemon/cron_log.js +72 -0
  23. package/dist/daemon/cron_log.js.map +1 -0
  24. package/dist/daemon/cron_registry.d.ts +80 -0
  25. package/dist/daemon/cron_registry.js +194 -0
  26. package/dist/daemon/cron_registry.js.map +1 -0
  27. package/dist/daemon/id.d.ts +24 -0
  28. package/dist/daemon/id.js +36 -0
  29. package/dist/daemon/id.js.map +1 -0
  30. package/dist/daemon/install.d.ts +170 -0
  31. package/dist/daemon/install.js +547 -0
  32. package/dist/daemon/install.js.map +1 -0
  33. package/dist/daemon/registry.d.ts +63 -0
  34. package/dist/daemon/registry.js +153 -0
  35. package/dist/daemon/registry.js.map +1 -0
  36. package/dist/daemon/rpc_child.d.ts +194 -0
  37. package/dist/daemon/rpc_child.js +389 -0
  38. package/dist/daemon/rpc_child.js.map +1 -0
  39. package/dist/daemon/supervisor.d.ts +93 -0
  40. package/dist/daemon/supervisor.js +596 -0
  41. package/dist/daemon/supervisor.js.map +1 -0
  42. package/dist/extension_ui_bridge.d.ts +26 -0
  43. package/dist/extension_ui_bridge.js +341 -0
  44. package/dist/extension_ui_bridge.js.map +1 -0
  45. package/dist/index.d.ts +213 -0
  46. package/dist/index.js +5090 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/mcp/mesh_result.d.ts +10 -0
  49. package/dist/mcp/mesh_result.js +42 -0
  50. package/dist/mcp/mesh_result.js.map +1 -0
  51. package/dist/mcp/mesh_server.d.ts +16 -0
  52. package/dist/mcp/mesh_server.js +327 -0
  53. package/dist/mcp/mesh_server.js.map +1 -0
  54. package/dist/mesh/canonical.d.ts +30 -0
  55. package/dist/mesh/canonical.js +61 -0
  56. package/dist/mesh/canonical.js.map +1 -0
  57. package/dist/mesh/client.d.ts +18 -0
  58. package/dist/mesh/client.js +125 -0
  59. package/dist/mesh/client.js.map +1 -0
  60. package/dist/mesh/encoding.d.ts +38 -0
  61. package/dist/mesh/encoding.js +216 -0
  62. package/dist/mesh/encoding.js.map +1 -0
  63. package/dist/mesh/self_revoke.d.ts +73 -0
  64. package/dist/mesh/self_revoke.js +401 -0
  65. package/dist/mesh/self_revoke.js.map +1 -0
  66. package/dist/mesh/siblings.d.ts +49 -0
  67. package/dist/mesh/siblings.js +159 -0
  68. package/dist/mesh/siblings.js.map +1 -0
  69. package/dist/mesh/types.d.ts +34 -0
  70. package/dist/mesh/types.js +11 -0
  71. package/dist/mesh/types.js.map +1 -0
  72. package/dist/mesh/verify.d.ts +17 -0
  73. package/dist/mesh/verify.js +86 -0
  74. package/dist/mesh/verify.js.map +1 -0
  75. package/dist/pairing/crypto.d.ts +8 -0
  76. package/dist/pairing/crypto.js +22 -0
  77. package/dist/pairing/crypto.js.map +1 -0
  78. package/dist/pairing/qr.d.ts +59 -0
  79. package/dist/pairing/qr.js +125 -0
  80. package/dist/pairing/qr.js.map +1 -0
  81. package/dist/pairing/storage.d.ts +120 -0
  82. package/dist/pairing/storage.js +604 -0
  83. package/dist/pairing/storage.js.map +1 -0
  84. package/dist/protocol/codec.d.ts +7 -0
  85. package/dist/protocol/codec.js +53 -0
  86. package/dist/protocol/codec.js.map +1 -0
  87. package/dist/protocol/types.d.ts +432 -0
  88. package/dist/protocol/types.js +2 -0
  89. package/dist/protocol/types.js.map +1 -0
  90. package/dist/rooms.d.ts +29 -0
  91. package/dist/rooms.js +57 -0
  92. package/dist/rooms.js.map +1 -0
  93. package/dist/session/bridge.d.ts +37 -0
  94. package/dist/session/bridge.js +130 -0
  95. package/dist/session/bridge.js.map +1 -0
  96. package/dist/session/broker.d.ts +189 -0
  97. package/dist/session/broker.js +507 -0
  98. package/dist/session/broker.js.map +1 -0
  99. package/dist/session/broker_remote.d.ts +74 -0
  100. package/dist/session/broker_remote.js +583 -0
  101. package/dist/session/broker_remote.js.map +1 -0
  102. package/dist/session/cwd_lock.d.ts +33 -0
  103. package/dist/session/cwd_lock.js +126 -0
  104. package/dist/session/cwd_lock.js.map +1 -0
  105. package/dist/session/envelope.d.ts +33 -0
  106. package/dist/session/envelope.js +117 -0
  107. package/dist/session/envelope.js.map +1 -0
  108. package/dist/session/global_config.d.ts +33 -0
  109. package/dist/session/global_config.js +73 -0
  110. package/dist/session/global_config.js.map +1 -0
  111. package/dist/session/ipc.d.ts +27 -0
  112. package/dist/session/ipc.js +22 -0
  113. package/dist/session/ipc.js.map +1 -0
  114. package/dist/session/leader_election.d.ts +32 -0
  115. package/dist/session/leader_election.js +106 -0
  116. package/dist/session/leader_election.js.map +1 -0
  117. package/dist/session/local_config.d.ts +55 -0
  118. package/dist/session/local_config.js +157 -0
  119. package/dist/session/local_config.js.map +1 -0
  120. package/dist/session/mesh_node.d.ts +116 -0
  121. package/dist/session/mesh_node.js +573 -0
  122. package/dist/session/mesh_node.js.map +1 -0
  123. package/dist/session/peer.d.ts +139 -0
  124. package/dist/session/peer.js +451 -0
  125. package/dist/session/peer.js.map +1 -0
  126. package/dist/session/peer_inventory.d.ts +13 -0
  127. package/dist/session/peer_inventory.js +48 -0
  128. package/dist/session/peer_inventory.js.map +1 -0
  129. package/dist/session/peer_limits.d.ts +9 -0
  130. package/dist/session/peer_limits.js +21 -0
  131. package/dist/session/peer_limits.js.map +1 -0
  132. package/dist/session/setup_wizard.d.ts +39 -0
  133. package/dist/session/setup_wizard.js +63 -0
  134. package/dist/session/setup_wizard.js.map +1 -0
  135. package/dist/session/tools.d.ts +24 -0
  136. package/dist/session/tools.js +252 -0
  137. package/dist/session/tools.js.map +1 -0
  138. package/dist/session/wizard.d.ts +13 -0
  139. package/dist/session/wizard.js +20 -0
  140. package/dist/session/wizard.js.map +1 -0
  141. package/dist/transport/peer_channel.d.ts +37 -0
  142. package/dist/transport/peer_channel.js +98 -0
  143. package/dist/transport/peer_channel.js.map +1 -0
  144. package/dist/transport/pi_forward_client.d.ts +29 -0
  145. package/dist/transport/pi_forward_client.js +62 -0
  146. package/dist/transport/pi_forward_client.js.map +1 -0
  147. package/dist/transport/relay_client.d.ts +91 -0
  148. package/dist/transport/relay_client.js +206 -0
  149. package/dist/transport/relay_client.js.map +1 -0
  150. package/dist/ui/footer.d.ts +32 -0
  151. package/dist/ui/footer.js +34 -0
  152. package/dist/ui/footer.js.map +1 -0
  153. package/docs/daemon.md +289 -0
  154. package/package.json +90 -0
  155. package/service-templates/launchd.plist.template +35 -0
  156. package/service-templates/systemd.service.template +19 -0
  157. package/service-templates/task-launcher.vbs.template +10 -0
  158. package/service-templates/task-scheduler.xml.template +38 -0
  159. package/skills/agent-network/SKILL.md +310 -0
@@ -0,0 +1,596 @@
1
+ import { existsSync, mkdirSync, unlinkSync } from "node:fs";
2
+ import { createConnection, createServer } from "node:net";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { addDaemon, listDaemons, migrateRegistryNames, removeDaemon } from "./registry.js";
6
+ import { daemonIdForCwd } from "./id.js";
7
+ import { defaultAgentName } from "../session/local_config.js";
8
+ import { ipcAddress, usesNamedPipe } from "../session/ipc.js";
9
+ import { EXIT_DAEMON_FRESH_SESSION, RpcChild } from "./rpc_child.js";
10
+ import { encodeReply, parseRequest, } from "./control_protocol.js";
11
+ import { Cron } from "croner";
12
+ import { addJob as addCronJob, getJob as getCronJob, listJobs as listCronJobs, nextRunFor, recordRun, removeJob as removeCronJob, setJobEnabled, validateSchedule, } from "./cron_registry.js";
13
+ import { appendCronLog, readCronLog } from "./cron_log.js";
14
+ /**
15
+ * Central process that owns the daemon fleet (plan/26).
16
+ *
17
+ * Responsibilities:
18
+ * - Spawn one `pi --mode rpc` child per registry entry. Track them in
19
+ * `_children: Map<id, RpcChild>`.
20
+ * - Auto-restart crashed children with exponential backoff
21
+ * (1s, 5s, 30s, 5min). Give up after 4 attempts to avoid log spam
22
+ * when the agent is misconfigured.
23
+ * - Listen on `~/.pi/remote/supervisor.sock` for `ControlRequest`s from
24
+ * the `remote-pi` CLI. Each connection: 1 request → 1 reply → close.
25
+ * - Graceful shutdown on SIGTERM/SIGINT: stop all children + unlink
26
+ * the UDS file so a next supervisor can bind cleanly.
27
+ *
28
+ * The supervisor itself is the only long-running process the user
29
+ * installs as a system service (plan/26 W3 will generate the unit/plist).
30
+ * If it crashes, systemd/launchd restarts it; on restart it re-reads
31
+ * the registry and re-spawns everything.
32
+ */
33
+ const SUPERVISOR_SOCK_NAME = "supervisor.sock";
34
+ /** Backoff schedule for auto-restart after a crash. After exhausting, the
35
+ * child stays in `crashed` state until manual `restart_all` or fresh
36
+ * registry add. Keeps logs sane when the agent dies on every boot. */
37
+ const RESTART_BACKOFFS_MS = [1_000, 5_000, 30_000, 5 * 60_000];
38
+ function supervisorSockPath() {
39
+ const root = process.env["REMOTE_PI_HOME"] || homedir();
40
+ // POSIX → ~/.pi/remote/supervisor.sock; Windows → per-user named pipe (plan/40).
41
+ return ipcAddress("supervisor", join(root, ".pi", "remote", SUPERVISOR_SOCK_NAME));
42
+ }
43
+ /** Thrown by `start()` when another live supervisor already holds the UDS.
44
+ * Prevents a second supervisor from orphaning the first's children. */
45
+ export class SupervisorAlreadyRunningError extends Error {
46
+ sockPath;
47
+ constructor(sockPath) {
48
+ super(`Another pi-supervisord is already running (UDS held at ${sockPath}). ` +
49
+ "Refusing to start a second instance. Use `remote-pi daemon …` to control it, " +
50
+ "or stop the running one first.");
51
+ this.sockPath = sockPath;
52
+ this.name = "SupervisorAlreadyRunningError";
53
+ }
54
+ }
55
+ /** Probes whether a live supervisor is accepting connections on `path`.
56
+ * Resolves true if the connect succeeds (a listener is there), false on
57
+ * ECONNREFUSED / ENOENT (stale socket file from a crashed supervisor). */
58
+ function _probeSupervisor(path) {
59
+ return new Promise((resolve) => {
60
+ const sock = createConnection({ path });
61
+ const done = (alive) => {
62
+ sock.removeAllListeners();
63
+ sock.destroy();
64
+ resolve(alive);
65
+ };
66
+ const timer = setTimeout(() => done(false), 1_000);
67
+ sock.once("connect", () => { clearTimeout(timer); done(true); });
68
+ sock.once("error", () => { clearTimeout(timer); done(false); });
69
+ });
70
+ }
71
+ export function decideFireAction(o) {
72
+ if (!o.running)
73
+ return o.wake ? "wake_and_send" : "skip_down";
74
+ if (o.skipIfBusy && o.busy)
75
+ return "skip_busy";
76
+ return "send";
77
+ }
78
+ export class Supervisor {
79
+ opts;
80
+ server = null;
81
+ children = new Map();
82
+ /** Live croner schedules, keyed by cron job id (plan/39). */
83
+ cronJobs = new Map();
84
+ shuttingDown = false;
85
+ constructor(opts) {
86
+ this.opts = opts;
87
+ }
88
+ /** Bind the control UDS + spawn all registered daemons. */
89
+ async start() {
90
+ this._mkdirParent();
91
+ // Backfill folder-derived names into legacy registry entries (pre-name
92
+ // field) so every daemon has a stable name to inject via env.
93
+ migrateRegistryNames();
94
+ await this._bindUds();
95
+ this._spawnAllFromRegistry();
96
+ // Cron (plan/39): schedule all enabled jobs, then run any missed catchup.
97
+ this._reconcileCron();
98
+ this._runCatchup();
99
+ }
100
+ /** Graceful shutdown: stop all children, close UDS. */
101
+ async stop() {
102
+ this.shuttingDown = true;
103
+ // Stop all cron schedules (plan/39) so no fire races with teardown.
104
+ for (const c of this.cronJobs.values())
105
+ c.stop();
106
+ this.cronJobs.clear();
107
+ // Cancel pending restart timers first so they don't race with stop().
108
+ for (const slot of this.children.values()) {
109
+ if (slot.restartTimer !== null) {
110
+ clearTimeout(slot.restartTimer);
111
+ slot.restartTimer = null;
112
+ }
113
+ }
114
+ await Promise.all([...this.children.values()].map((s) => s.child.stop()));
115
+ this.children.clear();
116
+ await new Promise((resolve) => {
117
+ if (!this.server)
118
+ return resolve();
119
+ this.server.close(() => resolve());
120
+ });
121
+ this.server = null;
122
+ // Best-effort: clear the socket file so a next supervisor bind succeeds.
123
+ // Windows named pipes have no file (auto-removed on exit) → nothing to do.
124
+ if (!usesNamedPipe()) {
125
+ try {
126
+ unlinkSync(supervisorSockPath());
127
+ }
128
+ catch { /* ignored */ }
129
+ }
130
+ }
131
+ // ── UDS binding ──────────────────────────────────────────────────────────
132
+ _mkdirParent() {
133
+ // A named pipe has no parent directory to create (the addr is `\\.\pipe\…`).
134
+ if (usesNamedPipe())
135
+ return;
136
+ mkdirSync(dirname(supervisorSockPath()), { recursive: true });
137
+ }
138
+ async _bindUds() {
139
+ const path = supervisorSockPath();
140
+ const pipe = usesNamedPipe();
141
+ // Single-instance guard. PROBE first: a live supervisor answering the
142
+ // connect means we must NOT start a second one. Stealing the socket
143
+ // (unlink + bind) would orphan the running supervisor's children — they'd
144
+ // keep running, unreachable by the CLI. Only on POSIX, when the probe
145
+ // fails (stale socket from a crash), do we unlink + bind. On Windows there
146
+ // is no file: always probe, never unlink (the pipe self-cleans on exit).
147
+ if (pipe || existsSync(path)) {
148
+ const alive = await _probeSupervisor(path);
149
+ if (alive) {
150
+ throw new SupervisorAlreadyRunningError(path);
151
+ }
152
+ if (!pipe) {
153
+ try {
154
+ unlinkSync(path);
155
+ }
156
+ catch { /* will throw on bind if still held */ }
157
+ }
158
+ }
159
+ const server = createServer((socket) => this._onConnection(socket));
160
+ await new Promise((resolve, reject) => {
161
+ server.once("error", reject);
162
+ server.listen(path, () => resolve());
163
+ });
164
+ this.server = server;
165
+ }
166
+ _onConnection(socket) {
167
+ let buf = "";
168
+ socket.setEncoding("utf8");
169
+ socket.on("data", (chunk) => {
170
+ buf += chunk;
171
+ const nl = buf.indexOf("\n");
172
+ if (nl < 0)
173
+ return;
174
+ const line = buf.slice(0, nl);
175
+ // Single request per connection; ignore anything past the newline.
176
+ void this._handleRequest(line)
177
+ .then((reply) => socket.end(encodeReply(reply)))
178
+ .catch((err) => socket.end(encodeReply({ ok: false, error: String(err) })));
179
+ });
180
+ socket.on("error", () => { });
181
+ }
182
+ // ── Request dispatch ─────────────────────────────────────────────────────
183
+ async _handleRequest(line) {
184
+ let req;
185
+ try {
186
+ req = parseRequest(line);
187
+ }
188
+ catch (e) {
189
+ return { ok: false, error: e.message };
190
+ }
191
+ switch (req.op) {
192
+ case "list": return { ok: true, data: { daemons: this._listInfo() } };
193
+ case "status": return { ok: true, data: { daemons: this._listInfo() } };
194
+ case "start_all": return this._opStartAll();
195
+ case "start": return this._opStart(req.id);
196
+ case "stop_all": return this._opStopAll();
197
+ case "stop": return this._opStop(req.id);
198
+ case "restart_all": return this._opRestartAll();
199
+ case "restart": return this._opRestart(req.id);
200
+ case "send": return this._opSend(req.id, req.text);
201
+ case "register": return this._opRegister(req.cwd);
202
+ case "unregister": return this._opUnregister(req.id);
203
+ case "cron_add": return this._opCronAdd(req);
204
+ case "cron_list": return this._opCronList();
205
+ case "cron_remove": return this._opCronRemove(req.job_id);
206
+ case "cron_enable": return this._opCronEnable(req.job_id, req.enabled);
207
+ case "cron_run": return this._opCronRun(req.job_id);
208
+ case "cron_log": return this._opCronLog(req.job_id, req.tail);
209
+ default: {
210
+ const unknown = req.op;
211
+ return { ok: false, error: `unknown op: ${unknown}` };
212
+ }
213
+ }
214
+ }
215
+ // ── Op handlers ──────────────────────────────────────────────────────────
216
+ _listInfo() {
217
+ const registry = listDaemons();
218
+ return registry.map((entry) => {
219
+ const slot = this.children.get(entry.id);
220
+ const name = entry.name ?? defaultAgentName(entry.cwd);
221
+ const info = {
222
+ id: entry.id,
223
+ cwd: entry.cwd,
224
+ name,
225
+ state: slot?.child.state ?? "stopped",
226
+ };
227
+ if (slot) {
228
+ if (slot.child.pid !== undefined)
229
+ info.pid = slot.child.pid;
230
+ if (slot.child.uptimeMs !== undefined)
231
+ info.uptime_s = Math.floor(slot.child.uptimeMs / 1000);
232
+ info.restart_count = slot.child.restartCount;
233
+ }
234
+ return info;
235
+ });
236
+ }
237
+ _opStartAll() {
238
+ const started = [];
239
+ const already = [];
240
+ for (const entry of listDaemons()) {
241
+ const slot = this.children.get(entry.id);
242
+ if (slot && slot.child.state === "running") {
243
+ already.push(entry.id);
244
+ continue;
245
+ }
246
+ this._spawnEntry(entry.id, entry.cwd);
247
+ started.push(entry.id);
248
+ }
249
+ return { ok: true, data: { started, already_running: already } };
250
+ }
251
+ /** Spawn a single registered daemon by id. Idempotent: a daemon already
252
+ * running returns `started: false`. Unknown id → ok:false. This is what
253
+ * `/remote-pi create` calls so a freshly-registered folder boots its Pi
254
+ * immediately instead of waiting for the next supervisor restart. */
255
+ _opStart(id) {
256
+ const entry = listDaemons().find((d) => d.id === id);
257
+ if (!entry)
258
+ return { ok: false, error: `no daemon with id ${id}` };
259
+ const slot = this.children.get(id);
260
+ if (slot && slot.child.state === "running") {
261
+ return { ok: true, data: { id, state: slot.child.state, started: false } };
262
+ }
263
+ this._spawnEntry(entry.id, entry.cwd, entry.name);
264
+ const state = this.children.get(id)?.child.state ?? "starting";
265
+ return { ok: true, data: { id, state, started: true } };
266
+ }
267
+ async _opStopAll() {
268
+ const stopped = [];
269
+ const already = [];
270
+ for (const [id, slot] of this.children) {
271
+ if (slot.child.state !== "running") {
272
+ already.push(id);
273
+ continue;
274
+ }
275
+ if (slot.restartTimer !== null) {
276
+ clearTimeout(slot.restartTimer);
277
+ slot.restartTimer = null;
278
+ }
279
+ await slot.child.stop();
280
+ stopped.push(id);
281
+ }
282
+ return { ok: true, data: { stopped, already_stopped: already } };
283
+ }
284
+ /** Stop a single registered daemon by id. Idempotent: a daemon that isn't
285
+ * running returns `stopped: false`. Unknown id → ok:false. Mirrors the
286
+ * per-id semantics of `_opStart`. Cancels any pending restart backoff so a
287
+ * deliberate stop stays stopped. */
288
+ async _opStop(id) {
289
+ const entry = listDaemons().find((d) => d.id === id);
290
+ if (!entry)
291
+ return { ok: false, error: `no daemon with id ${id}` };
292
+ const slot = this.children.get(id);
293
+ if (!slot || slot.child.state !== "running") {
294
+ return { ok: true, data: { id, state: slot?.child.state ?? "stopped", stopped: false } };
295
+ }
296
+ if (slot.restartTimer !== null) {
297
+ clearTimeout(slot.restartTimer);
298
+ slot.restartTimer = null;
299
+ }
300
+ await slot.child.stop();
301
+ return { ok: true, data: { id, state: slot.child.state, stopped: true } };
302
+ }
303
+ /** Restart a single registered daemon by id (stop-if-running, then spawn).
304
+ * Unknown id → ok:false. Resets the crash backoff. */
305
+ async _opRestart(id) {
306
+ const entry = listDaemons().find((d) => d.id === id);
307
+ if (!entry)
308
+ return { ok: false, error: `no daemon with id ${id}` };
309
+ const slot = this.children.get(id);
310
+ if (slot && slot.child.state === "running") {
311
+ if (slot.restartTimer !== null) {
312
+ clearTimeout(slot.restartTimer);
313
+ slot.restartTimer = null;
314
+ }
315
+ await slot.child.stop();
316
+ }
317
+ this._spawnEntry(entry.id, entry.cwd, entry.name);
318
+ const state = this.children.get(id)?.child.state ?? "starting";
319
+ return { ok: true, data: { id, state, restarted: true } };
320
+ }
321
+ async _opRestartAll() {
322
+ const stopReply = await this._opStopAll();
323
+ if (!stopReply.ok)
324
+ return stopReply;
325
+ const startReply = this._opStartAll();
326
+ if (!startReply.ok)
327
+ return startReply;
328
+ const restarted = startReply.data.started;
329
+ return { ok: true, data: { restarted } };
330
+ }
331
+ _opSend(id, text) {
332
+ const slot = this.children.get(id);
333
+ if (!slot)
334
+ return { ok: false, error: `daemon ${id} not running` };
335
+ if (slot.child.state !== "running") {
336
+ return { ok: false, error: `daemon ${id} state is ${slot.child.state}` };
337
+ }
338
+ const ok = slot.child.sendPrompt(text);
339
+ return { ok: true, data: { id, delivered: ok } };
340
+ }
341
+ _opRegister(rawCwd) {
342
+ try {
343
+ const { id, cwd } = addDaemon(rawCwd);
344
+ return { ok: true, data: { id, cwd } };
345
+ }
346
+ catch (e) {
347
+ return { ok: false, error: e.message };
348
+ }
349
+ }
350
+ async _opUnregister(id) {
351
+ // Stop the child first so we don't leave an orphan when the registry
352
+ // entry is gone.
353
+ const slot = this.children.get(id);
354
+ if (slot) {
355
+ if (slot.restartTimer !== null) {
356
+ clearTimeout(slot.restartTimer);
357
+ slot.restartTimer = null;
358
+ }
359
+ await slot.child.stop();
360
+ this.children.delete(id);
361
+ }
362
+ try {
363
+ const result = removeDaemon(id);
364
+ return { ok: true, data: result };
365
+ }
366
+ catch (e) {
367
+ return { ok: false, error: e.message };
368
+ }
369
+ }
370
+ // ── Cron ops + engine (plan/39) ────────────────────────────────────────────
371
+ _opCronAdd(req) {
372
+ const v = validateSchedule(req.schedule, req.tz);
373
+ if (!v.ok)
374
+ return { ok: false, error: v.error ?? "invalid schedule" };
375
+ const input = { daemon_id: req.daemon_id, schedule: req.schedule, prompt: req.prompt };
376
+ if (req.tz !== undefined)
377
+ input.tz = req.tz;
378
+ if (req.skip_if_busy !== undefined)
379
+ input.skip_if_busy = req.skip_if_busy;
380
+ if (req.wake !== undefined)
381
+ input.wake = req.wake;
382
+ if (req.catchup !== undefined)
383
+ input.catchup = req.catchup;
384
+ const job = addCronJob(input);
385
+ this._scheduleCron(job);
386
+ return { ok: true, data: { job: this._jobView(job) } };
387
+ }
388
+ _opCronList() {
389
+ const jobs = listCronJobs().map((j) => this._jobView(j));
390
+ return { ok: true, data: { jobs } };
391
+ }
392
+ _opCronRemove(jobId) {
393
+ const removed = removeCronJob(jobId);
394
+ this._stopCron(jobId);
395
+ return { ok: true, data: { removed } };
396
+ }
397
+ _opCronEnable(jobId, enabled) {
398
+ const updated = setJobEnabled(jobId, enabled);
399
+ if (updated) {
400
+ this._stopCron(jobId);
401
+ const job = getCronJob(jobId);
402
+ if (enabled && job)
403
+ this._scheduleCron(job);
404
+ }
405
+ return { ok: true, data: { job_id: jobId, enabled, updated } };
406
+ }
407
+ async _opCronRun(jobId) {
408
+ if (!getCronJob(jobId))
409
+ return { ok: false, error: `no cron job with id ${jobId}` };
410
+ const result = await this.fireJob(jobId, { manual: true });
411
+ return { ok: true, data: { job_id: jobId, result } };
412
+ }
413
+ _opCronLog(jobId, tail) {
414
+ const opts = {};
415
+ if (jobId !== undefined)
416
+ opts.jobId = jobId;
417
+ if (tail !== undefined)
418
+ opts.tail = tail;
419
+ return { ok: true, data: { entries: readCronLog(opts) } };
420
+ }
421
+ _jobView(job) {
422
+ const next = nextRunFor(job);
423
+ return { ...job, next_run: next ? next.toISOString() : null };
424
+ }
425
+ /** Rebuild all live `Cron` schedules from the registry (enabled jobs only).
426
+ * Called on start; mutations reconcile incrementally via _scheduleCron/_stopCron. */
427
+ _reconcileCron() {
428
+ for (const c of this.cronJobs.values())
429
+ c.stop();
430
+ this.cronJobs.clear();
431
+ for (const job of listCronJobs()) {
432
+ if (job.enabled)
433
+ this._scheduleCron(job);
434
+ }
435
+ }
436
+ _scheduleCron(job) {
437
+ this._stopCron(job.id);
438
+ try {
439
+ const opts = job.tz ? { timezone: job.tz, name: job.id } : { name: job.id };
440
+ const cron = new Cron(job.schedule, opts, () => { void this.fireJob(job.id); });
441
+ this.cronJobs.set(job.id, cron);
442
+ }
443
+ catch (e) {
444
+ process.stderr.write(`[remote-pi-supervisord] cron schedule failed for ${job.id}: ${String(e)}\n`);
445
+ }
446
+ }
447
+ _stopCron(jobId) {
448
+ const c = this.cronJobs.get(jobId);
449
+ if (c) {
450
+ c.stop();
451
+ this.cronJobs.delete(jobId);
452
+ }
453
+ }
454
+ /** Detail 2: on start, run a catchup job once if its previous scheduled run
455
+ * was missed while the supervisor was down. Opt-in (`catchup`), at most 1×. */
456
+ _runCatchup() {
457
+ for (const job of listCronJobs()) {
458
+ if (!job.enabled || !job.catchup)
459
+ continue;
460
+ try {
461
+ const cron = new Cron(job.schedule, job.tz ? { timezone: job.tz } : {});
462
+ const prev = cron.previousRun();
463
+ cron.stop();
464
+ if (!prev)
465
+ continue;
466
+ const lastRunMs = job.last_run ? Date.parse(job.last_run) : 0;
467
+ if (prev.getTime() > lastRunMs)
468
+ void this.fireJob(job.id, { manual: true });
469
+ }
470
+ catch { /* skip a malformed schedule */ }
471
+ }
472
+ }
473
+ /**
474
+ * Fires a cron job: resolves the daemon, decides the action (decideFireAction),
475
+ * acts, and records the outcome — ALWAYS one `last_status` update + one JSONL
476
+ * line, for both fires and skips. Returns the result. `manual` bypasses the
477
+ * disabled-skip (used by `cron run` + catchup).
478
+ */
479
+ async fireJob(jobId, opts = {}) {
480
+ const job = getCronJob(jobId);
481
+ if (!job)
482
+ return "missing";
483
+ let result;
484
+ if (!job.enabled && !opts.manual) {
485
+ result = "skipped_disabled";
486
+ }
487
+ else {
488
+ const slot = this.children.get(job.daemon_id);
489
+ const running = !!slot && slot.child.state === "running";
490
+ let busy = false;
491
+ if (running && job.skip_if_busy)
492
+ busy = await slot.child.refreshBusy();
493
+ const action = decideFireAction({ running, busy, wake: job.wake, skipIfBusy: job.skip_if_busy });
494
+ if (action === "skip_down") {
495
+ result = "skipped_down";
496
+ }
497
+ else if (action === "skip_busy") {
498
+ result = "skipped_busy";
499
+ }
500
+ else if (action === "wake_and_send") {
501
+ const entry = listDaemons().find((d) => d.id === job.daemon_id);
502
+ if (!entry) {
503
+ result = "skipped_down";
504
+ }
505
+ else {
506
+ this._spawnEntry(entry.id, entry.cwd, entry.name);
507
+ const woke = this.children.get(job.daemon_id);
508
+ result = woke && woke.child.sendPrompt(job.prompt) ? "woke_and_delivered" : "deliver_failed";
509
+ }
510
+ }
511
+ else {
512
+ result = slot.child.sendPrompt(job.prompt) ? "delivered" : "deliver_failed";
513
+ }
514
+ }
515
+ const at = new Date().toISOString();
516
+ recordRun(job.id, at, result);
517
+ appendCronLog({ job_id: job.id, daemon_id: job.daemon_id, schedule: job.schedule, result, prompt: job.prompt });
518
+ return result;
519
+ }
520
+ // ── Child lifecycle ──────────────────────────────────────────────────────
521
+ _spawnAllFromRegistry() {
522
+ for (const entry of listDaemons()) {
523
+ this._spawnEntry(entry.id, entry.cwd, entry.name);
524
+ }
525
+ }
526
+ _spawnEntry(id, cwd, name) {
527
+ // Clean up any prior slot (e.g. crashed + waiting for backoff).
528
+ const existing = this.children.get(id);
529
+ if (existing) {
530
+ if (existing.restartTimer !== null)
531
+ clearTimeout(existing.restartTimer);
532
+ // If somehow the child is still alive, stop it first so we don't
533
+ // leak. Fire-and-forget — caller doesn't await.
534
+ if (existing.child.state === "running")
535
+ void existing.child.stop();
536
+ }
537
+ // Build the daemon's config and inject it via REMOTE_PI_DIRECT_CONFIG —
538
+ // no per-cwd config file needed. The daemon scopes by (cwd, name) like any
539
+ // agent (plan/38); relay on.
540
+ const config = {
541
+ agent_name: name ?? defaultAgentName(cwd),
542
+ auto_start_relay: true,
543
+ };
544
+ const childOpts = {
545
+ extensionPath: this.opts.extensionPath,
546
+ cwd,
547
+ config,
548
+ };
549
+ if (this.opts.piBin !== undefined)
550
+ childOpts.piBin = this.opts.piBin;
551
+ const child = new RpcChild(childOpts);
552
+ const slot = { id, cwd, child, restartTimer: null, restartAttempt: 0 };
553
+ this.children.set(id, slot);
554
+ child.on("exit", (evt) => this._onChildExit(id, evt));
555
+ child.spawn();
556
+ }
557
+ _onChildExit(id, evt) {
558
+ if (this.shuttingDown)
559
+ return;
560
+ const slot = this.children.get(id);
561
+ if (!slot)
562
+ return;
563
+ if (!evt.isCrash) {
564
+ // Clean shutdown (e.g. via `stop_all`). Don't auto-restart.
565
+ return;
566
+ }
567
+ if (evt.code === EXIT_DAEMON_FRESH_SESSION) {
568
+ // App-triggered daemon `/new`: this is an intentional recycle, not a
569
+ // crash. Restart immediately and don't burn the crash backoff budget.
570
+ slot.restartAttempt = 0;
571
+ slot.child.noteRestart();
572
+ slot.child.spawn();
573
+ return;
574
+ }
575
+ // Crash: schedule restart with backoff. After exhausting the schedule
576
+ // we give up and stay in `crashed`.
577
+ if (slot.restartAttempt >= RESTART_BACKOFFS_MS.length) {
578
+ process.stderr.write(`[remote-pi-supervisord] giving up restart for ${id} after ${slot.restartAttempt} attempts\n`);
579
+ return;
580
+ }
581
+ const delay = RESTART_BACKOFFS_MS[slot.restartAttempt];
582
+ process.stderr.write(`[remote-pi-supervisord] scheduling restart of ${id} in ${delay}ms (attempt ${slot.restartAttempt + 1})\n`);
583
+ slot.restartTimer = setTimeout(() => {
584
+ slot.restartTimer = null;
585
+ slot.restartAttempt += 1;
586
+ slot.child.noteRestart();
587
+ slot.child.spawn();
588
+ }, delay);
589
+ }
590
+ }
591
+ /** Test helper: derive id from cwd without going through the registry. */
592
+ export function _idForCwdForTest(cwd) { return daemonIdForCwd(cwd); }
593
+ /** Exported for the bin/supervisord entry + tests to know where the
594
+ * supervisor will bind. */
595
+ export function getSupervisorSockPath() { return supervisorSockPath(); }
596
+ //# sourceMappingURL=supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/daemon/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAA4B,MAAM,UAAU,CAAC;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAgD,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAKL,WAAW,EACX,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,MAAM,IAAI,UAAU,EACpB,MAAM,IAAI,UAAU,EACpB,QAAQ,IAAI,YAAY,EACxB,UAAU,EACV,SAAS,EACT,SAAS,IAAI,aAAa,EAC1B,aAAa,EACb,gBAAgB,GAGjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAmB,MAAM,eAAe,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAE/C;;uEAEuE;AACvE,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;AAE/D,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,OAAO,EAAE,CAAC;IACxD,iFAAiF;IACjF,OAAO,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;AACrF,CAAC;AAED;wEACwE;AACxE,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAC1B;IAA5B,YAA4B,QAAgB;QAC1C,KAAK,CACH,0DAA0D,QAAQ,KAAK;YACvE,+EAA+E;YAC/E,gCAAgC,CACjC,CAAC;QALwB,aAAQ,GAAR,QAAQ,CAAQ;QAM1C,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED;;2EAE2E;AAC3E,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE;YAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC;AAcD,MAAM,UAAU,gBAAgB,CAAC,CAKhC;IACC,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9D,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,WAAW,CAAC;IAC/C,OAAO,MAAM,CAAC;AAChB,CAAC;AAUD,MAAM,OAAO,UAAU;IAOQ;IANrB,MAAM,GAAkB,IAAI,CAAC;IACpB,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzD,6DAA6D;IAC5C,QAAQ,GAAG,IAAI,GAAG,EAAgB,CAAC;IAC5C,YAAY,GAAG,KAAK,CAAC;IAE7B,YAA6B,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;IAAG,CAAC;IAExD,2DAA2D;IAC3D,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,uEAAuE;QACvE,8DAA8D;QAC9D,oBAAoB,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,0EAA0E;QAC1E,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,oEAAoE;QACpE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,sEAAsE;QACtE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,OAAO,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,yEAAyE;QACzE,2EAA2E;QAC3E,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,IAAI,CAAC;gBAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,4EAA4E;IAEpE,YAAY;QAClB,6EAA6E;QAC7E,IAAI,aAAa,EAAE;YAAE,OAAO;QAC5B,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;QAC7B,sEAAsE;QACtE,oEAAoE;QACpE,0EAA0E;QAC1E,sEAAsE;QACtE,2EAA2E;QAC3E,yEAAyE;QACzE,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,6BAA6B,CAAC,IAAI,CAAC,CAAC;YAChD,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC;oBAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,sCAAsC,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,aAAa,CAAC,MAAc;QAClC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,GAAG,IAAI,KAAK,CAAC;YACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,EAAE,GAAG,CAAC;gBAAE,OAAO;YACnB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,mEAAmE;YACnE,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;iBAC3B,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;iBAC/C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAU,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAuC,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,4EAA4E;IAEpE,KAAK,CAAC,cAAc,CAAC,IAAY;QACvC,IAAI,GAAmB,CAAC;QACxB,IAAI,CAAC;YAAC,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QACjC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QAEhE,QAAQ,GAAG,CAAC,EAAE,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,CAAS,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;YAC9E,KAAK,QAAQ,CAAC,CAAO,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;YAC9E,KAAK,WAAW,CAAC,CAAI,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/C,KAAK,OAAO,CAAC,CAAQ,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClD,KAAK,UAAU,CAAC,CAAK,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9C,KAAK,MAAM,CAAC,CAAS,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjD,KAAK,aAAa,CAAC,CAAE,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;YACjD,KAAK,SAAS,CAAC,CAAM,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpD,KAAK,MAAM,CAAC,CAAS,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3D,KAAK,UAAU,CAAC,CAAK,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtD,KAAK,YAAY,CAAC,CAAG,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvD,KAAK,UAAU,CAAC,CAAK,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACjD,KAAK,WAAW,CAAC,CAAI,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/C,KAAK,aAAa,CAAC,CAAE,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3D,KAAK,aAAa,CAAC,CAAE,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACxE,KAAK,UAAU,CAAC,CAAK,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxD,KAAK,UAAU,CAAC,CAAK,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAClE,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,OAAO,GAAI,GAAsB,CAAC,EAAE,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,OAAO,EAAE,EAAE,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAEpE,SAAS;QACf,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvD,MAAM,IAAI,GAAe;gBACvB,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI;gBACJ,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,SAAS;aACtC,CAAC;YACF,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS;oBAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC5D,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS;oBAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;gBAC9F,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;YAC/C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,WAAW;QACjB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACzC,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC3C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,CAAC;IACnE,CAAC;IAED;;;0EAGsE;IAC9D,QAAQ,CAAC,EAAU;QACzB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7E,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC;QAC/D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IAC1D,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,CAAC;IACnE,CAAC;IAED;;;yCAGqC;IAC7B,KAAK,CAAC,OAAO,CAAC,EAAU;QAC9B,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3F,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IAC5E,CAAC;IAED;2DACuD;IAC/C,KAAK,CAAC,UAAU,CAAC,EAAU;QACjC,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC;QAC/D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,EAAE;YAAE,OAAO,UAAU,CAAC;QACtC,MAAM,SAAS,GAAI,UAAU,CAAC,IAA8B,CAAC,OAAO,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC;IAC3C,CAAC;IAEO,OAAO,CAAC,EAAU,EAAE,IAAY;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC;QACnE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC3E,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC;IACnD,CAAC;IAEO,WAAW,CAAC,MAAc;QAChC,IAAI,CAAC;YACH,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YACtC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;QACzC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,EAAU;QACpC,qEAAqE;QACrE,iBAAiB;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;YAChC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACpC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IAED,8EAA8E;IAEtE,UAAU,CAAC,GAAgD;QACjE,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,kBAAkB,EAAE,CAAC;QACtE,MAAM,KAAK,GAAgB,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QACpG,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS;YAAE,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;QAC5C,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;YAAE,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;QAC1E,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAClD,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3D,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACzD,CAAC;IAEO,WAAW;QACjB,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;IACtC,CAAC;IAEO,aAAa,CAAC,KAAa;QACjC,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;IACzC,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,OAAgB;QACnD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,OAAO,IAAI,GAAG;gBAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;IACjE,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,KAAa;QACpC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,KAAK,EAAE,EAAE,CAAC;QACpF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;IACvD,CAAC;IAEO,UAAU,CAAC,KAAyB,EAAE,IAAwB;QACpE,MAAM,IAAI,GAAsC,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAC5C,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC5D,CAAC;IAEO,QAAQ,CAAC,GAAY;QAC3B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,CAAC;IAED;0FACsF;IAC9E,cAAc;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,OAAO;gBAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,GAAY;QAChC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,KAAa;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,CAAC;YAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;IACnD,CAAC;IAED;oFACgF;IACxE,WAAW;QACjB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO;gBAAE,SAAS;YAC3C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACxE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACpB,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9D,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS;oBAAE,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,CAAC;YAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAA6B,EAAE;QAC1D,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAE3B,IAAI,MAAkB,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,GAAG,kBAAkB,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC;YACzD,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,IAAI,OAAO,IAAI,GAAG,CAAC,YAAY;gBAAE,IAAI,GAAG,MAAM,IAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACxE,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YACjG,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC3B,MAAM,GAAG,cAAc,CAAC;YAC1B,CAAC;iBAAM,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,MAAM,GAAG,cAAc,CAAC;YAC1B,CAAC;iBAAM,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;gBAChE,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,MAAM,GAAG,cAAc,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAC9C,MAAM,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,gBAAgB,CAAC;gBAC/F,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,IAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAC9B,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAChH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,4EAA4E;IAEpE,qBAAqB;QAC3B,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,EAAU,EAAE,GAAW,EAAE,IAAa;QACxD,gEAAgE;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,QAAQ,CAAC,YAAY,KAAK,IAAI;gBAAE,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACxE,iEAAiE;YACjE,gDAAgD;YAChD,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS;gBAAE,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACrE,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,6BAA6B;QAC7B,MAAM,MAAM,GAAgB;YAC1B,UAAU,EAAE,IAAI,IAAI,gBAAgB,CAAC,GAAG,CAAC;YACzC,gBAAgB,EAAE,IAAI;SACvB,CAAC;QACF,MAAM,SAAS,GAAoB;YACjC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa;YACtC,GAAG;YACH,MAAM;SACP,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QACrE,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,IAAI,GAAc,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAE5B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;QACzE,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAEO,YAAY,CAAC,EAAU,EAAE,GAAsB;QACrD,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,4DAA4D;YAC5D,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,EAAE,CAAC;YAC3C,qEAAqE;YACrE,sEAAsE;YACtE,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,oCAAoC;QACpC,IAAI,IAAI,CAAC,cAAc,IAAI,mBAAmB,CAAC,MAAM,EAAE,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iDAAiD,EAAE,UAAU,IAAI,CAAC,cAAc,aAAa,CAC9F,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAE,CAAC;QACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iDAAiD,EAAE,OAAO,KAAK,eAAe,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,CAC3G,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB,CAAC,GAAW,IAAY,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAErF;4BAC4B;AAC5B,MAAM,UAAU,qBAAqB,KAAa,OAAO,kBAAkB,EAAE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import type { AskResponseEnrichmentWire, ExtensionUiResponseWire, ServerMessage } from "./protocol/types.js";
3
+ export interface ExtensionUiBridge {
4
+ /** Route an inbound `extension_ui_response` from a peer back to pi-ask. */
5
+ respond(msg: ExtensionUiResponseWire): void;
6
+ /**
7
+ * Requests for flows still awaiting an answer, for `session_sync` to replay.
8
+ *
9
+ * The `started` broadcast fires exactly once. A peer that connects *after*
10
+ * a flow opened never saw it: history replayed, but the interactive frame
11
+ * did not, so the phone showed the ask_user tool call as plain text while
12
+ * the desktop sat blocked on the TUI dialog. Replaying on sync closes that
13
+ * hole — the common real-world case is the agent asking while the app is
14
+ * closed.
15
+ */
16
+ pendingRequests(): ServerMessage[];
17
+ /** Drop all subscriptions + state (best-effort teardown). */
18
+ dispose(): void;
19
+ }
20
+ /**
21
+ * Wire pi-ask's event contract to the relay's extension_ui_request/response
22
+ * frames. Returns `null` only if the SDK exposes no usable `events` bus (defensive
23
+ * — modern Pi always has one); callers stay null-safe.
24
+ */
25
+ export declare function createExtensionUiBridge(pi: ExtensionAPI, broadcast: (msg: ServerMessage) => void): ExtensionUiBridge | null;
26
+ export type { AskResponseEnrichmentWire, ExtensionUiResponseWire };