@aigne/aos 0.2.0-beta

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 (533) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/LICENSE.md +26 -0
  3. package/dist/agent-dsl.cjs +116 -0
  4. package/dist/agent-dsl.d.cts +31 -0
  5. package/dist/agent-dsl.d.cts.map +1 -0
  6. package/dist/agent-dsl.d.mts +31 -0
  7. package/dist/agent-dsl.d.mts.map +1 -0
  8. package/dist/agent-dsl.mjs +115 -0
  9. package/dist/agent-dsl.mjs.map +1 -0
  10. package/dist/arc-compat.cjs +125 -0
  11. package/dist/arc-compat.d.cts +17 -0
  12. package/dist/arc-compat.d.cts.map +1 -0
  13. package/dist/arc-compat.d.mts +17 -0
  14. package/dist/arc-compat.d.mts.map +1 -0
  15. package/dist/arc-compat.mjs +123 -0
  16. package/dist/arc-compat.mjs.map +1 -0
  17. package/dist/auto-surface/compiler.cjs +36 -0
  18. package/dist/auto-surface/compiler.d.cts +7 -0
  19. package/dist/auto-surface/compiler.d.cts.map +1 -0
  20. package/dist/auto-surface/compiler.d.mts +7 -0
  21. package/dist/auto-surface/compiler.d.mts.map +1 -0
  22. package/dist/auto-surface/compiler.mjs +37 -0
  23. package/dist/auto-surface/compiler.mjs.map +1 -0
  24. package/dist/auto-surface/definition-dsl.cjs +333 -0
  25. package/dist/auto-surface/definition-dsl.d.cts +41 -0
  26. package/dist/auto-surface/definition-dsl.d.cts.map +1 -0
  27. package/dist/auto-surface/definition-dsl.d.mts +41 -0
  28. package/dist/auto-surface/definition-dsl.d.mts.map +1 -0
  29. package/dist/auto-surface/definition-dsl.mjs +332 -0
  30. package/dist/auto-surface/definition-dsl.mjs.map +1 -0
  31. package/dist/auto-surface/fragments.cjs +177 -0
  32. package/dist/auto-surface/fragments.d.cts +23 -0
  33. package/dist/auto-surface/fragments.d.cts.map +1 -0
  34. package/dist/auto-surface/fragments.d.mts +23 -0
  35. package/dist/auto-surface/fragments.d.mts.map +1 -0
  36. package/dist/auto-surface/fragments.mjs +175 -0
  37. package/dist/auto-surface/fragments.mjs.map +1 -0
  38. package/dist/auto-surface/index.d.mts +9 -0
  39. package/dist/auto-surface/layering.cjs +43 -0
  40. package/dist/auto-surface/layering.d.cts +7 -0
  41. package/dist/auto-surface/layering.d.cts.map +1 -0
  42. package/dist/auto-surface/layering.d.mts +7 -0
  43. package/dist/auto-surface/layering.d.mts.map +1 -0
  44. package/dist/auto-surface/layering.mjs +43 -0
  45. package/dist/auto-surface/layering.mjs.map +1 -0
  46. package/dist/auto-surface/projection.cjs +11 -0
  47. package/dist/auto-surface/projection.d.cts +11 -0
  48. package/dist/auto-surface/projection.d.cts.map +1 -0
  49. package/dist/auto-surface/projection.d.mts +11 -0
  50. package/dist/auto-surface/projection.d.mts.map +1 -0
  51. package/dist/auto-surface/projection.mjs +12 -0
  52. package/dist/auto-surface/projection.mjs.map +1 -0
  53. package/dist/auto-surface/projectors/settings-shell.cjs +114 -0
  54. package/dist/auto-surface/projectors/settings-shell.d.cts +10 -0
  55. package/dist/auto-surface/projectors/settings-shell.d.cts.map +1 -0
  56. package/dist/auto-surface/projectors/settings-shell.d.mts +10 -0
  57. package/dist/auto-surface/projectors/settings-shell.d.mts.map +1 -0
  58. package/dist/auto-surface/projectors/settings-shell.mjs +114 -0
  59. package/dist/auto-surface/projectors/settings-shell.mjs.map +1 -0
  60. package/dist/auto-surface/scenario.cjs +38 -0
  61. package/dist/auto-surface/scenario.d.cts +31 -0
  62. package/dist/auto-surface/scenario.d.cts.map +1 -0
  63. package/dist/auto-surface/scenario.d.mts +31 -0
  64. package/dist/auto-surface/scenario.d.mts.map +1 -0
  65. package/dist/auto-surface/scenario.mjs +37 -0
  66. package/dist/auto-surface/scenario.mjs.map +1 -0
  67. package/dist/auto-surface/types.cjs +9 -0
  68. package/dist/auto-surface/types.d.cts +153 -0
  69. package/dist/auto-surface/types.d.cts.map +1 -0
  70. package/dist/auto-surface/types.d.mts +153 -0
  71. package/dist/auto-surface/types.d.mts.map +1 -0
  72. package/dist/auto-surface/types.mjs +9 -0
  73. package/dist/auto-surface/types.mjs.map +1 -0
  74. package/dist/auto-surface/value-dsl.cjs +80 -0
  75. package/dist/auto-surface/value-dsl.d.cts +24 -0
  76. package/dist/auto-surface/value-dsl.d.cts.map +1 -0
  77. package/dist/auto-surface/value-dsl.d.mts +24 -0
  78. package/dist/auto-surface/value-dsl.d.mts.map +1 -0
  79. package/dist/auto-surface/value-dsl.mjs +79 -0
  80. package/dist/auto-surface/value-dsl.mjs.map +1 -0
  81. package/dist/blocklet/activation.cjs +94 -0
  82. package/dist/blocklet/activation.d.cts +30 -0
  83. package/dist/blocklet/activation.d.cts.map +1 -0
  84. package/dist/blocklet/activation.d.mts +30 -0
  85. package/dist/blocklet/activation.d.mts.map +1 -0
  86. package/dist/blocklet/activation.mjs +94 -0
  87. package/dist/blocklet/activation.mjs.map +1 -0
  88. package/dist/blocklet/did-space-registry.cjs +282 -0
  89. package/dist/blocklet/did-space-registry.d.cts +82 -0
  90. package/dist/blocklet/did-space-registry.d.cts.map +1 -0
  91. package/dist/blocklet/did-space-registry.d.mts +82 -0
  92. package/dist/blocklet/did-space-registry.d.mts.map +1 -0
  93. package/dist/blocklet/did-space-registry.mjs +281 -0
  94. package/dist/blocklet/did-space-registry.mjs.map +1 -0
  95. package/dist/blocklet/handlers.cjs +66 -0
  96. package/dist/blocklet/handlers.d.cts +16 -0
  97. package/dist/blocklet/handlers.d.cts.map +1 -0
  98. package/dist/blocklet/handlers.d.mts +16 -0
  99. package/dist/blocklet/handlers.d.mts.map +1 -0
  100. package/dist/blocklet/handlers.mjs +65 -0
  101. package/dist/blocklet/handlers.mjs.map +1 -0
  102. package/dist/blocklet/index.d.mts +7 -0
  103. package/dist/blocklet/manifest.d.cts +2 -0
  104. package/dist/blocklet/manifest.d.mts +2 -0
  105. package/dist/blocklet/manifest.mjs +3 -0
  106. package/dist/blocklet/registry.cjs +447 -0
  107. package/dist/blocklet/registry.d.cts +197 -0
  108. package/dist/blocklet/registry.d.cts.map +1 -0
  109. package/dist/blocklet/registry.d.mts +197 -0
  110. package/dist/blocklet/registry.d.mts.map +1 -0
  111. package/dist/blocklet/registry.mjs +441 -0
  112. package/dist/blocklet/registry.mjs.map +1 -0
  113. package/dist/blocklet/static-render.cjs +183 -0
  114. package/dist/blocklet/static-render.d.cts +55 -0
  115. package/dist/blocklet/static-render.d.cts.map +1 -0
  116. package/dist/blocklet/static-render.d.mts +55 -0
  117. package/dist/blocklet/static-render.d.mts.map +1 -0
  118. package/dist/blocklet/static-render.mjs +181 -0
  119. package/dist/blocklet/static-render.mjs.map +1 -0
  120. package/dist/blocklet/types.d.cts +70 -0
  121. package/dist/blocklet/types.d.cts.map +1 -0
  122. package/dist/blocklet/types.d.mts +70 -0
  123. package/dist/blocklet/types.d.mts.map +1 -0
  124. package/dist/devices/chain.cjs +127 -0
  125. package/dist/devices/chain.d.cts +48 -0
  126. package/dist/devices/chain.d.cts.map +1 -0
  127. package/dist/devices/chain.d.mts +48 -0
  128. package/dist/devices/chain.d.mts.map +1 -0
  129. package/dist/devices/chain.mjs +125 -0
  130. package/dist/devices/chain.mjs.map +1 -0
  131. package/dist/dsl-shared.cjs +290 -0
  132. package/dist/dsl-shared.d.cts +54 -0
  133. package/dist/dsl-shared.d.cts.map +1 -0
  134. package/dist/dsl-shared.d.mts +54 -0
  135. package/dist/dsl-shared.d.mts.map +1 -0
  136. package/dist/dsl-shared.mjs +287 -0
  137. package/dist/dsl-shared.mjs.map +1 -0
  138. package/dist/http/afs-mcp.cjs +85 -0
  139. package/dist/http/afs-mcp.d.cts +14 -0
  140. package/dist/http/afs-mcp.d.cts.map +1 -0
  141. package/dist/http/afs-mcp.d.mts +14 -0
  142. package/dist/http/afs-mcp.d.mts.map +1 -0
  143. package/dist/http/afs-mcp.mjs +86 -0
  144. package/dist/http/afs-mcp.mjs.map +1 -0
  145. package/dist/http/afs-raw.cjs +264 -0
  146. package/dist/http/afs-raw.d.cts +31 -0
  147. package/dist/http/afs-raw.d.cts.map +1 -0
  148. package/dist/http/afs-raw.d.mts +31 -0
  149. package/dist/http/afs-raw.d.mts.map +1 -0
  150. package/dist/http/afs-raw.mjs +264 -0
  151. package/dist/http/afs-raw.mjs.map +1 -0
  152. package/dist/http/afs-rest.cjs +30 -0
  153. package/dist/http/afs-rest.d.cts +21 -0
  154. package/dist/http/afs-rest.d.cts.map +1 -0
  155. package/dist/http/afs-rest.d.mts +21 -0
  156. package/dist/http/afs-rest.d.mts.map +1 -0
  157. package/dist/http/afs-rest.mjs +31 -0
  158. package/dist/http/afs-rest.mjs.map +1 -0
  159. package/dist/http/afs-rpc-wire.cjs +271 -0
  160. package/dist/http/afs-rpc-wire.d.cts +195 -0
  161. package/dist/http/afs-rpc-wire.d.cts.map +1 -0
  162. package/dist/http/afs-rpc-wire.d.mts +195 -0
  163. package/dist/http/afs-rpc-wire.d.mts.map +1 -0
  164. package/dist/http/afs-rpc-wire.mjs +262 -0
  165. package/dist/http/afs-rpc-wire.mjs.map +1 -0
  166. package/dist/http/afs-rpc.cjs +729 -0
  167. package/dist/http/afs-rpc.d.cts +103 -0
  168. package/dist/http/afs-rpc.d.cts.map +1 -0
  169. package/dist/http/afs-rpc.d.mts +103 -0
  170. package/dist/http/afs-rpc.d.mts.map +1 -0
  171. package/dist/http/afs-rpc.mjs +729 -0
  172. package/dist/http/afs-rpc.mjs.map +1 -0
  173. package/dist/http/afs-upload.cjs +116 -0
  174. package/dist/http/afs-upload.d.cts +40 -0
  175. package/dist/http/afs-upload.d.cts.map +1 -0
  176. package/dist/http/afs-upload.d.mts +40 -0
  177. package/dist/http/afs-upload.d.mts.map +1 -0
  178. package/dist/http/afs-upload.mjs +116 -0
  179. package/dist/http/afs-upload.mjs.map +1 -0
  180. package/dist/http/aup-client.cjs +60 -0
  181. package/dist/http/aup-client.d.cts +22 -0
  182. package/dist/http/aup-client.d.cts.map +1 -0
  183. package/dist/http/aup-client.d.mts +22 -0
  184. package/dist/http/aup-client.d.mts.map +1 -0
  185. package/dist/http/aup-client.mjs +59 -0
  186. package/dist/http/aup-client.mjs.map +1 -0
  187. package/dist/http/aup-event.cjs +100 -0
  188. package/dist/http/aup-event.d.cts +38 -0
  189. package/dist/http/aup-event.d.cts.map +1 -0
  190. package/dist/http/aup-event.d.mts +38 -0
  191. package/dist/http/aup-event.d.mts.map +1 -0
  192. package/dist/http/aup-event.mjs +101 -0
  193. package/dist/http/aup-event.mjs.map +1 -0
  194. package/dist/http/auth-context.cjs +66 -0
  195. package/dist/http/auth-context.d.cts +64 -0
  196. package/dist/http/auth-context.d.cts.map +1 -0
  197. package/dist/http/auth-context.d.mts +64 -0
  198. package/dist/http/auth-context.d.mts.map +1 -0
  199. package/dist/http/auth-context.mjs +66 -0
  200. package/dist/http/auth-context.mjs.map +1 -0
  201. package/dist/http/csrf.cjs +50 -0
  202. package/dist/http/csrf.d.cts +8 -0
  203. package/dist/http/csrf.d.cts.map +1 -0
  204. package/dist/http/csrf.d.mts +8 -0
  205. package/dist/http/csrf.d.mts.map +1 -0
  206. package/dist/http/csrf.mjs +49 -0
  207. package/dist/http/csrf.mjs.map +1 -0
  208. package/dist/http/handlers.cjs +106 -0
  209. package/dist/http/handlers.d.cts +39 -0
  210. package/dist/http/handlers.d.cts.map +1 -0
  211. package/dist/http/handlers.d.mts +39 -0
  212. package/dist/http/handlers.d.mts.map +1 -0
  213. package/dist/http/handlers.mjs +104 -0
  214. package/dist/http/handlers.mjs.map +1 -0
  215. package/dist/http/index.d.mts +1 -0
  216. package/dist/http/ingest-facade.cjs +315 -0
  217. package/dist/http/ingest-facade.mjs +314 -0
  218. package/dist/http/ingest-facade.mjs.map +1 -0
  219. package/dist/http/raw-url.cjs +136 -0
  220. package/dist/http/raw-url.d.cts +54 -0
  221. package/dist/http/raw-url.d.cts.map +1 -0
  222. package/dist/http/raw-url.d.mts +54 -0
  223. package/dist/http/raw-url.d.mts.map +1 -0
  224. package/dist/http/raw-url.mjs +136 -0
  225. package/dist/http/raw-url.mjs.map +1 -0
  226. package/dist/http/request-context.cjs +178 -0
  227. package/dist/http/request-context.d.cts +76 -0
  228. package/dist/http/request-context.d.cts.map +1 -0
  229. package/dist/http/request-context.d.mts +76 -0
  230. package/dist/http/request-context.d.mts.map +1 -0
  231. package/dist/http/request-context.mjs +179 -0
  232. package/dist/http/request-context.mjs.map +1 -0
  233. package/dist/index.cjs +197 -0
  234. package/dist/index.d.cts +63 -0
  235. package/dist/index.d.mts +68 -0
  236. package/dist/index.mjs +61 -0
  237. package/dist/mcp/index.cjs +9 -0
  238. package/dist/mcp/index.d.cts +5 -0
  239. package/dist/mcp/index.d.mts +5 -0
  240. package/dist/mcp/index.mjs +6 -0
  241. package/dist/mcp/prompts.cjs +17 -0
  242. package/dist/mcp/prompts.d.cts +8 -0
  243. package/dist/mcp/prompts.d.cts.map +1 -0
  244. package/dist/mcp/prompts.d.mts +8 -0
  245. package/dist/mcp/prompts.d.mts.map +1 -0
  246. package/dist/mcp/prompts.mjs +17 -0
  247. package/dist/mcp/prompts.mjs.map +1 -0
  248. package/dist/mcp/resources.cjs +22 -0
  249. package/dist/mcp/resources.d.cts +8 -0
  250. package/dist/mcp/resources.d.cts.map +1 -0
  251. package/dist/mcp/resources.d.mts +8 -0
  252. package/dist/mcp/resources.d.mts.map +1 -0
  253. package/dist/mcp/resources.mjs +22 -0
  254. package/dist/mcp/resources.mjs.map +1 -0
  255. package/dist/mcp/server.cjs +51 -0
  256. package/dist/mcp/server.d.cts +20 -0
  257. package/dist/mcp/server.d.cts.map +1 -0
  258. package/dist/mcp/server.d.mts +20 -0
  259. package/dist/mcp/server.d.mts.map +1 -0
  260. package/dist/mcp/server.mjs +52 -0
  261. package/dist/mcp/server.mjs.map +1 -0
  262. package/dist/mcp/tools.cjs +218 -0
  263. package/dist/mcp/tools.d.cts +8 -0
  264. package/dist/mcp/tools.d.cts.map +1 -0
  265. package/dist/mcp/tools.d.mts +8 -0
  266. package/dist/mcp/tools.d.mts.map +1 -0
  267. package/dist/mcp/tools.mjs +219 -0
  268. package/dist/mcp/tools.mjs.map +1 -0
  269. package/dist/mcp/utils.cjs +75 -0
  270. package/dist/mcp/utils.mjs +69 -0
  271. package/dist/mcp/utils.mjs.map +1 -0
  272. package/dist/mount/index.cjs +4 -0
  273. package/dist/mount/index.d.cts +3 -0
  274. package/dist/mount/index.d.mts +3 -0
  275. package/dist/mount/index.mjs +3 -0
  276. package/dist/mount/materializer.cjs +167 -0
  277. package/dist/mount/materializer.d.cts +97 -0
  278. package/dist/mount/materializer.d.cts.map +1 -0
  279. package/dist/mount/materializer.d.mts +97 -0
  280. package/dist/mount/materializer.d.mts.map +1 -0
  281. package/dist/mount/materializer.mjs +167 -0
  282. package/dist/mount/materializer.mjs.map +1 -0
  283. package/dist/mount/types.d.cts +90 -0
  284. package/dist/mount/types.d.cts.map +1 -0
  285. package/dist/mount/types.d.mts +90 -0
  286. package/dist/mount/types.d.mts.map +1 -0
  287. package/dist/mount-config.cjs +61 -0
  288. package/dist/mount-config.d.cts +19 -0
  289. package/dist/mount-config.d.cts.map +1 -0
  290. package/dist/mount-config.d.mts +19 -0
  291. package/dist/mount-config.d.mts.map +1 -0
  292. package/dist/mount-config.mjs +61 -0
  293. package/dist/mount-config.mjs.map +1 -0
  294. package/dist/projectors/aup-projector.cjs +190 -0
  295. package/dist/projectors/aup-projector.d.cts +59 -0
  296. package/dist/projectors/aup-projector.d.cts.map +1 -0
  297. package/dist/projectors/aup-projector.d.mts +59 -0
  298. package/dist/projectors/aup-projector.d.mts.map +1 -0
  299. package/dist/projectors/aup-projector.mjs +188 -0
  300. package/dist/projectors/aup-projector.mjs.map +1 -0
  301. package/dist/projectors/index.cjs +6 -0
  302. package/dist/projectors/index.d.cts +2 -0
  303. package/dist/projectors/index.d.mts +2 -0
  304. package/dist/projectors/index.mjs +3 -0
  305. package/dist/scaffold/afs.cjs +195 -0
  306. package/dist/scaffold/afs.d.cts +16 -0
  307. package/dist/scaffold/afs.d.cts.map +1 -0
  308. package/dist/scaffold/afs.d.mts +16 -0
  309. package/dist/scaffold/afs.d.mts.map +1 -0
  310. package/dist/scaffold/afs.mjs +195 -0
  311. package/dist/scaffold/afs.mjs.map +1 -0
  312. package/dist/scaffold/composition.cjs +92 -0
  313. package/dist/scaffold/composition.d.cts +10 -0
  314. package/dist/scaffold/composition.d.cts.map +1 -0
  315. package/dist/scaffold/composition.d.mts +10 -0
  316. package/dist/scaffold/composition.d.mts.map +1 -0
  317. package/dist/scaffold/composition.mjs +92 -0
  318. package/dist/scaffold/composition.mjs.map +1 -0
  319. package/dist/scaffold/dsl-error.cjs +21 -0
  320. package/dist/scaffold/dsl-error.d.cts +11 -0
  321. package/dist/scaffold/dsl-error.d.cts.map +1 -0
  322. package/dist/scaffold/dsl-error.d.mts +11 -0
  323. package/dist/scaffold/dsl-error.d.mts.map +1 -0
  324. package/dist/scaffold/dsl-error.mjs +20 -0
  325. package/dist/scaffold/dsl-error.mjs.map +1 -0
  326. package/dist/scaffold/index.d.mts +12 -0
  327. package/dist/scaffold/manifest-dsl.cjs +188 -0
  328. package/dist/scaffold/manifest-dsl.d.cts +8 -0
  329. package/dist/scaffold/manifest-dsl.d.cts.map +1 -0
  330. package/dist/scaffold/manifest-dsl.d.mts +8 -0
  331. package/dist/scaffold/manifest-dsl.d.mts.map +1 -0
  332. package/dist/scaffold/manifest-dsl.mjs +188 -0
  333. package/dist/scaffold/manifest-dsl.mjs.map +1 -0
  334. package/dist/scaffold/module-dsl.cjs +284 -0
  335. package/dist/scaffold/module-dsl.d.cts +8 -0
  336. package/dist/scaffold/module-dsl.d.cts.map +1 -0
  337. package/dist/scaffold/module-dsl.d.mts +8 -0
  338. package/dist/scaffold/module-dsl.d.mts.map +1 -0
  339. package/dist/scaffold/module-dsl.mjs +284 -0
  340. package/dist/scaffold/module-dsl.mjs.map +1 -0
  341. package/dist/scaffold/resolver.cjs +156 -0
  342. package/dist/scaffold/resolver.d.cts +7 -0
  343. package/dist/scaffold/resolver.d.cts.map +1 -0
  344. package/dist/scaffold/resolver.d.mts +7 -0
  345. package/dist/scaffold/resolver.d.mts.map +1 -0
  346. package/dist/scaffold/resolver.mjs +156 -0
  347. package/dist/scaffold/resolver.mjs.map +1 -0
  348. package/dist/scaffold/runtime.cjs +24 -0
  349. package/dist/scaffold/runtime.d.cts +19 -0
  350. package/dist/scaffold/runtime.d.cts.map +1 -0
  351. package/dist/scaffold/runtime.d.mts +19 -0
  352. package/dist/scaffold/runtime.d.mts.map +1 -0
  353. package/dist/scaffold/runtime.mjs +25 -0
  354. package/dist/scaffold/runtime.mjs.map +1 -0
  355. package/dist/scaffold/shell-dsl.cjs +279 -0
  356. package/dist/scaffold/shell-dsl.d.cts +8 -0
  357. package/dist/scaffold/shell-dsl.d.cts.map +1 -0
  358. package/dist/scaffold/shell-dsl.d.mts +8 -0
  359. package/dist/scaffold/shell-dsl.d.mts.map +1 -0
  360. package/dist/scaffold/shell-dsl.mjs +279 -0
  361. package/dist/scaffold/shell-dsl.mjs.map +1 -0
  362. package/dist/scaffold/surface-dsl.cjs +182 -0
  363. package/dist/scaffold/surface-dsl.d.cts +8 -0
  364. package/dist/scaffold/surface-dsl.d.cts.map +1 -0
  365. package/dist/scaffold/surface-dsl.d.mts +8 -0
  366. package/dist/scaffold/surface-dsl.d.mts.map +1 -0
  367. package/dist/scaffold/surface-dsl.mjs +182 -0
  368. package/dist/scaffold/surface-dsl.mjs.map +1 -0
  369. package/dist/scaffold/surfaces.cjs +84 -0
  370. package/dist/scaffold/surfaces.d.cts +23 -0
  371. package/dist/scaffold/surfaces.d.cts.map +1 -0
  372. package/dist/scaffold/surfaces.d.mts +24 -0
  373. package/dist/scaffold/surfaces.d.mts.map +1 -0
  374. package/dist/scaffold/surfaces.mjs +84 -0
  375. package/dist/scaffold/surfaces.mjs.map +1 -0
  376. package/dist/scaffold/types.d.cts +264 -0
  377. package/dist/scaffold/types.d.cts.map +1 -0
  378. package/dist/scaffold/types.d.mts +265 -0
  379. package/dist/scaffold/types.d.mts.map +1 -0
  380. package/dist/scaffold/workspace-dsl.cjs +339 -0
  381. package/dist/scaffold/workspace-dsl.d.cts +49 -0
  382. package/dist/scaffold/workspace-dsl.d.cts.map +1 -0
  383. package/dist/scaffold/workspace-dsl.d.mts +49 -0
  384. package/dist/scaffold/workspace-dsl.d.mts.map +1 -0
  385. package/dist/scaffold/workspace-dsl.mjs +337 -0
  386. package/dist/scaffold/workspace-dsl.mjs.map +1 -0
  387. package/dist/scope/index.d.mts +3 -0
  388. package/dist/scope/read-blocklet-scope.cjs +29 -0
  389. package/dist/scope/read-blocklet-scope.d.cts +8 -0
  390. package/dist/scope/read-blocklet-scope.d.cts.map +1 -0
  391. package/dist/scope/read-blocklet-scope.d.mts +8 -0
  392. package/dist/scope/read-blocklet-scope.d.mts.map +1 -0
  393. package/dist/scope/read-blocklet-scope.mjs +30 -0
  394. package/dist/scope/read-blocklet-scope.mjs.map +1 -0
  395. package/dist/scope/resolve-scoped-afs.cjs +87 -0
  396. package/dist/scope/resolve-scoped-afs.d.cts +7 -0
  397. package/dist/scope/resolve-scoped-afs.d.cts.map +1 -0
  398. package/dist/scope/resolve-scoped-afs.d.mts +7 -0
  399. package/dist/scope/resolve-scoped-afs.d.mts.map +1 -0
  400. package/dist/scope/resolve-scoped-afs.mjs +88 -0
  401. package/dist/scope/resolve-scoped-afs.mjs.map +1 -0
  402. package/dist/scope/types.d.cts +25 -0
  403. package/dist/scope/types.d.cts.map +1 -0
  404. package/dist/scope/types.d.mts +25 -0
  405. package/dist/scope/types.d.mts.map +1 -0
  406. package/dist/session/backends.cjs +90 -0
  407. package/dist/session/backends.d.cts +35 -0
  408. package/dist/session/backends.d.cts.map +1 -0
  409. package/dist/session/backends.d.mts +35 -0
  410. package/dist/session/backends.d.mts.map +1 -0
  411. package/dist/session/backends.mjs +89 -0
  412. package/dist/session/backends.mjs.map +1 -0
  413. package/dist/session/replication-resolver.cjs +323 -0
  414. package/dist/session/replication-resolver.d.cts +71 -0
  415. package/dist/session/replication-resolver.d.cts.map +1 -0
  416. package/dist/session/replication-resolver.d.mts +71 -0
  417. package/dist/session/replication-resolver.d.mts.map +1 -0
  418. package/dist/session/replication-resolver.mjs +323 -0
  419. package/dist/session/replication-resolver.mjs.map +1 -0
  420. package/dist/session/role-level.cjs +36 -0
  421. package/dist/session/role-level.d.cts +24 -0
  422. package/dist/session/role-level.d.cts.map +1 -0
  423. package/dist/session/role-level.d.mts +24 -0
  424. package/dist/session/role-level.d.mts.map +1 -0
  425. package/dist/session/role-level.mjs +35 -0
  426. package/dist/session/role-level.mjs.map +1 -0
  427. package/dist/session/session-dir-providers.cjs +254 -0
  428. package/dist/session/session-dir-providers.d.cts +32 -0
  429. package/dist/session/session-dir-providers.d.cts.map +1 -0
  430. package/dist/session/session-dir-providers.d.mts +32 -0
  431. package/dist/session/session-dir-providers.d.mts.map +1 -0
  432. package/dist/session/session-dir-providers.mjs +252 -0
  433. package/dist/session/session-dir-providers.mjs.map +1 -0
  434. package/dist/session/session-id.cjs +20 -0
  435. package/dist/session/session-id.d.cts +15 -0
  436. package/dist/session/session-id.d.cts.map +1 -0
  437. package/dist/session/session-id.d.mts +15 -0
  438. package/dist/session/session-id.d.mts.map +1 -0
  439. package/dist/session/session-id.mjs +20 -0
  440. package/dist/session/session-id.mjs.map +1 -0
  441. package/dist/session/session-user-afs.cjs +899 -0
  442. package/dist/session/session-user-afs.d.cts +296 -0
  443. package/dist/session/session-user-afs.d.cts.map +1 -0
  444. package/dist/session/session-user-afs.d.mts +296 -0
  445. package/dist/session/session-user-afs.d.mts.map +1 -0
  446. package/dist/session/session-user-afs.mjs +896 -0
  447. package/dist/session/session-user-afs.mjs.map +1 -0
  448. package/dist/session/settings-cascade.cjs +69 -0
  449. package/dist/session/settings-cascade.d.cts +81 -0
  450. package/dist/session/settings-cascade.d.cts.map +1 -0
  451. package/dist/session/settings-cascade.d.mts +81 -0
  452. package/dist/session/settings-cascade.d.mts.map +1 -0
  453. package/dist/session/settings-cascade.mjs +69 -0
  454. package/dist/session/settings-cascade.mjs.map +1 -0
  455. package/dist/session/settings-resolver.cjs +770 -0
  456. package/dist/session/settings-resolver.d.cts +177 -0
  457. package/dist/session/settings-resolver.d.cts.map +1 -0
  458. package/dist/session/settings-resolver.d.mts +177 -0
  459. package/dist/session/settings-resolver.d.mts.map +1 -0
  460. package/dist/session/settings-resolver.mjs +771 -0
  461. package/dist/session/settings-resolver.mjs.map +1 -0
  462. package/dist/session/settings-schema-store.cjs +0 -0
  463. package/dist/session/settings-schema-store.d.cts +72 -0
  464. package/dist/session/settings-schema-store.d.cts.map +1 -0
  465. package/dist/session/settings-schema-store.d.mts +72 -0
  466. package/dist/session/settings-schema-store.d.mts.map +1 -0
  467. package/dist/session/settings-schema-store.mjs +0 -0
  468. package/dist/session/settings-schema-store.mjs.map +1 -0
  469. package/dist/system-mounts/index.cjs +14 -0
  470. package/dist/system-mounts/index.d.cts +6 -0
  471. package/dist/system-mounts/index.d.mts +6 -0
  472. package/dist/system-mounts/index.mjs +6 -0
  473. package/dist/system-mounts/install.cjs +101 -0
  474. package/dist/system-mounts/install.d.cts +36 -0
  475. package/dist/system-mounts/install.d.cts.map +1 -0
  476. package/dist/system-mounts/install.d.mts +37 -0
  477. package/dist/system-mounts/install.d.mts.map +1 -0
  478. package/dist/system-mounts/install.mjs +102 -0
  479. package/dist/system-mounts/install.mjs.map +1 -0
  480. package/dist/system-mounts/installers.cjs +247 -0
  481. package/dist/system-mounts/installers.d.cts +13 -0
  482. package/dist/system-mounts/installers.d.cts.map +1 -0
  483. package/dist/system-mounts/installers.d.mts +14 -0
  484. package/dist/system-mounts/installers.d.mts.map +1 -0
  485. package/dist/system-mounts/installers.mjs +244 -0
  486. package/dist/system-mounts/installers.mjs.map +1 -0
  487. package/dist/system-mounts/lists.cjs +122 -0
  488. package/dist/system-mounts/lists.d.cts +34 -0
  489. package/dist/system-mounts/lists.d.cts.map +1 -0
  490. package/dist/system-mounts/lists.d.mts +34 -0
  491. package/dist/system-mounts/lists.d.mts.map +1 -0
  492. package/dist/system-mounts/lists.mjs +122 -0
  493. package/dist/system-mounts/lists.mjs.map +1 -0
  494. package/dist/system-mounts/types.d.cts +124 -0
  495. package/dist/system-mounts/types.d.cts.map +1 -0
  496. package/dist/system-mounts/types.d.mts +125 -0
  497. package/dist/system-mounts/types.d.mts.map +1 -0
  498. package/dist/system-mounts/validate.cjs +56 -0
  499. package/dist/system-mounts/validate.d.cts +34 -0
  500. package/dist/system-mounts/validate.d.cts.map +1 -0
  501. package/dist/system-mounts/validate.d.mts +34 -0
  502. package/dist/system-mounts/validate.d.mts.map +1 -0
  503. package/dist/system-mounts/validate.mjs +56 -0
  504. package/dist/system-mounts/validate.mjs.map +1 -0
  505. package/dist/terminal-llm.cjs +90 -0
  506. package/dist/terminal-llm.d.cts +50 -0
  507. package/dist/terminal-llm.d.cts.map +1 -0
  508. package/dist/terminal-llm.d.mts +50 -0
  509. package/dist/terminal-llm.d.mts.map +1 -0
  510. package/dist/terminal-llm.mjs +90 -0
  511. package/dist/terminal-llm.mjs.map +1 -0
  512. package/dist/terminal-repl.cjs +371 -0
  513. package/dist/terminal-repl.d.cts +69 -0
  514. package/dist/terminal-repl.d.cts.map +1 -0
  515. package/dist/terminal-repl.d.mts +69 -0
  516. package/dist/terminal-repl.d.mts.map +1 -0
  517. package/dist/terminal-repl.mjs +370 -0
  518. package/dist/terminal-repl.mjs.map +1 -0
  519. package/dist/transport/idle-timer.cjs +136 -0
  520. package/dist/transport/idle-timer.d.cts +92 -0
  521. package/dist/transport/idle-timer.d.cts.map +1 -0
  522. package/dist/transport/idle-timer.d.mts +92 -0
  523. package/dist/transport/idle-timer.d.mts.map +1 -0
  524. package/dist/transport/idle-timer.mjs +132 -0
  525. package/dist/transport/idle-timer.mjs.map +1 -0
  526. package/dist/web-component-dsl.cjs +153 -0
  527. package/dist/web-component-dsl.d.cts +27 -0
  528. package/dist/web-component-dsl.d.cts.map +1 -0
  529. package/dist/web-component-dsl.d.mts +27 -0
  530. package/dist/web-component-dsl.d.mts.map +1 -0
  531. package/dist/web-component-dsl.mjs +152 -0
  532. package/dist/web-component-dsl.mjs.map +1 -0
  533. package/package.json +81 -0
@@ -0,0 +1,370 @@
1
+ //#region src/terminal-repl.ts
2
+ const ARC_ART = ["▄▀█ █▀█ █▀▀", "█▀█ █▀▄ █▄▄"];
3
+ const TAGLINE = "Agentic Realm Computer";
4
+ const COPYRIGHT = "Copyright (c) 2026 ArcBlock Inc. All rights reserved.";
5
+ const R = "\x1B[0m";
6
+ const ART_GRADIENT = [[
7
+ 100,
8
+ 220,
9
+ 255
10
+ ], [
11
+ 180,
12
+ 120,
13
+ 255
14
+ ]];
15
+ const TAGLINE_GRADIENT = [
16
+ [
17
+ 100,
18
+ 255,
19
+ 255
20
+ ],
21
+ [
22
+ 80,
23
+ 220,
24
+ 255
25
+ ],
26
+ [
27
+ 60,
28
+ 180,
29
+ 255
30
+ ],
31
+ [
32
+ 100,
33
+ 140,
34
+ 255
35
+ ],
36
+ [
37
+ 180,
38
+ 120,
39
+ 255
40
+ ],
41
+ [
42
+ 220,
43
+ 100,
44
+ 255
45
+ ]
46
+ ];
47
+ function interpColor(t, stops) {
48
+ const scaled = t * (stops.length - 1);
49
+ const i = Math.min(Math.floor(scaled), stops.length - 2);
50
+ const frac = scaled - i;
51
+ const a = stops[i] ?? [
52
+ 0,
53
+ 0,
54
+ 0
55
+ ];
56
+ const b = stops[i + 1] ?? [
57
+ 0,
58
+ 0,
59
+ 0
60
+ ];
61
+ return [
62
+ Math.round(a[0] + (b[0] - a[0]) * frac),
63
+ Math.round(a[1] + (b[1] - a[1]) * frac),
64
+ Math.round(a[2] + (b[2] - a[2]) * frac)
65
+ ];
66
+ }
67
+ function rainbowText(text) {
68
+ const chars = [...text];
69
+ return chars.map((ch, i) => {
70
+ if (ch === " ") return ch;
71
+ const [r, g, b] = interpColor(chars.length > 1 ? i / (chars.length - 1) : 0, TAGLINE_GRADIENT);
72
+ return `\x1b[38;2;${r};${g};${b}m${ch}${R}`;
73
+ }).join("");
74
+ }
75
+ /**
76
+ * Render the ARC terminal banner.
77
+ *
78
+ * Uses 24-bit truecolor gradient (matches Node splash.ts exactly).
79
+ *
80
+ * Output (colored):
81
+ * ▄▀█ █▀█ █▀▀ Agentic Realm Computer
82
+ * █▀█ █▀▄ █▄▄ v1.0.0 (abc1234) · 2026-04-23
83
+ * Copyright (c) 2026 ArcBlock Inc. All rights reserved.
84
+ *
85
+ * Session: <id> · N providers · Type help for commands.
86
+ */
87
+ function renderArcBanner(opts) {
88
+ const color = opts.color !== false;
89
+ const { version, commit, date, providerCount, sessionId } = opts;
90
+ const tc = (rgb, s) => color ? `\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m${s}${R}` : s;
91
+ const cyan = (s) => color ? `\x1b[96m${s}${R}` : s;
92
+ const dim = (s) => color ? `\x1b[2m${s}${R}` : s;
93
+ const art = ARC_ART.map((line, i) => color ? tc(ART_GRADIENT[i], line) : line);
94
+ const tagline = color ? rainbowText(TAGLINE) : TAGLINE;
95
+ const versionStr = [
96
+ cyan(`v${version}`),
97
+ dim(`(${commit})`),
98
+ dim("·"),
99
+ dim(date)
100
+ ].join(" ");
101
+ const copyrightStr = dim(COPYRIGHT);
102
+ const gap = " ";
103
+ const lines = [
104
+ ` ${art[0]}${gap}${tagline}`,
105
+ ` ${art[1]}${gap}${versionStr}`,
106
+ ` ${copyrightStr}`
107
+ ];
108
+ if (providerCount !== void 0 || sessionId) {
109
+ const parts = [];
110
+ if (sessionId) parts.push(`Session: ${dim(sessionId)}`);
111
+ if (providerCount !== void 0) {
112
+ const plural = providerCount === 1 ? "provider" : "providers";
113
+ parts.push(`${providerCount} ${plural}`);
114
+ }
115
+ parts.push(`Type ${cyan("help")} for commands.`);
116
+ lines.push("", ` ${parts.join(dim(" · "))}`);
117
+ }
118
+ return lines.join("\r\n");
119
+ }
120
+ /** Generate a random hex session ID. */
121
+ function genSessionId() {
122
+ const arr = new Uint8Array(8);
123
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) crypto.getRandomValues(arr);
124
+ else for (let i = 0; i < arr.length; i++) arr[i] = Math.floor(Math.random() * 256);
125
+ return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
126
+ }
127
+ function resolvePath(cwd, raw) {
128
+ if (!raw || raw === ".") return cwd;
129
+ const parts = (raw.startsWith("/") ? raw : `${cwd === "/" ? "" : cwd}/${raw}`).split("/").filter(Boolean);
130
+ const resolved = [];
131
+ for (const p of parts) if (p === "..") resolved.pop();
132
+ else if (p !== ".") resolved.push(p);
133
+ return `/${resolved.join("/")}`;
134
+ }
135
+ function parseArgs(input) {
136
+ const args = [];
137
+ let current = "";
138
+ let quote = null;
139
+ for (const ch of input) if (quote) if (ch === quote) quote = null;
140
+ else current += ch;
141
+ else if (ch === "\"" || ch === "'") quote = ch;
142
+ else if (ch === " " || ch === " ") {
143
+ if (current) {
144
+ args.push(current);
145
+ current = "";
146
+ }
147
+ } else current += ch;
148
+ if (current) args.push(current);
149
+ return args;
150
+ }
151
+ function makeAnsi(color) {
152
+ const r = color ? "\x1B[0m" : "";
153
+ const red = color ? "\x1B[31m" : "";
154
+ const blue = color ? "\x1B[34m" : "";
155
+ const yellow = color ? "\x1B[33m" : "";
156
+ const bold = color ? "\x1B[1m" : "";
157
+ return {
158
+ r,
159
+ red,
160
+ blue,
161
+ yellow,
162
+ bold,
163
+ err: (msg) => `${red}Error:${r} ${msg}`,
164
+ help: () => [
165
+ `${bold}Available commands:${r}`,
166
+ "",
167
+ ` ${bold}AFS Commands:${r}`,
168
+ ` ${yellow}ls${r} [path] List directory contents (default: current dir)`,
169
+ ` ${yellow}read${r} <path> Read file content`,
170
+ ` ${yellow}write${r} <path> <content> Write content to file`,
171
+ ` ${yellow}stat${r} [path] Get file or directory info`,
172
+ ` ${yellow}exec${r} <path> [args] Execute an action`,
173
+ ` ${yellow}explain${r} [path] Explain path capabilities`,
174
+ ` ${yellow}search${r} <path> <query> Search content`,
175
+ "",
176
+ ` ${bold}REPL Commands:${r}`,
177
+ ` ${yellow}cd${r} [path] Change working directory`,
178
+ ` ${yellow}pwd${r} Print working directory`,
179
+ ` ${yellow}help${r} Show this help`,
180
+ ` ${yellow}clear${r} Clear screen`,
181
+ ` ${yellow}exit${r} / ${yellow}quit${r} Exit session`
182
+ ].join("\r\n")
183
+ };
184
+ }
185
+ async function cmdLs(afs, path, ansi) {
186
+ try {
187
+ const items = (await afs.list(path, { maxDepth: 1 })).data ?? [];
188
+ if (!items.length) return "(empty)";
189
+ return items.map((e) => {
190
+ const isDir = e.meta?.kind === "directory" || (e.meta?.childrenCount ?? 0) > 0;
191
+ const name = e.path.split("/").at(-1) ?? e.path;
192
+ return isDir ? `${ansi.blue}${name}/${ansi.r}` : name;
193
+ }).join("\r\n");
194
+ } catch (e) {
195
+ return ansi.err(e instanceof Error ? e.message : String(e));
196
+ }
197
+ }
198
+ async function cmdRead(afs, path, ansi) {
199
+ try {
200
+ const content = (await afs.read(path)).data?.content;
201
+ if (content === void 0 || content === null) return ansi.err("Not found or not readable");
202
+ if (typeof content === "string") return content;
203
+ if (content instanceof Uint8Array) return new TextDecoder().decode(content);
204
+ return JSON.stringify(content, null, 2);
205
+ } catch (e) {
206
+ const msg = e instanceof Error ? e.message : String(e);
207
+ if (/not found|ENOENT/i.test(msg)) return ansi.err(`Not found: ${path}`);
208
+ return ansi.err(msg);
209
+ }
210
+ }
211
+ async function cmdWrite(afs, path, content, ansi) {
212
+ try {
213
+ await afs.write(path, { content });
214
+ return `Written: ${path}`;
215
+ } catch (e) {
216
+ return ansi.err(e instanceof Error ? e.message : String(e));
217
+ }
218
+ }
219
+ async function cmdStat(afs, path, ansi) {
220
+ try {
221
+ const meta = (await afs.stat(path))?.data?.meta ?? {};
222
+ const lines = [`${ansi.bold}Path:${ansi.r} ${path}`];
223
+ for (const [k, v] of Object.entries(meta)) if (v !== void 0 && v !== null) lines.push(`${ansi.yellow}${k}:${ansi.r} ${JSON.stringify(v)}`);
224
+ return lines.join("\r\n");
225
+ } catch (e) {
226
+ const msg = e instanceof Error ? e.message : String(e);
227
+ if (/not found|ENOENT/i.test(msg)) return ansi.err(`Not found: ${path}`);
228
+ return ansi.err(msg);
229
+ }
230
+ }
231
+ async function cmdExec(afs, path, args, ansi) {
232
+ try {
233
+ const data = (await afs.exec(path, args))?.data;
234
+ if (data === void 0 || data === null) return "(no output)";
235
+ if (typeof data === "string") return data;
236
+ return JSON.stringify(data, null, 2);
237
+ } catch (e) {
238
+ return ansi.err(e instanceof Error ? e.message : String(e));
239
+ }
240
+ }
241
+ async function cmdExplain(afs, path, ansi) {
242
+ try {
243
+ const result = await afs.explain(path);
244
+ if (!result) return "(no explanation)";
245
+ return result.content ?? "(no explanation)";
246
+ } catch (e) {
247
+ return ansi.err(e instanceof Error ? e.message : String(e));
248
+ }
249
+ }
250
+ async function cmdSearch(afs, path, query, ansi) {
251
+ try {
252
+ const items = (await afs.search(path, query))?.data ?? [];
253
+ if (!Array.isArray(items) || !items.length) return "(no results)";
254
+ return items.map((e) => {
255
+ const entry = e;
256
+ return typeof entry.path === "string" ? entry.path : JSON.stringify(e);
257
+ }).join("\r\n");
258
+ } catch (e) {
259
+ return ansi.err(e instanceof Error ? e.message : String(e));
260
+ }
261
+ }
262
+ async function cmdCd(afs, cwd, target) {
263
+ const newCwd = resolvePath(cwd, target);
264
+ if (newCwd === "/") return { newCwd };
265
+ try {
266
+ const meta = (await afs.stat(newCwd))?.data?.meta ?? {};
267
+ if (!(meta.kind === "directory" || meta.childrenCount !== void 0 || newCwd.split("/").filter(Boolean).length === 1)) return {
268
+ newCwd: cwd,
269
+ error: `Not a directory: ${newCwd}`
270
+ };
271
+ return { newCwd };
272
+ } catch {
273
+ try {
274
+ await afs.list(newCwd, { maxDepth: 1 });
275
+ return { newCwd };
276
+ } catch {
277
+ return {
278
+ newCwd: cwd,
279
+ error: `Not found: ${newCwd}`
280
+ };
281
+ }
282
+ }
283
+ }
284
+ /**
285
+ * Create a platform-agnostic AFS REPL session.
286
+ *
287
+ * Used by both the CF Worker terminal and the Node daemon terminal.
288
+ * Transport (WebSocket send/receive) is handled by the caller.
289
+ */
290
+ function createAfsReplSession(afs, opts) {
291
+ const sessionId = genSessionId();
292
+ const ansi = makeAnsi(opts.color !== false);
293
+ let cwd = "/";
294
+ let cachedProviderCount = null;
295
+ return {
296
+ sessionId,
297
+ getPrompt() {
298
+ return `afs ${cwd === "/" ? "/" : cwd.split("/").at(-1)}> `;
299
+ },
300
+ async countProviders() {
301
+ if (cachedProviderCount !== null) return cachedProviderCount;
302
+ try {
303
+ const result = await afs.list("/");
304
+ const seen = /* @__PURE__ */ new Set();
305
+ for (const e of result.data ?? []) if (typeof e?.path === "string") seen.add(e.path);
306
+ cachedProviderCount = seen.size || 0;
307
+ } catch {
308
+ cachedProviderCount = 0;
309
+ }
310
+ return cachedProviderCount;
311
+ },
312
+ async route(line) {
313
+ const trimmed = line.trim();
314
+ if (!trimmed) return {};
315
+ const args = parseArgs(trimmed.startsWith("afs ") ? trimmed.slice(4).trim() : trimmed);
316
+ const cmd = args[0]?.toLowerCase() ?? "";
317
+ switch (cmd) {
318
+ case "ls": {
319
+ const rawPath = args[1] ?? cwd;
320
+ return { output: await cmdLs(afs, resolvePath(cwd, rawPath), ansi) };
321
+ }
322
+ case "read":
323
+ case "cat":
324
+ if (!args[1]) return { output: ansi.err("Usage: read <path>") };
325
+ return { output: (await cmdRead(afs, resolvePath(cwd, args[1]), ansi)).replace(/\n/g, "\r\n") };
326
+ case "write":
327
+ if (!args[1]) return { output: ansi.err("Usage: write <path> <content>") };
328
+ return { output: await cmdWrite(afs, resolvePath(cwd, args[1]), args.slice(2).join(" "), ansi) };
329
+ case "stat": {
330
+ const rawPath = args[1] ?? cwd;
331
+ return { output: await cmdStat(afs, resolvePath(cwd, rawPath), ansi) };
332
+ }
333
+ case "exec": {
334
+ if (!args[1]) return { output: ansi.err("Usage: exec <path> [args...]") };
335
+ const path = resolvePath(cwd, args[1]);
336
+ const execArgs = {};
337
+ for (let i = 2; i < args.length; i++) {
338
+ const kv = args[i].split("=");
339
+ if (kv.length === 2) execArgs[kv[0]] = kv[1];
340
+ else execArgs[`arg${i - 2}`] = args[i];
341
+ }
342
+ return { output: await cmdExec(afs, path, execArgs, ansi) };
343
+ }
344
+ case "explain": {
345
+ const rawPath = args[1] ?? cwd;
346
+ return { output: await cmdExplain(afs, resolvePath(cwd, rawPath), ansi) };
347
+ }
348
+ case "search":
349
+ if (!args[1] || !args[2]) return { output: ansi.err("Usage: search <path> <query>") };
350
+ return { output: await cmdSearch(afs, resolvePath(cwd, args[1]), args.slice(2).join(" "), ansi) };
351
+ case "cd": {
352
+ const target = args[1] ?? "/";
353
+ const { newCwd, error } = await cmdCd(afs, cwd, target);
354
+ cwd = newCwd;
355
+ return { output: error ? ansi.err(error) : void 0 };
356
+ }
357
+ case "pwd": return { output: cwd };
358
+ case "help": return { output: ansi.help() };
359
+ case "clear": return { clear: true };
360
+ case "exit":
361
+ case "quit": return { exit: true };
362
+ default: return { output: `${ansi.err(`Unknown command: ${cmd}`)} — type ${ansi.yellow}help${ansi.r} for available commands` };
363
+ }
364
+ }
365
+ };
366
+ }
367
+
368
+ //#endregion
369
+ export { createAfsReplSession, renderArcBanner };
370
+ //# sourceMappingURL=terminal-repl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-repl.mjs","names":[],"sources":["../src/terminal-repl.ts"],"sourcesContent":["/**\n * Shared AFS terminal REPL — portable, CF-compatible.\n *\n * Contains the business logic for the AFS interactive terminal:\n * - ARC banner rendering (ASCII art, version, session info)\n * - REPL session factory (command routing, cwd management)\n *\n * No Node.js APIs. Usable in Cloudflare Workers, Node, Bun, browsers.\n *\n * Transport (WebSocket / readline) is left to the caller:\n * - CF Worker: runtimes/cloudflare/src/terminal-handler.ts\n * - Node daemon: runtimes/node/src/daemon/server.ts\n */\n\nimport type { AFS } from \"@aigne/afs\";\n\n// ---------------------------------------------------------------------------\n// Banner\n// ---------------------------------------------------------------------------\n\nconst ARC_ART = [\"▄▀█ █▀█ █▀▀\", \"█▀█ █▀▄ █▄▄\"];\nconst TAGLINE = \"Agentic Realm Computer\";\nconst COPYRIGHT = \"Copyright (c) 2026 ArcBlock Inc. All rights reserved.\";\nconst R = \"\\x1b[0m\";\n\n// Truecolor gradient for ASCII art: light cyan → purple (matches splash.ts)\nconst ART_GRADIENT: readonly [number, number, number][] = [\n [100, 220, 255],\n [180, 120, 255],\n];\n\n// Per-character tagline gradient (matches splash.ts TAGLINE_TRUECOLOR)\nconst TAGLINE_GRADIENT: readonly [number, number, number][] = [\n [100, 255, 255],\n [80, 220, 255],\n [60, 180, 255],\n [100, 140, 255],\n [180, 120, 255],\n [220, 100, 255],\n];\n\nfunction interpColor(\n t: number,\n stops: readonly (readonly [number, number, number])[],\n): [number, number, number] {\n const scaled = t * (stops.length - 1);\n const i = Math.min(Math.floor(scaled), stops.length - 2);\n const frac = scaled - i;\n const a = stops[i] ?? [0, 0, 0];\n const b = stops[i + 1] ?? [0, 0, 0];\n return [\n Math.round(a[0] + (b[0] - a[0]) * frac),\n Math.round(a[1] + (b[1] - a[1]) * frac),\n Math.round(a[2] + (b[2] - a[2]) * frac),\n ];\n}\n\nfunction rainbowText(text: string): string {\n const chars = [...text];\n return chars\n .map((ch, i) => {\n if (ch === \" \") return ch;\n const t = chars.length > 1 ? i / (chars.length - 1) : 0;\n const [r, g, b] = interpColor(t, TAGLINE_GRADIENT);\n return `\\x1b[38;2;${r};${g};${b}m${ch}${R}`;\n })\n .join(\"\");\n}\n\nexport interface BannerOptions {\n version: string;\n commit: string;\n date: string;\n /** Provider count to display in the session line. */\n providerCount?: number;\n /** Session ID to display in the session line. */\n sessionId?: string;\n /** Use ANSI color codes. Default: true. */\n color?: boolean;\n}\n\n/**\n * Render the ARC terminal banner.\n *\n * Uses 24-bit truecolor gradient (matches Node splash.ts exactly).\n *\n * Output (colored):\n * ▄▀█ █▀█ █▀▀ Agentic Realm Computer\n * █▀█ █▀▄ █▄▄ v1.0.0 (abc1234) · 2026-04-23\n * Copyright (c) 2026 ArcBlock Inc. All rights reserved.\n *\n * Session: <id> · N providers · Type help for commands.\n */\nexport function renderArcBanner(opts: BannerOptions): string {\n const color = opts.color !== false;\n const { version, commit, date, providerCount, sessionId } = opts;\n\n const tc = (rgb: readonly [number, number, number], s: string) =>\n color ? `\\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m${s}${R}` : s;\n const cyan = (s: string) => (color ? `\\x1b[96m${s}${R}` : s);\n const dim = (s: string) => (color ? `\\x1b[2m${s}${R}` : s);\n\n const art = ARC_ART.map((line, i) => (color ? tc(ART_GRADIENT[i]!, line) : line));\n const tagline = color ? rainbowText(TAGLINE) : TAGLINE;\n const versionStr = [cyan(`v${version}`), dim(`(${commit})`), dim(\"·\"), dim(date)].join(\" \");\n const copyrightStr = dim(COPYRIGHT);\n const gap = \" \";\n\n const lines: string[] = [\n ` ${art[0]}${gap}${tagline}`,\n ` ${art[1]}${gap}${versionStr}`,\n ` ${copyrightStr}`,\n ];\n\n if (providerCount !== undefined || sessionId) {\n const parts: string[] = [];\n if (sessionId) parts.push(`Session: ${dim(sessionId)}`);\n if (providerCount !== undefined) {\n const plural = providerCount === 1 ? \"provider\" : \"providers\";\n parts.push(`${providerCount} ${plural}`);\n }\n parts.push(`Type ${cyan(\"help\")} for commands.`);\n lines.push(\"\", ` ${parts.join(dim(\" · \"))}`);\n }\n\n return lines.join(\"\\r\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Session\n// ---------------------------------------------------------------------------\n\nexport interface AfsReplResult {\n /** Text to display in the terminal (pre-formatted, CRLF line endings). */\n output?: string;\n /** If true, the terminal should clear its screen. */\n clear?: boolean;\n /** If true, the session is ending; caller should close the connection. */\n exit?: boolean;\n}\n\nexport interface AfsReplSession {\n /** Unique session ID (hex string). */\n readonly sessionId: string;\n /** Get current prompt string (e.g. `afs data> `). */\n getPrompt(): string;\n /**\n * Count mounted providers via `afs.list(\"/\")`.\n * Safe to call before the first command — result is cached.\n */\n countProviders(): Promise<number>;\n /**\n * Route a line of user input.\n * Handles builtins (cd, pwd, help, clear, exit) and AFS primitives\n * (ls, read, write, stat, exec, explain, search).\n */\n route(line: string): Promise<AfsReplResult>;\n}\n\nexport interface AfsReplOptions {\n version: string;\n commit: string;\n date: string;\n /** Use ANSI color. Default: true. */\n color?: boolean;\n}\n\n/** Generate a random hex session ID. */\nfunction genSessionId(): string {\n const arr = new Uint8Array(8);\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(arr);\n } else {\n for (let i = 0; i < arr.length; i++) arr[i] = Math.floor(Math.random() * 256);\n }\n return Array.from(arr, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Path helpers\n// ---------------------------------------------------------------------------\n\nfunction resolvePath(cwd: string, raw: string): string {\n if (!raw || raw === \".\") return cwd;\n const absolute = raw.startsWith(\"/\") ? raw : `${cwd === \"/\" ? \"\" : cwd}/${raw}`;\n const parts = absolute.split(\"/\").filter(Boolean);\n const resolved: string[] = [];\n for (const p of parts) {\n if (p === \"..\") resolved.pop();\n else if (p !== \".\") resolved.push(p);\n }\n return `/${resolved.join(\"/\")}`;\n}\n\n// ---------------------------------------------------------------------------\n// Arg parser\n// ---------------------------------------------------------------------------\n\nfunction parseArgs(input: string): string[] {\n const args: string[] = [];\n let current = \"\";\n let quote: '\"' | \"'\" | null = null;\n for (const ch of input) {\n if (quote) {\n if (ch === quote) quote = null;\n else current += ch;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n } else if (ch === \" \" || ch === \"\\t\") {\n if (current) {\n args.push(current);\n current = \"\";\n }\n } else {\n current += ch;\n }\n }\n if (current) args.push(current);\n return args;\n}\n\n// ---------------------------------------------------------------------------\n// Color helpers (injected from opts.color)\n// ---------------------------------------------------------------------------\n\ninterface Ansi {\n r: string;\n red: string;\n blue: string;\n yellow: string;\n bold: string;\n err(msg: string): string;\n help(): string;\n}\n\nfunction makeAnsi(color: boolean): Ansi {\n const r = color ? \"\\x1b[0m\" : \"\";\n const red = color ? \"\\x1b[31m\" : \"\";\n const blue = color ? \"\\x1b[34m\" : \"\";\n const yellow = color ? \"\\x1b[33m\" : \"\";\n const bold = color ? \"\\x1b[1m\" : \"\";\n return {\n r,\n red,\n blue,\n yellow,\n bold,\n err: (msg) => `${red}Error:${r} ${msg}`,\n help: () =>\n [\n `${bold}Available commands:${r}`,\n \"\",\n ` ${bold}AFS Commands:${r}`,\n ` ${yellow}ls${r} [path] List directory contents (default: current dir)`,\n ` ${yellow}read${r} <path> Read file content`,\n ` ${yellow}write${r} <path> <content> Write content to file`,\n ` ${yellow}stat${r} [path] Get file or directory info`,\n ` ${yellow}exec${r} <path> [args] Execute an action`,\n ` ${yellow}explain${r} [path] Explain path capabilities`,\n ` ${yellow}search${r} <path> <query> Search content`,\n \"\",\n ` ${bold}REPL Commands:${r}`,\n ` ${yellow}cd${r} [path] Change working directory`,\n ` ${yellow}pwd${r} Print working directory`,\n ` ${yellow}help${r} Show this help`,\n ` ${yellow}clear${r} Clear screen`,\n ` ${yellow}exit${r} / ${yellow}quit${r} Exit session`,\n ].join(\"\\r\\n\"),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Command implementations (pure AFS API calls, color-aware)\n// ---------------------------------------------------------------------------\n\nasync function cmdLs(afs: AFS, path: string, ansi: Ansi): Promise<string> {\n try {\n const result = await afs.list(path, { maxDepth: 1 });\n const items = result.data ?? [];\n if (!items.length) return \"(empty)\";\n return items\n .map((e) => {\n const isDir =\n (e.meta as Record<string, unknown> | undefined)?.kind === \"directory\" ||\n (((e.meta as Record<string, unknown> | undefined)?.childrenCount as number | undefined) ??\n 0) > 0;\n const name = e.path.split(\"/\").at(-1) ?? e.path;\n return isDir ? `${ansi.blue}${name}/${ansi.r}` : name;\n })\n .join(\"\\r\\n\");\n } catch (e) {\n return ansi.err(e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function cmdRead(afs: AFS, path: string, ansi: Ansi): Promise<string> {\n try {\n const result = await afs.read(path);\n const content = result.data?.content;\n if (content === undefined || content === null) return ansi.err(\"Not found or not readable\");\n if (typeof content === \"string\") return content;\n if (content instanceof Uint8Array) return new TextDecoder().decode(content);\n return JSON.stringify(content, null, 2);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (/not found|ENOENT/i.test(msg)) return ansi.err(`Not found: ${path}`);\n return ansi.err(msg);\n }\n}\n\nasync function cmdWrite(afs: AFS, path: string, content: string, ansi: Ansi): Promise<string> {\n try {\n await afs.write(path, { content });\n return `Written: ${path}`;\n } catch (e) {\n return ansi.err(e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function cmdStat(afs: AFS, path: string, ansi: Ansi): Promise<string> {\n try {\n const result = await afs.stat(path);\n const meta = (result?.data?.meta as Record<string, unknown>) ?? {};\n const lines = [`${ansi.bold}Path:${ansi.r} ${path}`];\n for (const [k, v] of Object.entries(meta)) {\n if (v !== undefined && v !== null)\n lines.push(`${ansi.yellow}${k}:${ansi.r} ${JSON.stringify(v)}`);\n }\n return lines.join(\"\\r\\n\");\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (/not found|ENOENT/i.test(msg)) return ansi.err(`Not found: ${path}`);\n return ansi.err(msg);\n }\n}\n\nasync function cmdExec(\n afs: AFS,\n path: string,\n args: Record<string, unknown>,\n ansi: Ansi,\n): Promise<string> {\n try {\n const result = await afs.exec(path, args);\n const data = result?.data;\n if (data === undefined || data === null) return \"(no output)\";\n if (typeof data === \"string\") return data;\n return JSON.stringify(data, null, 2);\n } catch (e) {\n return ansi.err(e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function cmdExplain(afs: AFS, path: string, ansi: Ansi): Promise<string> {\n try {\n const result = await afs.explain(path);\n if (!result) return \"(no explanation)\";\n return result.content ?? \"(no explanation)\";\n } catch (e) {\n return ansi.err(e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function cmdSearch(afs: AFS, path: string, query: string, ansi: Ansi): Promise<string> {\n try {\n const result = await afs.search(path, query);\n const items = result?.data ?? [];\n if (!Array.isArray(items) || !items.length) return \"(no results)\";\n return items\n .map((e: unknown) => {\n const entry = e as Record<string, unknown>;\n return typeof entry.path === \"string\" ? entry.path : JSON.stringify(e);\n })\n .join(\"\\r\\n\");\n } catch (e) {\n return ansi.err(e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function cmdCd(\n afs: AFS,\n cwd: string,\n target: string,\n): Promise<{ newCwd: string; error?: string }> {\n const newCwd = resolvePath(cwd, target);\n if (newCwd === \"/\") return { newCwd };\n try {\n const result = await afs.stat(newCwd);\n const meta = (result?.data?.meta as Record<string, unknown>) ?? {};\n const isDir =\n meta.kind === \"directory\" ||\n meta.childrenCount !== undefined ||\n newCwd.split(\"/\").filter(Boolean).length === 1;\n if (!isDir) return { newCwd: cwd, error: `Not a directory: ${newCwd}` };\n return { newCwd };\n } catch {\n try {\n await afs.list(newCwd, { maxDepth: 1 });\n return { newCwd };\n } catch {\n return { newCwd: cwd, error: `Not found: ${newCwd}` };\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a platform-agnostic AFS REPL session.\n *\n * Used by both the CF Worker terminal and the Node daemon terminal.\n * Transport (WebSocket send/receive) is handled by the caller.\n */\nexport function createAfsReplSession(afs: AFS, opts: AfsReplOptions): AfsReplSession {\n const sessionId = genSessionId();\n const ansi = makeAnsi(opts.color !== false);\n let cwd = \"/\";\n let cachedProviderCount: number | null = null;\n\n return {\n sessionId,\n\n getPrompt(): string {\n const dir = cwd === \"/\" ? \"/\" : cwd.split(\"/\").at(-1);\n return `afs ${dir}> `;\n },\n\n async countProviders(): Promise<number> {\n if (cachedProviderCount !== null) return cachedProviderCount;\n try {\n const result = await afs.list(\"/\");\n const seen = new Set<string>();\n for (const e of result.data ?? []) {\n if (typeof e?.path === \"string\") seen.add(e.path);\n }\n cachedProviderCount = seen.size || 0;\n } catch {\n cachedProviderCount = 0;\n }\n return cachedProviderCount;\n },\n\n async route(line: string): Promise<AfsReplResult> {\n const trimmed = line.trim();\n if (!trimmed) return {};\n\n // Strip optional \"afs \" prefix (users may type `afs ls /`)\n const input = trimmed.startsWith(\"afs \") ? trimmed.slice(4).trim() : trimmed;\n const args = parseArgs(input);\n const cmd = args[0]?.toLowerCase() ?? \"\";\n\n switch (cmd) {\n case \"ls\": {\n const rawPath = args[1] ?? cwd;\n const path = resolvePath(cwd, rawPath);\n return { output: await cmdLs(afs, path, ansi) };\n }\n case \"read\":\n case \"cat\": {\n if (!args[1]) return { output: ansi.err(\"Usage: read <path>\") };\n const path = resolvePath(cwd, args[1]);\n const out = await cmdRead(afs, path, ansi);\n return { output: out.replace(/\\n/g, \"\\r\\n\") };\n }\n case \"write\": {\n if (!args[1]) return { output: ansi.err(\"Usage: write <path> <content>\") };\n const path = resolvePath(cwd, args[1]);\n const content = args.slice(2).join(\" \");\n return { output: await cmdWrite(afs, path, content, ansi) };\n }\n case \"stat\": {\n const rawPath = args[1] ?? cwd;\n const path = resolvePath(cwd, rawPath);\n return { output: await cmdStat(afs, path, ansi) };\n }\n case \"exec\": {\n if (!args[1]) return { output: ansi.err(\"Usage: exec <path> [args...]\") };\n const path = resolvePath(cwd, args[1]);\n const execArgs: Record<string, unknown> = {};\n for (let i = 2; i < args.length; i++) {\n const kv = args[i]!.split(\"=\");\n if (kv.length === 2) execArgs[kv[0]!] = kv[1];\n else execArgs[`arg${i - 2}`] = args[i];\n }\n return { output: await cmdExec(afs, path, execArgs, ansi) };\n }\n case \"explain\": {\n const rawPath = args[1] ?? cwd;\n const path = resolvePath(cwd, rawPath);\n return { output: await cmdExplain(afs, path, ansi) };\n }\n case \"search\": {\n if (!args[1] || !args[2]) return { output: ansi.err(\"Usage: search <path> <query>\") };\n const path = resolvePath(cwd, args[1]);\n const query = args.slice(2).join(\" \");\n return { output: await cmdSearch(afs, path, query, ansi) };\n }\n case \"cd\": {\n const target = args[1] ?? \"/\";\n const { newCwd, error } = await cmdCd(afs, cwd, target);\n cwd = newCwd;\n return { output: error ? ansi.err(error) : undefined };\n }\n case \"pwd\":\n return { output: cwd };\n case \"help\":\n return { output: ansi.help() };\n case \"clear\":\n return { clear: true };\n case \"exit\":\n case \"quit\":\n return { exit: true };\n default:\n return {\n output: `${ansi.err(`Unknown command: ${cmd}`)} — type ${ansi.yellow}help${ansi.r} for available commands`,\n };\n }\n },\n };\n}\n"],"mappings":";AAoBA,MAAM,UAAU,CAAC,eAAe,cAAc;AAC9C,MAAM,UAAU;AAChB,MAAM,YAAY;AAClB,MAAM,IAAI;AAGV,MAAM,eAAoD,CACxD;CAAC;CAAK;CAAK;CAAI,EACf;CAAC;CAAK;CAAK;CAAI,CAChB;AAGD,MAAM,mBAAwD;CAC5D;EAAC;EAAK;EAAK;EAAI;CACf;EAAC;EAAI;EAAK;EAAI;CACd;EAAC;EAAI;EAAK;EAAI;CACd;EAAC;EAAK;EAAK;EAAI;CACf;EAAC;EAAK;EAAK;EAAI;CACf;EAAC;EAAK;EAAK;EAAI;CAChB;AAED,SAAS,YACP,GACA,OAC0B;CAC1B,MAAM,SAAS,KAAK,MAAM,SAAS;CACnC,MAAM,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,EAAE,MAAM,SAAS,EAAE;CACxD,MAAM,OAAO,SAAS;CACtB,MAAM,IAAI,MAAM,MAAM;EAAC;EAAG;EAAG;EAAE;CAC/B,MAAM,IAAI,MAAM,IAAI,MAAM;EAAC;EAAG;EAAG;EAAE;AACnC,QAAO;EACL,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;EACvC,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;EACvC,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;EACxC;;AAGH,SAAS,YAAY,MAAsB;CACzC,MAAM,QAAQ,CAAC,GAAG,KAAK;AACvB,QAAO,MACJ,KAAK,IAAI,MAAM;AACd,MAAI,OAAO,IAAK,QAAO;EAEvB,MAAM,CAAC,GAAG,GAAG,KAAK,YADR,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,KAAK,GACrB,iBAAiB;AAClD,SAAO,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK;GACxC,CACD,KAAK,GAAG;;;;;;;;;;;;;;AA2Bb,SAAgB,gBAAgB,MAA6B;CAC3D,MAAM,QAAQ,KAAK,UAAU;CAC7B,MAAM,EAAE,SAAS,QAAQ,MAAM,eAAe,cAAc;CAE5D,MAAM,MAAM,KAAwC,MAClD,QAAQ,aAAa,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,MAAM;CAC/D,MAAM,QAAQ,MAAe,QAAQ,WAAW,IAAI,MAAM;CAC1D,MAAM,OAAO,MAAe,QAAQ,UAAU,IAAI,MAAM;CAExD,MAAM,MAAM,QAAQ,KAAK,MAAM,MAAO,QAAQ,GAAG,aAAa,IAAK,KAAK,GAAG,KAAM;CACjF,MAAM,UAAU,QAAQ,YAAY,QAAQ,GAAG;CAC/C,MAAM,aAAa;EAAC,KAAK,IAAI,UAAU;EAAE,IAAI,IAAI,OAAO,GAAG;EAAE,IAAI,IAAI;EAAE,IAAI,KAAK;EAAC,CAAC,KAAK,IAAI;CAC3F,MAAM,eAAe,IAAI,UAAU;CACnC,MAAM,MAAM;CAEZ,MAAM,QAAkB;EACtB,KAAK,IAAI,KAAK,MAAM;EACpB,KAAK,IAAI,KAAK,MAAM;EACpB,KAAK;EACN;AAED,KAAI,kBAAkB,UAAa,WAAW;EAC5C,MAAM,QAAkB,EAAE;AAC1B,MAAI,UAAW,OAAM,KAAK,YAAY,IAAI,UAAU,GAAG;AACvD,MAAI,kBAAkB,QAAW;GAC/B,MAAM,SAAS,kBAAkB,IAAI,aAAa;AAClD,SAAM,KAAK,GAAG,cAAc,GAAG,SAAS;;AAE1C,QAAM,KAAK,QAAQ,KAAK,OAAO,CAAC,gBAAgB;AAChD,QAAM,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG;;AAG/C,QAAO,MAAM,KAAK,OAAO;;;AA2C3B,SAAS,eAAuB;CAC9B,MAAM,MAAM,IAAI,WAAW,EAAE;AAC7B,KAAI,OAAO,WAAW,eAAe,OAAO,gBAC1C,QAAO,gBAAgB,IAAI;KAE3B,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,KAAI,KAAK,KAAK,MAAM,KAAK,QAAQ,GAAG,IAAI;AAE/E,QAAO,MAAM,KAAK,MAAM,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG;;AAOzE,SAAS,YAAY,KAAa,KAAqB;AACrD,KAAI,CAAC,OAAO,QAAQ,IAAK,QAAO;CAEhC,MAAM,SADW,IAAI,WAAW,IAAI,GAAG,MAAM,GAAG,QAAQ,MAAM,KAAK,IAAI,GAAG,OACnD,MAAM,IAAI,CAAC,OAAO,QAAQ;CACjD,MAAM,WAAqB,EAAE;AAC7B,MAAK,MAAM,KAAK,MACd,KAAI,MAAM,KAAM,UAAS,KAAK;UACrB,MAAM,IAAK,UAAS,KAAK,EAAE;AAEtC,QAAO,IAAI,SAAS,KAAK,IAAI;;AAO/B,SAAS,UAAU,OAAyB;CAC1C,MAAM,OAAiB,EAAE;CACzB,IAAI,UAAU;CACd,IAAI,QAA0B;AAC9B,MAAK,MAAM,MAAM,MACf,KAAI,MACF,KAAI,OAAO,MAAO,SAAQ;KACrB,YAAW;UACP,OAAO,QAAO,OAAO,IAC9B,SAAQ;UACC,OAAO,OAAO,OAAO,KAC9B;MAAI,SAAS;AACX,QAAK,KAAK,QAAQ;AAClB,aAAU;;OAGZ,YAAW;AAGf,KAAI,QAAS,MAAK,KAAK,QAAQ;AAC/B,QAAO;;AAiBT,SAAS,SAAS,OAAsB;CACtC,MAAM,IAAI,QAAQ,YAAY;CAC9B,MAAM,MAAM,QAAQ,aAAa;CACjC,MAAM,OAAO,QAAQ,aAAa;CAClC,MAAM,SAAS,QAAQ,aAAa;CACpC,MAAM,OAAO,QAAQ,YAAY;AACjC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,GAAG;EAClC,YACE;GACE,GAAG,KAAK,qBAAqB;GAC7B;GACA,KAAK,KAAK,eAAe;GACzB,OAAO,OAAO,IAAI,EAAE;GACpB,OAAO,OAAO,MAAM,EAAE;GACtB,OAAO,OAAO,OAAO,EAAE;GACvB,OAAO,OAAO,MAAM,EAAE;GACtB,OAAO,OAAO,MAAM,EAAE;GACtB,OAAO,OAAO,SAAS,EAAE;GACzB,OAAO,OAAO,QAAQ,EAAE;GACxB;GACA,KAAK,KAAK,gBAAgB;GAC1B,OAAO,OAAO,IAAI,EAAE;GACpB,OAAO,OAAO,KAAK,EAAE;GACrB,OAAO,OAAO,MAAM,EAAE;GACtB,OAAO,OAAO,OAAO,EAAE;GACvB,OAAO,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,EAAE;GAC3C,CAAC,KAAK,OAAO;EACjB;;AAOH,eAAe,MAAM,KAAU,MAAc,MAA6B;AACxE,KAAI;EAEF,MAAM,SADS,MAAM,IAAI,KAAK,MAAM,EAAE,UAAU,GAAG,CAAC,EAC/B,QAAQ,EAAE;AAC/B,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,SAAO,MACJ,KAAK,MAAM;GACV,MAAM,QACH,EAAE,MAA8C,SAAS,gBACvD,EAAE,MAA8C,iBACjD,KAAK;GACT,MAAM,OAAO,EAAE,KAAK,MAAM,IAAI,CAAC,GAAG,GAAG,IAAI,EAAE;AAC3C,UAAO,QAAQ,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK,MAAM;IACjD,CACD,KAAK,OAAO;UACR,GAAG;AACV,SAAO,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC;;;AAI/D,eAAe,QAAQ,KAAU,MAAc,MAA6B;AAC1E,KAAI;EAEF,MAAM,WADS,MAAM,IAAI,KAAK,KAAK,EACZ,MAAM;AAC7B,MAAI,YAAY,UAAa,YAAY,KAAM,QAAO,KAAK,IAAI,4BAA4B;AAC3F,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,mBAAmB,WAAY,QAAO,IAAI,aAAa,CAAC,OAAO,QAAQ;AAC3E,SAAO,KAAK,UAAU,SAAS,MAAM,EAAE;UAChC,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,MAAI,oBAAoB,KAAK,IAAI,CAAE,QAAO,KAAK,IAAI,cAAc,OAAO;AACxE,SAAO,KAAK,IAAI,IAAI;;;AAIxB,eAAe,SAAS,KAAU,MAAc,SAAiB,MAA6B;AAC5F,KAAI;AACF,QAAM,IAAI,MAAM,MAAM,EAAE,SAAS,CAAC;AAClC,SAAO,YAAY;UACZ,GAAG;AACV,SAAO,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC;;;AAI/D,eAAe,QAAQ,KAAU,MAAc,MAA6B;AAC1E,KAAI;EAEF,MAAM,QADS,MAAM,IAAI,KAAK,KAAK,GACb,MAAM,QAAoC,EAAE;EAClE,MAAM,QAAQ,CAAC,GAAG,KAAK,KAAK,OAAO,KAAK,EAAE,GAAG,OAAO;AACpD,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,CACvC,KAAI,MAAM,UAAa,MAAM,KAC3B,OAAM,KAAK,GAAG,KAAK,SAAS,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,UAAU,EAAE,GAAG;AAEnE,SAAO,MAAM,KAAK,OAAO;UAClB,GAAG;EACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,MAAI,oBAAoB,KAAK,IAAI,CAAE,QAAO,KAAK,IAAI,cAAc,OAAO;AACxE,SAAO,KAAK,IAAI,IAAI;;;AAIxB,eAAe,QACb,KACA,MACA,MACA,MACiB;AACjB,KAAI;EAEF,MAAM,QADS,MAAM,IAAI,KAAK,MAAM,KAAK,GACpB;AACrB,MAAI,SAAS,UAAa,SAAS,KAAM,QAAO;AAChD,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,SAAO,KAAK,UAAU,MAAM,MAAM,EAAE;UAC7B,GAAG;AACV,SAAO,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC;;;AAI/D,eAAe,WAAW,KAAU,MAAc,MAA6B;AAC7E,KAAI;EACF,MAAM,SAAS,MAAM,IAAI,QAAQ,KAAK;AACtC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,WAAW;UAClB,GAAG;AACV,SAAO,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC;;;AAI/D,eAAe,UAAU,KAAU,MAAc,OAAe,MAA6B;AAC3F,KAAI;EAEF,MAAM,SADS,MAAM,IAAI,OAAO,MAAM,MAAM,GACtB,QAAQ,EAAE;AAChC,MAAI,CAAC,MAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,OAAQ,QAAO;AACnD,SAAO,MACJ,KAAK,MAAe;GACnB,MAAM,QAAQ;AACd,UAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,KAAK,UAAU,EAAE;IACtE,CACD,KAAK,OAAO;UACR,GAAG;AACV,SAAO,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC;;;AAI/D,eAAe,MACb,KACA,KACA,QAC6C;CAC7C,MAAM,SAAS,YAAY,KAAK,OAAO;AACvC,KAAI,WAAW,IAAK,QAAO,EAAE,QAAQ;AACrC,KAAI;EAEF,MAAM,QADS,MAAM,IAAI,KAAK,OAAO,GACf,MAAM,QAAoC,EAAE;AAKlE,MAAI,EAHF,KAAK,SAAS,eACd,KAAK,kBAAkB,UACvB,OAAO,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,WAAW,GACnC,QAAO;GAAE,QAAQ;GAAK,OAAO,oBAAoB;GAAU;AACvE,SAAO,EAAE,QAAQ;SACX;AACN,MAAI;AACF,SAAM,IAAI,KAAK,QAAQ,EAAE,UAAU,GAAG,CAAC;AACvC,UAAO,EAAE,QAAQ;UACX;AACN,UAAO;IAAE,QAAQ;IAAK,OAAO,cAAc;IAAU;;;;;;;;;;AAe3D,SAAgB,qBAAqB,KAAU,MAAsC;CACnF,MAAM,YAAY,cAAc;CAChC,MAAM,OAAO,SAAS,KAAK,UAAU,MAAM;CAC3C,IAAI,MAAM;CACV,IAAI,sBAAqC;AAEzC,QAAO;EACL;EAEA,YAAoB;AAElB,UAAO,OADK,QAAQ,MAAM,MAAM,IAAI,MAAM,IAAI,CAAC,GAAG,GAAG,CACnC;;EAGpB,MAAM,iBAAkC;AACtC,OAAI,wBAAwB,KAAM,QAAO;AACzC,OAAI;IACF,MAAM,SAAS,MAAM,IAAI,KAAK,IAAI;IAClC,MAAM,uBAAO,IAAI,KAAa;AAC9B,SAAK,MAAM,KAAK,OAAO,QAAQ,EAAE,CAC/B,KAAI,OAAO,GAAG,SAAS,SAAU,MAAK,IAAI,EAAE,KAAK;AAEnD,0BAAsB,KAAK,QAAQ;WAC7B;AACN,0BAAsB;;AAExB,UAAO;;EAGT,MAAM,MAAM,MAAsC;GAChD,MAAM,UAAU,KAAK,MAAM;AAC3B,OAAI,CAAC,QAAS,QAAO,EAAE;GAIvB,MAAM,OAAO,UADC,QAAQ,WAAW,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC,MAAM,GAAG,QACxC;GAC7B,MAAM,MAAM,KAAK,IAAI,aAAa,IAAI;AAEtC,WAAQ,KAAR;IACE,KAAK,MAAM;KACT,MAAM,UAAU,KAAK,MAAM;AAE3B,YAAO,EAAE,QAAQ,MAAM,MAAM,KADhB,YAAY,KAAK,QAAQ,EACE,KAAK,EAAE;;IAEjD,KAAK;IACL,KAAK;AACH,SAAI,CAAC,KAAK,GAAI,QAAO,EAAE,QAAQ,KAAK,IAAI,qBAAqB,EAAE;AAG/D,YAAO,EAAE,SADG,MAAM,QAAQ,KADb,YAAY,KAAK,KAAK,GAAG,EACD,KAAK,EACrB,QAAQ,OAAO,OAAO,EAAE;IAE/C,KAAK;AACH,SAAI,CAAC,KAAK,GAAI,QAAO,EAAE,QAAQ,KAAK,IAAI,gCAAgC,EAAE;AAG1E,YAAO,EAAE,QAAQ,MAAM,SAAS,KAFnB,YAAY,KAAK,KAAK,GAAG,EACtB,KAAK,MAAM,EAAE,CAAC,KAAK,IAAI,EACa,KAAK,EAAE;IAE7D,KAAK,QAAQ;KACX,MAAM,UAAU,KAAK,MAAM;AAE3B,YAAO,EAAE,QAAQ,MAAM,QAAQ,KADlB,YAAY,KAAK,QAAQ,EACI,KAAK,EAAE;;IAEnD,KAAK,QAAQ;AACX,SAAI,CAAC,KAAK,GAAI,QAAO,EAAE,QAAQ,KAAK,IAAI,+BAA+B,EAAE;KACzE,MAAM,OAAO,YAAY,KAAK,KAAK,GAAG;KACtC,MAAM,WAAoC,EAAE;AAC5C,UAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;MACpC,MAAM,KAAK,KAAK,GAAI,MAAM,IAAI;AAC9B,UAAI,GAAG,WAAW,EAAG,UAAS,GAAG,MAAO,GAAG;UACtC,UAAS,MAAM,IAAI,OAAO,KAAK;;AAEtC,YAAO,EAAE,QAAQ,MAAM,QAAQ,KAAK,MAAM,UAAU,KAAK,EAAE;;IAE7D,KAAK,WAAW;KACd,MAAM,UAAU,KAAK,MAAM;AAE3B,YAAO,EAAE,QAAQ,MAAM,WAAW,KADrB,YAAY,KAAK,QAAQ,EACO,KAAK,EAAE;;IAEtD,KAAK;AACH,SAAI,CAAC,KAAK,MAAM,CAAC,KAAK,GAAI,QAAO,EAAE,QAAQ,KAAK,IAAI,+BAA+B,EAAE;AAGrF,YAAO,EAAE,QAAQ,MAAM,UAAU,KAFpB,YAAY,KAAK,KAAK,GAAG,EACxB,KAAK,MAAM,EAAE,CAAC,KAAK,IAAI,EACc,KAAK,EAAE;IAE5D,KAAK,MAAM;KACT,MAAM,SAAS,KAAK,MAAM;KAC1B,MAAM,EAAE,QAAQ,UAAU,MAAM,MAAM,KAAK,KAAK,OAAO;AACvD,WAAM;AACN,YAAO,EAAE,QAAQ,QAAQ,KAAK,IAAI,MAAM,GAAG,QAAW;;IAExD,KAAK,MACH,QAAO,EAAE,QAAQ,KAAK;IACxB,KAAK,OACH,QAAO,EAAE,QAAQ,KAAK,MAAM,EAAE;IAChC,KAAK,QACH,QAAO,EAAE,OAAO,MAAM;IACxB,KAAK;IACL,KAAK,OACH,QAAO,EAAE,MAAM,MAAM;IACvB,QACE,QAAO,EACL,QAAQ,GAAG,KAAK,IAAI,oBAAoB,MAAM,CAAC,UAAU,KAAK,OAAO,MAAM,KAAK,EAAE,0BACnF;;;EAGR"}
@@ -0,0 +1,136 @@
1
+
2
+ //#region src/transport/idle-timer.ts
3
+ /**
4
+ * Per-WebSocket idle timer — runtime-neutral.
5
+ *
6
+ * Why: long-lived WebSockets that sit idle still consume runtime resources.
7
+ * On Cloudflare Durable Objects this is direct billing (`server.accept()`
8
+ * keeps the DO active for the full WS lifetime); on Node it's memory and
9
+ * file descriptors. Both runtimes benefit from closing WebSockets that
10
+ * haven't seen a client message in a configurable window.
11
+ *
12
+ * What: arm a timer per connection, reset on every inbound message; on
13
+ * expiry, close the WS with a close code ≥ 4000 so the AUP client suppresses
14
+ * its auto-reconnect loop (see `web-page/core.ts` — code ≥ 4000 means
15
+ * "server rejected, do not reconnect"). The user reconnects on next
16
+ * interaction; the existing `sessionId`-based handshake restores per-session
17
+ * state.
18
+ *
19
+ * On Cloudflare, once all WebSockets close, the DO is auto-evicted by the
20
+ * Workers runtime and duration billing stops. On Node, the WS object is GC'd
21
+ * and the file descriptor returned to the OS.
22
+ */
23
+ /** Close code used for intentional idle close (must be ≥ 4000). */
24
+ const IDLE_CLOSE_CODE = 4001;
25
+ /** Short ASCII reason — CF caps reason at 123 bytes. */
26
+ const IDLE_CLOSE_REASON = "idle-timeout";
27
+ /** Lower bound — under 1s is almost certainly a misconfiguration. */
28
+ const MIN_TIMEOUT_MS = 1e3;
29
+ /** Upper bound — keep one connection alive at most 24h on a single client. */
30
+ const MAX_TIMEOUT_MS = 1440 * 6e4;
31
+ function createIdleTimer(opts) {
32
+ const { timeoutMs, onIdle } = opts;
33
+ const setT = opts.setTimeout ?? globalThis.setTimeout;
34
+ const clearT = opts.clearTimeout ?? globalThis.clearTimeout;
35
+ if (timeoutMs <= 0) return {
36
+ rearm() {},
37
+ cancel() {}
38
+ };
39
+ let handle = null;
40
+ const fire = () => {
41
+ handle = null;
42
+ try {
43
+ onIdle();
44
+ } catch {}
45
+ };
46
+ return {
47
+ rearm() {
48
+ if (handle !== null) clearT(handle);
49
+ handle = setT(fire, timeoutMs);
50
+ },
51
+ cancel() {
52
+ if (handle !== null) {
53
+ clearT(handle);
54
+ handle = null;
55
+ }
56
+ }
57
+ };
58
+ }
59
+ /**
60
+ * Best-effort `{ type: string }` sniff of an inbound WS message event, used
61
+ * only to decide whether it should rearm the idle timer. Any parse failure
62
+ * (binary frame, non-JSON text, missing `.data`) is treated as "not a
63
+ * recognized synthetic type" — i.e. it still counts as real activity. This
64
+ * keeps `ignoreMessageTypes` strictly opt-in and never silently swallows a
65
+ * message the caller didn't ask to ignore.
66
+ */
67
+ function messageTypeOf(event) {
68
+ try {
69
+ const data = event?.data;
70
+ if (typeof data !== "string") return void 0;
71
+ const parsed = JSON.parse(data);
72
+ return typeof parsed?.type === "string" ? parsed.type : void 0;
73
+ } catch {
74
+ return;
75
+ }
76
+ }
77
+ /**
78
+ * Wire an idle timer to a WebSocket-like object: arm immediately, rearm on
79
+ * every inbound message, cancel on close/error. On expiry, close the socket
80
+ * with `IDLE_CLOSE_CODE` and `IDLE_CLOSE_REASON`.
81
+ *
82
+ * Returns the timer so callers can `cancel()` it during external teardown.
83
+ */
84
+ function attachIdleClose(server, timeoutMs, options) {
85
+ const timer = createIdleTimer({
86
+ timeoutMs,
87
+ onIdle: () => {
88
+ try {
89
+ if (server.readyState === 1) server.close(IDLE_CLOSE_CODE, IDLE_CLOSE_REASON);
90
+ } catch {}
91
+ },
92
+ setTimeout: options?.setTimeout,
93
+ clearTimeout: options?.clearTimeout
94
+ });
95
+ timer.rearm();
96
+ const ignoreTypes = options?.ignoreMessageTypes;
97
+ server.addEventListener("message", (event) => {
98
+ if (ignoreTypes?.length) {
99
+ const type = messageTypeOf(event);
100
+ if (type !== void 0 && ignoreTypes.includes(type)) return;
101
+ }
102
+ timer.rearm();
103
+ });
104
+ server.addEventListener("close", () => timer.cancel());
105
+ server.addEventListener("error", () => timer.cancel());
106
+ if (options?.rearmOnOutbound && server.send) {
107
+ const orig = server.send.bind(server);
108
+ server.send = (data) => {
109
+ timer.rearm();
110
+ orig(data);
111
+ };
112
+ }
113
+ return timer;
114
+ }
115
+ /**
116
+ * Parse an env-supplied idle timeout. Accepts undefined / empty / non-numeric
117
+ * (returns `defaultMs`), `0` (returns `0` — disabled), and clamps to
118
+ * [MIN_TIMEOUT_MS, MAX_TIMEOUT_MS] for any positive value.
119
+ */
120
+ function resolveIdleTimeoutMs(value, defaultMs) {
121
+ if (value === void 0 || value === "") return defaultMs;
122
+ if (!/^-?\d+$/.test(value.trim())) return defaultMs;
123
+ const n = Number.parseInt(value, 10);
124
+ if (Number.isNaN(n)) return defaultMs;
125
+ if (n <= 0) return 0;
126
+ if (n < MIN_TIMEOUT_MS) return MIN_TIMEOUT_MS;
127
+ if (n > MAX_TIMEOUT_MS) return MAX_TIMEOUT_MS;
128
+ return n;
129
+ }
130
+
131
+ //#endregion
132
+ exports.IDLE_CLOSE_CODE = IDLE_CLOSE_CODE;
133
+ exports.IDLE_CLOSE_REASON = IDLE_CLOSE_REASON;
134
+ exports.attachIdleClose = attachIdleClose;
135
+ exports.createIdleTimer = createIdleTimer;
136
+ exports.resolveIdleTimeoutMs = resolveIdleTimeoutMs;
@@ -0,0 +1,92 @@
1
+ //#region src/transport/idle-timer.d.ts
2
+ /**
3
+ * Per-WebSocket idle timer — runtime-neutral.
4
+ *
5
+ * Why: long-lived WebSockets that sit idle still consume runtime resources.
6
+ * On Cloudflare Durable Objects this is direct billing (`server.accept()`
7
+ * keeps the DO active for the full WS lifetime); on Node it's memory and
8
+ * file descriptors. Both runtimes benefit from closing WebSockets that
9
+ * haven't seen a client message in a configurable window.
10
+ *
11
+ * What: arm a timer per connection, reset on every inbound message; on
12
+ * expiry, close the WS with a close code ≥ 4000 so the AUP client suppresses
13
+ * its auto-reconnect loop (see `web-page/core.ts` — code ≥ 4000 means
14
+ * "server rejected, do not reconnect"). The user reconnects on next
15
+ * interaction; the existing `sessionId`-based handshake restores per-session
16
+ * state.
17
+ *
18
+ * On Cloudflare, once all WebSockets close, the DO is auto-evicted by the
19
+ * Workers runtime and duration billing stops. On Node, the WS object is GC'd
20
+ * and the file descriptor returned to the OS.
21
+ */
22
+ /** Close code used for intentional idle close (must be ≥ 4000). */
23
+ declare const IDLE_CLOSE_CODE = 4001;
24
+ /** Short ASCII reason — CF caps reason at 123 bytes. */
25
+ declare const IDLE_CLOSE_REASON = "idle-timeout";
26
+ interface IdleTimerOptions {
27
+ /** Idle window in ms. `0` disables the timer (useful for tests / opt-out). */
28
+ timeoutMs: number;
29
+ /** Invoked when the idle window elapses without a `rearm()`. */
30
+ onIdle: () => void;
31
+ /** Test seam — defaults to `globalThis.setTimeout`. */
32
+ setTimeout?: typeof setTimeout;
33
+ /** Test seam — defaults to `globalThis.clearTimeout`. */
34
+ clearTimeout?: typeof clearTimeout;
35
+ }
36
+ interface IdleTimer {
37
+ /** Reset (or start) the idle countdown. Safe to call repeatedly. */
38
+ rearm(): void;
39
+ /** Stop the timer. After cancel, `rearm()` resumes it. */
40
+ cancel(): void;
41
+ }
42
+ declare function createIdleTimer(opts: IdleTimerOptions): IdleTimer;
43
+ /**
44
+ * Minimal WebSocket surface used by `attachIdleClose`. Both the CF Workers
45
+ * `WebSocket` and the Node `ws` library satisfy this shape.
46
+ */
47
+ interface IdleCloseTarget {
48
+ readyState: number;
49
+ close(code?: number, reason?: string): void;
50
+ send?: (data: any) => void;
51
+ addEventListener(type: "message" | "close" | "error", listener: (event: unknown) => void): void;
52
+ }
53
+ /**
54
+ * Wire an idle timer to a WebSocket-like object: arm immediately, rearm on
55
+ * every inbound message, cancel on close/error. On expiry, close the socket
56
+ * with `IDLE_CLOSE_CODE` and `IDLE_CLOSE_REASON`.
57
+ *
58
+ * Returns the timer so callers can `cancel()` it during external teardown.
59
+ */
60
+ declare function attachIdleClose(server: IdleCloseTarget, timeoutMs: number, options?: {
61
+ /**
62
+ * When true, wraps `server.send` so that every outbound server push also
63
+ * rearms the idle timer. Without this, a session receiving only passive
64
+ * live-update pushes (no client→server traffic) is considered "idle" and
65
+ * closed after `timeoutMs` even though it has ongoing server activity.
66
+ */
67
+ rearmOnOutbound?: boolean;
68
+ /**
69
+ * Inbound message `type` values that must NOT rearm the idle timer.
70
+ * Exists for synthetic client keepalive frames (e.g. the AUP web client's
71
+ * `{type:"ping"}`, sent purely to defeat CF-edge / mobile-NAT idle-drop
72
+ * of an otherwise-unused connection — see WS_KEEPALIVE_MESSAGE_TYPE in
73
+ * `@aigne/afs-ui`). Without this, a keepalive ping would itself count as
74
+ * "activity" and the idle-close timer — whose entire purpose is evicting
75
+ * genuinely-unused connections to stop Durable Object duration billing —
76
+ * would never fire for as long as the tab merely sits open (arc#1243).
77
+ * Messages that fail to parse as `{type: string}` JSON are never treated
78
+ * as ignorable, so this can only narrow rearm triggers, never widen them.
79
+ */
80
+ ignoreMessageTypes?: string[];
81
+ setTimeout?: typeof setTimeout;
82
+ clearTimeout?: typeof clearTimeout;
83
+ }): IdleTimer;
84
+ /**
85
+ * Parse an env-supplied idle timeout. Accepts undefined / empty / non-numeric
86
+ * (returns `defaultMs`), `0` (returns `0` — disabled), and clamps to
87
+ * [MIN_TIMEOUT_MS, MAX_TIMEOUT_MS] for any positive value.
88
+ */
89
+ declare function resolveIdleTimeoutMs(value: string | undefined, defaultMs: number): number;
90
+ //#endregion
91
+ export { IDLE_CLOSE_CODE, IDLE_CLOSE_REASON, IdleCloseTarget, IdleTimer, IdleTimerOptions, attachIdleClose, createIdleTimer, resolveIdleTimeoutMs };
92
+ //# sourceMappingURL=idle-timer.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle-timer.d.cts","names":[],"sources":["../../src/transport/idle-timer.ts"],"mappings":";;AAsBA;;;;;AAGA;;;;;AAOA;;;;;;;;;;cAVa,eAAA;;cAGA,iBAAA;AAAA,UAOI,gBAAA;;EAEf,SAAA;EAaM;EAXN,MAAA;EAc6B;EAZ7B,UAAA,UAAoB,UAAA;EAY4C;EAVhE,YAAA,UAAsB,YAAA;AAAA;AAAA,UAGP,SAAA;EAOiD;EALhE,KAAA;EA2Ce;EAzCf,MAAA;AAAA;AAAA,iBAGc,eAAA,CAAgB,IAAA,EAAM,gBAAA,GAAmB,SAAA;;;;;UAsCxC,eAAA;EACf,UAAA;EACA,KAAA,CAAM,IAAA,WAAe,MAAA;EACrB,IAAA,IAAQ,IAAA;EACR,gBAAA,CAAiB,IAAA,iCAAqC,QAAA,GAAW,KAAA;AAAA;;;AA6BnE;;;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,eAAA,EACR,SAAA,UACA,OAAA;EAwBC;;;;;;EAjBC,eAAA;EAaA;;;;;;;;;AAgDJ;;;EAhDI,kBAAA;EACA,UAAA,UAAoB,UAAA;EACpB,YAAA,UAAsB,YAAA;AAAA,IAEvB,SAAA;;;;;;iBA4Ca,oBAAA,CAAqB,KAAA,sBAA2B,SAAA"}