@geohar/un-bien 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +726 -0
  3. package/dist/actions/handlers.d.ts +77 -0
  4. package/dist/actions/handlers.js +26 -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 +62 -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 +84 -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 +71 -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 +198 -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 +603 -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 +419 -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 +666 -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 +197 -0
  46. package/dist/index.js +5750 -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 +373 -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 +63 -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 +127 -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 +217 -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 +407 -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 +127 -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 +614 -0
  83. package/dist/pairing/storage.js.map +1 -0
  84. package/dist/panel_bridge.d.ts +15 -0
  85. package/dist/panel_bridge.js +409 -0
  86. package/dist/panel_bridge.js.map +1 -0
  87. package/dist/paths.d.ts +39 -0
  88. package/dist/paths.js +51 -0
  89. package/dist/paths.js.map +1 -0
  90. package/dist/protocol/codec.d.ts +7 -0
  91. package/dist/protocol/codec.js +48 -0
  92. package/dist/protocol/codec.js.map +1 -0
  93. package/dist/protocol/types.d.ts +404 -0
  94. package/dist/protocol/types.js +2 -0
  95. package/dist/protocol/types.js.map +1 -0
  96. package/dist/rooms.d.ts +42 -0
  97. package/dist/rooms.js +78 -0
  98. package/dist/rooms.js.map +1 -0
  99. package/dist/session/bridge.d.ts +37 -0
  100. package/dist/session/bridge.js +134 -0
  101. package/dist/session/bridge.js.map +1 -0
  102. package/dist/session/broker.d.ts +189 -0
  103. package/dist/session/broker.js +527 -0
  104. package/dist/session/broker.js.map +1 -0
  105. package/dist/session/broker_remote.d.ts +74 -0
  106. package/dist/session/broker_remote.js +581 -0
  107. package/dist/session/broker_remote.js.map +1 -0
  108. package/dist/session/cwd_lock.d.ts +33 -0
  109. package/dist/session/cwd_lock.js +127 -0
  110. package/dist/session/cwd_lock.js.map +1 -0
  111. package/dist/session/debug_log.d.ts +3 -0
  112. package/dist/session/debug_log.js +32 -0
  113. package/dist/session/debug_log.js.map +1 -0
  114. package/dist/session/envelope.d.ts +33 -0
  115. package/dist/session/envelope.js +117 -0
  116. package/dist/session/envelope.js.map +1 -0
  117. package/dist/session/global_config.d.ts +33 -0
  118. package/dist/session/global_config.js +73 -0
  119. package/dist/session/global_config.js.map +1 -0
  120. package/dist/session/ipc.d.ts +27 -0
  121. package/dist/session/ipc.js +22 -0
  122. package/dist/session/ipc.js.map +1 -0
  123. package/dist/session/leader_election.d.ts +32 -0
  124. package/dist/session/leader_election.js +108 -0
  125. package/dist/session/leader_election.js.map +1 -0
  126. package/dist/session/local_config.d.ts +67 -0
  127. package/dist/session/local_config.js +193 -0
  128. package/dist/session/local_config.js.map +1 -0
  129. package/dist/session/mesh_node.d.ts +116 -0
  130. package/dist/session/mesh_node.js +596 -0
  131. package/dist/session/mesh_node.js.map +1 -0
  132. package/dist/session/peer.d.ts +139 -0
  133. package/dist/session/peer.js +474 -0
  134. package/dist/session/peer.js.map +1 -0
  135. package/dist/session/peer_inventory.d.ts +13 -0
  136. package/dist/session/peer_inventory.js +48 -0
  137. package/dist/session/peer_inventory.js.map +1 -0
  138. package/dist/session/peer_limits.d.ts +9 -0
  139. package/dist/session/peer_limits.js +24 -0
  140. package/dist/session/peer_limits.js.map +1 -0
  141. package/dist/session/rpc_envelope.d.ts +108 -0
  142. package/dist/session/rpc_envelope.js +221 -0
  143. package/dist/session/rpc_envelope.js.map +1 -0
  144. package/dist/session/rpc_inbound.d.ts +55 -0
  145. package/dist/session/rpc_inbound.js +136 -0
  146. package/dist/session/rpc_inbound.js.map +1 -0
  147. package/dist/session/setup_wizard.d.ts +39 -0
  148. package/dist/session/setup_wizard.js +63 -0
  149. package/dist/session/setup_wizard.js.map +1 -0
  150. package/dist/session/tools.d.ts +24 -0
  151. package/dist/session/tools.js +272 -0
  152. package/dist/session/tools.js.map +1 -0
  153. package/dist/session/wizard.d.ts +13 -0
  154. package/dist/session/wizard.js +20 -0
  155. package/dist/session/wizard.js.map +1 -0
  156. package/dist/transport/peer_channel.d.ts +52 -0
  157. package/dist/transport/peer_channel.js +145 -0
  158. package/dist/transport/peer_channel.js.map +1 -0
  159. package/dist/transport/pi_forward_client.d.ts +29 -0
  160. package/dist/transport/pi_forward_client.js +68 -0
  161. package/dist/transport/pi_forward_client.js.map +1 -0
  162. package/dist/transport/relay_client.d.ts +96 -0
  163. package/dist/transport/relay_client.js +210 -0
  164. package/dist/transport/relay_client.js.map +1 -0
  165. package/dist/ui/footer.d.ts +32 -0
  166. package/dist/ui/footer.js +34 -0
  167. package/dist/ui/footer.js.map +1 -0
  168. package/docs/daemon.md +289 -0
  169. package/package.json +92 -0
  170. package/service-templates/launchd.plist.template +35 -0
  171. package/service-templates/systemd.service.template +19 -0
  172. package/service-templates/task-launcher.vbs.template +10 -0
  173. package/service-templates/task-scheduler.xml.template +38 -0
  174. package/skills/agent-network/SKILL.md +310 -0
@@ -0,0 +1,409 @@
1
+ // Bridge the in-process plan + subagents buses to the paired app as
2
+ // `panel_update` frames. pi-plan renders these same sources to a local TUI
3
+ // widget (render-only, process-local) and never puts them on the relay; this
4
+ // module mirrors that data over the wire so the app's side-panels populate
5
+ // from a live session.
6
+ //
7
+ // Two sources, ported from pi-plan (wire.ts + agents.ts):
8
+ // plan:snapshot { ns, seq?, items } — replace a source's whole set
9
+ // plan:update { ns, seq?, upsert?, remove? } — part-by-part patch
10
+ // subagents:* { id, type?, description? } — 6 lifecycle channels
11
+ //
12
+ // Each source accumulates and broadcasts `panel_update { key, title, data }`,
13
+ // coalesced so a burst of bus events yields one frame per tick. `data` is
14
+ // `{ items: [...] }`; the app decodes the plan panel's items through its own
15
+ // wave-order model, and renders others generically.
16
+ //
17
+ // Inert when the SDK exposes no events bus. Faithful to pi-plan so the two
18
+ // stay wire-compatible; kept self-contained (pi-plan is not a dependency).
19
+ import { appendFileSync, mkdirSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { loadConfig } from "./config.js";
22
+ import { unbienStateHome } from "./paths.js";
23
+ /** Coalesce window: bus events often arrive in bursts (a plan snapshot + N
24
+ * updates); one frame per source per tick is plenty and spares the relay. */
25
+ const COALESCE_MS = 60;
26
+ const PLAN_KEY = "plan";
27
+ const AGENTS_KEY = "subagents";
28
+ /**
29
+ * Subscribe the plan + subagents buses and broadcast `panel_update` frames.
30
+ * Returns `null` when the SDK exposes no usable events bus (defensive — modern
31
+ * Pi always has one); callers stay null-safe.
32
+ */
33
+ export function createPanelBridge(pi, broadcast) {
34
+ const eventsRaw = pi.events;
35
+ if (!eventsRaw || typeof eventsRaw.on !== "function") {
36
+ return null;
37
+ }
38
+ const events = eventsRaw;
39
+ // Opt-in tracing: shows whether bus events land and whether a panel frame is
40
+ // broadcast, to isolate capture vs render. Enabled by the `debug.panels` pref
41
+ // in the global config (`extensions/un-bien.json`) — logs to stderr AND appends
42
+ // to `<state>/panel-bridge.log`. stderr scrolls too fast — tail the file.
43
+ const debug = (() => {
44
+ if (loadConfig().debug?.panels !== true)
45
+ return () => { };
46
+ // Stable, findable location: `<state>/panel-bridge.log`.
47
+ const dir = unbienStateHome();
48
+ try {
49
+ mkdirSync(dir, { recursive: true });
50
+ }
51
+ catch {
52
+ /* best-effort */
53
+ }
54
+ const logFile = join(dir, "panel-bridge.log");
55
+ return (msg) => {
56
+ const line = `${new Date().toISOString()} [panel-bridge] ${msg}`;
57
+ try {
58
+ console.error(line);
59
+ }
60
+ catch {
61
+ /* stderr closed */
62
+ }
63
+ try {
64
+ appendFileSync(logFile, `${line}\n`);
65
+ }
66
+ catch {
67
+ /* best-effort file log */
68
+ }
69
+ };
70
+ })();
71
+ // ── Plan accumulation (port of pi-plan wire.ts) ──────────────────────────
72
+ // Per-source (`ns`) item maps + last-seen seq to drop out-of-order frames.
73
+ const planByNs = new Map();
74
+ const planLastSeq = new Map();
75
+ const allPlanItems = () => {
76
+ const out = [];
77
+ for (const map of planByNs.values())
78
+ for (const it of map.values())
79
+ out.push(it);
80
+ return out;
81
+ };
82
+ // ── Subagents fleet (port of pi-plan agents.ts) ──────────────────────────
83
+ const fleet = new Map();
84
+ // pi-plan's buildView SEPARATES agents from plans. A plan source can fold the
85
+ // fleet into its snapshot as `kind:"agent"` nodes (pi-acp does), so route those
86
+ // to the AGENTS panel and keep them out of the plan rows. Direct `subagents:*`
87
+ // fleet + any agent-kind plan items are merged by id (live fleet wins status).
88
+ const isAgent = (it) => it.kind === "agent";
89
+ const planPanelItems = () => allPlanItems().filter((it) => !isAgent(it));
90
+ const agentItems = () => {
91
+ const byId = new Map();
92
+ for (const it of allPlanItems())
93
+ if (isAgent(it))
94
+ byId.set(it.id, it);
95
+ for (const a of fleet.values()) {
96
+ const item = toAgentItem(a);
97
+ byId.set(item.id, item); // live fleet status wins
98
+ }
99
+ return [...byId.values()];
100
+ };
101
+ // ── Coalesced broadcast ──────────────────────────────────────────────────
102
+ const timers = new Map();
103
+ let disposed = false;
104
+ const planFrame = () => ({
105
+ type: "panel_update",
106
+ key: PLAN_KEY,
107
+ title: "Plan",
108
+ icon: "checklist",
109
+ data: { items: planPanelItems() },
110
+ });
111
+ const agentsFrame = () => ({
112
+ type: "panel_update",
113
+ key: AGENTS_KEY,
114
+ title: "Agents",
115
+ icon: "person.2",
116
+ data: { items: agentItems() },
117
+ });
118
+ const scheduleBroadcast = (key, build) => {
119
+ if (disposed)
120
+ return;
121
+ if (timers.has(key)) {
122
+ debug(`schedule ${key} coalesced (timer pending)`);
123
+ return;
124
+ }
125
+ debug(`schedule ${key}`);
126
+ timers.set(key, setTimeout(() => {
127
+ timers.delete(key);
128
+ if (disposed)
129
+ return;
130
+ let frame;
131
+ try {
132
+ frame = build();
133
+ }
134
+ catch (error) {
135
+ debug(`build ${key} THREW: ${error instanceof Error ? error.message : String(error)}`);
136
+ return;
137
+ }
138
+ const fitems = frame.type === "panel_update" &&
139
+ frame.data &&
140
+ typeof frame.data === "object"
141
+ ? (frame.data.items ?? [])
142
+ : [];
143
+ const kinds = fitems.reduce((acc, it) => {
144
+ const k = typeof it?.kind === "string" ? it.kind : "?";
145
+ acc[k] = (acc[k] ?? 0) + 1;
146
+ return acc;
147
+ }, {});
148
+ debug(`broadcast ${key} items=${fitems.length} kinds=${JSON.stringify(kinds)}`);
149
+ broadcast(frame);
150
+ }, COALESCE_MS));
151
+ };
152
+ // Broadcast NOW (no coalesce). Subagent lifecycle events are infrequent and
153
+ // discrete — coalescing them risks losing the frame if the bridge is disposed
154
+ // (session replacement / name collision) within the coalesce window, which is
155
+ // exactly what dropped the subagents panel. Plan stays coalesced (it bursts).
156
+ const broadcastNow = (key, build) => {
157
+ if (disposed)
158
+ return;
159
+ let frame;
160
+ try {
161
+ frame = build();
162
+ }
163
+ catch (error) {
164
+ debug(`build ${key} THREW: ${error instanceof Error ? error.message : String(error)}`);
165
+ return;
166
+ }
167
+ const items = frame.type === "panel_update" &&
168
+ frame.data &&
169
+ typeof frame.data === "object"
170
+ ? (frame.data.items?.length ?? 0)
171
+ : 0;
172
+ debug(`broadcast ${key} now items=${items}`);
173
+ broadcast(frame);
174
+ };
175
+ // ── Plan subscriptions ───────────────────────────────────────────────────
176
+ const onSnapshot = (raw) => {
177
+ const snap = parseSnapshot(raw);
178
+ if (!snap)
179
+ return;
180
+ const last = planLastSeq.get(snap.ns);
181
+ if (last != null && snap.seq < last)
182
+ return; // stale
183
+ planLastSeq.set(snap.ns, snap.seq);
184
+ const next = new Map();
185
+ for (const it of snap.items)
186
+ next.set(it.id, it);
187
+ planByNs.set(snap.ns, next);
188
+ scheduleBroadcast(PLAN_KEY, planFrame);
189
+ // Refresh the agents panel only when agents exist — never broadcast an empty
190
+ // agents frame off a plain plan update (that would spawn a bogus subagents icon).
191
+ if (agentItems().length > 0)
192
+ broadcastNow(AGENTS_KEY, agentsFrame);
193
+ };
194
+ const onUpdate = (raw) => {
195
+ const up = parseUpdate(raw);
196
+ if (!up)
197
+ return;
198
+ const last = planLastSeq.get(up.ns);
199
+ if (last != null && up.seq < last)
200
+ return; // stale
201
+ planLastSeq.set(up.ns, up.seq);
202
+ const map = planByNs.get(up.ns) ?? new Map();
203
+ let changed = false;
204
+ for (const it of up.upsert) {
205
+ map.set(it.id, it);
206
+ changed = true;
207
+ }
208
+ for (const id of up.remove)
209
+ changed = map.delete(id) || changed;
210
+ if (!changed)
211
+ return;
212
+ planByNs.set(up.ns, map);
213
+ scheduleBroadcast(PLAN_KEY, planFrame);
214
+ if (agentItems().length > 0)
215
+ broadcastNow(AGENTS_KEY, agentsFrame);
216
+ };
217
+ const unsubPlan = [
218
+ events.on("plan:snapshot", onSnapshot),
219
+ events.on("plan:update", onUpdate),
220
+ ];
221
+ // ── Subagents subscriptions ──────────────────────────────────────────────
222
+ const recordAgent = (status) => (data) => {
223
+ const p = (data ?? {});
224
+ const id = str(p.id);
225
+ debug(`event ${status} id=${id ?? "<none>"}`);
226
+ if (!id)
227
+ return;
228
+ const prev = fleet.get(id);
229
+ const incoming = {
230
+ id,
231
+ type: str(p.type),
232
+ description: str(p.description),
233
+ status,
234
+ startedAt: prev?.startedAt ?? (IN_PROGRESS.has(status) ? Date.now() : undefined),
235
+ };
236
+ fleet.set(id, mergeAgentState(prev, incoming));
237
+ debug(`fleet=${fleet.size} after ${status} ${id}`);
238
+ broadcastNow(AGENTS_KEY, agentsFrame);
239
+ };
240
+ const unsubAgents = Object.entries(LIFECYCLE).map(([channel, status]) => events.on(channel, recordAgent(status)));
241
+ // NB: unlike pi-plan's TUI (which clears its fleet on session_shutdown to reset
242
+ // the widget), we deliberately KEEP finished agents. Broadcasting an empty
243
+ // frame on shutdown would clobber the app's panel the instant a fast agent
244
+ // completes — the user expects done agents to linger for a while. The fleet
245
+ // resets naturally when the pi process restarts (a new session = a fresh
246
+ // bridge), and `pendingPanels` still replays the last fleet to a reconnecting
247
+ // app.
248
+ return {
249
+ pendingPanels() {
250
+ const out = [];
251
+ if (planPanelItems().length > 0)
252
+ out.push(planFrame());
253
+ if (agentItems().length > 0)
254
+ out.push(agentsFrame());
255
+ return out;
256
+ },
257
+ dispose() {
258
+ disposed = true;
259
+ for (const u of unsubPlan)
260
+ safeUnsub(u);
261
+ for (const u of unsubAgents)
262
+ safeUnsub(u);
263
+ for (const t of timers.values())
264
+ clearTimeout(t);
265
+ timers.clear();
266
+ planByNs.clear();
267
+ planLastSeq.clear();
268
+ fleet.clear();
269
+ },
270
+ };
271
+ }
272
+ function parseItem(raw) {
273
+ if (!raw || typeof raw !== "object")
274
+ return null;
275
+ const r = raw;
276
+ if (typeof r.id !== "string")
277
+ return null;
278
+ const display = typeof r.title === "string"
279
+ ? r.title
280
+ : typeof r.name === "string"
281
+ ? r.name
282
+ : r.id;
283
+ return {
284
+ id: r.id,
285
+ kind: typeof r.kind === "string" ? r.kind : "plan",
286
+ title: display,
287
+ status: typeof r.status === "string" ? r.status : null,
288
+ deps: Array.isArray(r.deps)
289
+ ? r.deps.filter((x) => typeof x === "string")
290
+ : [],
291
+ tainted: typeof r.tainted === "boolean" ? r.tainted : undefined,
292
+ meta: r.meta && typeof r.meta === "object"
293
+ ? r.meta
294
+ : undefined,
295
+ };
296
+ }
297
+ /** Parse `plan:snapshot`. Accepts `source` as a legacy alias for `ns`. */
298
+ function parseSnapshot(data) {
299
+ if (!data || typeof data !== "object")
300
+ return null;
301
+ const d = data;
302
+ const ns = typeof d.ns === "string"
303
+ ? d.ns
304
+ : typeof d.source === "string"
305
+ ? d.source
306
+ : null;
307
+ if (!ns || !Array.isArray(d.items))
308
+ return null;
309
+ const items = d.items.map(parseItem).filter((x) => x !== null);
310
+ return { ns, seq: typeof d.seq === "number" ? d.seq : 0, items };
311
+ }
312
+ /** Parse `plan:update`. Returns null when unusable or a no-op. */
313
+ function parseUpdate(data) {
314
+ if (!data || typeof data !== "object")
315
+ return null;
316
+ const d = data;
317
+ const ns = typeof d.ns === "string" ? d.ns : null;
318
+ if (!ns)
319
+ return null;
320
+ const upsert = Array.isArray(d.upsert)
321
+ ? d.upsert.map(parseItem).filter((x) => x !== null)
322
+ : [];
323
+ const remove = Array.isArray(d.remove)
324
+ ? d.remove.filter((x) => typeof x === "string")
325
+ : [];
326
+ if (upsert.length === 0 && remove.length === 0)
327
+ return null;
328
+ return { ns, seq: typeof d.seq === "number" ? d.seq : 0, upsert, remove };
329
+ }
330
+ const IN_PROGRESS = new Set(["started", "running", "steered", "compacted"]);
331
+ const FAILED = new Set(["failed", "stopped", "aborted", "error"]);
332
+ const LIFECYCLE = {
333
+ "subagents:created": "created",
334
+ "subagents:started": "started",
335
+ "subagents:completed": "completed",
336
+ "subagents:failed": "failed",
337
+ "subagents:steered": "steered",
338
+ "subagents:compacted": "compacted",
339
+ };
340
+ /** Lifecycle rank: pending(0) < in_progress(1) < terminal(2). */
341
+ function statusRank(status) {
342
+ const s = String(status ?? "").toLowerCase();
343
+ if (s === "completed" || FAILED.has(s))
344
+ return 2;
345
+ if (IN_PROGRESS.has(s))
346
+ return 1;
347
+ return 0;
348
+ }
349
+ /** Merge a lifecycle event into kept state: never downgrade status, keep a
350
+ * specific terminal reason over a generic `failed`. */
351
+ function mergeAgentState(prev, incoming) {
352
+ const merged = { ...prev, ...incoming };
353
+ if (prev?.type && !incoming.type)
354
+ merged.type = prev.type;
355
+ if (prev?.description && !incoming.description)
356
+ merged.description = prev.description;
357
+ if (prev) {
358
+ const prevStatus = String(prev.status ?? "").toLowerCase();
359
+ const inStatus = String(incoming.status ?? "").toLowerCase();
360
+ const prevRank = statusRank(prevStatus);
361
+ const inRank = statusRank(inStatus);
362
+ if (prevRank > inRank)
363
+ merged.status = prev.status;
364
+ else if (prevRank === 2 &&
365
+ inRank === 2 &&
366
+ inStatus === "failed" &&
367
+ prevStatus !== "failed")
368
+ merged.status = prev.status;
369
+ }
370
+ return merged;
371
+ }
372
+ /** Map a raw lifecycle status to the display status the app renders. */
373
+ function displayStatus(status) {
374
+ const s = String(status ?? "").toLowerCase();
375
+ if (s === "completed")
376
+ return "done";
377
+ if (FAILED.has(s))
378
+ return "failed";
379
+ if (IN_PROGRESS.has(s))
380
+ return "in_progress";
381
+ return "pending";
382
+ }
383
+ /** An AgentState → a `kind:"agent"` plan item for the Agents panel. */
384
+ function toAgentItem(a) {
385
+ const title = a.description?.trim() || a.type || a.id;
386
+ return {
387
+ id: `agent:${a.id}`,
388
+ kind: "agent",
389
+ title,
390
+ status: displayStatus(a.status),
391
+ deps: [],
392
+ meta: { agentType: a.type, startedAt: a.startedAt },
393
+ };
394
+ }
395
+ function str(v) {
396
+ return typeof v === "string" && v.length > 0 ? v : undefined;
397
+ }
398
+ /** Unsubscribe handles may be `() => void` or undefined; tolerate both. */
399
+ function safeUnsub(u) {
400
+ if (typeof u === "function") {
401
+ try {
402
+ u();
403
+ }
404
+ catch {
405
+ /* best-effort teardown */
406
+ }
407
+ }
408
+ }
409
+ //# sourceMappingURL=panel_bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel_bridge.js","sourceRoot":"","sources":["../src/panel_bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Absolute root for un-bien on-disk STATE: `sessions/`, `skills/`, the
3
+ * paired-identity/`peers.json` store, the daemon registries (`daemons.json`,
4
+ * `cron.json`), the cron/audit logs, the supervisor socket, and the cwd lock
5
+ * dir. Every state path in the codebase derives from this one resolver so a
6
+ * relocated install can never split its state across two roots.
7
+ *
8
+ * The GLOBAL config is the one exception — it follows the coding-agent dir via
9
+ * `unbienConfigHome()` (below) as `extensions/un-bien.json`, not this resolver.
10
+ *
11
+ * Precedence (resolved at CALL time so tests — and a relocated deployment —
12
+ * can override via env without re-importing):
13
+ *
14
+ * 1. `UNBIEN_DIR` — an ABSOLUTE override of the state dir itself. Lets the
15
+ * state live at an arbitrary path (e.g. an XDG-style `~/.config/pi/un-bien`)
16
+ * with no forced `.pi/un-bien` suffix. This is the knob to reach for when
17
+ * relocating; `UNBIEN_HOME` cannot express it.
18
+ * 2. `UNBIEN_HOME` — a stand-in `$HOME`; state lives at
19
+ * `<UNBIEN_HOME>/.pi/un-bien`. Long-standing test/override knob.
20
+ * 3. `os.homedir()` — the default, `~/.pi/un-bien`.
21
+ */
22
+ export declare function unbienStateHome(): string;
23
+ /**
24
+ * Root for un-bien's global config specifically — the machine-wide relay URL,
25
+ * the `defaults` block, and the `debug` prefs. The Pi host keeps its own global
26
+ * settings under `PI_CODING_AGENT_DIR`, and un-bien's config is a pi extension
27
+ * config: `<PI_CODING_AGENT_DIR|~/.pi>/extensions/un-bien.json`. This resolver
28
+ * returns the `extensions` dir; `config.ts` appends `un-bien.json`.
29
+ *
30
+ * Precedence (resolved at CALL time):
31
+ *
32
+ * 1. `PI_CODING_AGENT_DIR` — the Pi host's settings root (default `~/.pi`).
33
+ * Config lives at `<PI_CODING_AGENT_DIR>/extensions/un-bien.json`.
34
+ * 2. otherwise `~/.pi/extensions` — the default agent-dir location.
35
+ *
36
+ * State (sessions, daemon registries, cwd locks, identity) is unaffected — only
37
+ * the global config honours `PI_CODING_AGENT_DIR` this way.
38
+ */
39
+ export declare function unbienConfigHome(): string;
package/dist/paths.js ADDED
@@ -0,0 +1,51 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Absolute root for un-bien on-disk STATE: `sessions/`, `skills/`, the
5
+ * paired-identity/`peers.json` store, the daemon registries (`daemons.json`,
6
+ * `cron.json`), the cron/audit logs, the supervisor socket, and the cwd lock
7
+ * dir. Every state path in the codebase derives from this one resolver so a
8
+ * relocated install can never split its state across two roots.
9
+ *
10
+ * The GLOBAL config is the one exception — it follows the coding-agent dir via
11
+ * `unbienConfigHome()` (below) as `extensions/un-bien.json`, not this resolver.
12
+ *
13
+ * Precedence (resolved at CALL time so tests — and a relocated deployment —
14
+ * can override via env without re-importing):
15
+ *
16
+ * 1. `UNBIEN_DIR` — an ABSOLUTE override of the state dir itself. Lets the
17
+ * state live at an arbitrary path (e.g. an XDG-style `~/.config/pi/un-bien`)
18
+ * with no forced `.pi/un-bien` suffix. This is the knob to reach for when
19
+ * relocating; `UNBIEN_HOME` cannot express it.
20
+ * 2. `UNBIEN_HOME` — a stand-in `$HOME`; state lives at
21
+ * `<UNBIEN_HOME>/.pi/un-bien`. Long-standing test/override knob.
22
+ * 3. `os.homedir()` — the default, `~/.pi/un-bien`.
23
+ */
24
+ export function unbienStateHome() {
25
+ const dir = process.env["UNBIEN_DIR"];
26
+ if (dir && dir.length > 0)
27
+ return dir;
28
+ return join(process.env["UNBIEN_HOME"] || homedir(), ".pi", "un-bien");
29
+ }
30
+ /**
31
+ * Root for un-bien's global config specifically — the machine-wide relay URL,
32
+ * the `defaults` block, and the `debug` prefs. The Pi host keeps its own global
33
+ * settings under `PI_CODING_AGENT_DIR`, and un-bien's config is a pi extension
34
+ * config: `<PI_CODING_AGENT_DIR|~/.pi>/extensions/un-bien.json`. This resolver
35
+ * returns the `extensions` dir; `config.ts` appends `un-bien.json`.
36
+ *
37
+ * Precedence (resolved at CALL time):
38
+ *
39
+ * 1. `PI_CODING_AGENT_DIR` — the Pi host's settings root (default `~/.pi`).
40
+ * Config lives at `<PI_CODING_AGENT_DIR>/extensions/un-bien.json`.
41
+ * 2. otherwise `~/.pi/extensions` — the default agent-dir location.
42
+ *
43
+ * State (sessions, daemon registries, cwd locks, identity) is unaffected — only
44
+ * the global config honours `PI_CODING_AGENT_DIR` this way.
45
+ */
46
+ export function unbienConfigHome() {
47
+ const agentDir = process.env["PI_CODING_AGENT_DIR"];
48
+ const base = agentDir && agentDir.length > 0 ? agentDir : join(homedir(), ".pi");
49
+ return join(base, "extensions");
50
+ }
51
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACpD,MAAM,IAAI,GACR,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ClientMessage, ServerMessage } from "./types.js";
2
+ export declare class DecodeError extends Error {
3
+ readonly code: "invalid_message" | "unsupported_type";
4
+ constructor(code: "invalid_message" | "unsupported_type", message: string);
5
+ }
6
+ export declare function encodeClient(msg: ClientMessage): string;
7
+ export declare function decodeServer(line: string): ServerMessage;
@@ -0,0 +1,48 @@
1
+ const SERVER_TYPES = new Set([
2
+ "pair_ok",
3
+ "pair_error",
4
+ "user_input",
5
+ "queued_message_state",
6
+ "agent_chunk",
7
+ "agent_reasoning",
8
+ "agent_done",
9
+ "agent_message",
10
+ "tool_request",
11
+ "tool_result",
12
+ "error",
13
+ "cancelled",
14
+ "pong",
15
+ // Plan/57 — interactive extension prompt (ask_user via pi-ask).
16
+ "extension_ui_request",
17
+ ]);
18
+ export class DecodeError extends Error {
19
+ code;
20
+ constructor(code, message) {
21
+ super(message);
22
+ this.code = code;
23
+ this.name = "DecodeError";
24
+ }
25
+ }
26
+ export function encodeClient(msg) {
27
+ return JSON.stringify(msg) + "\n";
28
+ }
29
+ export function decodeServer(line) {
30
+ let obj;
31
+ try {
32
+ obj = JSON.parse(line.trim());
33
+ }
34
+ catch (e) {
35
+ throw new DecodeError("invalid_message", `not JSON: ${e.message}`);
36
+ }
37
+ if (!obj ||
38
+ typeof obj !== "object" ||
39
+ typeof obj.type !== "string") {
40
+ throw new DecodeError("invalid_message", "missing 'type'");
41
+ }
42
+ const t = obj.type;
43
+ if (!SERVER_TYPES.has(t)) {
44
+ throw new DecodeError("unsupported_type", `unknown type: ${t}`);
45
+ }
46
+ return obj;
47
+ }
48
+ //# sourceMappingURL=codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/protocol/codec.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAwB;IAClD,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,sBAAsB;IACtB,aAAa;IACb,iBAAiB;IACjB,YAAY;IACZ,eAAe;IACf,cAAc;IACd,aAAa;IACb,OAAO;IACP,WAAW;IACX,MAAM;IACN,gEAAgE;IAChE,sBAAsB;CACvB,CAAC,CAAC;AAEH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IADlB,YACkB,IAA4C,EAC5D,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAwC;QAI5D,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,GAAkB;IAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,WAAW,CACnB,iBAAiB,EACjB,aAAc,CAAW,CAAC,OAAO,EAAE,CACpC,CAAC;IACJ,CAAC;IACD,IACE,CAAC,GAAG;QACJ,OAAO,GAAG,KAAK,QAAQ;QACvB,OAAQ,GAA+B,CAAC,IAAI,KAAK,QAAQ,EACzD,CAAC;QACD,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,CAAC,GAAI,GAA+B,CAAC,IAAc,CAAC;IAC1D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAA0B,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,GAAoB,CAAC;AAC9B,CAAC"}