@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
@@ -1,14 +1,11 @@
1
1
  /**
2
- * The fastagent command registry: every command as data ({@link CommandSpec}) with a lazy-imported
3
- * implementation, so `fastagent <cmd>` pays only for the module graph that command actually uses.
4
- * This file is the CLI surface's single source of truth — the overview and every per-command help
5
- * render from these specs (no hand-maintained usage text).
2
+ * The fastagent command registry: every command as data ({@link CommandSpec}) with a lazy-imported implementation, so
3
+ * `fastagent <cmd>` pays only for the module graph that command actually uses.
6
4
  */
7
5
  import { fastagentVersion } from "../version.js";
8
6
  import { buildProgram } from "./kernel.js";
9
7
  import { DEPLOY_HOSTS } from "../deploy/hosts.js";
10
8
  // Help groups (clig: most common commands first) — the authoring loop leads, operations close.
11
- // Shared flags — same name, same meaning, on every command that supports them (clig: consistency).
12
9
  const DIR_ARG = {
13
10
  name: "[dir]",
14
11
  description: "workspace directory (the agent is here, or in a directory inside it)",
@@ -18,10 +15,6 @@ const MODEL = {
18
15
  flags: "--model <provider/modelId>",
19
16
  description: "model override (precedence: --model > FASTAGENT_MODEL > config)",
20
17
  };
21
- const AUTH_PATH = {
22
- flags: "--auth-path <file>",
23
- description: "credentials file (default: <agent dir>/.secrets/auth.json; env: FASTAGENT_AUTH_PATH)",
24
- };
25
18
  const JSON_FLAG = { flags: "--json", description: "machine-readable JSON output" };
26
19
  const NO_INPUT = {
27
20
  flags: "--no-input",
@@ -30,54 +23,48 @@ const NO_INPUT = {
30
23
  const PORT = { flags: "--port <n>", description: "HTTP port" };
31
24
  const BIND = {
32
25
  flags: "--bind <addr>",
33
- description: "bind address (default: all interfaces; 127.0.0.1 keeps it off the LAN)",
26
+ description: "bind address (dev defaults to 127.0.0.1; start defaults to all interfaces, which containers need)",
27
+ };
28
+ const NO_INVOKE = {
29
+ flags: "--no-invoke",
30
+ description: "do not serve POST /invoke on this run, nor POST /run — both are unauthenticated and run a turn with the " +
31
+ "agent's full tools, so a serve meant to be reached only through its channels' signed webhooks should withhold " +
32
+ "them (fastagent.config.ts http.invoke: false is the same choice, but it travels into a deployed image; this " +
33
+ "flag outranks http.run: true, because a flag is what a definition you cannot edit still answers to)",
34
34
  };
35
35
  const TUNNEL = {
36
36
  flags: "--tunnel",
37
37
  description: "expose a public HTTPS URL via a Cloudflare quick tunnel (needs cloudflared) and auto-register " +
38
- "webhook channels (telegram, onboarded slack, feishu, lark; github/manual slack print the URL) — for hosting a bot from your " +
38
+ "webhook channels (telegram, onboarded slack, feishu, lark; manual slack prints the URL) — for hosting a bot from your " +
39
39
  "own box without deploying (the quick-tunnel URL is ephemeral, not for production)",
40
40
  };
41
41
  const init = {
42
42
  name: "init",
43
43
  summary: "scaffold a runnable agent and install its dependencies",
44
- description: "Scaffold a runnable agent and run npm install. By default the agent goes into ./fastagent/ in dir " +
45
- "(default .; --agent-dir names it otherwise) — the rest of the directory gets zero writes, and it is " +
46
- "the WORKSPACE the agent works ON when you point fastagent there. Default content is a " +
44
+ description: "Scaffold a runnable agent and run npm install. The agent ALWAYS goes into a subdirectory of dir " +
45
+ "(default .): ./fastagent/, or --agent-dir <name> — the rest of the directory gets zero writes, and " +
46
+ "it is the WORKSPACE the agent works ON when you point fastagent there. Content is a " +
47
47
  "self-iterating agent: persona.md (its identity), a writing-great-skills " +
48
48
  "example skill, a fetch-url code tool, config, package.json, .gitignore. An existing AGENTS.md is " +
49
49
  "kept as project context.",
50
50
  args: [DIR_ARG],
51
51
  flags: [
52
- { flags: "--minimal", description: "persona.md + the example skill + config only (no code tool / package.json)" },
53
52
  { flags: "--no-install", description: "scaffold everything but skip npm install" },
54
- { flags: "--agent-dir <name>", description: "name the agent directory (default fastagent; . = dir itself)" },
55
- {
56
- flags: "--flat",
57
- description: "alias for --agent-dir . — the directory IS the agent; keeps existing files",
58
- // Two spellings of ONE knob: `--flat --agent-dir bot` names the same thing twice with different
59
- // values, which is a usage error, not a precedence question to settle silently.
60
- conflicts: ["agentDir"],
61
- },
53
+ { flags: "--agent-dir <name>", description: "name the agent directory (default fastagent)" },
62
54
  ],
63
55
  examples: [
64
56
  { cmd: "fastagent init", note: "the agent lands in ./fastagent/" },
65
57
  { cmd: "fastagent init my-project", note: "my-project/fastagent/ (created)" },
66
58
  { cmd: "fastagent init . --agent-dir bot", note: "./bot/ — any name works" },
67
- { cmd: "fastagent init . --flat", note: "this repo IS the agent" },
68
59
  ],
69
- notes: "An agent is a directory holding a fastagent.config.* — never its NAME, so --agent-dir can call it " +
60
+ notes: "An agent is a directory holding a fastagent.config.ts — never its NAME, so --agent-dir can call it " +
70
61
  "anything (the name decides only which agent answers when a workspace holds several: see " +
71
62
  "FASTAGENT_AGENT). What the agent works ON (its cwd, where its AGENTS.md context is read from) is " +
72
- "whatever directory you later point fastagent at: point at the project and the agent inside it " +
73
- "serves with the project as its workspace; point at the agent directory (all a deployed box may " +
74
- "hold) and it works on itself. A directory resolves to ONE agent, at it or one level inside.",
63
+ "the agent directory's parent — the project you ran init in — whether you point fastagent at the " +
64
+ "project or at the agent directory. A directory resolves to ONE agent, at it or one level inside.",
75
65
  run: async (args, f) => (await import("./commands/init.js")).runInit(args[0], {
76
- minimal: f.minimal === true,
77
66
  install: f.install !== false,
78
- // `--flat` is the spelling for the common case of the same knob (they conflict, so only one is
79
- // ever set); both land in ONE value, so the scaffolder never sees two ways to say ".".
80
- agentDir: f.flat === true ? "." : typeof f.agentDir === "string" ? f.agentDir : undefined,
67
+ agentDir: typeof f.agentDir === "string" ? f.agentDir : undefined,
81
68
  }),
82
69
  };
83
70
  const dev = {
@@ -85,16 +72,16 @@ const dev = {
85
72
  summary: "serve the agent locally, restarting on code edits",
86
73
  description: "Assemble the agent in dir (default .) and serve a local HTTP channel. persona.md/AGENTS.md/skills " +
87
74
  "are re-read every turn (edits go live next turn); edits to code inputs — tools/, channels/, " +
88
- "fastagent.config.*, package.json, .secrets/.env — restart the worker. Files the agent writes as " +
75
+ "fastagent.config.ts, package.json, .secrets/.env — restart the worker. Files the agent writes as " +
89
76
  "work product never trigger a restart.",
90
77
  args: [DIR_ARG],
91
78
  flags: [
92
79
  PORT,
93
80
  BIND,
94
81
  MODEL,
95
- AUTH_PATH,
96
82
  { flags: "--no-watch", description: "serve once, no file-watching" },
97
83
  TUNNEL,
84
+ NO_INVOKE,
98
85
  NO_INPUT,
99
86
  ],
100
87
  examples: [
@@ -105,31 +92,12 @@ const dev = {
105
92
  port: f.port,
106
93
  bind: f.bind,
107
94
  model: f.model,
108
- authPath: f.authPath,
109
95
  watch: f.watch !== false,
110
96
  tunnel: f.tunnel === true,
97
+ ...(f.invoke === false ? { invoke: false } : {}),
111
98
  input: f.input !== false,
112
99
  }),
113
100
  };
114
- const attach = {
115
- name: "attach",
116
- summary: "watch a session's live events from a running serve and steer it",
117
- description: "Attach to a session served by a running dev/start with `sessionControl: true` in the config: " +
118
- "stream its live events (text, tools, run boundaries), steer the active run by typing — or, with " +
119
- "no run active, start one (detaching cancels a run YOU started) — /abort to stop a run. Discovers " +
120
- "the local endpoint from <stateRoot>/control.json; --url/--token reach a remote serve. The same " +
121
- "wire protocol a Web panel or desktop app uses.",
122
- args: [{ name: "<session>", description: "the session id to attach to" }, DIR_ARG],
123
- flags: [
124
- { flags: "--url <url>", description: "control endpoint (skip control.json discovery)" },
125
- { flags: "--token <token>", description: "bearer token for --url" },
126
- ],
127
- examples: [{ cmd: "fastagent attach tg-chat-42" }],
128
- run: async (args, f) => (await import("./commands/attach.js")).runAttach(args[0], args[1], {
129
- url: f.url,
130
- token: f.token,
131
- }),
132
- };
133
101
  const chat = {
134
102
  name: "chat",
135
103
  summary: "open the SAME assembled agent in pi's interactive TUI",
@@ -137,12 +105,9 @@ const chat = {
137
105
  "try it locally before serving. Same model/tool/skill/auth resolution as dev; pi handles " +
138
106
  "rendering, sessions, and /resume natively (its /login writes to the same fastagent auth file).",
139
107
  args: [DIR_ARG],
140
- flags: [MODEL, AUTH_PATH],
108
+ flags: [MODEL],
141
109
  examples: [{ cmd: "fastagent chat" }],
142
- run: async (args, f) => (await import("./commands/chat.js")).runChat(args[0], {
143
- model: f.model,
144
- authPath: f.authPath,
145
- }),
110
+ run: async (args, f) => (await import("./commands/chat.js")).runChat(args[0], { model: f.model }),
146
111
  };
147
112
  const info = {
148
113
  name: "info",
@@ -152,13 +117,11 @@ const info = {
152
117
  "Read-only (never creates sessions / writes .gitignore); an unset model is reported, not fatal. " +
153
118
  "Run it first when something looks off.",
154
119
  args: [DIR_ARG],
155
- flags: [JSON_FLAG, MODEL, AUTH_PATH, { flags: "--sessions-dir <dir>", description: "sessions directory override" }],
120
+ flags: [JSON_FLAG, MODEL],
156
121
  examples: [{ cmd: "fastagent info" }, { cmd: "fastagent info --json", note: "for CI" }],
157
122
  run: async (args, f) => (await import("./commands/info.js")).runInfo(args[0], {
158
123
  json: f.json === true,
159
124
  model: f.model,
160
- authPath: f.authPath,
161
- sessionsDir: f.sessionsDir,
162
125
  }),
163
126
  };
164
127
  const tool = {
@@ -183,25 +146,10 @@ const invoke = {
183
146
  "stdout, tool/diagnostics to stderr, a failed turn exits non-zero. The all-agent counterpart of " +
184
147
  "`tool`, for CI smoke and quick checks. Same model resolution as dev.",
185
148
  args: [{ name: "<message>", description: "the user message for the turn" }, DIR_ARG],
186
- flags: [MODEL, AUTH_PATH, NO_INPUT],
149
+ flags: [MODEL, NO_INPUT],
187
150
  examples: [{ cmd: `fastagent invoke "summarize today's inbox"` }],
188
151
  run: async (args, f) => (await import("./commands/invoke.js")).runInvoke(args[0], args[1], {
189
152
  model: f.model,
190
- authPath: f.authPath,
191
- input: f.input !== false,
192
- }),
193
- };
194
- const fire = {
195
- name: "fire",
196
- summary: "run ONE schedule's turn immediately, without waiting for its cron",
197
- description: "Run ONE schedule's turn immediately (authoring loop, like invoke) — fires schedules/<name>.ts now " +
198
- "without waiting for its cron. Reply→stdout; does NOT advance the schedule's fire state.",
199
- args: [{ name: "<name>", description: "the schedule name (schedules/<name>.ts)" }, DIR_ARG],
200
- flags: [MODEL, AUTH_PATH, NO_INPUT],
201
- examples: [{ cmd: "fastagent fire daily-digest" }],
202
- run: async (args, f) => (await import("./commands/fire.js")).runFire(args[0], args[1], {
203
- model: f.model,
204
- authPath: f.authPath,
205
153
  input: f.input !== false,
206
154
  }),
207
155
  };
@@ -223,37 +171,33 @@ const start = {
223
171
  "is the agent), just no file-watching. No build step: start reads the definition directly; " +
224
172
  "model/http come from fastagent.config.ts (frozen by git).",
225
173
  args: [DIR_ARG],
226
- flags: [
227
- PORT,
228
- BIND,
229
- MODEL,
230
- { flags: "--sessions-dir <dir>", description: "sessions directory override" },
231
- AUTH_PATH,
232
- TUNNEL,
233
- NO_INPUT,
234
- ],
174
+ flags: [PORT, BIND, MODEL, TUNNEL, NO_INVOKE, NO_INPUT],
235
175
  examples: [
236
176
  { cmd: "fastagent start" },
237
177
  { cmd: "fastagent start --tunnel", note: "host a bot from your own box, no deploy" },
238
178
  ],
239
179
  notes: "Precedence chains:\n" +
240
180
  " port: --port > PORT env > fastagent.config.ts http.port > 8787\n" +
241
- " bind: --bind > fastagent.config.ts http.host > all interfaces\n" +
181
+ " bind: --bind > all interfaces (dev: 127.0.0.1)\n" +
182
+ " /invoke: --no-invoke > fastagent.config.ts http.invoke > served\n" +
183
+ " /run: --no-invoke > fastagent.config.ts http.run > http.invoke\n" +
184
+ " (with GET /routines; both only where routines/ declares something)\n" +
242
185
  " state: FASTAGENT_STATE_DIR > <agent dir>/.state — mutable machine state\n" +
243
186
  " (sessions, channel state, schedule state); point it at a mounted\n" +
244
187
  " volume so a redeploy that replaces the directory never wipes it\n" +
245
188
  " secrets: FASTAGENT_SECRETS_DIR > <agent dir>/.secrets — .env + auth.json\n" +
246
- " sessions: --sessions-dir > FASTAGENT_SESSIONS_DIR > <state>/sessions\n" +
247
- " auth: --auth-path > FASTAGENT_AUTH_PATH > <secrets>/auth.json\n" +
189
+ " sessions: <state>/sessions — no separate knob; move the state root\n" +
190
+ " auth: FASTAGENT_AUTH_PATH > <secrets>/auth.json\n" +
248
191
  " (project-level; point it at ~/.fastagent/.secrets/auth.json to\n" +
249
- " share one credential across projects)",
192
+ " share one credential across projects)\n" +
193
+ " endpoints: FASTAGENT_MODELS_PATH > ~/.fastagent/models.json, under the agent's\n" +
194
+ " own models.json (the machine's; it does not ship with a deploy)",
250
195
  run: async (args, f) => (await import("./commands/start.js")).runStart(args[0], {
251
196
  port: f.port,
252
197
  bind: f.bind,
253
198
  model: f.model,
254
- sessionsDir: f.sessionsDir,
255
- authPath: f.authPath,
256
199
  tunnel: f.tunnel === true,
200
+ ...(f.invoke === false ? { invoke: false } : {}),
257
201
  input: f.input !== false,
258
202
  }),
259
203
  };
@@ -295,13 +239,10 @@ const channelSub = (kind, summary, description, notes) => ({
295
239
  });
296
240
  const add = {
297
241
  name: "add",
298
- summary: "connect a channel (github, telegram, slack, feishu, lark) or vendor a skill",
299
- description: "Scaffold channels/<kind>.ts — first-party adapter glue with the policy to edit (github maps " +
300
- "events in on(); telegram/slack/feishu/lark route in the optional route()) — or vendor an Agent Skills " +
301
- "skill into skills/<name>/.",
242
+ summary: "connect a channel (telegram, slack, feishu, lark) or vendor a skill",
243
+ description: "Scaffold channels/<kind>.ts — first-party adapter glue with the policy to edit in the optional " +
244
+ "route() — or vendor an Agent Skills skill into skills/<name>/.",
302
245
  subcommands: [
303
- channelSub("github", "scaffold the GitHub webhook channel (issues/PRs → agent turns)", "Scaffold channels/github.ts — webhook adapter glue that maps repository events (issues, PRs, " +
304
- "comments) to agent turns in its on() policy."),
305
246
  channelSub("telegram", "scaffold the Telegram bot channel (durable turns, live preview)", "Scaffold channels/telegram.ts — the Telegram bot channel with durable turns, a live-preview " +
306
247
  "message pump, and an optional route() policy."),
307
248
  channelSub("slack", "scaffold the Slack Events API channel (files, threads, context, live preview)", "Choose group visibility, scaffold channels/slack.ts plus slack-send.ts, create a single-workspace " +
@@ -369,21 +310,11 @@ const deploy = {
369
310
  "with --run. Existing Compose stays authoritative",
370
311
  },
371
312
  { flags: "--force", description: "overwrite existing target config/Dockerfile/.dockerignore (else kept)" },
372
- {
373
- flags: "--stop",
374
- description: "(fly only) autostop by stopping (cold start) instead of suspending (fast resume)",
375
- },
376
- {
377
- flags: "--no-scale-to-zero",
378
- description: "(fly only) keep one machine running when idle (min_machines_running=1)",
379
- },
380
313
  {
381
314
  flags: "--into-linked",
382
315
  description: "(railway --run) provision INTO the project this dir is already linked to (skip create); by " +
383
316
  "default --run refuses a pre-existing link (could be unrelated/production)",
384
317
  },
385
- MODEL,
386
- AUTH_PATH,
387
318
  NO_INPUT,
388
319
  ],
389
320
  examples: [
@@ -399,55 +330,82 @@ const deploy = {
399
330
  run: f.run === true,
400
331
  tunnel: f.tunnel === true,
401
332
  force: f.force === true,
402
- stop: f.stop === true,
403
- scaleToZero: f.scaleToZero !== false,
404
333
  intoLinked: f.intoLinked === true,
405
- model: f.model,
406
- authPath: f.authPath,
407
334
  input: f.input !== false,
408
335
  }),
409
336
  };
410
- const schedule = {
411
- name: "schedule",
412
- summary: "inspect and control time triggers: run audit, pending fires, cancel a wake-up",
337
+ const routine = {
338
+ name: "routine",
339
+ summary: "run and inspect the units of work this definition declares: run now, fire history, what exists",
413
340
  subcommands: [
341
+ {
342
+ name: "run",
343
+ summary: "run ONE routine's turn immediately, without waiting for a clock",
344
+ description: "Run ONE routine's turn immediately (authoring loop, like invoke) — runs routines/<name>.ts now, " +
345
+ "whether or not it declares a cron. Reply→stdout; does NOT advance its fire state.",
346
+ args: [{ name: "<name>", description: "the routine name (routines/<name>.ts)" }, DIR_ARG],
347
+ flags: [MODEL, NO_INPUT],
348
+ examples: [{ cmd: "fastagent routine run daily-digest" }],
349
+ run: async (args, f) => (await import("./commands/routine-run.js")).runRoutine(args[0], args[1], {
350
+ model: f.model,
351
+ input: f.input !== false,
352
+ }),
353
+ },
414
354
  {
415
355
  name: "history",
416
- summary: 'print the run audit for a schedule (or "wake" for self-scheduled wake-ups)',
417
- description: "Print the run audit for a schedule: when each run fired, completed/failed/deferred, duration, and " +
418
- 'the reply/error — the answer to "did last night\'s run silently fail?". Read-only.',
419
- args: [
420
- { name: "<name>", description: 'the schedule name, or "wake" for the agent\'s self-scheduled wake-ups' },
421
- DIR_ARG,
422
- ],
423
- flags: [{ flags: "--json", description: "the full records (complete reply text)" }],
424
- examples: [
425
- { cmd: "fastagent schedule history daily-digest" },
426
- { cmd: "fastagent schedule history wake --json", note: "the agent's own wake-ups" },
427
- ],
428
- run: async (args, flags) => (await import("./commands/schedule.js")).runScheduleHistory(args[0], args[1], flags.json === true),
356
+ summary: "print the recent fires of a routine",
357
+ description: "Print a routine's recent fires: when each fired, completed/failed/skipped/interrupted, and how long it " +
358
+ 'took — the answer to "did last night\'s run silently fail?". What the run SAID is in its session, a ' +
359
+ "JSON-lines journal under the state root's sessions/ — which this command points at. Read-only.",
360
+ args: [{ name: "<name>", description: "the routine name" }, DIR_ARG],
361
+ flags: [{ flags: "--json", description: "the full records" }],
362
+ examples: [{ cmd: "fastagent routine history daily-digest" }],
363
+ run: async (args, flags) => (await import("./commands/routine.js")).runRoutineHistory(args[0], args[1], flags.json === true),
429
364
  },
430
365
  {
431
366
  name: "list",
432
- summary: "everything that will fire: static schedules (next instant) + pending wake-ups",
433
- description: "List everything that will fire, from BOTH producers: the static schedules/ files (name + next " +
434
- "cron instant) and the agent's pending self-scheduled wake-ups. Read-only.",
367
+ summary: "every declared routine, and when (or whether) a clock fires it",
368
+ description: "List the routines this definition declares: the next cron instant for each that has one, and " +
369
+ '"on demand" for each that does not — those are reached by name (POST /run, `routine run`). The agent\'s ' +
370
+ "own pending wake-ups are listed too, prefixed `wake`: a different owner (the STATE, not the " +
371
+ "definition), and only the agent cancels them (the `unwake` tool). Read-only.",
435
372
  args: [DIR_ARG],
436
373
  flags: [JSON_FLAG],
437
- examples: [{ cmd: "fastagent schedule list" }],
438
- run: async (args, flags) => (await import("./commands/schedule.js")).runScheduleList(args[0], flags.json === true),
439
- },
440
- {
441
- name: "cancel",
442
- summary: "remove a pending wake-up — the operator's kill switch for a runaway recurring wake",
443
- description: "Remove a pending wake-up — the operator's kill switch for a runaway recurring wake (the agent's own " +
444
- "is the `unwake` tool). Not session-scoped: the operator owns the box.",
445
- args: [{ name: "<id>", description: "the wake-up id (`fastagent schedule list` shows ids)" }, DIR_ARG],
446
- examples: [{ cmd: "fastagent schedule cancel wake-1700000000000-ab12" }],
447
- run: async (args) => (await import("./commands/schedule.js")).runScheduleCancel(args[0], args[1]),
374
+ examples: [{ cmd: "fastagent routine list" }],
375
+ run: async (args, flags) => (await import("./commands/routine.js")).runRoutineList(args[0], flags.json === true),
448
376
  },
449
377
  ],
450
378
  };
379
+ const destroy = {
380
+ name: "destroy",
381
+ summary: "delete every AWS resource `deploy agentcore` created for a workspace",
382
+ description: "AgentCore only, and it exists because `aws cloudformation delete-stack` is not enough: the S3 " +
383
+ "artifact bucket and the ECR repository have to exist BEFORE the stack that reads from them, BOTH " +
384
+ "log groups (the forwarder's and the runtime's own stdout) are created by AWS on first write so no " +
385
+ "template mentions them, and a wake alarm is minted at runtime by the container — a schedule that " +
386
+ "keeps retrying into a deleted Lambda. " +
387
+ "Derives the same names from dir that deploy did. Without --run it deletes nothing and reports what " +
388
+ "is out there.",
389
+ args: [{ name: "<host>", description: "deployed host", choices: ["agentcore"] }, DIR_ARG],
390
+ flags: [{ flags: "--run", description: "actually delete. Without it, this is a read-only inventory" }],
391
+ // The other hosts need no command of their own, and saying which one to use belongs where it can be READ:
392
+ // `<host>` has `choices`, so a `destroy fly` never reaches the command body.
393
+ examples: [
394
+ { cmd: "fastagent destroy agentcore", note: "what would be deleted" },
395
+ { cmd: "fastagent destroy agentcore --run", note: "delete it" },
396
+ ],
397
+ notes: "A bucket holding anything other than the forwarder's zips is reported and KEPT: an older deploy " +
398
+ "wrote agent state there, and it may be the only copy. Everything else is deleted unconditionally, " +
399
+ "including the agent's session storage on the AgentCore runtime — this host keeps it inside the " +
400
+ "stack, so there is no way to delete the deployment and keep the conversations. The other hosts need " +
401
+ "no command here: `fly apps destroy`, `railway down`, `docker compose -f fastagent.compose.yml down -v`. " +
402
+ "AWS ONLY: the " +
403
+ "webhook registrations `deploy --run` made with Telegram/Slack/Feishu still point at the deleted " +
404
+ "Function URL, and clearing them is a call to those platforms (for Telegram, deleteWebhook).",
405
+ run: async (args, f) => (await import("./commands/destroy.js")).runDestroy(args[0], args[1], {
406
+ run: f.run === true,
407
+ }),
408
+ };
451
409
  const logs = {
452
410
  name: "logs",
453
411
  summary: "find and tail a deployed host's application logs",
@@ -480,39 +438,44 @@ const login = {
480
438
  "agent it writes the global ~/.fastagent/.secrets/auth.json, and says so): pick a method " +
481
439
  "(subscription/OAuth or API " +
482
440
  "key), then a provider that offers it (configured status shown). [provider] takes the method from " +
483
- "what that provider supports, asked only when both.",
441
+ "what that provider supports, asked only when both. An agent READS the global store for any provider " +
442
+ "its own file does not have, so `-g` logs in once for every agent on this machine.",
484
443
  args: [{ name: "[provider]", description: "provider id (skip the provider menu)" }],
485
- flags: [AUTH_PATH, NO_INPUT],
486
- examples: [{ cmd: "fastagent login" }, { cmd: "fastagent login openai" }],
444
+ flags: [
445
+ {
446
+ flags: "-g, --global",
447
+ description: `store in ~/.fastagent/.secrets/auth.json — every agent here reads it for providers its own file lacks`,
448
+ },
449
+ NO_INPUT,
450
+ ],
451
+ examples: [{ cmd: "fastagent login" }, { cmd: "fastagent login openai" }, { cmd: "fastagent login openai -g" }],
487
452
  notes: "The positional is the PROVIDER (not a dir) — `cd` into your agent before logging in.",
488
453
  run: async (args, f) => (await import("./commands/login.js")).runLogin(args[0], {
489
- authPath: f.authPath,
454
+ global: f.global === true,
490
455
  input: f.input !== false,
491
456
  }),
492
457
  };
493
- /** Registration order = help order — the ORIGINAL usage wall's order, kept verbatim (this is a
494
- * commander refactor of the same CLI, not a redesign). Exported for the kernel conformance tests. */
458
+ /**
459
+ * Registration order = help order — the ORIGINAL usage wall's order, kept verbatim (this is a commander refactor of
460
+ * the same CLI, not a redesign).
461
+ */
495
462
  export const specs = [
496
463
  init,
497
464
  models,
498
465
  info,
499
466
  tool,
500
467
  invoke,
501
- fire,
502
- schedule,
468
+ routine,
503
469
  dev,
504
470
  chat,
505
- attach,
506
471
  start,
507
472
  add,
508
473
  deploy,
509
474
  logs,
475
+ destroy,
510
476
  login,
511
477
  ];
512
- /**
513
- * The production program assembly (specs + the top-level examples/docs). Tests build through THIS —
514
- * with their IO/width/color seams as overrides — so they exercise the real shape, not a lookalike.
515
- */
478
+ /** The production program assembly (specs + the top-level examples/docs). */
516
479
  export function buildCliProgram(overrides = {}) {
517
480
  return buildProgram(specs, {
518
481
  examples: [
@@ -524,7 +487,7 @@ export function buildCliProgram(overrides = {}) {
524
487
  ...overrides,
525
488
  });
526
489
  }
527
- /** Parse and run one CLI invocation (`argv` = process.argv). Usage errors exit 2 via the kernel policy. */
490
+ /** Parse and run one CLI invocation (`argv` = process.argv). */
528
491
  export async function runCli(argv) {
529
492
  await buildCliProgram({ version: await fastagentVersion() }).parseAsync([...argv]);
530
493
  }
@@ -1,26 +1,30 @@
1
1
  import type { Agent } from "../agent.ts";
2
- import type { AgentService, MountAgentServiceOptions } from "../service.ts";
2
+ import type { ChannelHandler } from "../channel.ts";
3
+ import { type AgentService, type MountableAgent, type MountAgentServiceOptions } from "../service.ts";
4
+ /** Refuse `--tunnel` with a `--bind` that cloudflared cannot reach. */
5
+ export declare function assertTunnelBindable(host: string | undefined, tunnel: boolean): void;
3
6
  /**
4
- * Refuse `--tunnel` with a bind that cloudflared cannot reach: it dials the NAME `localhost:<port>`
5
- * (the dev supervisor's tunnel too), so anything outside `127.0.0.1`/`::1`/wildcard — including a
6
- * `127.0.0.2` bind, loopback though it is — would leave the tunnel up and 502ing every request.
7
- * Checked BEFORE the bind (the flag alone pre-spawn in `dev`, again once config is loaded, since
8
- * `http.host` can carry the address), so the failure is clean rather than a live-but-broken public URL.
9
- * `source` decides the exit code, per fail.ts: a flag COMBINATION is a usage error (2), a value that
10
- * came from config is broken runtime configuration (1).
11
- */
12
- export declare function assertTunnelBindable(host: string | undefined, tunnel: boolean, source: "flag" | "config"): void;
13
- /**
14
- * The bind address a serve uses: the flag, else `http.host` from the config — through `bindAddress`,
15
- * so a configured `localhost` is an ADDRESS by the time anything binds, renders or dials it — checked
16
- * against `--tunnel` with the exit code the SOURCE of the value earns (serve.ts assertTunnelBindable).
7
+ * Apply the flags that override what the definition said, for THIS run only.
8
+ *
9
+ * ONE place, because `dev` and `start` both do it and a mapping two call sites must each remember is one a third
10
+ * will not.
11
+ *
12
+ * `--no-invoke` outranks `http.invoke`: a config value travels into a deployed image, so "do not publish a turn
13
+ * endpoint on this tunnel" has to be sayable without editing the definition.
14
+ *
15
+ * It takes `POST /run` WITH it, including over a definition that said `http.run: true`. Both routes start a
16
+ * turn for an anonymous caller, and the flag's whole reason for existing is the case where the definition cannot be
17
+ * edited — `dev --tunnel --no-invoke` leaving the other one published at the tunnel URL would be the flag failing at
18
+ * exactly the job it was added for.
17
19
  */
18
- export declare function resolveBindHost(bindFlag: string | undefined, configured: string | undefined, tunnel: boolean): string | undefined;
20
+ export declare function withRunOverrides<T extends MountableAgent>(opened: T, run: {
21
+ invoke?: boolean;
22
+ }): T;
19
23
  /** What the CLI adds to the assembly: its shutdown grace, and exit on a connection that drops. */
20
24
  export declare function cliMountOptions(wrapAgent: (agent: Agent) => Agent): MountAgentServiceOptions;
21
25
  /**
22
- * Bind, report, announce the control plane, open the tunnel, and close in order on a signal — the
23
- * tail dev's worker and start share once the service is assembled.
26
+ * Bind, report, announce the control plane, open the tunnel, and close in order on a signal — the tail dev's worker
27
+ * and start share once the service is assembled.
24
28
  */
25
29
  export declare function serveService(service: AgentService, bind: {
26
30
  port: number;
@@ -30,36 +34,48 @@ export declare function serveService(service: AgentService, bind: {
30
34
  agentDir: string;
31
35
  stateRoot: string;
32
36
  }): void;
33
- /**
34
- * The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and
35
- * what mounted. One function because both commands must say the same thing at the same moment —
36
- * after readiness, never at socket bind.
37
- */
37
+ /** The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and what mounted. */
38
38
  export declare function reportServing(service: AgentService, host: string | undefined, boundPort: number): void;
39
+ /** The line that names WHERE the serve is — every posture reports it, including AgentCore's own surface. */
40
+ export declare function bindLine(host: string | undefined, boundPort: number): string;
39
41
  /**
40
- * The startup lines that name WHERE the serve is: the bind report, and the curl the reader copies.
41
- * ONE function because they are one message — they were two, and `--bind` updated the first while the
42
- * second went on dialing `localhost`, which is precisely what a non-wildcard bind stops answering. Now
43
- * neither can be changed without the other in view, and the address has a single derivation.
42
+ * The startup lines for a serve of OUR surface: the bind report, and the curl the reader copies.
44
43
  *
45
- * A wildcard bind is every interface, and naming one address there would understate it — but the curl
46
- * still needs one to dial, which is what `clientHost` gives (loopback for a wildcard, itself otherwise).
44
+ * `servesInvoke` is `AgentService.unverifiedRoutes`, never a guess from the route table: `http.invoke: false` leaves no
45
+ * `/invoke` to curl, and a channel may serve that path with a protocol of its own — both would turn this line into
46
+ * a copyable request that fails.
47
47
  */
48
- export declare function readyAddressLines(host: string | undefined, boundPort: number, builtinInvoke: boolean): string[];
48
+ export declare function readyAddressLines(host: string | undefined, boundPort: number, servesInvoke: boolean): string[];
49
49
  /**
50
- * Write `<stateRoot>/control.json` so a LOCAL client (`fastagent attach`) can find the control plane
51
- * once the port is known, and say what reaches it. Returns the file's removal — wired into the
52
- * shutdown so a stale file cannot point a client at a dead port (`attach` then fails with "cannot
53
- * read", accurate, instead of a stale token's misleading 401/ECONNREFUSED). A hard exit leaves the
54
- * file behind: advisory, overwritten by the next boot.
50
+ * Say what this port exposes and how far it reaches.
55
51
  *
56
- * Here and not in the assembly: the file, its permissions and the warnings are how THIS process's
57
- * operator finds and protects the plane. An embedder distributes `service.control` itself.
52
+ * NOTHING fastagent serves is authenticated — authentication belongs to the deployment (a gateway, a private
53
+ * network, AgentCore's IAM, an embedder's middleware). Two of the three warnings fire at a REACH the operator did
54
+ * not get by default: a bind off this machine, and `--tunnel`'s public URL.
55
+ *
56
+ * The cross-origin one is UNCONDITIONAL, including on a loopback `dev`, because the grant is. `*` is the default
57
+ * (`channels/serve.ts`), so a page the developer merely visits can drive this port from their browser and read the
58
+ * reply, loopback bind or not. Nobody opts into a default, so the one posture the decision costs is the one that
59
+ * has to hear about it.
60
+ *
61
+ * WHAT IS EXPOSED is read off `AgentService.unverifiedRoutes`, never assumed and never guessed from the route table.
62
+ * `POST /invoke` is on most serves but not all: AgentCore answers the Runtime's `/invocations` behind IAM,
63
+ * `http.invoke: false` withholds it, and a channel may serve that path itself — in which case the caller it is
64
+ * open to is the platform that signs its requests, not anyone at all. A warning naming an endpoint this process
65
+ * does not serve is how an operator learns to skim past all of them — the same reason `preflightDeploy` takes
66
+ * `publicUrl`.
58
67
  */
59
- export declare function announceControl(control: {
60
- token: string;
61
- prefix: string;
62
- } | undefined, stateRoot: string, bind: {
68
+ export declare function announceControl(service: Pick<AgentService, "controlPrefix" | "unverifiedRoutes" | "corsOrigins">, bind: {
63
69
  host?: string;
64
70
  tunnel: boolean;
65
- }, boundPort: number): () => void;
71
+ }): void;
72
+ /** Bind HTTP and report ready — but only once the SERVICE is, which is not the same moment. */
73
+ export declare function serve(handler: ChannelHandler, bind: {
74
+ port: number;
75
+ host?: string;
76
+ }, hooks?: {
77
+ /** Awaited before anything is reported ready — see the listening handler. */
78
+ ready?: Promise<void>;
79
+ onListening?: (boundPort: number) => void;
80
+ onShutdown?: () => Promise<void> | void;
81
+ }): void;