@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,16 @@
1
+ import pLimit from "p-limit";
2
+ /**
3
+ * Bounded-concurrency helpers (adopted `p-limit`). Use these wherever the daemon fans out concurrent
4
+ * I/O — multi-workspace git status, provider-snapshot batch refresh, bulk archive cascade — so a
5
+ * large workspace set can't open hundreds of simultaneous git/fs operations.
6
+ */
7
+ /** Default fan-out cap for filesystem / subprocess heavy work. */
8
+ export declare const DEFAULT_CONCURRENCY = 8;
9
+ /**
10
+ * Map `items` through `fn` with at most `limit` running at once, preserving input order in the
11
+ * result. Rejections propagate (like `Promise.all`).
12
+ */
13
+ export declare function mapWithConcurrency<T, R>(items: readonly T[], fn: (item: T, index: number) => Promise<R>, limit?: number): Promise<R[]>;
14
+ /** A reusable limiter for ad-hoc scheduling. */
15
+ export declare function createLimiter(limit?: number): ReturnType<typeof pLimit>;
16
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/util/concurrency.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B;;;;GAIG;AAEH,kEAAkE;AAClE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAC3C,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,KAAK,GAAE,MAA4B,GAClC,OAAO,CAAC,CAAC,EAAE,CAAC,CAId;AAED,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,KAAK,GAAE,MAA4B,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAE5F"}
@@ -0,0 +1,23 @@
1
+ import pLimit from "p-limit";
2
+ /**
3
+ * Bounded-concurrency helpers (adopted `p-limit`). Use these wherever the daemon fans out concurrent
4
+ * I/O — multi-workspace git status, provider-snapshot batch refresh, bulk archive cascade — so a
5
+ * large workspace set can't open hundreds of simultaneous git/fs operations.
6
+ */
7
+ /** Default fan-out cap for filesystem / subprocess heavy work. */
8
+ export const DEFAULT_CONCURRENCY = 8;
9
+ /**
10
+ * Map `items` through `fn` with at most `limit` running at once, preserving input order in the
11
+ * result. Rejections propagate (like `Promise.all`).
12
+ */
13
+ export async function mapWithConcurrency(items, fn, limit = DEFAULT_CONCURRENCY) {
14
+ if (items.length === 0)
15
+ return [];
16
+ const run = pLimit(Math.max(1, limit));
17
+ return Promise.all(items.map((item, index) => run(() => fn(item, index))));
18
+ }
19
+ /** A reusable limiter for ad-hoc scheduling. */
20
+ export function createLimiter(limit = DEFAULT_CONCURRENCY) {
21
+ return pLimit(Math.max(1, limit));
22
+ }
23
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/util/concurrency.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B;;;;GAIG;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAmB,EACnB,EAA0C,EAC1C,QAAgB,mBAAmB;IAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,aAAa,CAAC,QAAgB,mBAAmB;IAC/D,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createLimiter, DEFAULT_CONCURRENCY, mapWithConcurrency } from "./concurrency.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createLimiter, DEFAULT_CONCURRENCY, mapWithConcurrency } from "./concurrency.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Stores client capabilities keyed by `clientId` so they can be rehydrated when the same client
3
+ * reconnects (architecture/websocket-protocol.md § Behavior). Default implementation is in-memory
4
+ * for the daemon process lifetime; a persistent implementation can be swapped in later.
5
+ */
6
+ export interface CapabilityStore {
7
+ get(clientId: string): Record<string, boolean> | undefined;
8
+ set(clientId: string, capabilities: Record<string, boolean>): void;
9
+ }
10
+ export declare function createInMemoryCapabilityStore(): CapabilityStore;
11
+ //# sourceMappingURL=capability-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-store.d.ts","sourceRoot":"","sources":["../../src/ws/capability-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3D,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACpE;AAED,wBAAgB,6BAA6B,IAAI,eAAe,CAQ/D"}
@@ -0,0 +1,10 @@
1
+ export function createInMemoryCapabilityStore() {
2
+ const map = new Map();
3
+ return {
4
+ get: (clientId) => map.get(clientId),
5
+ set: (clientId, capabilities) => {
6
+ map.set(clientId, capabilities);
7
+ },
8
+ };
9
+ }
10
+ //# sourceMappingURL=capability-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-store.js","sourceRoot":"","sources":["../../src/ws/capability-store.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,6BAA6B;IAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmC,CAAC;IACvD,OAAO;QACL,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;QACpC,GAAG,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE;YAC9B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./session.js";
2
+ export * from "./capability-store.js";
3
+ export * from "./ws-server.js";
4
+ export * from "./router.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ws/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ // WebSocket server: handshake, sessions, capability rehydrate, frame routing.
2
+ export * from "./session.js";
3
+ export * from "./capability-store.js";
4
+ export * from "./ws-server.js";
5
+ export * from "./router.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ws/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Session } from "./session.js";
2
+ /**
3
+ * Frame router + handler registry (architecture/websocket-protocol.md § Behavior, § Error Handling,
4
+ * § RPC naming).
5
+ *
6
+ * Text frames are parsed as top-level envelopes: `ping` is answered with `pong` (liveness over the
7
+ * data path — an RPC timeout is an operation failure and must NOT close the socket); `session`
8
+ * envelopes are dispatched to a registered handler by message `type`. A handler that throws yields
9
+ * an `rpc_error` correlated by `requestId`. Unknown types with a `requestId` get an `rpc_error`;
10
+ * otherwise they are ignored.
11
+ */
12
+ export interface RpcHandlerContext {
13
+ session: Session;
14
+ message: Record<string, unknown>;
15
+ requestId?: string;
16
+ }
17
+ /** A handler returns a response message (wrapped + correlated by the router) or `undefined`. */
18
+ export type RpcHandler = (ctx: RpcHandlerContext) => unknown | Promise<unknown>;
19
+ export type BinaryHandler = (session: Session, bytes: Uint8Array) => void;
20
+ /** Registry of RPC handlers keyed by message type, with legacy flat-name aliases. */
21
+ export declare class HandlerRegistry {
22
+ private readonly handlers;
23
+ private readonly aliases;
24
+ /** Register a handler for a canonical (dotted) message type. */
25
+ register(type: string, handler: RpcHandler): this;
26
+ /** Map a legacy flat name to a canonical type so both names resolve to the same handler. */
27
+ registerAlias(alias: string, canonical: string): this;
28
+ get(type: string): RpcHandler | undefined;
29
+ }
30
+ /** Route a text frame received after the handshake. */
31
+ export declare function routeTextFrame(session: Session, text: string, registry: HandlerRegistry): Promise<void>;
32
+ /** Route a binary frame (terminal/file streams). Decoding handlers are registered by later sprints. */
33
+ export declare function routeBinaryFrame(session: Session, bytes: Uint8Array, binaryHandler?: BinaryHandler): void;
34
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/ws/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;;;GASG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gGAAgG;AAChG,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAE1E,qFAAqF;AACrF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAKjD,4FAA4F;IAC5F,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKrD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;CAG1C;AA2CD,uDAAuD;AACvD,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED,uGAAuG;AACvG,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,EACjB,aAAa,CAAC,EAAE,aAAa,GAC5B,IAAI,CAEN"}
@@ -0,0 +1,97 @@
1
+ import { pongSchema } from "@av-pi-studio/protocol";
2
+ /** Registry of RPC handlers keyed by message type, with legacy flat-name aliases. */
3
+ export class HandlerRegistry {
4
+ handlers = new Map();
5
+ aliases = new Map();
6
+ /** Register a handler for a canonical (dotted) message type. */
7
+ register(type, handler) {
8
+ this.handlers.set(type, handler);
9
+ return this;
10
+ }
11
+ /** Map a legacy flat name to a canonical type so both names resolve to the same handler. */
12
+ registerAlias(alias, canonical) {
13
+ this.aliases.set(alias, canonical);
14
+ return this;
15
+ }
16
+ get(type) {
17
+ return this.handlers.get(type) ?? this.handlers.get(this.aliases.get(type) ?? "");
18
+ }
19
+ }
20
+ function sendRpcError(session, requestId, code, message) {
21
+ session.send({ type: "session", message: { type: "rpc_error", requestId, code, message } });
22
+ }
23
+ async function dispatchSessionMessage(session, message, registry) {
24
+ const type = typeof message.type === "string" ? message.type : undefined;
25
+ const requestId = typeof message.requestId === "string" ? message.requestId : undefined;
26
+ if (!type)
27
+ return;
28
+ const handler = registry.get(type);
29
+ if (!handler) {
30
+ // Unknown type → rpc_error if it expected a reply, otherwise ignore (handler policy).
31
+ if (requestId)
32
+ sendRpcError(session, requestId, "unknown_message_type", `no handler for ${type}`);
33
+ return;
34
+ }
35
+ try {
36
+ const result = await handler({ session, message, requestId });
37
+ if (result !== undefined) {
38
+ const response = requestId &&
39
+ typeof result === "object" &&
40
+ result !== null &&
41
+ result.requestId === undefined
42
+ ? { ...result, requestId }
43
+ : result;
44
+ session.send({ type: "session", message: response });
45
+ }
46
+ }
47
+ catch (error) {
48
+ // A handler failure (including a timeout) is an operation error, never a dead socket.
49
+ if (requestId) {
50
+ sendRpcError(session, requestId, "handler_error", error?.message ?? String(error));
51
+ }
52
+ }
53
+ }
54
+ /** Route a text frame received after the handshake. */
55
+ export async function routeTextFrame(session, text, registry) {
56
+ let envelope;
57
+ try {
58
+ envelope = JSON.parse(text);
59
+ }
60
+ catch {
61
+ return; // ignore non-JSON
62
+ }
63
+ if (!envelope || typeof envelope !== "object")
64
+ return;
65
+ const env = envelope;
66
+ switch (env.type) {
67
+ case "ping": {
68
+ const now = Date.now();
69
+ const pong = pongSchema.safeParse({
70
+ type: "pong",
71
+ requestId: env.requestId,
72
+ clientSentAt: env.clientSentAt,
73
+ serverReceivedAt: now,
74
+ serverSentAt: Date.now(),
75
+ });
76
+ if (pong.success)
77
+ session.send(pong.data);
78
+ return;
79
+ }
80
+ case "pong":
81
+ return; // liveness ack from client — nothing to do
82
+ case "session": {
83
+ const message = env.message;
84
+ if (message && typeof message === "object") {
85
+ await dispatchSessionMessage(session, message, registry);
86
+ }
87
+ return;
88
+ }
89
+ default:
90
+ return; // unknown top-level type → ignore
91
+ }
92
+ }
93
+ /** Route a binary frame (terminal/file streams). Decoding handlers are registered by later sprints. */
94
+ export function routeBinaryFrame(session, bytes, binaryHandler) {
95
+ binaryHandler?.(session, bytes);
96
+ }
97
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/ws/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { WebSocket } from "ws";
2
+ /**
3
+ * A per-connection session (architecture/websocket-protocol.md § Behavior). Holds the client
4
+ * identity, the (rehydrated) capability set, and the socket. The wire boundary asks exactly one
5
+ * question — `session.supports(flag)` — using the protocol gating helper.
6
+ */
7
+ export declare class Session {
8
+ readonly id: string;
9
+ readonly clientId: string;
10
+ readonly clientType: string;
11
+ capabilities: Record<string, boolean>;
12
+ private readonly socket;
13
+ constructor(opts: {
14
+ id: string;
15
+ clientId: string;
16
+ clientType: string;
17
+ capabilities: Record<string, boolean>;
18
+ socket: WebSocket;
19
+ });
20
+ /** True if the client advertised support for `flag` (or it was rehydrated from a prior hello). */
21
+ supports(flag: string): boolean;
22
+ /** Send a top-level envelope as a JSON text frame. */
23
+ send(envelope: unknown): void;
24
+ /** Send raw bytes as a binary frame (terminal/file streams). */
25
+ sendBinary(bytes: Uint8Array): void;
26
+ close(code?: number, reason?: string): void;
27
+ }
28
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/ws/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC;;;;GAIG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;gBAEvB,IAAI,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,EAAE,SAAS,CAAC;KACnB;IAQD,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,sDAAsD;IACtD,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI7B,gEAAgE;IAChE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAInC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAG5C"}
@@ -0,0 +1,36 @@
1
+ import { supports } from "@av-pi-studio/protocol";
2
+ /**
3
+ * A per-connection session (architecture/websocket-protocol.md § Behavior). Holds the client
4
+ * identity, the (rehydrated) capability set, and the socket. The wire boundary asks exactly one
5
+ * question — `session.supports(flag)` — using the protocol gating helper.
6
+ */
7
+ export class Session {
8
+ id;
9
+ clientId;
10
+ clientType;
11
+ capabilities;
12
+ socket;
13
+ constructor(opts) {
14
+ this.id = opts.id;
15
+ this.clientId = opts.clientId;
16
+ this.clientType = opts.clientType;
17
+ this.capabilities = opts.capabilities;
18
+ this.socket = opts.socket;
19
+ }
20
+ /** True if the client advertised support for `flag` (or it was rehydrated from a prior hello). */
21
+ supports(flag) {
22
+ return supports(this.capabilities, flag);
23
+ }
24
+ /** Send a top-level envelope as a JSON text frame. */
25
+ send(envelope) {
26
+ this.socket.send(JSON.stringify(envelope));
27
+ }
28
+ /** Send raw bytes as a binary frame (terminal/file streams). */
29
+ sendBinary(bytes) {
30
+ this.socket.send(bytes);
31
+ }
32
+ close(code, reason) {
33
+ this.socket.close(code, reason);
34
+ }
35
+ }
36
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/ws/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGlD;;;;GAIG;AACH,MAAM,OAAO,OAAO;IACT,EAAE,CAAS;IACX,QAAQ,CAAS;IACjB,UAAU,CAAS;IAC5B,YAAY,CAA0B;IACrB,MAAM,CAAY;IAEnC,YAAY,IAMX;QACC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,kGAAkG;IAClG,QAAQ,CAAC,IAAY;QACnB,OAAO,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,sDAAsD;IACtD,IAAI,CAAC,QAAiB;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,gEAAgE;IAChE,UAAU,CAAC,KAAiB;QAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAa,EAAE,MAAe;QAClC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,41 @@
1
+ import type { Server as HttpServer } from "node:http";
2
+ import { WebSocketServer } from "ws";
3
+ import type { PasswordAuth } from "../auth/password-auth.js";
4
+ import { type CapabilityStore } from "./capability-store.js";
5
+ import { Session } from "./session.js";
6
+ /**
7
+ * WebSocket server (architecture/websocket-protocol.md § Connection & handshake, § Behavior).
8
+ *
9
+ * On connection: validate Host + auth at upgrade, expect the first frame to be `hello`, register a
10
+ * {@link Session}, persist/rehydrate the client's capabilities keyed by `clientId`, emit
11
+ * `status`/`server_info`, then begin streaming. A non-`hello` first frame closes the socket.
12
+ */
13
+ /** Message delivered to the router (task-005) after the handshake. */
14
+ export type SessionFrame = {
15
+ text: string;
16
+ } | {
17
+ binary: Uint8Array;
18
+ };
19
+ export interface WebSocketServerDeps {
20
+ serverId: string;
21
+ hostname?: string;
22
+ version?: string;
23
+ /** Server-side capability map echoed in `server_info.capabilities`. */
24
+ serverCapabilities?: Record<string, unknown>;
25
+ /** Advertised server features (`server_info.features`). Defaults to all SERVER_FEATURES enabled. */
26
+ features?: Record<string, unknown>;
27
+ auth?: PasswordAuth;
28
+ hostCheck?: (hostHeader: string | undefined) => boolean;
29
+ capabilityStore?: CapabilityStore;
30
+ /** Called once a session completes its handshake. */
31
+ onSession?: (session: Session) => void;
32
+ /** Called for every post-handshake frame. */
33
+ onMessage?: (session: Session, frame: SessionFrame) => void;
34
+ }
35
+ export interface WebSocketServerHandle {
36
+ readonly wss: WebSocketServer;
37
+ readonly sessions: Set<Session>;
38
+ close(): Promise<void>;
39
+ }
40
+ export declare function createWebSocketServer(httpServer: HttpServer, deps: WebSocketServerDeps): WebSocketServerHandle;
41
+ //# sourceMappingURL=ws-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-server.d.ts","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAQvE,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,KAAK,eAAe,EAAiC,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AAEH,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;IACxD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAMD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,mBAAmB,GACxB,qBAAqB,CAiGvB"}
@@ -0,0 +1,104 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { helloSchema, SERVER_FEATURES, serverInfoPayloadSchema, statusSchema, } from "@av-pi-studio/protocol";
3
+ import { WebSocketServer } from "ws";
4
+ import { WS_BEARER_SUBPROTOCOL_PREFIX } from "../auth/password-auth.js";
5
+ import { createInMemoryCapabilityStore } from "./capability-store.js";
6
+ import { Session } from "./session.js";
7
+ function defaultFeatures() {
8
+ return Object.fromEntries(Object.values(SERVER_FEATURES).map((key) => [key, true]));
9
+ }
10
+ export function createWebSocketServer(httpServer, deps) {
11
+ const store = deps.capabilityStore ?? createInMemoryCapabilityStore();
12
+ const sessions = new Set();
13
+ const wss = new WebSocketServer({
14
+ noServer: true,
15
+ // Echo the bearer subprotocol back so a browser client's offered protocol is accepted.
16
+ handleProtocols: (protocols) => {
17
+ for (const proto of protocols) {
18
+ if (proto.startsWith(WS_BEARER_SUBPROTOCOL_PREFIX))
19
+ return proto;
20
+ }
21
+ return false;
22
+ },
23
+ });
24
+ httpServer.on("upgrade", (req, socket, head) => {
25
+ if (deps.hostCheck && !deps.hostCheck(req.headers.host)) {
26
+ socket.write("HTTP/1.1 403 Host not allowed\r\n\r\n");
27
+ socket.destroy();
28
+ return;
29
+ }
30
+ if (deps.auth && !deps.auth.authenticateUpgrade(req)) {
31
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
32
+ socket.destroy();
33
+ return;
34
+ }
35
+ wss.handleUpgrade(req, socket, head, (ws) => wss.emit("connection", ws, req));
36
+ });
37
+ wss.on("connection", (ws, _req) => {
38
+ let session = null;
39
+ ws.on("message", (data, isBinary) => {
40
+ if (session === null) {
41
+ // First frame must be a valid JSON `hello`.
42
+ if (isBinary) {
43
+ ws.close(1008, "expected hello");
44
+ return;
45
+ }
46
+ let parsed;
47
+ try {
48
+ parsed = JSON.parse(data.toString("utf8"));
49
+ }
50
+ catch {
51
+ ws.close(1008, "invalid hello");
52
+ return;
53
+ }
54
+ const hello = helloSchema.safeParse(parsed);
55
+ if (!hello.success) {
56
+ ws.close(1008, "first frame must be hello");
57
+ return;
58
+ }
59
+ // Persist on hello; rehydrate stored caps when the hello omits them.
60
+ const stored = store.get(hello.data.clientId);
61
+ const capabilities = hello.data.capabilities ?? stored ?? {};
62
+ store.set(hello.data.clientId, capabilities);
63
+ session = new Session({
64
+ id: randomUUID(),
65
+ clientId: hello.data.clientId,
66
+ clientType: hello.data.clientType,
67
+ capabilities,
68
+ socket: ws,
69
+ });
70
+ sessions.add(session);
71
+ const payload = serverInfoPayloadSchema.parse({
72
+ status: "server_info",
73
+ serverId: deps.serverId,
74
+ ...(deps.hostname ? { hostname: deps.hostname } : {}),
75
+ ...(deps.version ? { version: deps.version } : {}),
76
+ capabilities: deps.serverCapabilities ?? {},
77
+ features: deps.features ?? defaultFeatures(),
78
+ });
79
+ session.send(statusSchema.parse({ type: "status", payload }));
80
+ deps.onSession?.(session);
81
+ return;
82
+ }
83
+ // Post-handshake frames → router (task-005).
84
+ if (isBinary)
85
+ deps.onMessage?.(session, { binary: new Uint8Array(data) });
86
+ else
87
+ deps.onMessage?.(session, { text: data.toString("utf8") });
88
+ });
89
+ ws.on("close", () => {
90
+ if (session)
91
+ sessions.delete(session);
92
+ });
93
+ });
94
+ return {
95
+ wss,
96
+ sessions,
97
+ async close() {
98
+ for (const session of sessions)
99
+ session.close(1001, "server shutting down");
100
+ await new Promise((resolve) => wss.close(() => resolve()));
101
+ },
102
+ };
103
+ }
104
+ //# sourceMappingURL=ws-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-server.js","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@av-pi-studio/server",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "bin": {
11
+ "pi-studio-daemon": "./dist/daemon/main.js"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "build": "tsc -b",
21
+ "start": "node ./dist/daemon/main.js",
22
+ "clean": "rm -rf dist *.tsbuildinfo"
23
+ },
24
+ "dependencies": {
25
+ "@av-pi-studio/highlight": "^0.0.1",
26
+ "@av-pi-studio/protocol": "^0.0.1",
27
+ "@earendil-works/pi-coding-agent": "^0.79.4",
28
+ "@xterm/headless": "^6.0.0",
29
+ "bcryptjs": "^3.0.3",
30
+ "lru-cache": "^11.5.1",
31
+ "node-pty": "1.2.0-beta.11",
32
+ "p-limit": "^7.3.0",
33
+ "pino": "^10.2.0",
34
+ "pino-pretty": "^13.1.3",
35
+ "rotating-file-stream": "^3.2.9",
36
+ "strip-ansi": "^7.1.2",
37
+ "tree-kill": "^1.2.2",
38
+ "tweetnacl": "^1.0.3",
39
+ "which": "^5.0.0",
40
+ "ws": "^8.21.0",
41
+ "zod": "^3.23.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/bcryptjs": "^2.4.6",
45
+ "@types/which": "^3.0.4",
46
+ "@types/ws": "^8.18.1"
47
+ }
48
+ }