@av-pi-studio/server 0.0.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 (315) hide show
  1. package/README.md +411 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/agent/agent-manager.d.ts +107 -0
  4. package/dist/agent/agent-manager.d.ts.map +1 -0
  5. package/dist/agent/agent-manager.js +218 -0
  6. package/dist/agent/agent-manager.js.map +1 -0
  7. package/dist/agent/agent-service.d.ts +36 -0
  8. package/dist/agent/agent-service.d.ts.map +1 -0
  9. package/dist/agent/agent-service.js +195 -0
  10. package/dist/agent/agent-service.js.map +1 -0
  11. package/dist/agent/index.d.ts +17 -0
  12. package/dist/agent/index.d.ts.map +1 -0
  13. package/dist/agent/index.js +18 -0
  14. package/dist/agent/index.js.map +1 -0
  15. package/dist/agent/manifest.d.ts +7 -0
  16. package/dist/agent/manifest.d.ts.map +1 -0
  17. package/dist/agent/manifest.js +27 -0
  18. package/dist/agent/manifest.js.map +1 -0
  19. package/dist/agent/mcp-server.d.ts +100 -0
  20. package/dist/agent/mcp-server.d.ts.map +1 -0
  21. package/dist/agent/mcp-server.js +163 -0
  22. package/dist/agent/mcp-server.js.map +1 -0
  23. package/dist/agent/permissions.d.ts +71 -0
  24. package/dist/agent/permissions.d.ts.map +1 -0
  25. package/dist/agent/permissions.js +132 -0
  26. package/dist/agent/permissions.js.map +1 -0
  27. package/dist/agent/provider-contract.d.ts +134 -0
  28. package/dist/agent/provider-contract.d.ts.map +1 -0
  29. package/dist/agent/provider-contract.js +2 -0
  30. package/dist/agent/provider-contract.js.map +1 -0
  31. package/dist/agent/provider-registry.d.ts +37 -0
  32. package/dist/agent/provider-registry.d.ts.map +1 -0
  33. package/dist/agent/provider-registry.js +92 -0
  34. package/dist/agent/provider-registry.js.map +1 -0
  35. package/dist/agent/provider-snapshot.d.ts +52 -0
  36. package/dist/agent/provider-snapshot.d.ts.map +1 -0
  37. package/dist/agent/provider-snapshot.js +73 -0
  38. package/dist/agent/provider-snapshot.js.map +1 -0
  39. package/dist/agent/providers/mock/mock-provider.d.ts +44 -0
  40. package/dist/agent/providers/mock/mock-provider.d.ts.map +1 -0
  41. package/dist/agent/providers/mock/mock-provider.js +162 -0
  42. package/dist/agent/providers/mock/mock-provider.js.map +1 -0
  43. package/dist/agent/providers/pi/agent.d.ts +80 -0
  44. package/dist/agent/providers/pi/agent.d.ts.map +1 -0
  45. package/dist/agent/providers/pi/agent.js +322 -0
  46. package/dist/agent/providers/pi/agent.js.map +1 -0
  47. package/dist/agent/providers/pi/event-mapper.d.ts +17 -0
  48. package/dist/agent/providers/pi/event-mapper.d.ts.map +1 -0
  49. package/dist/agent/providers/pi/event-mapper.js +150 -0
  50. package/dist/agent/providers/pi/event-mapper.js.map +1 -0
  51. package/dist/agent/providers/pi/rpc-transport.d.ts +53 -0
  52. package/dist/agent/providers/pi/rpc-transport.d.ts.map +1 -0
  53. package/dist/agent/providers/pi/rpc-transport.js +190 -0
  54. package/dist/agent/providers/pi/rpc-transport.js.map +1 -0
  55. package/dist/agent/providers/pi/session-hydration.d.ts +11 -0
  56. package/dist/agent/providers/pi/session-hydration.d.ts.map +1 -0
  57. package/dist/agent/providers/pi/session-hydration.js +167 -0
  58. package/dist/agent/providers/pi/session-hydration.js.map +1 -0
  59. package/dist/agent/rewind-rpc.d.ts +15 -0
  60. package/dist/agent/rewind-rpc.d.ts.map +1 -0
  61. package/dist/agent/rewind-rpc.js +30 -0
  62. package/dist/agent/rewind-rpc.js.map +1 -0
  63. package/dist/agent/session-operations.d.ts +32 -0
  64. package/dist/agent/session-operations.d.ts.map +1 -0
  65. package/dist/agent/session-operations.js +130 -0
  66. package/dist/agent/session-operations.js.map +1 -0
  67. package/dist/agent/structured-generation.d.ts +39 -0
  68. package/dist/agent/structured-generation.d.ts.map +1 -0
  69. package/dist/agent/structured-generation.js +78 -0
  70. package/dist/agent/structured-generation.js.map +1 -0
  71. package/dist/agent/timeline-rpc.d.ts +21 -0
  72. package/dist/agent/timeline-rpc.d.ts.map +1 -0
  73. package/dist/agent/timeline-rpc.js +59 -0
  74. package/dist/agent/timeline-rpc.js.map +1 -0
  75. package/dist/agent/timeline-store.d.ts +100 -0
  76. package/dist/agent/timeline-store.d.ts.map +1 -0
  77. package/dist/agent/timeline-store.js +255 -0
  78. package/dist/agent/timeline-store.js.map +1 -0
  79. package/dist/auth/index.d.ts +2 -0
  80. package/dist/auth/index.d.ts.map +1 -0
  81. package/dist/auth/index.js +3 -0
  82. package/dist/auth/index.js.map +1 -0
  83. package/dist/auth/password-auth.d.ts +44 -0
  84. package/dist/auth/password-auth.d.ts.map +1 -0
  85. package/dist/auth/password-auth.js +78 -0
  86. package/dist/auth/password-auth.js.map +1 -0
  87. package/dist/config/daemon-config.d.ts +634 -0
  88. package/dist/config/daemon-config.d.ts.map +1 -0
  89. package/dist/config/daemon-config.js +258 -0
  90. package/dist/config/daemon-config.js.map +1 -0
  91. package/dist/config/index.d.ts +3 -0
  92. package/dist/config/index.d.ts.map +1 -0
  93. package/dist/config/index.js +4 -0
  94. package/dist/config/index.js.map +1 -0
  95. package/dist/config/project-config.d.ts +104 -0
  96. package/dist/config/project-config.d.ts.map +1 -0
  97. package/dist/config/project-config.js +106 -0
  98. package/dist/config/project-config.js.map +1 -0
  99. package/dist/daemon/bootstrap.d.ts +37 -0
  100. package/dist/daemon/bootstrap.d.ts.map +1 -0
  101. package/dist/daemon/bootstrap.js +448 -0
  102. package/dist/daemon/bootstrap.js.map +1 -0
  103. package/dist/daemon/dev-bootstrap.d.ts +14 -0
  104. package/dist/daemon/dev-bootstrap.d.ts.map +1 -0
  105. package/dist/daemon/dev-bootstrap.js +231 -0
  106. package/dist/daemon/dev-bootstrap.js.map +1 -0
  107. package/dist/daemon/dev-main.d.ts +3 -0
  108. package/dist/daemon/dev-main.d.ts.map +1 -0
  109. package/dist/daemon/dev-main.js +36 -0
  110. package/dist/daemon/dev-main.js.map +1 -0
  111. package/dist/daemon/index.d.ts +15 -0
  112. package/dist/daemon/index.d.ts.map +1 -0
  113. package/dist/daemon/index.js +21 -0
  114. package/dist/daemon/index.js.map +1 -0
  115. package/dist/daemon/main.d.ts +3 -0
  116. package/dist/daemon/main.d.ts.map +1 -0
  117. package/dist/daemon/main.js +29 -0
  118. package/dist/daemon/main.js.map +1 -0
  119. package/dist/daemon/orchestration-rpc.d.ts +19 -0
  120. package/dist/daemon/orchestration-rpc.d.ts.map +1 -0
  121. package/dist/daemon/orchestration-rpc.js +136 -0
  122. package/dist/daemon/orchestration-rpc.js.map +1 -0
  123. package/dist/files/download-token-store.d.ts +14 -0
  124. package/dist/files/download-token-store.d.ts.map +1 -0
  125. package/dist/files/download-token-store.js +33 -0
  126. package/dist/files/download-token-store.js.map +1 -0
  127. package/dist/files/file-explorer.d.ts +54 -0
  128. package/dist/files/file-explorer.d.ts.map +1 -0
  129. package/dist/files/file-explorer.js +182 -0
  130. package/dist/files/file-explorer.js.map +1 -0
  131. package/dist/files/file-transfer.d.ts +30 -0
  132. package/dist/files/file-transfer.d.ts.map +1 -0
  133. package/dist/files/file-transfer.js +132 -0
  134. package/dist/files/file-transfer.js.map +1 -0
  135. package/dist/files/index.d.ts +4 -0
  136. package/dist/files/index.d.ts.map +1 -0
  137. package/dist/files/index.js +5 -0
  138. package/dist/files/index.js.map +1 -0
  139. package/dist/http/host-allowlist.d.ts +15 -0
  140. package/dist/http/host-allowlist.d.ts.map +1 -0
  141. package/dist/http/host-allowlist.js +52 -0
  142. package/dist/http/host-allowlist.js.map +1 -0
  143. package/dist/http/http-server.d.ts +27 -0
  144. package/dist/http/http-server.d.ts.map +1 -0
  145. package/dist/http/http-server.js +76 -0
  146. package/dist/http/http-server.js.map +1 -0
  147. package/dist/http/index.d.ts +3 -0
  148. package/dist/http/index.d.ts.map +1 -0
  149. package/dist/http/index.js +4 -0
  150. package/dist/http/index.js.map +1 -0
  151. package/dist/index.d.ts +18 -0
  152. package/dist/index.d.ts.map +1 -0
  153. package/dist/index.js +35 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/logging/index.d.ts +2 -0
  156. package/dist/logging/index.d.ts.map +1 -0
  157. package/dist/logging/index.js +2 -0
  158. package/dist/logging/index.js.map +1 -0
  159. package/dist/logging/logger.d.ts +48 -0
  160. package/dist/logging/logger.d.ts.map +1 -0
  161. package/dist/logging/logger.js +53 -0
  162. package/dist/logging/logger.js.map +1 -0
  163. package/dist/orchestration/chat-service.d.ts +61 -0
  164. package/dist/orchestration/chat-service.d.ts.map +1 -0
  165. package/dist/orchestration/chat-service.js +156 -0
  166. package/dist/orchestration/chat-service.js.map +1 -0
  167. package/dist/orchestration/cron.d.ts +30 -0
  168. package/dist/orchestration/cron.d.ts.map +1 -0
  169. package/dist/orchestration/cron.js +136 -0
  170. package/dist/orchestration/cron.js.map +1 -0
  171. package/dist/orchestration/index.d.ts +5 -0
  172. package/dist/orchestration/index.d.ts.map +1 -0
  173. package/dist/orchestration/index.js +6 -0
  174. package/dist/orchestration/index.js.map +1 -0
  175. package/dist/orchestration/loop-service.d.ts +129 -0
  176. package/dist/orchestration/loop-service.d.ts.map +1 -0
  177. package/dist/orchestration/loop-service.js +234 -0
  178. package/dist/orchestration/loop-service.js.map +1 -0
  179. package/dist/orchestration/schedule-service.d.ts +65 -0
  180. package/dist/orchestration/schedule-service.d.ts.map +1 -0
  181. package/dist/orchestration/schedule-service.js +201 -0
  182. package/dist/orchestration/schedule-service.js.map +1 -0
  183. package/dist/persistence/atomic-store.d.ts +45 -0
  184. package/dist/persistence/atomic-store.d.ts.map +1 -0
  185. package/dist/persistence/atomic-store.js +92 -0
  186. package/dist/persistence/atomic-store.js.map +1 -0
  187. package/dist/persistence/entity-schemas.d.ts +1707 -0
  188. package/dist/persistence/entity-schemas.d.ts.map +1 -0
  189. package/dist/persistence/entity-schemas.js +250 -0
  190. package/dist/persistence/entity-schemas.js.map +1 -0
  191. package/dist/persistence/entity-stores.d.ts +46 -0
  192. package/dist/persistence/entity-stores.d.ts.map +1 -0
  193. package/dist/persistence/entity-stores.js +167 -0
  194. package/dist/persistence/entity-stores.js.map +1 -0
  195. package/dist/persistence/index.d.ts +4 -0
  196. package/dist/persistence/index.d.ts.map +1 -0
  197. package/dist/persistence/index.js +5 -0
  198. package/dist/persistence/index.js.map +1 -0
  199. package/dist/projects/checkout-diff-manager.d.ts +44 -0
  200. package/dist/projects/checkout-diff-manager.d.ts.map +1 -0
  201. package/dist/projects/checkout-diff-manager.js +82 -0
  202. package/dist/projects/checkout-diff-manager.js.map +1 -0
  203. package/dist/projects/git-checkout-rpc.d.ts +18 -0
  204. package/dist/projects/git-checkout-rpc.d.ts.map +1 -0
  205. package/dist/projects/git-checkout-rpc.js +57 -0
  206. package/dist/projects/git-checkout-rpc.js.map +1 -0
  207. package/dist/projects/git-detect.d.ts +21 -0
  208. package/dist/projects/git-detect.d.ts.map +1 -0
  209. package/dist/projects/git-detect.js +34 -0
  210. package/dist/projects/git-detect.js.map +1 -0
  211. package/dist/projects/git-operations.d.ts +67 -0
  212. package/dist/projects/git-operations.d.ts.map +1 -0
  213. package/dist/projects/git-operations.js +200 -0
  214. package/dist/projects/git-operations.js.map +1 -0
  215. package/dist/projects/github-service.d.ts +80 -0
  216. package/dist/projects/github-service.d.ts.map +1 -0
  217. package/dist/projects/github-service.js +172 -0
  218. package/dist/projects/github-service.js.map +1 -0
  219. package/dist/projects/index.d.ts +13 -0
  220. package/dist/projects/index.d.ts.map +1 -0
  221. package/dist/projects/index.js +19 -0
  222. package/dist/projects/index.js.map +1 -0
  223. package/dist/projects/open-project.d.ts +35 -0
  224. package/dist/projects/open-project.d.ts.map +1 -0
  225. package/dist/projects/open-project.js +106 -0
  226. package/dist/projects/open-project.js.map +1 -0
  227. package/dist/projects/reconciliation.d.ts +15 -0
  228. package/dist/projects/reconciliation.d.ts.map +1 -0
  229. package/dist/projects/reconciliation.js +63 -0
  230. package/dist/projects/reconciliation.js.map +1 -0
  231. package/dist/projects/status-projection.d.ts +33 -0
  232. package/dist/projects/status-projection.d.ts.map +1 -0
  233. package/dist/projects/status-projection.js +98 -0
  234. package/dist/projects/status-projection.js.map +1 -0
  235. package/dist/projects/workspace-activity.d.ts +28 -0
  236. package/dist/projects/workspace-activity.d.ts.map +1 -0
  237. package/dist/projects/workspace-activity.js +74 -0
  238. package/dist/projects/workspace-activity.js.map +1 -0
  239. package/dist/projects/workspace-git-service.d.ts +27 -0
  240. package/dist/projects/workspace-git-service.d.ts.map +1 -0
  241. package/dist/projects/workspace-git-service.js +60 -0
  242. package/dist/projects/workspace-git-service.js.map +1 -0
  243. package/dist/projects/workspace-registry.d.ts +59 -0
  244. package/dist/projects/workspace-registry.d.ts.map +1 -0
  245. package/dist/projects/workspace-registry.js +149 -0
  246. package/dist/projects/workspace-registry.js.map +1 -0
  247. package/dist/projects/worktree-service.d.ts +100 -0
  248. package/dist/projects/worktree-service.d.ts.map +1 -0
  249. package/dist/projects/worktree-service.js +216 -0
  250. package/dist/projects/worktree-service.js.map +1 -0
  251. package/dist/proxy/index.d.ts +4 -0
  252. package/dist/proxy/index.d.ts.map +1 -0
  253. package/dist/proxy/index.js +5 -0
  254. package/dist/proxy/index.js.map +1 -0
  255. package/dist/proxy/service-hostname.d.ts +21 -0
  256. package/dist/proxy/service-hostname.d.ts.map +1 -0
  257. package/dist/proxy/service-hostname.js +44 -0
  258. package/dist/proxy/service-hostname.js.map +1 -0
  259. package/dist/proxy/service-port-registry.d.ts +36 -0
  260. package/dist/proxy/service-port-registry.d.ts.map +1 -0
  261. package/dist/proxy/service-port-registry.js +55 -0
  262. package/dist/proxy/service-port-registry.js.map +1 -0
  263. package/dist/proxy/service-proxy.d.ts +34 -0
  264. package/dist/proxy/service-proxy.d.ts.map +1 -0
  265. package/dist/proxy/service-proxy.js +54 -0
  266. package/dist/proxy/service-proxy.js.map +1 -0
  267. package/dist/terminal/index.d.ts +4 -0
  268. package/dist/terminal/index.d.ts.map +1 -0
  269. package/dist/terminal/index.js +5 -0
  270. package/dist/terminal/index.js.map +1 -0
  271. package/dist/terminal/pty-backend.d.ts +44 -0
  272. package/dist/terminal/pty-backend.d.ts.map +1 -0
  273. package/dist/terminal/pty-backend.js +119 -0
  274. package/dist/terminal/pty-backend.js.map +1 -0
  275. package/dist/terminal/screen-buffer.d.ts +21 -0
  276. package/dist/terminal/screen-buffer.d.ts.map +1 -0
  277. package/dist/terminal/screen-buffer.js +55 -0
  278. package/dist/terminal/screen-buffer.js.map +1 -0
  279. package/dist/terminal/terminal-manager.d.ts +79 -0
  280. package/dist/terminal/terminal-manager.d.ts.map +1 -0
  281. package/dist/terminal/terminal-manager.js +174 -0
  282. package/dist/terminal/terminal-manager.js.map +1 -0
  283. package/dist/terminal/terminal-rpc.d.ts +20 -0
  284. package/dist/terminal/terminal-rpc.d.ts.map +1 -0
  285. package/dist/terminal/terminal-rpc.js +122 -0
  286. package/dist/terminal/terminal-rpc.js.map +1 -0
  287. package/dist/util/concurrency.d.ts +16 -0
  288. package/dist/util/concurrency.d.ts.map +1 -0
  289. package/dist/util/concurrency.js +23 -0
  290. package/dist/util/concurrency.js.map +1 -0
  291. package/dist/util/index.d.ts +2 -0
  292. package/dist/util/index.d.ts.map +1 -0
  293. package/dist/util/index.js +2 -0
  294. package/dist/util/index.js.map +1 -0
  295. package/dist/ws/capability-store.d.ts +11 -0
  296. package/dist/ws/capability-store.d.ts.map +1 -0
  297. package/dist/ws/capability-store.js +10 -0
  298. package/dist/ws/capability-store.js.map +1 -0
  299. package/dist/ws/index.d.ts +5 -0
  300. package/dist/ws/index.d.ts.map +1 -0
  301. package/dist/ws/index.js +6 -0
  302. package/dist/ws/index.js.map +1 -0
  303. package/dist/ws/router.d.ts +34 -0
  304. package/dist/ws/router.d.ts.map +1 -0
  305. package/dist/ws/router.js +97 -0
  306. package/dist/ws/router.js.map +1 -0
  307. package/dist/ws/session.d.ts +28 -0
  308. package/dist/ws/session.d.ts.map +1 -0
  309. package/dist/ws/session.js +36 -0
  310. package/dist/ws/session.js.map +1 -0
  311. package/dist/ws/ws-server.d.ts +41 -0
  312. package/dist/ws/ws-server.d.ts.map +1 -0
  313. package/dist/ws/ws-server.js +104 -0
  314. package/dist/ws/ws-server.js.map +1 -0
  315. package/package.json +48 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Dev bootstrap — wires HTTP + WS server + HandlerRegistry + in-memory agent
3
+ * services for local development. Not for production (in-memory persistence,
4
+ * mock provider only, no auth).
5
+ *
6
+ * See: AGENTS.md "RPC handler registration is explicit" — this is that
7
+ * bootstrap module.
8
+ */
9
+ import { randomUUID } from "node:crypto";
10
+ import { readFileSync, statSync } from "node:fs";
11
+ import { execFile } from "node:child_process";
12
+ import { homedir } from "node:os";
13
+ import { join } from "node:path";
14
+ import { createHttpServer } from "../http/http-server.js";
15
+ import { createWebSocketServer } from "../ws/ws-server.js";
16
+ import { HandlerRegistry, routeTextFrame } from "../ws/router.js";
17
+ import { AgentManager } from "../agent/agent-manager.js";
18
+ import { AgentService } from "../agent/agent-service.js";
19
+ import { SessionOperationsService } from "../agent/session-operations.js";
20
+ import { registerTimelineHandler } from "../agent/timeline-rpc.js";
21
+ import { PermissionService } from "../agent/permissions.js";
22
+ import { createMockClient } from "../agent/providers/mock/mock-provider.js";
23
+ import { ProviderRegistry } from "../agent/provider-registry.js";
24
+ import { FileExplorerService } from "../files/file-explorer.js";
25
+ import { wrapSessionEnvelope } from "./bootstrap.js";
26
+ export function startDevDaemon(opts) {
27
+ const serverId = opts.serverId ?? randomUUID();
28
+ // ── In-memory agent manager (no disk persistence in dev mode) ──────────────
29
+ const agentsById = new Map();
30
+ const manager = new AgentManager({
31
+ home: "/tmp/pi-studio-dev",
32
+ saveAgent: async (record) => {
33
+ agentsById.set(record.id, record);
34
+ },
35
+ loadAllAgents: async () => [...agentsById.values()],
36
+ deleteAgent: async (_cwd, id) => agentsById.delete(id),
37
+ });
38
+ // ── Provider resolution: mock only in dev ───────────────────────────────────
39
+ const mockClient = createMockClient();
40
+ const resolveClient = (_provider) => mockClient;
41
+ // ── Broadcast helper ─────────────────────────────────────────────────────────
42
+ // See `bootstrap.ts`'s `wrapSessionEnvelope` for the full rationale.
43
+ const broadcast = (sessions, message) => {
44
+ const envelope = wrapSessionEnvelope(message);
45
+ for (const s of sessions) {
46
+ try {
47
+ s.send(envelope);
48
+ }
49
+ catch {
50
+ /* ignore send errors on dead sockets */
51
+ }
52
+ }
53
+ };
54
+ // Session set is created by the WS server below; handlers close over this
55
+ // mutable holder so they can be registered before the WS server exists.
56
+ const sessionsHolder = { sessions: [] };
57
+ const getActiveSessions = () => sessionsHolder.sessions;
58
+ // Forward archive/delete lifecycle events to every connected client (see bootstrap.ts's
59
+ // production twin for the full rationale).
60
+ manager.subscribe((event) => {
61
+ if (event.type === "agent_archived" || event.type === "agent_deleted") {
62
+ broadcast(getActiveSessions(), { type: "session", message: event });
63
+ }
64
+ });
65
+ // ── Handler registry ────────────────────────────────────────────────────────
66
+ const registry = new HandlerRegistry();
67
+ const agentService = new AgentService({ manager, resolveClient, broadcast });
68
+ agentService.registerHandlers(registry, getActiveSessions);
69
+ const sessionOps = new SessionOperationsService({
70
+ manager,
71
+ resolveClient,
72
+ service: agentService,
73
+ broadcast,
74
+ });
75
+ sessionOps.registerHandlers(registry, getActiveSessions);
76
+ registerTimelineHandler(registry, { manager, resolveClient });
77
+ const permissionService = new PermissionService({ manager, broadcast });
78
+ permissionService.registerHandlers(registry, getActiveSessions);
79
+ // ── list_agents_request: minimal directory listing (not in scope elsewhere) ─
80
+ registry.register("list_agents_request", (ctx) => {
81
+ const agents = manager.list().map((m) => ({
82
+ agentId: m.record.id,
83
+ status: m.record.lastStatus,
84
+ title: m.record.labels?.["title"] ?? undefined,
85
+ cwd: m.record.cwd,
86
+ labels: m.record.labels ?? {},
87
+ lastActivity: new Date(m.record.updatedAt).getTime(),
88
+ }));
89
+ return {
90
+ type: "list_agents_response",
91
+ requestId: ctx.requestId ?? "",
92
+ agents,
93
+ };
94
+ });
95
+ // ── Archive (soft delete) / delete (hard delete) ────────────────────────────
96
+ registry.register("archive_agent", async (ctx) => {
97
+ const agentId = String(ctx.message.agentId ?? "");
98
+ await manager.archiveAgent(agentId);
99
+ return { type: "archive_agent_response", requestId: ctx.requestId ?? "", agentId, ok: true };
100
+ });
101
+ registry.register("delete_agent", async (ctx) => {
102
+ const agentId = String(ctx.message.agentId ?? "");
103
+ const deleted = await manager.deleteAgent(agentId);
104
+ return {
105
+ type: "delete_agent_response",
106
+ requestId: ctx.requestId ?? "",
107
+ agentId,
108
+ ok: deleted,
109
+ };
110
+ });
111
+ // ── list_workspaces_request: dev-mode 1:1 synthesis ─────────────────────────
112
+ // There is no real workspace registry in this dev bootstrap (that's the full
113
+ // sprint-008 projects/workspaces feature). Until that's wired, synthesize
114
+ // one workspace per known agent (workspaceId === agentId) so the client's
115
+ // workspace-route-gate (features/workspace-ui.md § Route gating) has a
116
+ // `knownWorkspaceIds` entry to resolve against instead of always gating on
117
+ // "missing". TODO(verify): replace with the real WorkspaceRegistry once
118
+ // sprint-008's daemon-side projects/workspaces feature is implemented.
119
+ registry.register("list_workspaces_request", (ctx) => {
120
+ const workspaces = manager.list().map((m) => ({
121
+ workspaceId: m.record.id,
122
+ projectId: "dev-project",
123
+ cwd: m.record.cwd,
124
+ kind: "directory",
125
+ displayName: m.record.labels?.["title"] ?? m.record.cwd,
126
+ agentStatus: m.record.lastStatus === "running" ? "running" : m.record.lastStatus === "error" ? "error" : "idle",
127
+ createdAt: new Date(m.record.createdAt).getTime(),
128
+ updatedAt: new Date(m.record.updatedAt).getTime(),
129
+ }));
130
+ return {
131
+ type: "list_workspaces_response",
132
+ requestId: ctx.requestId ?? "",
133
+ workspaces,
134
+ };
135
+ });
136
+ registry.register("list_projects_request", (ctx) => ({
137
+ type: "list_projects_response",
138
+ requestId: ctx.requestId ?? "",
139
+ projects: [],
140
+ }));
141
+ // ── list_providers: expose the provider registry manifest (metadata only) ───
142
+ // The client's new-agent provider/profile picker (sprint-030 task-002) reads
143
+ // this to populate its provider + mode dropdowns. Metadata only — no client is
144
+ // constructed or launched here. features/agent-providers.md § Registration surface.
145
+ const providerRegistry = new ProviderRegistry();
146
+ registry.register("list_providers", (ctx) => ({
147
+ type: "list_providers_response",
148
+ requestId: ctx.requestId ?? "",
149
+ providers: providerRegistry.listMetadata(),
150
+ }));
151
+ // ── File explorer: real directory listing + file preview from disk ───────
152
+ // (features/file-explorer-transfer.md). Lets the workspace Explorer + file
153
+ // preview panes show actual files.
154
+ new FileExplorerService().registerHandlers(registry);
155
+ // Simple file diff RPC for the POC UI. Untracked (brand-new) files have no git-tracked "before"
156
+ // state, so a plain `git diff` against them is always empty — git only diffs a path once it's
157
+ // in the index or committed. Fall back to `git diff --no-index /dev/null <path>` (exit code 1
158
+ // is expected/non-fatal there) so new files render as a full "all lines added" diff instead of
159
+ // a blank tab.
160
+ registry.register("file_diff_request", async (ctx) => {
161
+ const filePath = String(ctx.message.path ?? "");
162
+ const cwd = String(ctx.message.cwd ?? "");
163
+ const staged = Boolean(ctx.message.staged);
164
+ const resolvedCwd = cwd.startsWith("~") ? join(homedir(), cwd.slice(1)) : (cwd || undefined);
165
+ const runGitDiff = (args) => new Promise((resolve) => {
166
+ execFile("git", args, { cwd: resolvedCwd, maxBuffer: 1024 * 1024 }, (_err, stdout) => {
167
+ resolve(stdout || "");
168
+ });
169
+ });
170
+ const args = ["diff"];
171
+ if (staged)
172
+ args.push("--staged");
173
+ args.push("--", filePath);
174
+ let patch = await runGitDiff(args);
175
+ if (!patch && !staged) {
176
+ patch = await runGitDiff(["diff", "--no-index", "--", "/dev/null", filePath]);
177
+ }
178
+ return { type: "file_diff_response", ok: true, path: filePath, patch };
179
+ });
180
+ // Simple text file read RPC for the POC UI.
181
+ registry.register("file_read_request", (ctx) => {
182
+ const filePath = String(ctx.message.path ?? "");
183
+ const resolved = filePath.startsWith("~") ? join(homedir(), filePath.slice(1)) : filePath;
184
+ try {
185
+ const stat = statSync(resolved);
186
+ if (stat.isDirectory())
187
+ return { type: "file_read_response", ok: false, error: "is_directory" };
188
+ if (stat.size > 512 * 1024)
189
+ return { type: "file_read_response", ok: false, error: "file_too_large", size: stat.size };
190
+ const content = readFileSync(resolved, "utf8");
191
+ return { type: "file_read_response", ok: true, path: resolved, content, size: stat.size };
192
+ }
193
+ catch (e) {
194
+ return { type: "file_read_response", ok: false, error: e.message ?? "read_failed" };
195
+ }
196
+ });
197
+ registry.register("schedule_list_request", (ctx) => ({
198
+ type: "schedule_list_response",
199
+ requestId: ctx.requestId ?? "",
200
+ schedules: [],
201
+ }));
202
+ // ── HTTP + WS wiring ─────────────────────────────────────────────────────────
203
+ const hostnames = opts.hostnames ?? true;
204
+ const httpServer = createHttpServer({ hostnames });
205
+ const wsHandle = createWebSocketServer(httpServer, {
206
+ serverId,
207
+ hostname: opts.host,
208
+ version: "0.1.0-dev",
209
+ onSession: (session) => {
210
+ console.log(`[ws] client connected: ${session.clientId} (${session.clientType})`);
211
+ },
212
+ onMessage: (session, frame) => {
213
+ if ("text" in frame) {
214
+ void routeTextFrame(session, frame.text, registry);
215
+ }
216
+ // Binary (terminal) frames not wired in dev bootstrap yet.
217
+ },
218
+ });
219
+ // Now that the WS server exists, point the holder at its live session set.
220
+ sessionsHolder.sessions = wsHandle.sessions;
221
+ httpServer.listen(opts.port, opts.host);
222
+ return {
223
+ httpServer,
224
+ serverId,
225
+ close: async () => {
226
+ await wsHandle.close();
227
+ await new Promise((resolve) => httpServer.close(() => resolve()));
228
+ },
229
+ };
230
+ }
231
+ //# sourceMappingURL=dev-bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-bootstrap.js","sourceRoot":"","sources":["../../src/daemon/dev-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAerD,MAAM,UAAU,cAAc,CAAC,IAAyB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,EAAE,CAAC;IAE/C,8EAA8E;IAC9E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAuB,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAC/B,IAAI,EAAE,oBAAoB;QAC1B,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC1B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACnD,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;KACvD,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;IACtC,MAAM,aAAa,GAAG,CAAC,SAAiB,EAAe,EAAE,CAAC,UAAU,CAAC;IAErE,gFAAgF;IAChF,qEAAqE;IACrE,MAAM,SAAS,GAAG,CAAC,QAA2B,EAAE,OAAgB,EAAE,EAAE;QAClE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,wCAAwC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,cAAc,GAAoC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzE,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC;IAExD,wFAAwF;IACxF,2CAA2C;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACtE,SAAS,CAAC,iBAAiB,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IAEvC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG,IAAI,wBAAwB,CAAC;QAC9C,OAAO;QACP,aAAa;QACb,OAAO,EAAE,YAAY;QACrB,SAAS;KACV,CAAC,CAAC;IACH,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAEzD,uBAAuB,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAE9D,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACxE,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAEhE,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU;YAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS;YAC9C,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG;YACjB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE;YAC7B,YAAY,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;SACrD,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,MAAM;SACP,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC/F,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO;YACL,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,OAAO;YACP,EAAE,EAAE,OAAO;SACZ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,2EAA2E;IAC3E,wEAAwE;IACxE,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC,GAAG,EAAE,EAAE;QACnD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;YACxB,SAAS,EAAE,aAAa;YACxB,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG;YACjB,IAAI,EAAE,WAAoB;YAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG;YACvD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YAC/G,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;YACjD,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;SAClD,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,IAAI,EAAE,0BAA0B;YAChC,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,UAAU;SACX,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,EAAE,wBAAwB;QAC9B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QAC9B,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC,CAAC;IAEJ,+EAA+E;IAC/E,6EAA6E;IAC7E,+EAA+E;IAC/E,oFAAoF;IACpF,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,EAAE,yBAAyB;QAC/B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QAC9B,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;KAC3C,CAAC,CAAC,CAAC;IAEJ,4EAA4E;IAC5E,2EAA2E;IAC3E,mCAAmC;IACnC,IAAI,mBAAmB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAErD,gGAAgG;IAChG,8FAA8F;IAC9F,8FAA8F;IAC9F,+FAA+F;IAC/F,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC;QAC7F,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,EAAE,CACpC,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAC9B,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;gBACnF,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YACxB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACL,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1B,IAAI,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,GAAG,MAAM,UAAU,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;QAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC1F,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,WAAW,EAAE;gBAAE,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;YAChG,IAAI,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI;gBAAE,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YACvH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5F,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,EAAE,wBAAwB;QAC9B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QAC9B,SAAS,EAAE,EAAE;KACd,CAAC,CAAC,CAAC;IAEJ,gFAAgF;IAChF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;IACzC,MAAM,UAAU,GAAG,gBAAgB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,UAAU,EAAE;QACjD,QAAQ;QACR,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,OAAO,CAAC,GAAG,CAAC,0BAA0B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QACpF,CAAC;QACD,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YAC5B,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;gBACpB,KAAK,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;YACD,2DAA2D;QAC7D,CAAC;KACF,CAAC,CAAC;IAEH,2EAA2E;IAC3E,cAAc,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAE5C,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAExC,OAAO;QACL,UAAU;QACV,QAAQ;QACR,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=dev-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-main.d.ts","sourceRoot":"","sources":["../../src/daemon/dev-main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Dev daemon entry point — starts the full dev bootstrap (HTTP + WS + agent
4
+ * services) for local development against the real app UI.
5
+ */
6
+ import { createDaemonRuntimeInfo } from "./index.js";
7
+ import { startDevDaemon } from "./dev-bootstrap.js";
8
+ const info = createDaemonRuntimeInfo({
9
+ mode: "development",
10
+ listen: process.env.PI_STUDIO_LISTEN ?? "0.0.0.0:6767",
11
+ });
12
+ const hostnamesEnv = process.env.PI_STUDIO_HOSTNAMES;
13
+ const hostnames = hostnamesEnv
14
+ ? hostnamesEnv.split(",").map((h) => h.trim())
15
+ : true; // allow all in dev mode
16
+ const handle = startDevDaemon({
17
+ host: info.listen.host,
18
+ port: info.listen.port,
19
+ serverId: process.env.PI_STUDIO_SERVER_ID,
20
+ hostnames,
21
+ });
22
+ console.log(`pi-studio dev daemon listening on http://${info.listen.host}:${info.listen.port}`);
23
+ console.log(` serverId: ${handle.serverId}`);
24
+ console.log(` provider: mock (dev only)`);
25
+ console.log(` ws: ready`);
26
+ console.log(` Press Ctrl+C to stop`);
27
+ process.on("SIGINT", async () => {
28
+ console.log("\nShutting down...");
29
+ await handle.close();
30
+ process.exit(0);
31
+ });
32
+ process.on("SIGTERM", async () => {
33
+ await handle.close();
34
+ process.exit(0);
35
+ });
36
+ //# sourceMappingURL=dev-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-main.js","sourceRoot":"","sources":["../../src/daemon/dev-main.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,IAAI,GAAG,uBAAuB,CAAC;IACnC,IAAI,EAAE,aAAa;IACnB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;CACvD,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AACrD,MAAM,SAAS,GAAoB,YAAY;IAC7C,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,CAAC,CAAC,IAAI,CAAC,CAAC,wBAAwB;AAElC,MAAM,MAAM,GAAG,cAAc,CAAC;IAC5B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;IACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;IACtB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;IACzC,SAAS;CACV,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAChG,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAC3C,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC3B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAEtC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const DEFAULT_DAEMON_LISTEN: "127.0.0.1:6767";
2
+ export type DaemonListenAddress = {
3
+ host: string;
4
+ port: number;
5
+ };
6
+ export declare function parseDaemonListen(value?: string): DaemonListenAddress;
7
+ export type DaemonRuntimeInfo = {
8
+ listen: DaemonListenAddress;
9
+ mode: "production" | "development";
10
+ };
11
+ export declare function createDaemonRuntimeInfo(input?: {
12
+ listen?: string;
13
+ mode?: "production" | "development";
14
+ }): DaemonRuntimeInfo;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,EAAG,gBAAyB,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,MAA8B,GAAG,mBAAmB,CAS5F;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC;CACpC,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,KAAK,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,GAAG,aAAa,CAAA;CAAO,GAAG,iBAAiB,CAK/H"}
@@ -0,0 +1,21 @@
1
+ // Daemon bootstrap public surface.
2
+ // Minimal clean-room scaffold used by the package root export and bin entrypoints.
3
+ export const DEFAULT_DAEMON_LISTEN = "127.0.0.1:6767";
4
+ export function parseDaemonListen(value = DEFAULT_DAEMON_LISTEN) {
5
+ const idx = value.lastIndexOf(":");
6
+ if (idx <= 0)
7
+ throw new Error(`Invalid listen address: ${value}`);
8
+ const host = value.slice(0, idx);
9
+ const port = Number(value.slice(idx + 1));
10
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
11
+ throw new Error(`Invalid listen port: ${value}`);
12
+ }
13
+ return { host, port };
14
+ }
15
+ export function createDaemonRuntimeInfo(input = {}) {
16
+ return {
17
+ listen: parseDaemonListen(input.listen ?? process.env.PI_STUDIO_LISTEN ?? DEFAULT_DAEMON_LISTEN),
18
+ mode: input.mode ?? "production",
19
+ };
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,mFAAmF;AAEnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAyB,CAAC;AAO/D,MAAM,UAAU,iBAAiB,CAAC,QAAgB,qBAAqB;IACrE,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC;AAOD,MAAM,UAAU,uBAAuB,CAAC,QAAkE,EAAE;IAC1G,OAAO;QACL,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,qBAAqB,CAAC;QAChG,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,YAAY;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/daemon/main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Production daemon entry point — starts the REAL daemon (real Pi provider, disk persistence, full
4
+ * RPC surface). Binds `PI_STUDIO_LISTEN` (default `0.0.0.0:6767`).
5
+ */
6
+ import { createDaemonRuntimeInfo } from "./index.js";
7
+ import { startDaemon } from "./bootstrap.js";
8
+ const info = createDaemonRuntimeInfo({
9
+ mode: "production",
10
+ listen: process.env.PI_STUDIO_LISTEN ?? "0.0.0.0:6767",
11
+ });
12
+ const handle = startDaemon({
13
+ host: info.listen.host,
14
+ port: info.listen.port,
15
+ });
16
+ console.log(`pi-studio daemon listening on http://${info.listen.host}:${info.listen.port}`);
17
+ console.log(` serverId: ${handle.serverId}`);
18
+ console.log(` home: ${handle.home}`);
19
+ console.log(` provider: ${handle.provider}`);
20
+ console.log(` ws: ready`);
21
+ console.log(` Press Ctrl+C to stop`);
22
+ async function shutdown() {
23
+ console.log("\nShutting down...");
24
+ await handle.close();
25
+ process.exit(0);
26
+ }
27
+ process.on("SIGINT", () => void shutdown());
28
+ process.on("SIGTERM", () => void shutdown());
29
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/daemon/main.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,IAAI,GAAG,uBAAuB,CAAC;IACnC,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;CACvD,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,WAAW,CAAC;IACzB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;IACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;CACvB,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5F,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9C,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC3B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAEtC,KAAK,UAAU,QAAQ;IACrB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Orchestration RPC surface — schedules/heartbeats, chat rooms, and loops, backed by the real disk
3
+ * stores (features/schedules-heartbeats.md, chat-rooms.md, loops.md). These domain services expose
4
+ * method surfaces but no RPC layer; this module wires them for the production daemon.
5
+ *
6
+ * Both the app naming (`create_schedule_request`, `schedule_list_request`, …) and the CLI naming
7
+ * (`schedule_create_request`, `schedule_inspect_request`, …) are accepted where they diverge.
8
+ */
9
+ import type { HandlerRegistry } from "../ws/router.js";
10
+ import type { ScheduleService } from "../orchestration/schedule-service.js";
11
+ import type { ChatService } from "../orchestration/chat-service.js";
12
+ import type { LoopService } from "../orchestration/loop-service.js";
13
+ export interface OrchestrationRpcDeps {
14
+ scheduleService: ScheduleService;
15
+ chatService: ChatService;
16
+ loopService: LoopService;
17
+ }
18
+ export declare function registerOrchestrationHandlers(registry: HandlerRegistry, deps: OrchestrationRpcDeps): void;
19
+ //# sourceMappingURL=orchestration-rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-rpc.d.ts","sourceRoot":"","sources":["../../src/daemon/orchestration-rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,sCAAsC,CAAC;AACjG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,kCAAkC,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAmJN"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Orchestration RPC surface — schedules/heartbeats, chat rooms, and loops, backed by the real disk
3
+ * stores (features/schedules-heartbeats.md, chat-rooms.md, loops.md). These domain services expose
4
+ * method surfaces but no RPC layer; this module wires them for the production daemon.
5
+ *
6
+ * Both the app naming (`create_schedule_request`, `schedule_list_request`, …) and the CLI naming
7
+ * (`schedule_create_request`, `schedule_inspect_request`, …) are accepted where they diverge.
8
+ */
9
+ export function registerOrchestrationHandlers(registry, deps) {
10
+ const { scheduleService, chatService, loopService } = deps;
11
+ const str = (v) => (typeof v === "string" ? v : "");
12
+ // ── Schedules ──────────────────────────────────────────────────────────────
13
+ registry.register("schedule_list_request", async (ctx) => ({
14
+ type: "schedule_list_response",
15
+ requestId: ctx.requestId ?? "",
16
+ schedules: await scheduleService.list(),
17
+ }));
18
+ const createSchedule = async (ctx) => {
19
+ const m = ctx.message;
20
+ const input = {
21
+ name: m.name ?? m.title,
22
+ prompt: str(m.prompt),
23
+ cadence: m.cadence,
24
+ target: m.target,
25
+ expiresAt: m.expiresAt,
26
+ maxRuns: m.maxRuns,
27
+ };
28
+ return scheduleService.create(input);
29
+ };
30
+ registry.register("create_schedule_request", async (ctx) => ({
31
+ type: "create_schedule_response",
32
+ schedule: await createSchedule(ctx),
33
+ }));
34
+ registry.registerAlias("schedule_create_request", "create_schedule_request");
35
+ registry.register("update_schedule_request", async (ctx) => {
36
+ const id = str(ctx.message.scheduleId ?? ctx.message.id);
37
+ const patch = ctx.message.patch ?? {
38
+ ...(ctx.message.prompt !== undefined && { prompt: str(ctx.message.prompt) }),
39
+ ...(ctx.message.cadence !== undefined && { cadence: ctx.message.cadence }),
40
+ ...(ctx.message.name !== undefined && { name: str(ctx.message.name) }),
41
+ };
42
+ return { type: "update_schedule_response", schedule: await scheduleService.update(id, patch) };
43
+ });
44
+ registry.registerAlias("schedule_update_request", "update_schedule_request");
45
+ registry.register("delete_schedule_request", async (ctx) => ({
46
+ type: "delete_schedule_response",
47
+ scheduleId: str(ctx.message.scheduleId ?? ctx.message.id),
48
+ ok: await scheduleService.delete(str(ctx.message.scheduleId ?? ctx.message.id)),
49
+ }));
50
+ registry.registerAlias("schedule_delete_request", "delete_schedule_request");
51
+ registry.register("pause_schedule_request", async (ctx) => ({
52
+ type: "pause_schedule_response",
53
+ schedule: await scheduleService.pause(str(ctx.message.scheduleId ?? ctx.message.id)),
54
+ }));
55
+ registry.registerAlias("schedule_pause_request", "pause_schedule_request");
56
+ registry.register("resume_schedule_request", async (ctx) => ({
57
+ type: "resume_schedule_response",
58
+ schedule: await scheduleService.resume(str(ctx.message.scheduleId ?? ctx.message.id)),
59
+ }));
60
+ registry.registerAlias("schedule_resume_request", "resume_schedule_request");
61
+ registry.register("schedule_run_once_request", async (ctx) => ({
62
+ type: "schedule_run_once_response",
63
+ run: await scheduleService.runOnce(str(ctx.message.scheduleId ?? ctx.message.id)),
64
+ }));
65
+ registry.register("schedule_logs_request", async (ctx) => ({
66
+ type: "schedule_logs_response",
67
+ runs: await scheduleService.logs(str(ctx.message.scheduleId ?? ctx.message.id)),
68
+ }));
69
+ registry.register("schedule_inspect_request", async (ctx) => ({
70
+ type: "schedule_inspect_response",
71
+ schedule: await scheduleService.inspect(str(ctx.message.scheduleId ?? ctx.message.id)),
72
+ }));
73
+ // ── Chat rooms ───────────────────────────────────────────────────────────────
74
+ registry.register("chat_create_request", async (ctx) => ({
75
+ type: "chat_create_response",
76
+ room: await chatService.createRoom({
77
+ name: str(ctx.message.name),
78
+ purpose: ctx.message.purpose,
79
+ }),
80
+ }));
81
+ registry.register("chat_list_request", async () => ({
82
+ type: "chat_list_response",
83
+ rooms: await chatService.listRooms(),
84
+ }));
85
+ registry.register("chat_inspect_request", async (ctx) => {
86
+ const result = await chatService.inspectRoom(str(ctx.message.roomId));
87
+ return { type: "chat_inspect_response", room: result?.room ?? null, messages: result?.messages ?? [] };
88
+ });
89
+ registry.register("chat_delete_request", async (ctx) => ({
90
+ type: "chat_delete_response",
91
+ roomId: str(ctx.message.roomId),
92
+ ok: await chatService.deleteRoom(str(ctx.message.roomId)),
93
+ }));
94
+ registry.register("chat_post_request", async (ctx) => ({
95
+ type: "chat_post_response",
96
+ message: await chatService.postMessage({
97
+ roomId: str(ctx.message.roomId),
98
+ authorAgentId: str(ctx.message.authorAgentId ?? ctx.message.author ?? "user"),
99
+ body: str(ctx.message.body ?? ctx.message.text),
100
+ replyToMessageId: ctx.message.replyToMessageId,
101
+ }),
102
+ }));
103
+ registry.register("chat_read_request", async (ctx) => {
104
+ const result = await chatService.readMessages(str(ctx.message.roomId), ctx.message.cursor ?? ctx.message.sinceCursor ?? 0);
105
+ return { type: "chat_read_response", messages: result.messages, cursor: result.cursor };
106
+ });
107
+ registry.register("chat_wait_request", async (ctx) => {
108
+ const result = await chatService.waitForMessages(str(ctx.message.roomId), ctx.message.sinceCursor ?? ctx.message.cursor ?? 0, ctx.message.timeoutMs);
109
+ return { type: "chat_wait_response", messages: result.messages, cursor: result.cursor };
110
+ });
111
+ // ── Loops ────────────────────────────────────────────────────────────────────
112
+ registry.register("loop_list_request", async () => ({
113
+ type: "loop_list_response",
114
+ loops: await loopService.list(),
115
+ }));
116
+ registry.register("loop_inspect_request", async (ctx) => ({
117
+ type: "loop_inspect_response",
118
+ loop: await loopService.inspect(str(ctx.message.loopId ?? ctx.message.id)),
119
+ }));
120
+ registry.register("loop_logs_request", async (ctx) => ({
121
+ type: "loop_logs_response",
122
+ logs: await loopService.logs(str(ctx.message.loopId ?? ctx.message.id), ctx.message.sinceSeq ?? 0),
123
+ }));
124
+ registry.register("loop_stop_request", async (ctx) => {
125
+ await loopService.stop(str(ctx.message.loopId ?? ctx.message.id));
126
+ return { type: "loop_stop_response", loopId: str(ctx.message.loopId ?? ctx.message.id), ok: true };
127
+ });
128
+ registry.register("loop_run_request", (ctx) => {
129
+ // Loops are long-running; start it in the background and ack immediately so
130
+ // the RPC does not block for the loop's lifetime.
131
+ const input = ctx.message;
132
+ void loopService.run(input).catch(() => { });
133
+ return { type: "loop_run_response", ok: true, started: true };
134
+ });
135
+ }
136
+ //# sourceMappingURL=orchestration-rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-rpc.js","sourceRoot":"","sources":["../../src/daemon/orchestration-rpc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare class DownloadTokenStore {
2
+ private readonly ttlMs;
3
+ private readonly now;
4
+ private readonly tokens;
5
+ constructor(ttlMs?: number, now?: () => number, maxTokens?: number);
6
+ /** Issue a single-use token for `path`. */
7
+ issue(path: string): {
8
+ token: string;
9
+ expiresAt: number;
10
+ };
11
+ /** Validate + consume a token. Returns the path, or null if invalid/expired/already used. */
12
+ consume(token: string): string | null;
13
+ }
14
+ //# sourceMappingURL=download-token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-token-store.d.ts","sourceRoot":"","sources":["../../src/files/download-token-store.ts"],"names":[],"mappings":"AAqBA,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;gBAGnC,KAAK,SAAS,EACd,GAAG,GAAE,MAAM,MAAyB,EACrD,SAAS,SAAS;IAKpB,2CAA2C;IAC3C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAOzD,6FAA6F;IAC7F,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAWtC"}
@@ -0,0 +1,33 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { LRUCache } from "lru-cache";
3
+ export class DownloadTokenStore {
4
+ ttlMs;
5
+ now;
6
+ tokens;
7
+ constructor(ttlMs = 60_000, now = () => Date.now(), maxTokens = 10_000) {
8
+ this.ttlMs = ttlMs;
9
+ this.now = now;
10
+ this.tokens = new LRUCache({ max: maxTokens });
11
+ }
12
+ /** Issue a single-use token for `path`. */
13
+ issue(path) {
14
+ const token = randomUUID();
15
+ const expiresAt = this.now() + this.ttlMs;
16
+ this.tokens.set(token, { path, expiresAt, used: false });
17
+ return { token, expiresAt };
18
+ }
19
+ /** Validate + consume a token. Returns the path, or null if invalid/expired/already used. */
20
+ consume(token) {
21
+ const entry = this.tokens.get(token);
22
+ if (!entry)
23
+ return null;
24
+ if (entry.used || entry.expiresAt < this.now()) {
25
+ this.tokens.delete(token);
26
+ return null;
27
+ }
28
+ entry.used = true;
29
+ this.tokens.delete(token); // single-use
30
+ return entry.path;
31
+ }
32
+ }
33
+ //# sourceMappingURL=download-token-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-token-store.js","sourceRoot":"","sources":["../../src/files/download-token-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAmBrC,MAAM,OAAO,kBAAkB;IAIV;IACA;IAJF,MAAM,CAA+B;IAEtD,YACmB,QAAQ,MAAM,EACd,MAAoB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EACrD,SAAS,GAAG,MAAM;QAFD,UAAK,GAAL,KAAK,CAAS;QACd,QAAG,GAAH,GAAG,CAAiC;QAGrD,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,IAAY;QAChB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC9B,CAAC;IAED,6FAA6F;IAC7F,OAAO,CAAC,KAAa;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;CACF"}