@fastagent-sh/fastagent 0.21.1 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 -40
  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 +233 -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 +166 -229
  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,49 +1,24 @@
1
1
  import { preflightDeploy } from "../../deploy/preflight.js";
2
- import { loadConfig, resolveModelSpec } from "../../engines/pi/config.js";
2
+ import { loadConfig } from "../../engines/pi/config.js";
3
3
  import { failStartup, failUsage } from "../fail.js";
4
4
  import { enterAgentCommand } from "../shared.js";
5
5
  import { agentcoreHost } from "./deploy/agentcore.js";
6
6
  import { dockerHost } from "./deploy/docker.js";
7
7
  import { flyHost } from "./deploy/fly.js";
8
8
  import { railwayHost } from "./deploy/railway.js";
9
- import { writeArtifacts } from "./deploy/shared.js";
10
- export { writeArtifacts };
11
- /** Every host, by the name the CLI takes. Typed over {@link DeployHost} so a host added to the list
12
- * without a module here fails to compile. */
9
+ import { applyArtifactPlan, planArtifacts } from "./deploy/shared.js";
10
+ export { applyArtifactPlan, planArtifacts };
11
+ /** Every host, by the name the CLI takes. */
13
12
  export const HOSTS = {
14
13
  docker: dockerHost,
15
14
  fly: flyHost,
16
15
  railway: railwayHost,
17
16
  agentcore: agentcoreHost,
18
17
  };
19
- /** Infers `Owner` from the literal's own `owner`, so each row carries its exhaustiveness itself. The
20
- * alternative — annotating the array as a tuple of `HostOnlyFlag<"fly"> | …` — put the whole guarantee
21
- * in one annotation that a third rule invites relaxing to `HostOnlyFlag<DeployHost>[]`, where
22
- * `Exclude<DeployHost, DeployHost>` collapses to `never` and every `instead` type-checks empty. */
18
+ /** Infers `Owner` from the literal's own `owner`, so each row carries its exhaustiveness itself. */
23
19
  const hostOnlyFlag = (rule) => rule;
24
- /**
25
- * ONE table for "this flag belongs to that host", because the fact is symmetric and was not stored
26
- * that way: each host branch stated the OTHER hosts' flags in its own words, so the same sentence
27
- * existed three times per flag and had already drifted (`Railway-only` twice, `railway-only` once).
28
- *
29
- * Every row is a flag that only WARNS elsewhere. `--tunnel` is host-only too and is deliberately not
30
- * here: it is a usage GATE (`failUsage`, exit 2) raised in `runDeploy`, not a warning — moving it in
31
- * would downgrade a refusal to a line of advice.
32
- *
33
- * Exported for the exhaustiveness test: the type stops a missing `instead` line, and the test stops it
34
- * from being typed away.
35
- */
20
+ /** ONE table for "this flag belongs to that host", because the fact is symmetric and was not stored that way. */
36
21
  export const HOST_ONLY_FLAGS = [
37
- hostOnlyFlag({
38
- flag: "--stop/--no-scale-to-zero",
39
- owner: "fly",
40
- passed: (opts) => opts.stop === true || opts.scaleToZero === false,
41
- instead: {
42
- docker: "local Compose stays running",
43
- railway: "Railway's App Sleeping is a dashboard toggle (the runbook states the manual step)",
44
- agentcore: "AgentCore's idle/lifetime policy lives in the template's LifecycleConfiguration",
45
- },
46
- }),
47
22
  hostOnlyFlag({
48
23
  flag: "--into-linked",
49
24
  owner: "railway",
@@ -55,26 +30,23 @@ export const HOST_ONLY_FLAGS = [
55
30
  },
56
31
  }),
57
32
  ];
58
- /** Exported for its own test: nothing covered these six sentences, which is how three of them came to
59
- * disagree about the spelling of a host name. */
33
+ /**
34
+ * Exported for its own test: nothing covered these six sentences, which is how three of them came to disagree about
35
+ * the spelling of a host name.
36
+ */
60
37
  export function warnHostOnlyFlags(host, opts) {
61
38
  for (const rule of HOST_ONLY_FLAGS) {
62
39
  if (host === rule.owner || !rule.passed(opts))
63
40
  continue;
64
- // The `continue` above is exactly the key set `instead` is typed over, but TS cannot narrow a
65
- // union member out through a comparison against a per-rule literal, so the read needs a cast —
66
- // and a cast is how a hole would reach the operator as the word "undefined". Unreachable while
67
- // the rows stay exhaustive, which is what the table's own test asserts.
41
+ // The `continue` above is exactly the key set `instead` is typed over, but TS cannot narrow a union member out
42
+ // through a comparison against a per-rule literal, so the read needs a cast — and a cast is how a hole would
43
+ // reach the operator as the word "undefined".
68
44
  const instead = rule.instead[host];
69
- // THROWN, not `failStartup`ed, though every other failure in this file exits through that: an
70
- // incomplete table is a bug, and fail.ts prints a plain Error's message WITHOUT its stack (it
71
- // reserves that shape for user-fixable problems) while exiting the process — which in the test
72
- // that covers this table would kill the worker instead of reporting which row is short.
45
+ // THROWN, not `failStartup`ed, though every other failure in this file exits through that.
73
46
  if (instead === undefined) {
74
47
  throw new Error(`deploy: HOST_ONLY_FLAGS has no "instead" line for ${host} on ${rule.flag}`);
75
48
  }
76
- // A colon, not "is": one row names a single flag and the other names a pair, and no verb agrees
77
- // with both (the hand-written copies this replaced said "is" and "are" respectively).
49
+ // A colon, not "is": one row names a single flag and the other names a pair, and no verb agrees with both.
78
50
  console.error(`[fastagent] warn: ${rule.flag}: ${rule.owner}-only — ${instead}`);
79
51
  }
80
52
  }
@@ -83,28 +55,22 @@ export async function runDeploy(host, dirArg, opts) {
83
55
  // A flag/host combination the parser cannot see (host is an argument) — usage class, exit 2.
84
56
  failUsage(`deploy stopped: --tunnel is supported only by the local Docker target`);
85
57
  }
86
- // The picker's write-back lands the model in fastagent.config.* — exactly what the model-travel
87
- // gate below requires (--model/env don't reach the deployed box) — and an inline login stores the
88
- // credential `--run` then carries. Runs BEFORE loadConfig; the read-back sees the rewritten file
89
- // because loadConfig cache-busts on mtime (a failed write-back still gates, correctly).
58
+ // The picker's write-back lands the model in fastagent.config.ts.
90
59
  const placement = await enterAgentCommand(dirArg, opts);
91
- // ONE deploy semantic: bake the WORKSPACE (WYSIWYG). Artifacts land under the agent dir
92
- // (`fastagent/`) plus the one workspace-root `.dockerignore` the packers require; host CLIs run
93
- // from the workspace, which is the build context.
60
+ // ONE deploy semantic: bake the WORKSPACE (WYSIWYG).
94
61
  const { agentDir, workspace } = placement;
95
62
  const { config } = await loadConfig(agentDir).catch(failStartup);
96
- const modelSpec = resolveModelSpec(opts.model, config);
97
- // The host-neutral pre-flight (model-travel gate, channel discovery, model-auth probe, container facts +
98
- // their warnings) lives in deploy/preflight.ts — testable in isolation. The CLI prints its messages and
99
- // stops on its gate; the host branch below adds only the host-specific artifacts + runbook + run drive.
63
+ // The host-neutral pre-flight (the model and its source, channel discovery, model-auth probe, container facts +
64
+ // their warnings) lives in deploy/preflight.ts.
100
65
  const pre = await preflightDeploy({
101
66
  placement,
102
67
  config,
103
- modelSpec,
104
68
  run: !!opts.run,
105
69
  force: !!opts.force,
106
70
  externalClock: host === "agentcore", // cron rides EventBridge there — the resident-host notes don't apply
107
- authPathFlag: opts.authPath, // flag > FASTAGENT_AUTH_PATH > default — resolved by preflight (one owner)
71
+ // AgentCore DOES get a public URL (the forwarder's, AuthType NONE) — but nothing of ours answers behind it:
72
+ // that relay reaches the channels' routes only, each verifying its platform's signature (agentcore-service.ts).
73
+ publicUrl: host !== "agentcore",
108
74
  }).catch(failStartup);
109
75
  if (!pre.ok)
110
76
  failStartup(new Error(`deploy stopped: ${pre.gate}`));
@@ -122,9 +88,21 @@ export async function runDeploy(host, dirArg, opts) {
122
88
  channels,
123
89
  webhookChannels: channels.filter((channel) => channel.ingress === "webhook"),
124
90
  longConnectionChannels: channels.filter((channel) => channel.ingress === "long-connection"),
125
- // The ownership predicate is bound HERE, from the same lookup that chose the host, so no host
126
- // module can pass one — the four that did each stated theirs twice, in a position where a
127
- // neighbour's type-checks and silently makes `--force` a no-op for the host's own artifact.
128
- write: (artifacts, options) => writeArtifacts(workspace, artifacts, { ...options, isOurs: target.isOurs }),
91
+ // The ownership predicate is bound HERE, from the same lookup that chose the host, so no host module can pass
92
+ // one.
93
+ // Reporting a stale artifact is enough when only generating them — the operator reads the line and decides. But
94
+ // `--run` would then deploy FROM it: a determinate mismatch between what ships and what the definition says,
95
+ // the same class as a Dockerfile that cannot read the manifest, and gated the
96
+ // same way. `--force` regenerates ours; a file we did not generate is never touched by either, and the marker
97
+ // line is how an operator takes a path back on purpose.
98
+ write: async (artifacts, options) => {
99
+ const plan = await planArtifacts(workspace, artifacts, { ...options, isOurs: target.isOurs });
100
+ if (opts.run && plan.stale.length > 0) {
101
+ failStartup(new Error(`deploy stopped: ${plan.stale.join(", ")} no longer match what this definition generates, and --run ` +
102
+ `would deploy from them. Re-run with --force to regenerate, or remove each file's generated-by ` +
103
+ `marker to own it yourself.`));
104
+ }
105
+ await applyArtifactPlan(plan);
106
+ },
129
107
  });
130
108
  }
@@ -0,0 +1,4 @@
1
+ export interface DestroyOptions {
2
+ run?: boolean;
3
+ }
4
+ export declare function runDestroy(host: string, dirArg: string, opts: DestroyOptions): Promise<void>;
@@ -0,0 +1,56 @@
1
+ /** `fastagent destroy agentcore [dir]`: remove every AWS resource the deploy created. */
2
+ import { basename, resolve } from "node:path";
3
+ import { destroyAgentcoreDeployment } from "../../deploy/agentcore/destroy.js";
4
+ import { agentcoreName } from "../../deploy/agentcore/plan.js";
5
+ import { spawnRunner } from "../../deploy/runner.js";
6
+ import { enterAgentEnv } from "../../env.js";
7
+ import { failStartup, failUsage, placementOrExit } from "../fail.js";
8
+ export async function runDestroy(host, dirArg, opts) {
9
+ // The host argument is DISPATCHED here, as in runLogs. In practice commander rejects anything else first
10
+ // (the spec declares `choices`), so what the operator reads is its message plus the spec's notes, which name
11
+ // the other hosts' own commands. This stays as the seam: a host added to `choices` must not be silently
12
+ // treated as agentcore.
13
+ if (host !== "agentcore")
14
+ failUsage(`destroy: unsupported host "${host}"`);
15
+ const placement = placementOrExit(resolve(dirArg));
16
+ enterAgentEnv(placement.agentDir); // AWS_PROFILE/region/proxy may be definition-local, as on deploy
17
+ const name = agentcoreName(basename(placement.workspace));
18
+ const outcome = await destroyAgentcoreDeployment({ name, run: opts.run === true }, spawnRunner("aws", placement.workspace), (message) => console.error(`[fastagent] destroy: ${message}`));
19
+ if (!outcome.ok) {
20
+ // THE WHOLE PICTURE, before the gate: a half-finished teardown is exactly when an operator needs to know
21
+ // what is out there, what is already gone, and what the retry still has to reach.
22
+ if (outcome.found.length > 0) {
23
+ console.log(`what a deploy of "${name}" put in this account:`);
24
+ for (const item of outcome.found)
25
+ console.log(` ${item}`);
26
+ }
27
+ if (outcome.removed.length > 0) {
28
+ console.log(`deleted before stopping:`);
29
+ for (const item of outcome.removed)
30
+ console.log(` ${item}`);
31
+ }
32
+ // The kept bucket belongs in EVERY report: it is the one thing this command decided not to delete, and a
33
+ // failure elsewhere is no reason for the operator to stop hearing about it.
34
+ for (const item of outcome.kept)
35
+ console.log(`\nKEPT: ${item}`);
36
+ failStartup(new Error(`destroy stopped: ${outcome.gate}`));
37
+ }
38
+ if (!opts.run) {
39
+ if (outcome.found.length === 0) {
40
+ console.log(`nothing in this account for "${name}" — no stack, bucket, repository or log group.`);
41
+ return;
42
+ }
43
+ console.log(`what a deploy of "${name}" put in this account:`);
44
+ for (const item of outcome.found)
45
+ console.log(` ${item}`);
46
+ for (const item of outcome.kept)
47
+ console.log(` NOT MINE TO DELETE: ${item}`);
48
+ console.log(`\nnothing was deleted. Re-run with --run to delete all of it.`);
49
+ return;
50
+ }
51
+ console.log(outcome.removed.length > 0 ? `deleted:` : `nothing left to delete for "${name}".`);
52
+ for (const item of outcome.removed)
53
+ console.log(` ${item}`);
54
+ for (const item of outcome.kept)
55
+ console.log(`\nKEPT: ${item}`);
56
+ }
@@ -2,10 +2,11 @@ export interface DevOptions {
2
2
  port?: string;
3
3
  bind?: string;
4
4
  model?: string;
5
- authPath?: string;
6
5
  /** false ⇔ `--no-watch`. */
7
6
  watch?: boolean;
8
7
  tunnel?: boolean;
8
+ /** false ⇔ `--no-invoke`: withhold `POST /invoke` for THIS run (`http.invoke` is the persistent form). */
9
+ invoke?: boolean;
9
10
  /** false ⇔ `--no-input`. */
10
11
  input?: boolean;
11
12
  }
@@ -1,51 +1,48 @@
1
1
  /**
2
- * `fastagent dev`: a SUPERVISOR that spawns a worker (this command with FASTAGENT_DEV_WORKER set) to
3
- * assemble + serve, restarting it on agent edits. A fresh process per reload means what is served
4
- * is always the latest code, including modules a tool/config imports.
2
+ * `fastagent dev`: a SUPERVISOR that spawns a worker (this command with FASTAGENT_DEV_WORKER set) to assemble + serve,
3
+ * restarting it on agent edits.
5
4
  */
6
5
  import { runDevSupervisor } from "../../dev-supervisor.js";
7
6
  import { setLogLevel } from "../../log.js";
8
7
  import { createPiAgentFromDir } from "../../engines/pi/open.js";
9
- import { mountAgentService } from "../../service.js";
8
+ import { DEFAULT_HTTP_PORT, mountAgentService } from "../../service.js";
10
9
  import { logAgentLoop } from "../../observe.js";
11
10
  import { failStartup } from "../fail.js";
12
- import { assertTunnelBindable, cliMountOptions, resolveBindHost, serveService } from "../serve.js";
11
+ import { assertTunnelBindable, cliMountOptions, serveService, withRunOverrides } from "../serve.js";
13
12
  import { enterAgentCommand, parseBind, parsePort, reportAssembly } from "../shared.js";
13
+ /**
14
+ * `dev` binds loopback unless `--bind` says otherwise: a dev serve carries the agent's full tool authority and lands on
15
+ * networks its author does not own. `--bind 0.0.0.0` gives back the reach a container or a phone needs.
16
+ */
17
+ const DEV_BIND = "127.0.0.1";
14
18
  export async function runDev(dirArg, opts) {
15
19
  setLogLevel("debug"); // dev posture: verbose, includes the debug turn trace (content) — supervisor and worker both
16
20
  const isWorker = process.env.FASTAGENT_DEV_WORKER === "1";
17
- // The model is picked ONCE, in the parent process (a TTY; watch and --no-watch both); a spawned
18
- // worker inherits the choice through FASTAGENT_MODEL and must not prompt even when the pick was
19
- // cancelled.
21
+ // The model is picked ONCE, in the parent process (a TTY; watch and --no-watch both).
20
22
  const placement = await enterAgentCommand(dirArg, { ...opts, input: isWorker ? false : opts.input });
21
23
  if (isWorker || opts.watch === false) {
22
24
  await serveOnce(placement, opts);
23
25
  return;
24
26
  }
25
27
  parsePort(opts.port, "--port", "flag"); // flag-shape checks before spawning
26
- // The --bind/--tunnel conflict is decidable from flags alone: refuse it HERE, before a worker and a
27
- // tunnel exist. The worker repeats the check because `http.host` can supply the address instead.
28
- assertTunnelBindable(parseBind(opts.bind), opts.tunnel ?? false, "flag");
28
+ // The --bind/--tunnel conflict is decidable from flags alone: refuse it HERE, before a worker and a tunnel exist.
29
+ assertTunnelBindable(parseBind(opts.bind), opts.tunnel ?? false);
29
30
  await runDevSupervisor(placement, { tunnel: opts.tunnel ?? false });
30
31
  }
31
32
  /** Assemble the agent and serve it once (the dev worker; also the --no-watch path). */
32
33
  async function serveOnce(placement, opts) {
33
34
  const portFlag = parsePort(opts.port, "--port", "flag");
34
- const bindFlag = parseBind(opts.bind);
35
+ const host = parseBind(opts.bind) ?? DEV_BIND;
35
36
  const tunnel = opts.tunnel ?? false;
36
- const a = await createPiAgentFromDir(placement.workspace, {
37
+ assertTunnelBindable(host, tunnel);
38
+ const a = await createPiAgentFromDir(placement.agentDir, {
37
39
  model: opts.model,
38
- authPath: opts.authPath, // flag > FASTAGENT_AUTH_PATH > default — resolved by the opener (one owner)
39
- serving: true, // long-running serve: the scheduler poller runs (wake mounts iff config.selfSchedule)
40
+ serving: true, // long-running serve: the scheduler poller runs (and the wake tool is mounted)
40
41
  }).catch(failStartup);
41
42
  // The same report `start` prints; `config:` is dev's own extra (see reportAssembly on the asymmetry).
42
43
  await reportAssembly(a, { beforeModel: [["config", a.configPath ?? "(none)"]] });
43
- const host = resolveBindHost(bindFlag, a.config.http?.host, tunnel);
44
- // The SAME assembly an embedder gets from `createAgentService` — channels, control plane,
45
- // schedules, long connections. `dev` opens the directory itself only because its startup report
46
- // prints the opened values before anything mounts. The turn trace (tool calls + reply) logs at
47
- // debug level: shown here, gated out in start (level info), keeping end-user content out of
48
- // production logs.
49
- const service = await mountAgentService(a, cliMountOptions(logAgentLoop)).catch(failStartup);
50
- serveService(service, { port: portFlag ?? a.config.http?.port ?? 8787, host }, { tunnel, agentDir: a.agentDir, stateRoot: a.stateRoot });
44
+ // The SAME assembly an embedder gets from `createAgentService` — channels, control plane, schedules, long
45
+ // connections.
46
+ const service = await mountAgentService(withRunOverrides(a, opts), cliMountOptions(logAgentLoop)).catch(failStartup);
47
+ serveService(service, { port: portFlag ?? a.config.http?.port ?? DEFAULT_HTTP_PORT, host }, { tunnel, agentDir: a.agentDir, stateRoot: a.stateRoot });
51
48
  }
@@ -1,7 +1,5 @@
1
1
  export interface InfoOptions {
2
2
  json?: boolean;
3
3
  model?: string;
4
- authPath?: string;
5
- sessionsDir?: string;
6
4
  }
7
5
  export declare function runInfo(dirArg: string, opts: InfoOptions): Promise<void>;
@@ -1,37 +1,40 @@
1
- /** `fastagent info [dir] [--json]`: print what the directory ASSEMBLES into, WITHOUT booting a server. Read-only. */
1
+ /** `fastagent info [dir] [--json]`: print what the directory ASSEMBLES into, WITHOUT booting a server. */
2
2
  import { resolve } from "node:path";
3
- import { loadDotEnv } from "../../env.js";
4
- import { discoverChannelFiles } from "../../channels/discover.js";
5
- import { defaultSessionsDir, loadConfig, resolveAuthPath, resolveModel, resolveModelSpec, resolveSessionsDirOverride, } from "../../engines/pi/config.js";
6
- import { createPiModelRuntime } from "../../engines/pi/models.js";
7
- import { resolveStateRoot, workspaceHint } from "../../paths.js";
3
+ import { enterAgentEnv } from "../../env.js";
4
+ import { inspectChannels } from "../../channels/discover.js";
5
+ import { loadConfig, providerOf, resolveAuthLayers, resolveModel, resolveModelSpec } from "../../engines/pi/config.js";
6
+ import { createPiModelRuntime, machineModels } from "../../engines/pi/models.js";
7
+ import { resolveSessionsDir, resolveStateRoot } from "../../paths.js";
8
8
  import { CODING_TOOL_NAMES, resolveAgentTools } from "../../engines/pi/create.js";
9
9
  import { loadAgentDefinition } from "../../engines/pi/definition.js";
10
10
  import { reportFindingsIfChanged, reportToolCollisions } from "../../engines/pi/report.js";
11
+ import { allSecrets, describeSecrets, missingSecrets } from "../../declared-secrets.js";
11
12
  import { log } from "../../log.js";
12
13
  import { reportModuleLoadFailures } from "../../loader.js";
14
+ import { readMachine, withMachine } from "../../engines/pi/machine.js";
13
15
  import { nextRun } from "../../schedule/cron.js";
14
- import { loadSchedules } from "../../schedule/discover.js";
16
+ import { loadRoutines } from "../../schedule/discover.js";
15
17
  import { failStartup, placementOrExit } from "../fail.js";
16
18
  export async function runInfo(dirArg, opts) {
17
19
  const dir = resolve(dirArg);
18
20
  const { agentDir, workspace } = placementOrExit(dir);
19
- loadDotEnv(agentDir); // skills/tools may read env at load time
21
+ enterAgentEnv(agentDir); // skills/tools may read env — and fetch — at load time
20
22
  const { config, path: configPath } = await loadConfig(agentDir).catch(failStartup);
21
23
  const modelSpec = resolveModelSpec(opts.model, config);
22
- // agentDir = where the agent lives (definition + config + machinery); workspace = what it works ON
23
- // (its cwd, whose AGENTS.md ancestors are ② context).
24
+ // agentDir = where the agent lives (definition + config + machinery); workspace = what it works ON (its cwd, whose
25
+ // AGENTS.md ancestors are ② context).
24
26
  const definition = await loadAgentDefinition(agentDir, { cwd: workspace }).catch(failStartup);
25
- // A tool that fails to load, for any reason (a missing dep, a top-level throw, or just not being a
26
- // tool), is isolated the same way everywhere (G2): info, dev, AND start report it and keep going with
27
- // the tools that loaded. The `error`/`.catch` below only fires for a whole-load fault (an unreadable
28
- // tools/ dir), not a single bad file.
27
+ // What this agent HAS: the definition's skills plus the ones its machine lends (machine.ts).
28
+ const skills = withMachine(definition.skills, (await readMachine(workspace)).skills);
29
+ // A tool that fails to load, for any reason (a missing dep, a top-level throw, or just not being a tool), is
30
+ // isolated the same way everywhere (G2).
29
31
  const tools = await resolveAgentTools(config, agentDir, workspace)
30
32
  .then((r) => ({
31
33
  names: r.toolNames,
32
34
  deferred: r.deferredToolNames,
33
35
  collisions: r.toolCollisions,
34
36
  failures: r.toolFailures,
37
+ secrets: allSecrets(r.toolSecrets),
35
38
  error: undefined,
36
39
  }))
37
40
  .catch((e) => ({
@@ -39,38 +42,52 @@ export async function runInfo(dirArg, opts) {
39
42
  deferred: [],
40
43
  collisions: [],
41
44
  failures: [],
45
+ secrets: [],
42
46
  error: e.message,
43
47
  }));
44
- const channels = await discoverChannelFiles(agentDir).catch(failStartup);
45
- // Loaded (imported + validated), not just discovered: info's job is "fix only what it reports", so a
46
- // broken schedule file (bad cron/tz, failed import) must show up HERE, not first at dev/start — and
47
- // loading is what makes the next fire instant printable. Consistent with tools (info imports those too).
48
- const sched = await loadSchedules(agentDir).catch(failStartup);
49
- const schedules = sched.schedules.map((s) => ({
50
- name: s.name,
51
- cron: s.cron,
52
- tz: s.tz ?? null,
53
- next: nextRun(s.cron, s.tz, new Date())?.toISOString() ?? null,
48
+ // IMPORTED, like tools and schedules: a channel's declared secrets are part of what this command
49
+ // exists to report (and a channel that cannot load is what `dev` would fail on next).
50
+ const inspected = await inspectChannels(agentDir).catch(failStartup);
51
+ const channels = inspected.channels.map((c) => c.name);
52
+ // Loaded (imported + validated), not just discovered.
53
+ const sched = await loadRoutines(agentDir).catch(failStartup);
54
+ // What the definition DECLARED it needs, and which of those have no value here. `info` reports
55
+ // (never asserts): it is the read-only view of the same list `dev`/`start` refuse to boot without
56
+ // and `deploy` requires a value for.
57
+ const declaredSecrets = [
58
+ ...tools.secrets,
59
+ ...allSecrets(sched.secrets),
60
+ ...allSecrets(inspected.secrets),
61
+ ];
62
+ const unsetSecrets = missingSecrets(declaredSecrets);
63
+ const routines = sched.routines.map((r) => ({
64
+ name: r.name,
65
+ cron: r.cron ?? null,
66
+ tz: r.tz ?? null,
67
+ // A routine with no cron has no next fire — it is reached by name (`POST /run`, `routine run`), which is a
68
+ // fact worth printing rather than a null to squint at.
69
+ next: r.cron === undefined ? null : (nextRun(r.cron, r.tz, new Date())?.toISOString() ?? null),
54
70
  }));
55
- // The default sessions/auth paths WITHOUT creating anything (info is read-only; dev/start mkdir/login
56
- // create them, info must not).
71
+ // The default sessions/auth paths WITHOUT creating anything (info is read-only; dev/start mkdir/login create them,
72
+ // info must not).
57
73
  const stateRoot = resolveStateRoot(agentDir);
58
- const sessionsDir = resolveSessionsDirOverride(opts.sessionsDir) ?? defaultSessionsDir(stateRoot);
59
- const authPath = resolveAuthPath(agentDir, opts.authPath); // flag > FASTAGENT_AUTH_PATH > default — the one owner
60
- // RESOLVE the spec, do not just echo it: a spec is only real once its provider/model exist in the
61
- // agent's own surface (built-ins + its models.json), which is exactly what a custom endpoint changes.
62
- // Reporting a healthy-looking spec that `dev`/`start` then reject is the failure this pre-empts.
63
- // Reported as DATA rather than thrown — a broken agent is what `info` is for — and read-only: the
64
- // runtime reads models.json without creating anything (its catalog cache is written on refresh, and
65
- // there is none here).
74
+ const sessionsDir = resolveSessionsDir(agentDir);
75
+ // Both layers: "what is this agent's state" is the question `info` answers, and a credential it runs on can live in
76
+ // a file the agent dir does not contain.
77
+ const auth = resolveAuthLayers(agentDir);
78
+ // RESOLVE the spec, do not just echo it: a spec is only real once its provider/model exist in the agent's own
79
+ // surface (built-ins + its models.json), which is exactly what a custom endpoint changes.
66
80
  const modelError = modelSpec
67
- ? await createPiModelRuntime({ agentDir, authPath })
81
+ ? await createPiModelRuntime({ agentDir, auth })
68
82
  .then((models) => {
69
83
  resolveModel(models, modelSpec);
70
84
  return undefined;
71
85
  })
72
86
  .catch((error) => error.message)
73
87
  : undefined;
88
+ // The machine's own endpoints, which this agent inherits unless its models.json declares the same provider.
89
+ const machine = await machineModels(agentDir).then((value) => ({ value, error: undefined }), (error) => ({ value: undefined, error: error.message }));
90
+ const modelFromMachine = modelSpec !== undefined && machine.value?.inherited.includes(providerOf(modelSpec)) === true;
74
91
  if (opts.json) {
75
92
  console.log(JSON.stringify({
76
93
  agentDir,
@@ -78,60 +95,77 @@ export async function runInfo(dirArg, opts) {
78
95
  configPath: configPath ?? null,
79
96
  model: modelSpec ?? null,
80
97
  modelError: modelError ?? null,
98
+ modelFromMachine,
99
+ machineModels: machine.value ?? null,
100
+ machineModelsError: machine.error ?? null,
81
101
  thinkingLevel: config.thinkingLevel ?? null,
82
102
  codingTools: [...CODING_TOOL_NAMES],
83
103
  context: definition.contextFiles.map((f) => f.path),
84
104
  persona: definition.persona !== undefined,
85
- skills: definition.skills.map((skill) => ({ name: skill.name, description: skill.description })),
105
+ skills: skills.map((skill) => ({ name: skill.name, description: skill.description })),
86
106
  tools: tools.names,
87
107
  deferredTools: tools.deferred,
88
108
  toolError: tools.error ?? null,
89
109
  channels,
90
- schedules,
91
- scheduleFailures: sched.failures,
92
- selfSchedule: config.selfSchedule ?? false,
110
+ routines,
111
+ routineFailures: sched.failures,
112
+ channelFailures: inspected.failures,
93
113
  stateRoot,
94
114
  sessionsDir,
95
- authPath,
115
+ authPath: auth.path,
116
+ fallbackAuthPath: auth.fallback ?? null,
96
117
  diagnostics: definition.diagnostics,
97
118
  skillCollisions: definition.collisions,
98
119
  toolCollisions: tools.collisions,
99
120
  toolFailures: tools.failures,
121
+ declaredSecrets,
122
+ unsetSecrets,
100
123
  }, null, 2));
101
124
  return;
102
125
  }
103
- // One padded label writer: hand-spaced labels drifted out of alignment the moment a longer one
104
- // (agent/workspace/selfSchedule) joined the report.
126
+ // One padded label writer, so labels stay aligned.
105
127
  const line = (label, value) => console.log(`${`${label}:`.padEnd(13)} ${value}`);
106
128
  /** A continuation under the previous line, aligned to the same column (no label, so no bare colon). */
107
129
  const cont = (value) => console.log(`${"".padEnd(13)} ${value}`);
108
130
  line("agent", agentDir);
109
131
  line("workspace", workspace);
110
- const hint = workspaceHint({ agentDir, workspace });
111
- if (hint)
112
- line("hint", hint);
113
132
  line("config", configPath ?? "(none)");
114
133
  line("model", modelSpec ?? "(not set — pass --model, set FASTAGENT_MODEL, or config.model)");
115
134
  if (modelError)
116
135
  cont(`⚠ does not resolve: ${modelError}`);
136
+ if (modelFromMachine)
137
+ cont(`endpoint from the machine's ${machine.value?.path} (does not ship with a deploy)`);
117
138
  if (config.thinkingLevel)
118
139
  line("thinking", config.thinkingLevel);
119
140
  line("codingTools", CODING_TOOL_NAMES.join(", "));
120
141
  line("context", definition.contextFiles.map((f) => f.path).join(", ") || "(none)");
121
142
  line("persona", definition.persona ? "persona.md" : "(none)");
122
- line("skills", definition.skills.map((skill) => skill.name).join(", ") || "(none)");
143
+ line("skills", skills.map((skill) => skill.name).join(", ") || "(none)");
123
144
  line("tools", tools.error ? "(could not load — see warning below)" : tools.names.join(", ") || "(none)");
124
145
  if (tools.deferred.length > 0)
125
146
  line("deferred", `${tools.deferred.join(", ")} (activated via search_tools)`);
126
147
  line("channels", channels.join(", ") || "(none)");
127
- line("schedules", schedules.map((s) => `${s.name} (next ${s.next ?? "never"})`).join(", ") || "(none)");
128
- line("selfSchedule", config.selfSchedule ? "on (mounts the wake tool when serving)" : "off");
148
+ line("routines", routines.map((r) => `${r.name} (${r.cron === null ? "on demand" : `next ${r.next ?? "never"}`})`).join(", ") ||
149
+ "(none)");
150
+ line("secrets", declaredSecrets.length > 0 ? describeSecrets(declaredSecrets) : "(none declared)");
151
+ if (unsetSecrets.length > 0)
152
+ cont(`⚠ dev/start refuse to boot until set: ${unsetSecrets.map((s) => s.name).join(", ")}`);
129
153
  line("state", stateRoot);
130
154
  line("sessions", sessionsDir);
131
- line("auth", authPath);
155
+ line("auth", auth.fallback === undefined ? auth.path : `${auth.path} (then ${auth.fallback})`);
156
+ if (machine.error)
157
+ line("endpoints", `⚠ ${machine.error}`);
158
+ else if (machine.value) {
159
+ const { path, inherited, overridden } = machine.value;
160
+ const parts = [inherited.join(", ") || "(none inherited)"];
161
+ if (overridden.length > 0)
162
+ parts.push(`overridden by the agent: ${overridden.join(", ")}`);
163
+ line("endpoints", `${path}: ${parts.join("; ")}`);
164
+ }
132
165
  reportToolCollisions(tools.collisions);
133
166
  reportModuleLoadFailures(tools.failures);
134
167
  reportModuleLoadFailures(sched.failures);
168
+ reportModuleLoadFailures(inspected.failures);
135
169
  if (tools.error)
136
170
  log.warn(`[fastagent] ${tools.error}`);
137
171
  reportFindingsIfChanged(definition.dir, definition);
@@ -1,8 +1,7 @@
1
1
  export interface InitOptions {
2
- minimal: boolean;
3
2
  /** false ⇔ `--no-install`. */
4
3
  install: boolean;
5
- /** The agent directory's name inside `dir` — undefined = the default, `"."` = `dir` itself (`--flat`). */
4
+ /** The agent directory's name inside `dir` — undefined = the default. */
6
5
  agentDir?: string;
7
6
  }
8
7
  export declare function runInit(dirArg: string, opts: InitOptions): Promise<void>;