@fastagent-sh/fastagent 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/README.md +9 -12
  2. package/dist/agent.d.ts +24 -37
  3. package/dist/agent.js +7 -15
  4. package/dist/atomic-write.d.ts +13 -17
  5. package/dist/atomic-write.js +18 -29
  6. package/dist/bind.d.ts +12 -22
  7. package/dist/bind.js +18 -27
  8. package/dist/channel.d.ts +11 -33
  9. package/dist/channels/agentcore-limits.d.ts +2 -13
  10. package/dist/channels/agentcore-limits.js +2 -13
  11. package/dist/channels/agentcore-protocol.d.ts +67 -58
  12. package/dist/channels/agentcore-protocol.js +23 -15
  13. package/dist/channels/agentcore-service.d.ts +19 -33
  14. package/dist/channels/agentcore-service.js +176 -59
  15. package/dist/channels/agentcore.d.ts +39 -33
  16. package/dist/channels/agentcore.js +90 -224
  17. package/dist/channels/body.d.ts +15 -2
  18. package/dist/channels/body.js +24 -2
  19. package/dist/channels/busy.d.ts +1 -21
  20. package/dist/channels/busy.js +2 -39
  21. package/dist/channels/control.d.ts +17 -62
  22. package/dist/channels/control.js +74 -182
  23. package/dist/channels/define-channel.d.ts +39 -0
  24. package/dist/channels/define-channel.js +9 -0
  25. package/dist/channels/discover.d.ts +10 -31
  26. package/dist/channels/discover.js +37 -31
  27. package/dist/channels/feishu/bootstrap-token.d.ts +1 -8
  28. package/dist/channels/feishu/bootstrap-token.js +7 -23
  29. package/dist/channels/feishu/card.d.ts +14 -28
  30. package/dist/channels/feishu/card.js +16 -30
  31. package/dist/channels/feishu/cloud.d.ts +1 -5
  32. package/dist/channels/feishu/context-buffer.d.ts +4 -23
  33. package/dist/channels/feishu/context-buffer.js +8 -31
  34. package/dist/channels/feishu/crypto.d.ts +10 -5
  35. package/dist/channels/feishu/crypto.js +12 -19
  36. package/dist/channels/feishu/feishu-api.d.ts +2 -1
  37. package/dist/channels/feishu/feishu-api.js +5 -4
  38. package/dist/channels/feishu/feishu.d.ts +4 -10
  39. package/dist/channels/feishu/feishu.js +113 -227
  40. package/dist/channels/feishu/invoke-turn.d.ts +5 -4
  41. package/dist/channels/feishu/invoke-turn.js +36 -54
  42. package/dist/channels/feishu/model.d.ts +4 -21
  43. package/dist/channels/feishu/model.js +1 -8
  44. package/dist/channels/feishu/normalize.d.ts +2 -10
  45. package/dist/channels/feishu/normalize.js +7 -42
  46. package/dist/channels/feishu/parse.d.ts +9 -29
  47. package/dist/channels/feishu/parse.js +8 -26
  48. package/dist/channels/feishu/preview.d.ts +12 -14
  49. package/dist/channels/feishu/preview.js +108 -207
  50. package/dist/channels/feishu/register-app.d.ts +8 -23
  51. package/dist/channels/feishu/register-app.js +7 -20
  52. package/dist/channels/feishu/register-webhook.d.ts +2 -9
  53. package/dist/channels/feishu/register-webhook.js +9 -33
  54. package/dist/channels/feishu/scaffold/channel.ts +27 -19
  55. package/dist/channels/feishu/scaffold/channel.websocket.ts +31 -0
  56. package/dist/channels/feishu/setup-mode.d.ts +11 -36
  57. package/dist/channels/feishu/setup-mode.js +7 -26
  58. package/dist/channels/feishu/ws-ingress.d.ts +1 -2
  59. package/dist/channels/feishu/ws-ingress.js +6 -8
  60. package/dist/channels/http.d.ts +15 -15
  61. package/dist/channels/http.js +19 -9
  62. package/dist/channels/kit/attachment-path.d.ts +4 -5
  63. package/dist/channels/kit/attachment-path.js +10 -34
  64. package/dist/channels/kit/context-buffer.d.ts +14 -21
  65. package/dist/channels/kit/context-buffer.js +25 -38
  66. package/dist/channels/kit/delivery.d.ts +35 -0
  67. package/dist/channels/kit/delivery.js +129 -0
  68. package/dist/channels/kit/event-stream.d.ts +5 -0
  69. package/dist/channels/kit/event-stream.js +29 -0
  70. package/dist/channels/kit/invoke-turn-kit.d.ts +53 -26
  71. package/dist/channels/kit/invoke-turn-kit.js +89 -32
  72. package/dist/channels/kit/preview-kit.d.ts +18 -72
  73. package/dist/channels/kit/preview-kit.js +22 -88
  74. package/dist/channels/kit/signature.d.ts +3 -9
  75. package/dist/channels/kit/signature.js +3 -9
  76. package/dist/channels/kit/state.d.ts +1 -2
  77. package/dist/channels/kit/state.js +5 -14
  78. package/dist/channels/kit/stop-command.d.ts +1 -2
  79. package/dist/channels/kit/stop-command.js +6 -9
  80. package/dist/channels/kit/tasks.d.ts +1 -1
  81. package/dist/channels/kit/tasks.js +8 -21
  82. package/dist/channels/kit/text.d.ts +2 -16
  83. package/dist/channels/kit/text.js +23 -31
  84. package/dist/channels/kit/thread-participants.d.ts +4 -17
  85. package/dist/channels/kit/thread-participants.js +8 -55
  86. package/dist/channels/kit/transport.d.ts +26 -0
  87. package/dist/channels/kit/transport.js +20 -0
  88. package/dist/channels/kit/turn-queue.d.ts +7 -11
  89. package/dist/channels/kit/turn-queue.js +21 -39
  90. package/dist/channels/kit/turn-runner.d.ts +32 -18
  91. package/dist/channels/kit/turn-runner.js +98 -53
  92. package/dist/channels/kit/turn-store.d.ts +32 -32
  93. package/dist/channels/kit/turn-store.js +45 -88
  94. package/dist/channels/lark/lark.d.ts +1 -5
  95. package/dist/channels/lark/onboard.d.ts +3 -12
  96. package/dist/channels/lark/onboard.js +3 -13
  97. package/dist/channels/lark/scaffold/channel.ts +27 -19
  98. package/dist/channels/lark/scaffold/channel.websocket.ts +31 -0
  99. package/dist/channels/registration.d.ts +9 -35
  100. package/dist/channels/registration.js +6 -37
  101. package/dist/channels/secret.js +2 -5
  102. package/dist/channels/serve.d.ts +47 -44
  103. package/dist/channels/serve.js +165 -101
  104. package/dist/channels/slack/config-api.d.ts +4 -27
  105. package/dist/channels/slack/config-api.js +5 -34
  106. package/dist/channels/slack/context-buffer.d.ts +2 -3
  107. package/dist/channels/slack/context-buffer.js +5 -5
  108. package/dist/channels/slack/invoke-turn.d.ts +3 -1
  109. package/dist/channels/slack/invoke-turn.js +25 -34
  110. package/dist/channels/slack/manifest.js +1 -3
  111. package/dist/channels/slack/model.d.ts +1 -2
  112. package/dist/channels/slack/model.js +1 -1
  113. package/dist/channels/slack/onboard.d.ts +4 -3
  114. package/dist/channels/slack/onboard.js +8 -11
  115. package/dist/channels/slack/onboarding-state.d.ts +3 -5
  116. package/dist/channels/slack/onboarding-state.js +9 -6
  117. package/dist/channels/slack/parse.d.ts +4 -13
  118. package/dist/channels/slack/parse.js +7 -28
  119. package/dist/channels/slack/preview.d.ts +12 -2
  120. package/dist/channels/slack/preview.js +292 -269
  121. package/dist/channels/slack/reaction.d.ts +11 -3
  122. package/dist/channels/slack/reaction.js +19 -8
  123. package/dist/channels/slack/register-webhook.js +4 -7
  124. package/dist/channels/slack/scaffold/channel.ts +20 -13
  125. package/dist/channels/slack/scaffold/slack-send.ts +2 -2
  126. package/dist/channels/slack/setup-server.d.ts +1 -5
  127. package/dist/channels/slack/setup-server.js +1 -5
  128. package/dist/channels/slack/shared-api.d.ts +1 -4
  129. package/dist/channels/slack/shared-api.js +2 -13
  130. package/dist/channels/slack/slack-api.d.ts +2 -1
  131. package/dist/channels/slack/slack-api.js +6 -4
  132. package/dist/channels/slack/slack.d.ts +11 -14
  133. package/dist/channels/slack/slack.js +121 -122
  134. package/dist/channels/sse.d.ts +1 -1
  135. package/dist/channels/sse.js +1 -1
  136. package/dist/channels/telegram/context-buffer.d.ts +7 -22
  137. package/dist/channels/telegram/context-buffer.js +6 -23
  138. package/dist/channels/telegram/invoke-turn.d.ts +7 -7
  139. package/dist/channels/telegram/invoke-turn.js +24 -43
  140. package/dist/channels/telegram/parse.d.ts +24 -51
  141. package/dist/channels/telegram/parse.js +32 -84
  142. package/dist/channels/telegram/preview.d.ts +10 -1
  143. package/dist/channels/telegram/preview.js +79 -100
  144. package/dist/channels/telegram/register-webhook.js +5 -23
  145. package/dist/channels/telegram/scaffold/channel.ts +25 -18
  146. package/dist/channels/telegram/scaffold/telegram-send.ts +6 -4
  147. package/dist/channels/telegram/telegram-api.d.ts +4 -3
  148. package/dist/channels/telegram/telegram-api.js +9 -7
  149. package/dist/channels/telegram/telegram.d.ts +4 -18
  150. package/dist/channels/telegram/telegram.js +38 -94
  151. package/dist/channels/telegram/turn-store.d.ts +11 -14
  152. package/dist/channels/telegram/turn-store.js +8 -6
  153. package/dist/channels/wait-health.d.ts +4 -6
  154. package/dist/channels/wait-health.js +10 -14
  155. package/dist/cli/add-feishu.d.ts +2 -12
  156. package/dist/cli/add-feishu.js +24 -71
  157. package/dist/cli/add-slack.d.ts +5 -3
  158. package/dist/cli/add-slack.js +53 -76
  159. package/dist/cli/auth-view.d.ts +2 -16
  160. package/dist/cli/auth-view.js +2 -16
  161. package/dist/cli/commands/add.js +25 -43
  162. package/dist/cli/commands/chat.d.ts +0 -1
  163. package/dist/cli/commands/chat.js +5 -6
  164. package/dist/cli/commands/deploy/agentcore.js +60 -65
  165. package/dist/cli/commands/deploy/docker.js +50 -23
  166. package/dist/cli/commands/deploy/fly.js +23 -61
  167. package/dist/cli/commands/deploy/railway.js +23 -18
  168. package/dist/cli/commands/deploy/shared.d.ts +38 -57
  169. package/dist/cli/commands/deploy/shared.js +40 -59
  170. package/dist/cli/commands/deploy.d.ts +10 -27
  171. package/dist/cli/commands/deploy.js +38 -60
  172. package/dist/cli/commands/destroy.d.ts +4 -0
  173. package/dist/cli/commands/destroy.js +56 -0
  174. package/dist/cli/commands/dev.d.ts +2 -1
  175. package/dist/cli/commands/dev.js +20 -23
  176. package/dist/cli/commands/info.d.ts +0 -2
  177. package/dist/cli/commands/info.js +83 -49
  178. package/dist/cli/commands/init.d.ts +1 -2
  179. package/dist/cli/commands/init.js +16 -55
  180. package/dist/cli/commands/invoke.d.ts +0 -1
  181. package/dist/cli/commands/invoke.js +5 -7
  182. package/dist/cli/commands/login.d.ts +2 -1
  183. package/dist/cli/commands/login.js +33 -38
  184. package/dist/cli/commands/logs.js +3 -4
  185. package/dist/cli/commands/models.js +1 -5
  186. package/dist/cli/commands/routine-run.d.ts +6 -0
  187. package/dist/cli/commands/routine-run.js +47 -0
  188. package/dist/cli/commands/routine.d.ts +25 -0
  189. package/dist/cli/commands/routine.js +122 -0
  190. package/dist/cli/commands/start.d.ts +31 -3
  191. package/dist/cli/commands/start.js +131 -81
  192. package/dist/cli/commands/tool.js +26 -12
  193. package/dist/cli/fail.d.ts +13 -23
  194. package/dist/cli/fail.js +20 -23
  195. package/dist/cli/invoke-stream.d.ts +1 -8
  196. package/dist/cli/kernel.d.ts +6 -38
  197. package/dist/cli/kernel.js +14 -77
  198. package/dist/cli/models-view.d.ts +1 -9
  199. package/dist/cli/models-view.js +11 -22
  200. package/dist/cli/program.d.ts +5 -6
  201. package/dist/cli/program.js +120 -157
  202. package/dist/cli/serve.d.ts +57 -41
  203. package/dist/cli/serve.js +94 -121
  204. package/dist/cli/shared.d.ts +15 -61
  205. package/dist/cli/shared.js +55 -181
  206. package/dist/cli.js +1 -8
  207. package/dist/collect.d.ts +6 -0
  208. package/dist/collect.js +6 -0
  209. package/dist/core.d.ts +4 -1
  210. package/dist/core.js +9 -7
  211. package/dist/declared-secrets.d.ts +55 -0
  212. package/dist/declared-secrets.js +88 -0
  213. package/dist/deploy/agentcore/aws-cli.d.ts +91 -0
  214. package/dist/deploy/agentcore/aws-cli.js +64 -0
  215. package/dist/deploy/agentcore/destroy.d.ts +51 -0
  216. package/dist/deploy/agentcore/destroy.js +273 -0
  217. package/dist/deploy/agentcore/forwarder.js +28 -79
  218. package/dist/deploy/agentcore/logs.d.ts +2 -18
  219. package/dist/deploy/agentcore/logs.js +27 -51
  220. package/dist/deploy/agentcore/plan.d.ts +85 -105
  221. package/dist/deploy/agentcore/plan.js +152 -314
  222. package/dist/deploy/agentcore/run.d.ts +28 -28
  223. package/dist/deploy/agentcore/run.js +227 -306
  224. package/dist/deploy/agentcore/zip.d.ts +2 -15
  225. package/dist/deploy/agentcore/zip.js +3 -17
  226. package/dist/deploy/build-context.d.ts +21 -0
  227. package/dist/deploy/build-context.js +137 -0
  228. package/dist/deploy/channel-ingress.d.ts +26 -39
  229. package/dist/deploy/channel-ingress.js +57 -28
  230. package/dist/deploy/container.d.ts +20 -34
  231. package/dist/deploy/container.js +49 -100
  232. package/dist/deploy/docker/plan.d.ts +12 -11
  233. package/dist/deploy/docker/plan.js +43 -24
  234. package/dist/deploy/docker/run.d.ts +22 -25
  235. package/dist/deploy/docker/run.js +39 -37
  236. package/dist/deploy/fly/plan.d.ts +15 -44
  237. package/dist/deploy/fly/plan.js +41 -73
  238. package/dist/deploy/fly/run.d.ts +16 -51
  239. package/dist/deploy/fly/run.js +42 -95
  240. package/dist/deploy/hosts.d.ts +24 -3
  241. package/dist/deploy/hosts.js +24 -3
  242. package/dist/deploy/preflight.d.ts +47 -41
  243. package/dist/deploy/preflight.js +282 -383
  244. package/dist/deploy/railway/plan.d.ts +16 -42
  245. package/dist/deploy/railway/plan.js +42 -60
  246. package/dist/deploy/railway/run.d.ts +30 -68
  247. package/dist/deploy/railway/run.js +86 -100
  248. package/dist/deploy/registration-gate.d.ts +6 -13
  249. package/dist/deploy/residency.d.ts +37 -0
  250. package/dist/deploy/residency.js +24 -0
  251. package/dist/deploy/runner.d.ts +10 -9
  252. package/dist/deploy/runner.js +7 -18
  253. package/dist/deploy/secrets.d.ts +40 -41
  254. package/dist/deploy/secrets.js +117 -103
  255. package/dist/deploy/workspace.d.ts +50 -0
  256. package/dist/deploy/workspace.js +197 -0
  257. package/dist/dev-supervisor.d.ts +1 -9
  258. package/dist/dev-supervisor.js +21 -64
  259. package/dist/effect-port.d.ts +50 -0
  260. package/dist/effect-port.js +77 -0
  261. package/dist/engines/pi/agent-session-factory.d.ts +50 -69
  262. package/dist/engines/pi/agent-session-factory.js +249 -146
  263. package/dist/engines/pi/auth.d.ts +15 -11
  264. package/dist/engines/pi/auth.js +96 -99
  265. package/dist/engines/pi/chat.d.ts +1 -5
  266. package/dist/engines/pi/chat.js +2 -14
  267. package/dist/engines/pi/config.d.ts +53 -51
  268. package/dist/engines/pi/config.js +83 -92
  269. package/dist/engines/pi/create.d.ts +60 -75
  270. package/dist/engines/pi/create.js +108 -141
  271. package/dist/engines/pi/definition.d.ts +14 -58
  272. package/dist/engines/pi/definition.js +21 -85
  273. package/dist/engines/pi/invoke-session.d.ts +5 -25
  274. package/dist/engines/pi/invoke-session.js +209 -244
  275. package/dist/engines/pi/login.d.ts +95 -35
  276. package/dist/engines/pi/login.js +259 -107
  277. package/dist/engines/pi/machine.d.ts +31 -0
  278. package/dist/engines/pi/machine.js +106 -0
  279. package/dist/engines/pi/models.d.ts +70 -89
  280. package/dist/engines/pi/models.js +188 -81
  281. package/dist/engines/pi/open.d.ts +65 -53
  282. package/dist/engines/pi/open.js +129 -69
  283. package/dist/engines/pi/report.d.ts +3 -12
  284. package/dist/engines/pi/report.js +2 -16
  285. package/dist/engines/pi/search-tools.d.ts +1 -9
  286. package/dist/engines/pi/search-tools.js +26 -57
  287. package/dist/engines/pi/service.d.ts +2 -16
  288. package/dist/engines/pi/service.js +2 -16
  289. package/dist/engines/pi/session-builder.d.ts +5 -9
  290. package/dist/engines/pi/session-builder.js +44 -82
  291. package/dist/engines/pi/session-control.js +286 -269
  292. package/dist/engines/pi/session-effects.d.ts +14 -0
  293. package/dist/engines/pi/session-effects.js +30 -0
  294. package/dist/engines/pi/session-inheritance.d.ts +9 -18
  295. package/dist/engines/pi/session-inheritance.js +103 -160
  296. package/dist/engines/pi/session-markers.d.ts +31 -30
  297. package/dist/engines/pi/session-markers.js +26 -25
  298. package/dist/engines/pi/session-settings.d.ts +6 -22
  299. package/dist/engines/pi/session-settings.js +10 -21
  300. package/dist/engines/pi/session-store.d.ts +26 -92
  301. package/dist/engines/pi/session-store.js +96 -310
  302. package/dist/engines/pi/tool-context.d.ts +17 -45
  303. package/dist/engines/pi/tool-context.js +7 -26
  304. package/dist/engines/pi/tool.d.ts +45 -36
  305. package/dist/engines/pi/tool.js +43 -57
  306. package/dist/engines/pi/turn-kit.d.ts +14 -52
  307. package/dist/engines/pi/turn-kit.js +18 -67
  308. package/dist/engines/pi/wake-tool.d.ts +2 -10
  309. package/dist/engines/pi/wake-tool.js +7 -27
  310. package/dist/env.d.ts +27 -28
  311. package/dist/env.js +45 -50
  312. package/dist/index.js +0 -2
  313. package/dist/lark.d.ts +1 -2
  314. package/dist/lark.js +1 -2
  315. package/dist/loader.d.ts +14 -55
  316. package/dist/loader.js +24 -43
  317. package/dist/log.d.ts +2 -12
  318. package/dist/log.js +3 -24
  319. package/dist/node.d.ts +2 -15
  320. package/dist/node.js +2 -18
  321. package/dist/observe.d.ts +2 -8
  322. package/dist/open-url.d.ts +1 -1
  323. package/dist/open-url.js +1 -1
  324. package/dist/paths.d.ts +70 -134
  325. package/dist/paths.js +165 -232
  326. package/dist/pi.d.ts +4 -6
  327. package/dist/pi.js +3 -3
  328. package/dist/proxy.d.ts +16 -6
  329. package/dist/proxy.js +52 -16
  330. package/dist/runtime.d.ts +18 -12
  331. package/dist/runtime.js +18 -11
  332. package/dist/scaffold/add-channel.d.ts +14 -31
  333. package/dist/scaffold/add-channel.js +48 -112
  334. package/dist/scaffold/init.d.ts +9 -31
  335. package/dist/scaffold/init.js +45 -138
  336. package/dist/scaffold/templates/env.example +6 -4
  337. package/dist/scaffold/templates/fastagent.config.ts +36 -0
  338. package/dist/scaffold/templates.d.ts +3 -3
  339. package/dist/scaffold/templates.js +5 -8
  340. package/dist/scaffold/vendor-skill.d.ts +2 -5
  341. package/dist/scaffold/vendor-skill.js +19 -29
  342. package/dist/schedule/cron.d.ts +9 -5
  343. package/dist/schedule/cron.js +9 -11
  344. package/dist/schedule/discover.d.ts +12 -12
  345. package/dist/schedule/discover.js +43 -34
  346. package/dist/schedule/routine.d.ts +43 -0
  347. package/dist/schedule/routine.js +32 -0
  348. package/dist/schedule/run.d.ts +55 -0
  349. package/dist/schedule/run.js +146 -0
  350. package/dist/schedule/scheduler.d.ts +44 -55
  351. package/dist/schedule/scheduler.js +291 -265
  352. package/dist/schedule/state.d.ts +105 -10
  353. package/dist/schedule/state.js +293 -19
  354. package/dist/schedule/wake-alarm.d.ts +10 -23
  355. package/dist/schedule/wake-alarm.js +91 -121
  356. package/dist/schedule/wakeups.d.ts +23 -39
  357. package/dist/schedule/wakeups.js +33 -75
  358. package/dist/secrets-gate.d.ts +32 -0
  359. package/dist/secrets-gate.js +33 -0
  360. package/dist/service.d.ts +137 -98
  361. package/dist/service.js +250 -252
  362. package/dist/session-remote.d.ts +33 -44
  363. package/dist/session-remote.js +203 -192
  364. package/dist/session.d.ts +153 -228
  365. package/dist/session.js +33 -55
  366. package/dist/tunnel.d.ts +8 -36
  367. package/dist/tunnel.js +24 -65
  368. package/dist/version.d.ts +2 -2
  369. package/dist/version.js +2 -2
  370. package/package.json +10 -16
  371. package/dist/channels/agentcore-state.d.ts +0 -77
  372. package/dist/channels/agentcore-state.js +0 -276
  373. package/dist/channels/github/github.d.ts +0 -31
  374. package/dist/channels/github/github.js +0 -89
  375. package/dist/channels/github/scaffold/channel.ts +0 -25
  376. package/dist/cli/commands/attach.d.ts +0 -108
  377. package/dist/cli/commands/attach.js +0 -637
  378. package/dist/cli/commands/fire.d.ts +0 -7
  379. package/dist/cli/commands/fire.js +0 -38
  380. package/dist/cli/commands/schedule.d.ts +0 -12
  381. package/dist/cli/commands/schedule.js +0 -87
  382. package/dist/github.d.ts +0 -3
  383. package/dist/github.js +0 -2
  384. package/dist/scaffold/templates/fastagent.config.mjs +0 -23
  385. package/dist/schedule/audit.d.ts +0 -18
  386. package/dist/schedule/audit.js +0 -57
  387. package/dist/schedule/schedule.d.ts +0 -35
  388. package/dist/schedule/schedule.js +0 -23
package/dist/session.js CHANGED
@@ -1,75 +1,53 @@
1
1
  /**
2
- * Can this id be ADDRESSED by a client? A session id is an opaque Caller string, and the data plane
3
- * takes any of it — but a control plane carries the id as a URL path segment, and three strings are
4
- * not path segments: the empty one, `.` and `..`. URL normalisation eats them before any router
5
- * sees them (`encodeURIComponent` does not help; the spec normalises `%2E` too), so a request for
6
- * `.` arrives as a request for the collection and answers about something else entirely.
7
- *
8
- * The rule lives HERE, in the contract, because both sides enforce it and they must not drift: a
9
- * transport rejects such an id rather than sending a request that will silently address its
10
- * neighbour, and an implementation refuses to MINT one (a fork target nothing could open) — while a
11
- * session a channel already created under one keeps running, and keeps appearing in `list()`, since
12
- * hiding it would be the silent half of the same problem.
2
+ * Can this id be ADDRESSED by a client? URL normalisation eats `""`, `.` and `..` before any router sees them, so a
3
+ * request for `.` would answer about the collection instead. The rule lives in the contract because both sides
4
+ * enforce it and must not drift: a transport refuses to send such an id, and an implementation refuses to MINT one.
13
5
  */
14
6
  export function isAddressableSession(session) {
15
7
  return session !== "" && session !== "." && session !== "..";
16
8
  }
17
- /** Every field name, as a value — what an implementation checks a patch against, and what a
18
- * transport rejects an unknown key by. The `satisfies` anchor keeps it exhaustive: a field added to
19
- * {@link SessionUpdate} must be added here too, or this stops compiling. */
9
+ /**
10
+ * Every field name, as a value — what an implementation checks a patch against, and what a transport rejects an
11
+ * unknown key by.
12
+ */
20
13
  export const UPDATE_FIELDS = [
21
14
  "name",
22
15
  "model",
23
16
  "thinkingLevel",
24
17
  "leafEntryId",
25
18
  ];
26
- /** Stable `SessionResult.error.code` for a call, or an update field, the implementation does not
27
- * support — the answer to calling past a {@link SessionCapabilities} gate. */
19
+ /**
20
+ * Stable `SessionResult.error.code` for a call, or an update field, the implementation does not support — the answer
21
+ * to calling past a {@link SessionCapabilities} gate.
22
+ */
28
23
  export const UNSUPPORTED_CAPABILITY_CODE = "unsupported_capability";
29
- /** Stable `SessionResult.error.code` for a run action
30
- * (`steer`/`follow_up`/`abort`) called while the session has no active run — and, for `abort`, no
31
- * in-flight compaction either (`abort` is also the door out of a `compacting` state; the outcome
32
- * then travels as `compaction_finished{aborted}`). `retryable: false` — the same call fails again;
33
- * call it after `state()` shows an active run. */
24
+ /**
25
+ * Stable `SessionResult.error.code` for a run action (`steer`/`follow_up`/`abort`) called while the session has no
26
+ * active run.
27
+ */
34
28
  export const NO_ACTIVE_RUN_CODE = "no_active_run";
35
- /** Stable `SessionResult.error.code` for a PAYLOAD that is invalid for this runtime — an unknown
36
- * model spec, an unsupported thinking level, an entry id that is not a position, a fork onto an id
37
- * another history already holds. Permanent for that payload; a different value may succeed.
38
- * Rejected before acceptance. */
29
+ /** Stable `SessionResult.error.code` for a PAYLOAD that is invalid for this runtime. */
39
30
  export const INVALID_COMMAND_CODE = "invalid_command";
40
- /** Stable `SessionResult.error.code` for a write against a session that does not exist. Sessions are
41
- * created by the DATA plane (`invoke`) or copied by `fork`, never minted by an update — a write on
42
- * an unknown id (a typo, a not-yet-started conversation) must not create a ghost record. Rejected
43
- * before acceptance; retry once the session's first turn exists. */
31
+ /** Stable `SessionResult.error.code` for a write against a session that does not exist. */
44
32
  export const NO_SUCH_SESSION_CODE = "no_such_session";
45
- /** Stable `SessionResult.error.code` for a write rejected BEFORE acceptance with nothing durable
46
- * landed — a failed property append, a fork whose copy could not be written, or compact's admission
47
- * failing (binding the session, the local preparation). Acceptance sits where the work becomes asynchronous and
48
- * expensive: the model call — compact is accept-fast (holding the dispatch open for a full model
49
- * call would make acceptance = outcome), and post-acceptance outcomes travel as
50
- * `compaction_finished{summary|error|aborted}` events. `retryable: true` throughout: the same
51
- * command may succeed on retry (the state-dependent "nothing to compact" has its own code,
52
- * {@link NOTHING_TO_COMPACT_CODE}). */
33
+ /** Stable `SessionResult.error.code` for a write rejected BEFORE acceptance with nothing durable landed. */
53
34
  export const BOUNDARY_COMMAND_FAILED_CODE = "boundary_command_failed";
54
- /** Stable `SessionResult.error.code` for `compact` on a session with no compactable history yet —
55
- * a no-op, not a failure, rejected before acceptance. The {@link NO_ACTIVE_RUN_CODE} pattern:
56
- * `retryable: false` (as-is retry fails now), call it again once the session has grown. */
35
+ /**
36
+ * Stable `SessionResult.error.code` for `compact` on a session with no compactable history yet — a no-op, not a
37
+ * failure, rejected before acceptance.
38
+ */
57
39
  export const NOTHING_TO_COMPACT_CODE = "nothing_to_compact";
58
- /** Stable `SessionResult.error.code` for a run action that reached an active run but could not take
59
- * effect because the run raced to settlement (or the engine refused it). Distinct from
60
- * {@link NO_ACTIVE_RUN_CODE}: the run existed — and TRANSIENT: the session's next run can be acted
61
- * on. Still pre-acceptance — nothing was queued — and `retryable: false`: the same call fails
62
- * again. (A run registered without modulation controls is a capability problem, not a run problem,
63
- * and rejects with {@link UNSUPPORTED_CAPABILITY_CODE}.) */
40
+ /**
41
+ * Stable `SessionResult.error.code` for a run action that reached an active run but could not take effect because the
42
+ * run raced to settlement (or the engine refused it).
43
+ */
64
44
  export const RUN_COMMAND_FAILED_CODE = "run_command_failed";
65
- /** What {@link SessionCollection.list} rejects with — the only read that can (see it for why). Not a
66
- * `SessionResult`: it REJECTS, and a transport carries this code in the error body of a non-2xx
67
- * (design §13). `retryable: true` — the condition is the store's availability, not the request. */
45
+ /** What {@link SessionCollection.list} rejects with — the only read that can. `retryable: true`: the condition is
46
+ * the store's availability, not the request. */
68
47
  export const SESSIONS_UNAVAILABLE_CODE = "sessions_unavailable";
69
- /** Stable `SessionResult.error.code` for a multi-field {@link Session.update} that wrote some of its
70
- * fields and then failed. It exists because {@link BOUNDARY_COMMAND_FAILED_CODE} promises the
71
- * opposite — nothing durable landed — and an implementation cannot keep that promise across
72
- * properties an engine records as separate journal entries. `retryable: false`: re-sending the same
73
- * patch would re-apply what already landed, so a client reads `state()` (or the `state_changed`
74
- * this emits first, which reports the record as it now is) and decides what is left to ask for. */
48
+ /**
49
+ * Stable `SessionResult.error.code` for a multi-field {@link Session.update} that wrote some of its fields and then
50
+ * failed — the ONE code that reports durable work behind an `ok: false`. The message names what landed, and a
51
+ * `state_changed` event reporting the record as it now is precedes it.
52
+ */
75
53
  export const PARTIAL_UPDATE_CODE = "partial_update";
package/dist/tunnel.d.ts CHANGED
@@ -1,10 +1,7 @@
1
1
  /**
2
- * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then
3
- * auto-register the first-party webhook channels against it (Telegram setWebhook; onboarded Slack
4
- * App Manifest update; Feishu/Lark application-config PATCH; GitHub/manual Slack print URLs). This closes the
5
- * "local dev → public URL" gap webhooks need.
6
- *
7
- * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
2
+ * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then auto-register the
3
+ * first-party webhook channels against it (Telegram setWebhook; onboarded Slack App Manifest update; Feishu/Lark
4
+ * application-config PATCH; manual Slack prints the URL).
8
5
  */
9
6
  import { type ChildProcess } from "node:child_process";
10
7
  import type { RegistrationOutcome } from "./channels/registration.ts";
@@ -17,42 +14,17 @@ export interface Tunnel {
17
14
  export declare function parseTunnelUrl(chunk: string): string | undefined;
18
15
  /** Whether cloudflared's output so far reports an edge connection — see {@link TUNNEL_CONNECTED_RE}. */
19
16
  export declare function hasTunnelConnection(output: string): boolean;
20
- /**
21
- * How long after that connection to hand the URL over. The one number here that is not observed: 5s
22
- * covers the widest of the 7 measured gaps (3.9s), all taken over cloudflared's http2 transport
23
- * because this network blocks its QUIC. Costs a beat of `dev --tunnel` start-up; buys the first
24
- * registration attempt landing on a name that resolves.
25
- */
17
+ /** How long after that connection to hand the URL over. */
26
18
  export declare const TUNNEL_DNS_LAG_MS = 5000;
27
19
  /** How cloudflared is launched; injectable so tests can drive the child without a real process. */
28
20
  type SpawnCloudflared = (port: number) => ChildProcess;
29
21
  /**
30
- * Start a Cloudflare quick tunnel to localhost:`port`, resolving once its public URL is assigned AND
31
- * the tunnel has an edge connection — the URL is printed first and is not usable yet
32
- * ({@link hasTunnelConnection}). cloudflared sometimes exits before printing a URL (a transient
33
- * trycloudflare API error), so retry a few times. ALWAYS resolves to undefined WITH an operator log
34
- * saying why — missing binary, the exit reason, or "gave up after retries" — never silently; serving
35
- * continues without a tunnel either way. What remains after this is the PLATFORM's own warm-up, which
36
- * each registrar absorbs by retrying while the platform reports it cannot yet verify the URL.
22
+ * Start a Cloudflare quick tunnel to localhost:`port`, resolving once its public URL is assigned AND the tunnel has an
23
+ * edge connection.
37
24
  */
38
25
  export declare function startCloudflareTunnel(port: number, spawnFn?: SpawnCloudflared, attemptTimeoutMs?: number): Promise<Tunnel | undefined>;
39
- /**
40
- * Print the public URL and wire up first-party webhook channels found under `dir` (the agent
41
- * ROOT): Telegram and Feishu/Lark use runtime credentials; onboarded Slack uses its owner-local config
42
- * token; GitHub and a manually scaffolded Slack app receive explicit console URLs.
43
- *
44
- * Returns what each registrar ANSWERED, because two kinds of caller need different things from a
45
- * failure. `dev`/`start` are long-running: a webhook that did not register is a logged problem, not
46
- * a reason to stop serving, and they void this. `deploy … --run` is a command that exits, and an
47
- * exit 0 there tells its caller the deployment is reachable — so it feeds these through
48
- * `registrationGate`, exactly as the fly/railway/agentcore runners feed their own registrar calls
49
- * (docker used to be the one host that could not, because this returned nothing).
50
- */
51
- export declare function announceWebhooks(dir: string, baseUrl: string,
52
- /** Every declared channel with its ingress. Not a pre-filtered list: this used to accept "the route
53
- * channels" and default to every basename in `channels/`, which pointed a webhook at a
54
- * long-connection channel whenever a caller forgot to filter. {@link pointChannelsAt} filters. */
55
- channels: readonly DeclaredChannel[], opts?: {
26
+ /** Print the public URL and wire up first-party webhook channels found under `dir` (the agent ROOT). */
27
+ export declare function announceWebhooks(dir: string, baseUrl: string, channels: readonly DeclaredChannel[], opts?: {
56
28
  openUrl?: (url: string) => void;
57
29
  stateRoot?: string;
58
30
  }): Promise<{
package/dist/tunnel.js CHANGED
@@ -1,10 +1,7 @@
1
1
  /**
2
- * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then
3
- * auto-register the first-party webhook channels against it (Telegram setWebhook; onboarded Slack
4
- * App Manifest update; Feishu/Lark application-config PATCH; GitHub/manual Slack print URLs). This closes the
5
- * "local dev → public URL" gap webhooks need.
6
- *
7
- * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
2
+ * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then auto-register the
3
+ * first-party webhook channels against it (Telegram setWebhook; onboarded Slack App Manifest update; Feishu/Lark
4
+ * application-config PATCH; manual Slack prints the URL).
8
5
  */
9
6
  import { spawn } from "node:child_process";
10
7
  import { registerFeishuWebhook } from "./channels/feishu/register-webhook.js";
@@ -12,38 +9,25 @@ import { registerSlackWebhook } from "./channels/slack/register-webhook.js";
12
9
  import { registerTelegramWebhook } from "./channels/telegram/register-webhook.js";
13
10
  import { pointChannelsAt } from "./deploy/channel-ingress.js";
14
11
  import { dotEnvPath, loadDotEnv } from "./env.js";
12
+ import { installProxyFetch } from "./proxy.js";
15
13
  import { resolveStateRoot } from "./paths.js";
16
14
  import { log } from "./log.js";
17
- // `(?!api\.)`: cloudflared's ERROR lines mention its request endpoint (`https://api.trycloudflare.com/tunnel`,
18
- // e.g. "failed to request quick Tunnel: Post ... timeout" under a flaky proxy) — without the exclusion a
19
- // transient error line parses as the assigned URL and the webhook gets registered against Cloudflare's
20
- // API host instead of the tunnel.
15
+ // `(?!api\.)`: cloudflared's ERROR lines mention its request endpoint (`https://api.trycloudflare.com/tunnel`, e.g.
16
+ // "failed to request quick Tunnel: Post ... timeout" under a flaky proxy) — without the exclusion a transient error
17
+ // line parses as the assigned URL and the webhook gets registered against Cloudflare's API host instead of the
18
+ // tunnel.
21
19
  const TUNNEL_URL_RE = /https:\/\/(?!api\.)[a-z0-9-]+\.trycloudflare\.com/i;
22
20
  /** Extract a Cloudflare quick-tunnel URL from a chunk of cloudflared output, if present. */
23
21
  export function parseTunnelUrl(chunk) {
24
22
  return chunk.match(TUNNEL_URL_RE)?.[0];
25
23
  }
26
- /**
27
- * cloudflared's line for an established edge connection. THIS, not the URL, is when the hostname
28
- * begins to exist: `*.trycloudflare.com` is no wildcard, and a quick tunnel's record is published
29
- * once the tunnel registers a connection — so the URL is printed while the name is still NXDOMAIN.
30
- * A platform told about it inside that window answers "Failed to resolve host" and goes on answering
31
- * it far longer than any registrar's retry budget (#435); the record going live seconds later does
32
- * not undo the answer it already gave, which is why more retries were never the fix.
33
- *
34
- * Measured over 7 quick tunnels: the URL at +0s, this line at +1.1-1.9s, the record 0.5-3.9s later.
35
- */
24
+ /** cloudflared's line for an established edge connection. */
36
25
  const TUNNEL_CONNECTED_RE = /Registered tunnel connection/i;
37
26
  /** Whether cloudflared's output so far reports an edge connection — see {@link TUNNEL_CONNECTED_RE}. */
38
27
  export function hasTunnelConnection(output) {
39
28
  return TUNNEL_CONNECTED_RE.test(output);
40
29
  }
41
- /**
42
- * How long after that connection to hand the URL over. The one number here that is not observed: 5s
43
- * covers the widest of the 7 measured gaps (3.9s), all taken over cloudflared's http2 transport
44
- * because this network blocks its QUIC. Costs a beat of `dev --tunnel` start-up; buys the first
45
- * registration attempt landing on a name that resolves.
46
- */
30
+ /** How long after that connection to hand the URL over. */
47
31
  export const TUNNEL_DNS_LAG_MS = 5000;
48
32
  /** Global timer (rather than timers/promises) so timeout/retry behavior is deterministic under fake timers. */
49
33
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -53,13 +37,8 @@ const TUNNEL_RETRY_MS = 2000;
53
37
  const TUNNEL_START_TIMEOUT_MS = 30_000;
54
38
  const spawnCloudflared = (port) => spawn("cloudflared", ["tunnel", "--url", `http://localhost:${port}`], { stdio: ["ignore", "pipe", "pipe"] });
55
39
  /**
56
- * Start a Cloudflare quick tunnel to localhost:`port`, resolving once its public URL is assigned AND
57
- * the tunnel has an edge connection — the URL is printed first and is not usable yet
58
- * ({@link hasTunnelConnection}). cloudflared sometimes exits before printing a URL (a transient
59
- * trycloudflare API error), so retry a few times. ALWAYS resolves to undefined WITH an operator log
60
- * saying why — missing binary, the exit reason, or "gave up after retries" — never silently; serving
61
- * continues without a tunnel either way. What remains after this is the PLATFORM's own warm-up, which
62
- * each registrar absorbs by retrying while the platform reports it cannot yet verify the URL.
40
+ * Start a Cloudflare quick tunnel to localhost:`port`, resolving once its public URL is assigned AND the tunnel has an
41
+ * edge connection.
63
42
  */
64
43
  export async function startCloudflareTunnel(port, spawnFn = spawnCloudflared, attemptTimeoutMs = TUNNEL_START_TIMEOUT_MS) {
65
44
  for (let attempt = 1; attempt <= TUNNEL_ATTEMPTS; attempt++) {
@@ -78,8 +57,10 @@ export async function startCloudflareTunnel(port, spawnFn = spawnCloudflared, at
78
57
  }
79
58
  return undefined;
80
59
  }
81
- /** One cloudflared launch: a Tunnel once its URL is assigned AND the edge connection is up, or a
82
- * failure (missing binary / exit before a URL). */
60
+ /**
61
+ * One cloudflared launch: a Tunnel once its URL is assigned AND the edge connection is up, or a failure (missing
62
+ * binary / exit before a URL).
63
+ */
83
64
  function spawnTunnelOnce(port, spawnFn, timeoutMs) {
84
65
  return new Promise((resolve) => {
85
66
  const child = spawnFn(port);
@@ -123,8 +104,7 @@ function spawnTunnelOnce(port, spawnFn, timeoutMs) {
123
104
  });
124
105
  child.on("exit", () => finish({ fatal: false, detail: lastErrorLine(tail) }));
125
106
  timer = setTimeout(() => {
126
- // A URL whose tunnel never connected is not worth a fresh one — the next attempt meets the same
127
- // network. Serve it and name what is wrong, rather than retrying into the same wall.
107
+ // A URL whose tunnel never connected is not worth a fresh one — the next attempt meets the same network.
128
108
  if (assigned) {
129
109
  log.warn(`[fastagent] --tunnel: cloudflared never reported an edge connection for ${assigned} within ` +
130
110
  `${Math.round(timeoutMs / 1000)}s — serving it anyway. Nothing reaches a tunnel that has not ` +
@@ -146,41 +126,20 @@ function lastErrorLine(tail) {
146
126
  .filter(Boolean);
147
127
  return ([...lines].reverse().find((l) => /err|error|failed/i.test(l)) ?? lines.at(-1) ?? "").slice(0, 200);
148
128
  }
149
- /**
150
- * Print the public URL and wire up first-party webhook channels found under `dir` (the agent
151
- * ROOT): Telegram and Feishu/Lark use runtime credentials; onboarded Slack uses its owner-local config
152
- * token; GitHub and a manually scaffolded Slack app receive explicit console URLs.
153
- *
154
- * Returns what each registrar ANSWERED, because two kinds of caller need different things from a
155
- * failure. `dev`/`start` are long-running: a webhook that did not register is a logged problem, not
156
- * a reason to stop serving, and they void this. `deploy … --run` is a command that exits, and an
157
- * exit 0 there tells its caller the deployment is reachable — so it feeds these through
158
- * `registrationGate`, exactly as the fly/railway/agentcore runners feed their own registrar calls
159
- * (docker used to be the one host that could not, because this returned nothing).
160
- */
161
- export async function announceWebhooks(dir, baseUrl,
162
- /** Every declared channel with its ingress. Not a pre-filtered list: this used to accept "the route
163
- * channels" and default to every basename in `channels/`, which pointed a webhook at a
164
- * long-connection channel whenever a caller forgot to filter. {@link pointChannelsAt} filters. */
165
- channels, opts = {}) {
129
+ /** Print the public URL and wire up first-party webhook channels found under `dir` (the agent ROOT). */
130
+ export async function announceWebhooks(dir, baseUrl, channels, opts = {}) {
166
131
  log.info(`[fastagent] public URL: ${baseUrl}`);
167
132
  try {
168
133
  loadDotEnv(dir); // webhook registrars read channel credentials from .env
169
134
  }
170
135
  catch (error) {
171
- // best-effort boundary: a MISSING .env is already tolerated by loadDotEnv; an unreadable one (EACCES,
172
- // or .env is a directory) must NOT crash the long-running dev/start server — announceWebhooks is
173
- // void-called with no unhandledRejection handler, so a throw here would terminate the process. Warn
174
- // (surface it, rule 8) and continue best-effort; each registrar then surfaces its own
175
- // missing-credential guidance. loadDotEnv keeps throwing for the synchronous command callers.
136
+ // best-effort boundary: an unreadable .env (a MISSING one is already tolerated) still leaves registrars that can
137
+ // report their own missing credentials, so this one names the file instead of aborting the tunnel announcement.
176
138
  log.warn(`[fastagent] could not read ${dotEnvPath(dir)}: ${error.message} — continuing without it`);
177
139
  }
178
- // Readiness is the registrar's job: a fresh quick tunnel returns Cloudflare 530 for ~20-30s before its
179
- // origin connects, and each registrar absorbs that by retrying the platform call whose own URL
180
- // verification reports it. GitHub needs no wait — the operator adds that webhook by hand.
181
- //
182
- // The registrars differ from the deploy path's in what they carry, not in which channels they answer
183
- // for: this one narrates to the log and opens the console for a manual Feishu step.
140
+ installProxyFetch(); // the registrars' platform calls follow the proxy that .env may declare
141
+ // Readiness is the registrar's job: a fresh quick tunnel returns Cloudflare 530 for ~20-30s before its origin
142
+ // connects, and each registrar absorbs that by retrying the platform call whose own URL verification reports it.
184
143
  const feishuOptions = {
185
144
  onManualRegistration: ({ consoleUrl }) => opts.openUrl?.(consoleUrl),
186
145
  };
package/dist/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This build's own @fastagent-sh/fastagent version. THROWS if unreadable — the version is load-bearing for
3
- * the scaffolded dependency range (`^${version}`), so init must never scaffold an uninstallable `^0.0.0`.
2
+ * This build's own @fastagent-sh/fastagent version. THROWS if unreadable — the version is load-bearing for the
3
+ * scaffolded dependency range (`^${version}`), so `init` must never fall back and scaffold an uninstallable `^0.0.0`.
4
4
  */
5
5
  export declare function fastagentVersion(): Promise<string>;
package/dist/version.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { fileURLToPath } from "node:url";
3
3
  /**
4
- * This build's own @fastagent-sh/fastagent version. THROWS if unreadable — the version is load-bearing for
5
- * the scaffolded dependency range (`^${version}`), so init must never scaffold an uninstallable `^0.0.0`.
4
+ * This build's own @fastagent-sh/fastagent version. THROWS if unreadable — the version is load-bearing for the
5
+ * scaffolded dependency range (`^${version}`), so `init` must never fall back and scaffold an uninstallable `^0.0.0`.
6
6
  */
7
7
  export async function fastagentVersion() {
8
8
  const pkgPath = fileURLToPath(new URL("../package.json", import.meta.url));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fastagent-sh/fastagent",
3
- "version": "0.21.0",
4
- "description": "Vibe first. Then FastAgent: turn a local agent directory into a live service in your app, on GitHub, Telegram, Slack, or behind any channel.",
3
+ "version": "0.22.0",
4
+ "description": "Vibe first. Then FastAgent: turn a local agent directory into a live service in your app, on Telegram, Slack, Feishu, or behind any channel.",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "ai-agent",
@@ -11,7 +11,6 @@
11
11
  "agent-serving",
12
12
  "telegram",
13
13
  "slack",
14
- "github",
15
14
  "webhook",
16
15
  "sse",
17
16
  "pi",
@@ -55,10 +54,6 @@
55
54
  "types": "./dist/pi.d.ts",
56
55
  "default": "./dist/pi.js"
57
56
  },
58
- "./github": {
59
- "types": "./dist/github.d.ts",
60
- "default": "./dist/github.js"
61
- },
62
57
  "./telegram": {
63
58
  "types": "./dist/telegram.d.ts",
64
59
  "default": "./dist/telegram.js"
@@ -106,16 +101,15 @@
106
101
  },
107
102
  "dependencies": {
108
103
  "@clack/prompts": "^1.6.0",
109
- "@earendil-works/pi-agent-core": "^0.85.1",
110
- "@earendil-works/pi-ai": "^0.85.1",
111
- "@earendil-works/pi-coding-agent": "^0.85.1",
104
+ "@earendil-works/pi-agent-core": "^0.87.1",
105
+ "@earendil-works/pi-ai": "^0.87.1",
106
+ "@earendil-works/pi-coding-agent": "^0.87.1",
112
107
  "@hono/node-server": "^2.1.1",
113
108
  "@larksuiteoapi/node-sdk": "^1.71.1",
114
- "@octokit/webhooks-methods": "^6.0.0",
115
- "@octokit/webhooks-types": "^7.6.1",
116
109
  "chokidar": "^5.0.0",
117
110
  "commander": "^15.0.0",
118
111
  "croner": "^10.0.1",
112
+ "effect": "4.0.0-rc.117",
119
113
  "giget": "^3.3.0",
120
114
  "ignore": "^7.0.5",
121
115
  "proper-lockfile": "^4.1.2",
@@ -123,14 +117,14 @@
123
117
  "zod": "^4.4.3"
124
118
  },
125
119
  "devDependencies": {
126
- "@biomejs/biome": "^2.5.2",
120
+ "@biomejs/biome": "^2.5.14",
127
121
  "@types/express": "^5.0.6",
128
122
  "@types/proper-lockfile": "^4.1.4",
129
123
  "express": "^5.2.1",
130
- "fastify": "^5.12.1",
131
- "knip": "^6.29.0",
124
+ "fastify": "^5.12.5",
125
+ "knip": "^6.37.0",
132
126
  "typescript": "^7.0.2",
133
- "vitest": "^4.1.9",
127
+ "vitest": "^5.0.1",
134
128
  "yaml": "^2.9.0"
135
129
  }
136
130
  }
@@ -1,77 +0,0 @@
1
- /**
2
- * Cross-deploy durability for the state root on AgentCore.
3
- *
4
- * WHY THIS EXISTS: AgentCore's managed SessionStorage — the `/mnt/state` mount — is reset on every
5
- * runtime VERSION UPDATE, i.e. on EVERY deploy ("On runtime version update: Data wiped — fresh file
6
- * system on next invoke", AWS file-system configuration docs), and again after 14 idle days. The
7
- * mount is therefore a fast LOCAL disk, not the source of truth. Without this module a deploy
8
- * silently resurrects the agent with no sessions, no channel dedup, no pending wake-ups — and the
9
- * wake ALARM, which lives in the operator's EventBridge and survives independently, still fires into
10
- * that empty store: a miss with no error anywhere (exactly the silent-failure class the repo's
11
- * fail-visibly rule exists to prevent).
12
- *
13
- * The durable copy is ONE S3 object reached through PRESIGNED URLS minted per-envelope by the
14
- * forwarder Lambda. The container holds no AWS credentials (the platform injects none — verified on
15
- * a live deployment) and stays AWS-SDK-free: a snapshot is one `fetch` GET and one `fetch` PUT.
16
- *
17
- * Format: gzip(JSON `{ v, files: { relPath: base64 } }`). Deliberately NOT tar — the state root is a
18
- * handful of small JSON/JSONL files, and a single self-describing object makes restore ATOMIC: a
19
- * half-applied state root is far worse than a slightly stale one.
20
- */
21
- import { Buffer } from "node:buffer";
22
- import type { StateUrls } from "./agentcore-protocol.ts";
23
- /** Snapshot envelope version — an unknown version fails the restore loudly (never a silent skip). */
24
- export declare const SNAPSHOT_VERSION = 1;
25
- /** Refuse to pack beyond this (before gzip): a runaway state root would OOM the microVM silently. */
26
- export declare const MAX_SNAPSHOT_BYTES: number;
27
- /** Pack the whole state root into one gzipped snapshot object.
28
- * ponytail: the WHOLE root, every idle edge — O(state size) per settled turn, and session jsonl
29
- * grows without bound. Upgrade path when the 16 MiB warning is real for someone: a per-file
30
- * manifest with content hashes, uploading only what changed. */
31
- export declare function packStateRoot(stateRoot: string, maxBytes?: number): Promise<Buffer>;
32
- /** Apply a snapshot over the state root. Returns how many files were written. */
33
- export declare function unpackIntoStateRoot(stateRoot: string, packed: Buffer): Promise<number>;
34
- export interface StateSyncOptions {
35
- stateRoot: string;
36
- /** Injected in tests. */
37
- fetchImpl?: typeof fetch;
38
- }
39
- /**
40
- * The per-process snapshot lifecycle: restore ONCE before anything reads the state root, then push a
41
- * coalesced snapshot whenever work settles.
42
- */
43
- export interface StateSync {
44
- /** Remember the newest presigned URLs (each envelope carries a fresh pair). */
45
- use(urls: StateUrls): void;
46
- /** Resolve once the state root is authoritative. REJECTS if a snapshot exists but cannot be
47
- * restored — the caller must fail the request rather than serve from an empty state root (and a
48
- * failed restore also blocks {@link StateSync.save}, so bad state is never written back).
49
- * Resolves immediately while no URLs are known: a direct programmatic invoke runs in its OWN
50
- * isolated session/storage and must neither read nor overwrite the ingress snapshot. */
51
- ready(): Promise<void>;
52
- /** Whether snapshotting is active (URLs seen). Lets the caller flag a forwarder envelope that
53
- * arrived WITHOUT them — a topology fault that would otherwise lose state silently. */
54
- configured(): boolean;
55
- /** Request a snapshot upload; coalesces while one is in flight. Errors are logged, not thrown —
56
- * the next settle retries, and the local mount still holds the data until the version changes. */
57
- save(): void;
58
- /** Await the in-flight (and any queued) upload — the shutdown/test seam. */
59
- flush(): Promise<void>;
60
- /**
61
- * Push a snapshot NOW and report whether one was actually written — the pre-stop checkpoint
62
- * (`--run`, before `stop-runtime-session`). Distinct from {@link StateSync.save} on both counts:
63
- * it forces a fresh round rather than joining a coalescing window (the caller is about to lose
64
- * this process, so "an upload from a second ago" is not good enough), and it THROWS on failure
65
- * instead of logging, because the whole point of the call is to know.
66
- *
67
- * `written: false` is a legitimate outcome, not an error: a session that never served a forwarder
68
- * envelope has no URLs and nothing of the shared state to write. The caller must not report that
69
- * as a successful checkpoint — it is exactly the case where an operator would otherwise believe an
70
- * in-flight turn had been protected.
71
- */
72
- checkpoint(): Promise<{
73
- written: boolean;
74
- reason?: string;
75
- }>;
76
- }
77
- export declare function createStateSync(options: StateSyncOptions): StateSync;