@fastagent-sh/fastagent 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/README.md +9 -12
  2. package/dist/agent.d.ts +24 -37
  3. package/dist/agent.js +7 -15
  4. package/dist/atomic-write.d.ts +13 -17
  5. package/dist/atomic-write.js +18 -29
  6. package/dist/bind.d.ts +12 -22
  7. package/dist/bind.js +18 -27
  8. package/dist/channel.d.ts +11 -33
  9. package/dist/channels/agentcore-limits.d.ts +2 -13
  10. package/dist/channels/agentcore-limits.js +2 -13
  11. package/dist/channels/agentcore-protocol.d.ts +67 -58
  12. package/dist/channels/agentcore-protocol.js +23 -15
  13. package/dist/channels/agentcore-service.d.ts +19 -33
  14. package/dist/channels/agentcore-service.js +176 -59
  15. package/dist/channels/agentcore.d.ts +39 -33
  16. package/dist/channels/agentcore.js +90 -224
  17. package/dist/channels/body.d.ts +15 -2
  18. package/dist/channels/body.js +24 -2
  19. package/dist/channels/busy.d.ts +1 -21
  20. package/dist/channels/busy.js +2 -39
  21. package/dist/channels/control.d.ts +17 -62
  22. package/dist/channels/control.js +74 -182
  23. package/dist/channels/define-channel.d.ts +39 -0
  24. package/dist/channels/define-channel.js +9 -0
  25. package/dist/channels/discover.d.ts +10 -31
  26. package/dist/channels/discover.js +37 -31
  27. package/dist/channels/feishu/bootstrap-token.d.ts +1 -8
  28. package/dist/channels/feishu/bootstrap-token.js +7 -23
  29. package/dist/channels/feishu/card.d.ts +14 -28
  30. package/dist/channels/feishu/card.js +16 -30
  31. package/dist/channels/feishu/cloud.d.ts +1 -5
  32. package/dist/channels/feishu/context-buffer.d.ts +4 -23
  33. package/dist/channels/feishu/context-buffer.js +8 -31
  34. package/dist/channels/feishu/crypto.d.ts +10 -5
  35. package/dist/channels/feishu/crypto.js +12 -19
  36. package/dist/channels/feishu/feishu-api.d.ts +2 -1
  37. package/dist/channels/feishu/feishu-api.js +5 -4
  38. package/dist/channels/feishu/feishu.d.ts +4 -10
  39. package/dist/channels/feishu/feishu.js +113 -227
  40. package/dist/channels/feishu/invoke-turn.d.ts +5 -4
  41. package/dist/channels/feishu/invoke-turn.js +36 -54
  42. package/dist/channels/feishu/model.d.ts +4 -21
  43. package/dist/channels/feishu/model.js +1 -8
  44. package/dist/channels/feishu/normalize.d.ts +2 -10
  45. package/dist/channels/feishu/normalize.js +7 -42
  46. package/dist/channels/feishu/parse.d.ts +9 -29
  47. package/dist/channels/feishu/parse.js +8 -26
  48. package/dist/channels/feishu/preview.d.ts +12 -14
  49. package/dist/channels/feishu/preview.js +108 -207
  50. package/dist/channels/feishu/register-app.d.ts +8 -23
  51. package/dist/channels/feishu/register-app.js +7 -20
  52. package/dist/channels/feishu/register-webhook.d.ts +2 -9
  53. package/dist/channels/feishu/register-webhook.js +9 -33
  54. package/dist/channels/feishu/scaffold/channel.ts +27 -19
  55. package/dist/channels/feishu/scaffold/channel.websocket.ts +31 -0
  56. package/dist/channels/feishu/setup-mode.d.ts +11 -36
  57. package/dist/channels/feishu/setup-mode.js +7 -26
  58. package/dist/channels/feishu/ws-ingress.d.ts +1 -2
  59. package/dist/channels/feishu/ws-ingress.js +6 -8
  60. package/dist/channels/http.d.ts +15 -15
  61. package/dist/channels/http.js +19 -9
  62. package/dist/channels/kit/attachment-path.d.ts +4 -5
  63. package/dist/channels/kit/attachment-path.js +10 -34
  64. package/dist/channels/kit/context-buffer.d.ts +14 -21
  65. package/dist/channels/kit/context-buffer.js +25 -38
  66. package/dist/channels/kit/delivery.d.ts +35 -0
  67. package/dist/channels/kit/delivery.js +129 -0
  68. package/dist/channels/kit/event-stream.d.ts +5 -0
  69. package/dist/channels/kit/event-stream.js +29 -0
  70. package/dist/channels/kit/invoke-turn-kit.d.ts +53 -26
  71. package/dist/channels/kit/invoke-turn-kit.js +89 -32
  72. package/dist/channels/kit/preview-kit.d.ts +18 -72
  73. package/dist/channels/kit/preview-kit.js +22 -88
  74. package/dist/channels/kit/signature.d.ts +3 -9
  75. package/dist/channels/kit/signature.js +3 -9
  76. package/dist/channels/kit/state.d.ts +1 -2
  77. package/dist/channels/kit/state.js +5 -14
  78. package/dist/channels/kit/stop-command.d.ts +1 -2
  79. package/dist/channels/kit/stop-command.js +6 -9
  80. package/dist/channels/kit/tasks.d.ts +1 -1
  81. package/dist/channels/kit/tasks.js +8 -21
  82. package/dist/channels/kit/text.d.ts +2 -16
  83. package/dist/channels/kit/text.js +23 -31
  84. package/dist/channels/kit/thread-participants.d.ts +4 -17
  85. package/dist/channels/kit/thread-participants.js +8 -55
  86. package/dist/channels/kit/transport.d.ts +26 -0
  87. package/dist/channels/kit/transport.js +20 -0
  88. package/dist/channels/kit/turn-queue.d.ts +7 -11
  89. package/dist/channels/kit/turn-queue.js +21 -39
  90. package/dist/channels/kit/turn-runner.d.ts +32 -18
  91. package/dist/channels/kit/turn-runner.js +98 -53
  92. package/dist/channels/kit/turn-store.d.ts +32 -32
  93. package/dist/channels/kit/turn-store.js +45 -88
  94. package/dist/channels/lark/lark.d.ts +1 -5
  95. package/dist/channels/lark/onboard.d.ts +3 -12
  96. package/dist/channels/lark/onboard.js +3 -13
  97. package/dist/channels/lark/scaffold/channel.ts +27 -19
  98. package/dist/channels/lark/scaffold/channel.websocket.ts +31 -0
  99. package/dist/channels/registration.d.ts +9 -35
  100. package/dist/channels/registration.js +6 -37
  101. package/dist/channels/secret.js +2 -5
  102. package/dist/channels/serve.d.ts +47 -44
  103. package/dist/channels/serve.js +165 -101
  104. package/dist/channels/slack/config-api.d.ts +4 -27
  105. package/dist/channels/slack/config-api.js +5 -34
  106. package/dist/channels/slack/context-buffer.d.ts +2 -3
  107. package/dist/channels/slack/context-buffer.js +5 -5
  108. package/dist/channels/slack/invoke-turn.d.ts +3 -1
  109. package/dist/channels/slack/invoke-turn.js +25 -34
  110. package/dist/channels/slack/manifest.js +1 -3
  111. package/dist/channels/slack/model.d.ts +1 -2
  112. package/dist/channels/slack/model.js +1 -1
  113. package/dist/channels/slack/onboard.d.ts +4 -3
  114. package/dist/channels/slack/onboard.js +8 -11
  115. package/dist/channels/slack/onboarding-state.d.ts +3 -5
  116. package/dist/channels/slack/onboarding-state.js +9 -6
  117. package/dist/channels/slack/parse.d.ts +4 -13
  118. package/dist/channels/slack/parse.js +7 -28
  119. package/dist/channels/slack/preview.d.ts +12 -2
  120. package/dist/channels/slack/preview.js +292 -269
  121. package/dist/channels/slack/reaction.d.ts +11 -3
  122. package/dist/channels/slack/reaction.js +19 -8
  123. package/dist/channels/slack/register-webhook.js +4 -7
  124. package/dist/channels/slack/scaffold/channel.ts +20 -13
  125. package/dist/channels/slack/scaffold/slack-send.ts +2 -2
  126. package/dist/channels/slack/setup-server.d.ts +1 -5
  127. package/dist/channels/slack/setup-server.js +1 -5
  128. package/dist/channels/slack/shared-api.d.ts +1 -4
  129. package/dist/channels/slack/shared-api.js +2 -13
  130. package/dist/channels/slack/slack-api.d.ts +2 -1
  131. package/dist/channels/slack/slack-api.js +6 -4
  132. package/dist/channels/slack/slack.d.ts +11 -14
  133. package/dist/channels/slack/slack.js +121 -122
  134. package/dist/channels/sse.d.ts +1 -1
  135. package/dist/channels/sse.js +1 -1
  136. package/dist/channels/telegram/context-buffer.d.ts +7 -22
  137. package/dist/channels/telegram/context-buffer.js +6 -23
  138. package/dist/channels/telegram/invoke-turn.d.ts +7 -7
  139. package/dist/channels/telegram/invoke-turn.js +24 -43
  140. package/dist/channels/telegram/parse.d.ts +24 -51
  141. package/dist/channels/telegram/parse.js +32 -84
  142. package/dist/channels/telegram/preview.d.ts +10 -1
  143. package/dist/channels/telegram/preview.js +79 -100
  144. package/dist/channels/telegram/register-webhook.js +5 -23
  145. package/dist/channels/telegram/scaffold/channel.ts +25 -18
  146. package/dist/channels/telegram/scaffold/telegram-send.ts +6 -4
  147. package/dist/channels/telegram/telegram-api.d.ts +4 -3
  148. package/dist/channels/telegram/telegram-api.js +9 -7
  149. package/dist/channels/telegram/telegram.d.ts +4 -18
  150. package/dist/channels/telegram/telegram.js +38 -94
  151. package/dist/channels/telegram/turn-store.d.ts +11 -14
  152. package/dist/channels/telegram/turn-store.js +8 -6
  153. package/dist/channels/wait-health.d.ts +4 -6
  154. package/dist/channels/wait-health.js +10 -14
  155. package/dist/cli/add-feishu.d.ts +2 -12
  156. package/dist/cli/add-feishu.js +24 -71
  157. package/dist/cli/add-slack.d.ts +5 -3
  158. package/dist/cli/add-slack.js +53 -76
  159. package/dist/cli/auth-view.d.ts +2 -16
  160. package/dist/cli/auth-view.js +2 -16
  161. package/dist/cli/commands/add.js +25 -43
  162. package/dist/cli/commands/chat.d.ts +0 -1
  163. package/dist/cli/commands/chat.js +5 -6
  164. package/dist/cli/commands/deploy/agentcore.js +60 -65
  165. package/dist/cli/commands/deploy/docker.js +50 -23
  166. package/dist/cli/commands/deploy/fly.js +23 -61
  167. package/dist/cli/commands/deploy/railway.js +23 -18
  168. package/dist/cli/commands/deploy/shared.d.ts +38 -57
  169. package/dist/cli/commands/deploy/shared.js +40 -59
  170. package/dist/cli/commands/deploy.d.ts +10 -27
  171. package/dist/cli/commands/deploy.js +38 -60
  172. package/dist/cli/commands/destroy.d.ts +4 -0
  173. package/dist/cli/commands/destroy.js +56 -0
  174. package/dist/cli/commands/dev.d.ts +2 -1
  175. package/dist/cli/commands/dev.js +20 -23
  176. package/dist/cli/commands/info.d.ts +0 -2
  177. package/dist/cli/commands/info.js +83 -49
  178. package/dist/cli/commands/init.d.ts +1 -2
  179. package/dist/cli/commands/init.js +16 -55
  180. package/dist/cli/commands/invoke.d.ts +0 -1
  181. package/dist/cli/commands/invoke.js +5 -7
  182. package/dist/cli/commands/login.d.ts +2 -1
  183. package/dist/cli/commands/login.js +33 -38
  184. package/dist/cli/commands/logs.js +3 -4
  185. package/dist/cli/commands/models.js +1 -5
  186. package/dist/cli/commands/routine-run.d.ts +6 -0
  187. package/dist/cli/commands/routine-run.js +47 -0
  188. package/dist/cli/commands/routine.d.ts +25 -0
  189. package/dist/cli/commands/routine.js +122 -0
  190. package/dist/cli/commands/start.d.ts +31 -3
  191. package/dist/cli/commands/start.js +131 -81
  192. package/dist/cli/commands/tool.js +26 -12
  193. package/dist/cli/fail.d.ts +13 -23
  194. package/dist/cli/fail.js +20 -23
  195. package/dist/cli/invoke-stream.d.ts +1 -8
  196. package/dist/cli/kernel.d.ts +6 -38
  197. package/dist/cli/kernel.js +14 -77
  198. package/dist/cli/models-view.d.ts +1 -9
  199. package/dist/cli/models-view.js +11 -22
  200. package/dist/cli/program.d.ts +5 -6
  201. package/dist/cli/program.js +120 -157
  202. package/dist/cli/serve.d.ts +57 -41
  203. package/dist/cli/serve.js +94 -121
  204. package/dist/cli/shared.d.ts +15 -61
  205. package/dist/cli/shared.js +55 -181
  206. package/dist/cli.js +1 -8
  207. package/dist/collect.d.ts +6 -0
  208. package/dist/collect.js +6 -0
  209. package/dist/core.d.ts +4 -1
  210. package/dist/core.js +9 -7
  211. package/dist/declared-secrets.d.ts +55 -0
  212. package/dist/declared-secrets.js +88 -0
  213. package/dist/deploy/agentcore/aws-cli.d.ts +91 -0
  214. package/dist/deploy/agentcore/aws-cli.js +64 -0
  215. package/dist/deploy/agentcore/destroy.d.ts +51 -0
  216. package/dist/deploy/agentcore/destroy.js +273 -0
  217. package/dist/deploy/agentcore/forwarder.js +28 -79
  218. package/dist/deploy/agentcore/logs.d.ts +2 -18
  219. package/dist/deploy/agentcore/logs.js +27 -51
  220. package/dist/deploy/agentcore/plan.d.ts +85 -105
  221. package/dist/deploy/agentcore/plan.js +152 -314
  222. package/dist/deploy/agentcore/run.d.ts +28 -28
  223. package/dist/deploy/agentcore/run.js +227 -306
  224. package/dist/deploy/agentcore/zip.d.ts +2 -15
  225. package/dist/deploy/agentcore/zip.js +3 -17
  226. package/dist/deploy/build-context.d.ts +21 -0
  227. package/dist/deploy/build-context.js +137 -0
  228. package/dist/deploy/channel-ingress.d.ts +26 -39
  229. package/dist/deploy/channel-ingress.js +57 -28
  230. package/dist/deploy/container.d.ts +20 -34
  231. package/dist/deploy/container.js +49 -100
  232. package/dist/deploy/docker/plan.d.ts +12 -11
  233. package/dist/deploy/docker/plan.js +43 -24
  234. package/dist/deploy/docker/run.d.ts +22 -25
  235. package/dist/deploy/docker/run.js +39 -37
  236. package/dist/deploy/fly/plan.d.ts +15 -44
  237. package/dist/deploy/fly/plan.js +41 -73
  238. package/dist/deploy/fly/run.d.ts +16 -51
  239. package/dist/deploy/fly/run.js +42 -95
  240. package/dist/deploy/hosts.d.ts +24 -3
  241. package/dist/deploy/hosts.js +24 -3
  242. package/dist/deploy/preflight.d.ts +47 -41
  243. package/dist/deploy/preflight.js +282 -383
  244. package/dist/deploy/railway/plan.d.ts +16 -42
  245. package/dist/deploy/railway/plan.js +42 -60
  246. package/dist/deploy/railway/run.d.ts +30 -68
  247. package/dist/deploy/railway/run.js +86 -100
  248. package/dist/deploy/registration-gate.d.ts +6 -13
  249. package/dist/deploy/residency.d.ts +37 -0
  250. package/dist/deploy/residency.js +24 -0
  251. package/dist/deploy/runner.d.ts +10 -9
  252. package/dist/deploy/runner.js +7 -18
  253. package/dist/deploy/secrets.d.ts +40 -41
  254. package/dist/deploy/secrets.js +117 -103
  255. package/dist/deploy/workspace.d.ts +50 -0
  256. package/dist/deploy/workspace.js +197 -0
  257. package/dist/dev-supervisor.d.ts +1 -9
  258. package/dist/dev-supervisor.js +21 -64
  259. package/dist/effect-port.d.ts +50 -0
  260. package/dist/effect-port.js +77 -0
  261. package/dist/engines/pi/agent-session-factory.d.ts +50 -69
  262. package/dist/engines/pi/agent-session-factory.js +249 -146
  263. package/dist/engines/pi/auth.d.ts +15 -11
  264. package/dist/engines/pi/auth.js +96 -99
  265. package/dist/engines/pi/chat.d.ts +1 -5
  266. package/dist/engines/pi/chat.js +2 -14
  267. package/dist/engines/pi/config.d.ts +53 -51
  268. package/dist/engines/pi/config.js +83 -92
  269. package/dist/engines/pi/create.d.ts +60 -75
  270. package/dist/engines/pi/create.js +108 -141
  271. package/dist/engines/pi/definition.d.ts +14 -58
  272. package/dist/engines/pi/definition.js +21 -85
  273. package/dist/engines/pi/invoke-session.d.ts +5 -25
  274. package/dist/engines/pi/invoke-session.js +209 -244
  275. package/dist/engines/pi/login.d.ts +95 -35
  276. package/dist/engines/pi/login.js +259 -107
  277. package/dist/engines/pi/machine.d.ts +31 -0
  278. package/dist/engines/pi/machine.js +106 -0
  279. package/dist/engines/pi/models.d.ts +70 -89
  280. package/dist/engines/pi/models.js +188 -81
  281. package/dist/engines/pi/open.d.ts +65 -53
  282. package/dist/engines/pi/open.js +129 -69
  283. package/dist/engines/pi/report.d.ts +3 -12
  284. package/dist/engines/pi/report.js +2 -16
  285. package/dist/engines/pi/search-tools.d.ts +1 -9
  286. package/dist/engines/pi/search-tools.js +26 -57
  287. package/dist/engines/pi/service.d.ts +2 -16
  288. package/dist/engines/pi/service.js +2 -16
  289. package/dist/engines/pi/session-builder.d.ts +5 -9
  290. package/dist/engines/pi/session-builder.js +44 -82
  291. package/dist/engines/pi/session-control.js +286 -269
  292. package/dist/engines/pi/session-effects.d.ts +14 -0
  293. package/dist/engines/pi/session-effects.js +30 -0
  294. package/dist/engines/pi/session-inheritance.d.ts +9 -18
  295. package/dist/engines/pi/session-inheritance.js +103 -160
  296. package/dist/engines/pi/session-markers.d.ts +31 -30
  297. package/dist/engines/pi/session-markers.js +26 -25
  298. package/dist/engines/pi/session-settings.d.ts +6 -22
  299. package/dist/engines/pi/session-settings.js +10 -21
  300. package/dist/engines/pi/session-store.d.ts +26 -92
  301. package/dist/engines/pi/session-store.js +96 -310
  302. package/dist/engines/pi/tool-context.d.ts +17 -45
  303. package/dist/engines/pi/tool-context.js +7 -26
  304. package/dist/engines/pi/tool.d.ts +45 -36
  305. package/dist/engines/pi/tool.js +43 -57
  306. package/dist/engines/pi/turn-kit.d.ts +14 -52
  307. package/dist/engines/pi/turn-kit.js +18 -67
  308. package/dist/engines/pi/wake-tool.d.ts +2 -10
  309. package/dist/engines/pi/wake-tool.js +7 -27
  310. package/dist/env.d.ts +27 -28
  311. package/dist/env.js +45 -50
  312. package/dist/index.js +0 -2
  313. package/dist/lark.d.ts +1 -2
  314. package/dist/lark.js +1 -2
  315. package/dist/loader.d.ts +14 -55
  316. package/dist/loader.js +24 -43
  317. package/dist/log.d.ts +2 -12
  318. package/dist/log.js +3 -24
  319. package/dist/node.d.ts +2 -15
  320. package/dist/node.js +2 -18
  321. package/dist/observe.d.ts +2 -8
  322. package/dist/open-url.d.ts +1 -1
  323. package/dist/open-url.js +1 -1
  324. package/dist/paths.d.ts +70 -134
  325. package/dist/paths.js +165 -232
  326. package/dist/pi.d.ts +4 -6
  327. package/dist/pi.js +3 -3
  328. package/dist/proxy.d.ts +16 -6
  329. package/dist/proxy.js +52 -16
  330. package/dist/runtime.d.ts +18 -12
  331. package/dist/runtime.js +18 -11
  332. package/dist/scaffold/add-channel.d.ts +14 -31
  333. package/dist/scaffold/add-channel.js +48 -112
  334. package/dist/scaffold/init.d.ts +9 -31
  335. package/dist/scaffold/init.js +45 -138
  336. package/dist/scaffold/templates/env.example +6 -4
  337. package/dist/scaffold/templates/fastagent.config.ts +36 -0
  338. package/dist/scaffold/templates.d.ts +3 -3
  339. package/dist/scaffold/templates.js +5 -8
  340. package/dist/scaffold/vendor-skill.d.ts +2 -5
  341. package/dist/scaffold/vendor-skill.js +19 -29
  342. package/dist/schedule/cron.d.ts +9 -5
  343. package/dist/schedule/cron.js +9 -11
  344. package/dist/schedule/discover.d.ts +12 -12
  345. package/dist/schedule/discover.js +43 -34
  346. package/dist/schedule/routine.d.ts +43 -0
  347. package/dist/schedule/routine.js +32 -0
  348. package/dist/schedule/run.d.ts +55 -0
  349. package/dist/schedule/run.js +146 -0
  350. package/dist/schedule/scheduler.d.ts +44 -55
  351. package/dist/schedule/scheduler.js +291 -265
  352. package/dist/schedule/state.d.ts +105 -10
  353. package/dist/schedule/state.js +293 -19
  354. package/dist/schedule/wake-alarm.d.ts +10 -23
  355. package/dist/schedule/wake-alarm.js +91 -121
  356. package/dist/schedule/wakeups.d.ts +23 -39
  357. package/dist/schedule/wakeups.js +33 -75
  358. package/dist/secrets-gate.d.ts +32 -0
  359. package/dist/secrets-gate.js +33 -0
  360. package/dist/service.d.ts +137 -98
  361. package/dist/service.js +250 -252
  362. package/dist/session-remote.d.ts +33 -44
  363. package/dist/session-remote.js +203 -192
  364. package/dist/session.d.ts +153 -228
  365. package/dist/session.js +33 -55
  366. package/dist/tunnel.d.ts +8 -36
  367. package/dist/tunnel.js +24 -65
  368. package/dist/version.d.ts +2 -2
  369. package/dist/version.js +2 -2
  370. package/package.json +10 -16
  371. package/dist/channels/agentcore-state.d.ts +0 -77
  372. package/dist/channels/agentcore-state.js +0 -276
  373. package/dist/channels/github/github.d.ts +0 -31
  374. package/dist/channels/github/github.js +0 -89
  375. package/dist/channels/github/scaffold/channel.ts +0 -25
  376. package/dist/cli/commands/attach.d.ts +0 -108
  377. package/dist/cli/commands/attach.js +0 -637
  378. package/dist/cli/commands/fire.d.ts +0 -7
  379. package/dist/cli/commands/fire.js +0 -38
  380. package/dist/cli/commands/schedule.d.ts +0 -12
  381. package/dist/cli/commands/schedule.js +0 -87
  382. package/dist/github.d.ts +0 -3
  383. package/dist/github.js +0 -2
  384. package/dist/scaffold/templates/fastagent.config.mjs +0 -23
  385. package/dist/schedule/audit.d.ts +0 -18
  386. package/dist/schedule/audit.js +0 -57
  387. package/dist/schedule/schedule.d.ts +0 -35
  388. package/dist/schedule/schedule.js +0 -23
package/dist/cli/serve.js CHANGED
@@ -1,53 +1,35 @@
1
- /**
2
- * What `dev` (its worker) and `start` need beyond the service itself: binding a port, the shutdown
3
- * order, the startup report, the optional Cloudflare quick tunnel, and the options the CLI hands the
4
- * assembly (`cliMountOptions`, `resolveBindHost` — policy ABOUT the assembly, decided per command).
5
- *
6
- * The ASSEMBLY itself is not here — it lives in `src/service.ts`, which a public entry may import and
7
- * this directory may not be (it decides process-level things: `fail.ts` calls `process.exit`).
8
- */
9
- import { mkdirSync, rmSync } from "node:fs";
10
- import { join } from "node:path";
1
+ /** What `dev` (its worker) and `start` need beyond the service itself. */
11
2
  import { INVOKE_EXAMPLE_BODY } from "../channels/http.js";
12
- import { answersLocalhost, bindAddress, bindLabel, classifyBind, clientHost } from "../bind.js";
13
- import { writeFileAtomic } from "../atomic-write.js";
3
+ import { answersLocalhost, bindLabel, classifyBind, clientHost } from "../bind.js";
4
+ import { describeAnonymousSurface, } from "../service.js";
14
5
  import { serveNode } from "../channels/serve.js";
15
6
  import { log } from "../log.js";
16
7
  import { openExternalUrl } from "../open-url.js";
17
8
  import { declaredChannels } from "../channels/discover.js";
18
9
  import { announceWebhooks, startCloudflareTunnel } from "../tunnel.js";
19
10
  import { failStartup, failUsage } from "./fail.js";
20
- /**
21
- * Refuse `--tunnel` with a bind that cloudflared cannot reach: it dials the NAME `localhost:<port>`
22
- * (the dev supervisor's tunnel too), so anything outside `127.0.0.1`/`::1`/wildcard — including a
23
- * `127.0.0.2` bind, loopback though it is — would leave the tunnel up and 502ing every request.
24
- * Checked BEFORE the bind (the flag alone pre-spawn in `dev`, again once config is loaded, since
25
- * `http.host` can carry the address), so the failure is clean rather than a live-but-broken public URL.
26
- * `source` decides the exit code, per fail.ts: a flag COMBINATION is a usage error (2), a value that
27
- * came from config is broken runtime configuration (1).
28
- */
29
- export function assertTunnelBindable(host, tunnel, source) {
11
+ /** Refuse `--tunnel` with a `--bind` that cloudflared cannot reach. */
12
+ export function assertTunnelBindable(host, tunnel) {
30
13
  if (!tunnel || answersLocalhost(host))
31
14
  return;
32
- // Name the source, not just the exit code: under `config` there is no `--bind` to change and no flag
33
- // to drop, so flag-only wording would send the reader looking for something they never typed.
34
- const fix = source === "flag"
35
- ? "bind 0.0.0.0 (or 127.0.0.1), or drop --tunnel"
36
- : "set http.host to 0.0.0.0 (or 127.0.0.1) in fastagent.config.*, override it with --bind, or drop --tunnel";
37
- const message = `--tunnel reaches the serve by dialing localhost, which the bind address ${host} does not answer — ${fix}`;
38
- if (source === "flag")
39
- failUsage(message);
40
- failStartup(new Error(message));
15
+ failUsage(`--tunnel reaches the serve by dialing localhost, which the bind address ${host} does not answer — bind 0.0.0.0 (or 127.0.0.1), or drop --tunnel`);
41
16
  }
42
17
  /**
43
- * The bind address a serve uses: the flag, else `http.host` from the config — through `bindAddress`,
44
- * so a configured `localhost` is an ADDRESS by the time anything binds, renders or dials it — checked
45
- * against `--tunnel` with the exit code the SOURCE of the value earns (serve.ts assertTunnelBindable).
18
+ * Apply the flags that override what the definition said, for THIS run only.
19
+ *
20
+ * ONE place, because `dev` and `start` both do it and a mapping two call sites must each remember is one a third
21
+ * will not.
22
+ *
23
+ * `--no-invoke` outranks `http.invoke`: a config value travels into a deployed image, so "do not publish a turn
24
+ * endpoint on this tunnel" has to be sayable without editing the definition.
25
+ *
26
+ * It takes `POST /run` WITH it, including over a definition that said `http.run: true`. Both routes start a
27
+ * turn for an anonymous caller, and the flag's whole reason for existing is the case where the definition cannot be
28
+ * edited — `dev --tunnel --no-invoke` leaving the other one published at the tunnel URL would be the flag failing at
29
+ * exactly the job it was added for.
46
30
  */
47
- export function resolveBindHost(bindFlag, configured, tunnel) {
48
- const host = bindFlag ?? (configured === undefined ? undefined : bindAddress(configured));
49
- assertTunnelBindable(host, tunnel, bindFlag ? "flag" : "config");
50
- return host;
31
+ export function withRunOverrides(opened, run) {
32
+ return run.invoke === false ? { ...opened, http: { ...opened.http, invoke: false, run: false } } : opened;
51
33
  }
52
34
  /** What the CLI adds to the assembly: its shutdown grace, and exit on a connection that drops. */
53
35
  export function cliMountOptions(wrapAgent) {
@@ -58,111 +40,109 @@ export function cliMountOptions(wrapAgent) {
58
40
  };
59
41
  }
60
42
  /**
61
- * Bind, report, announce the control plane, open the tunnel, and close in order on a signal — the
62
- * tail dev's worker and start share once the service is assembled.
43
+ * Bind, report, announce the control plane, open the tunnel, and close in order on a signal — the tail dev's worker
44
+ * and start share once the service is assembled.
63
45
  */
64
46
  export function serveService(service, bind, posture) {
65
47
  const { host } = bind;
66
48
  const { tunnel, agentDir, stateRoot } = posture;
67
- let unannounce = () => { };
68
49
  serve(service.handler, bind, {
69
50
  ready: service.ready,
70
51
  onListening: (p) => {
71
52
  reportServing(service, host, p);
72
- unannounce = announceControl(service.control, stateRoot, { host, tunnel }, p);
53
+ announceControl(service, { host, tunnel });
73
54
  maybeTunnel(agentDir, service.channels.routes, p, tunnel, stateRoot);
74
55
  },
75
- onShutdown: () => {
76
- unannounce();
77
- return service.close();
78
- },
56
+ onShutdown: () => service.close(),
79
57
  });
80
58
  }
81
- /**
82
- * The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and
83
- * what mounted. One function because both commands must say the same thing at the same moment —
84
- * after readiness, never at socket bind.
85
- */
59
+ /** The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and what mounted. */
86
60
  export function reportServing(service, host, boundPort) {
87
61
  process.send?.({ type: "ready", port: boundPort, routeChannels: service.channels.routes });
88
- for (const line of readyAddressLines(host, boundPort, service.channels.builtinInvoke))
62
+ for (const line of readyAddressLines(host, boundPort, service.unverifiedRoutes.includes("POST /invoke"))) {
89
63
  log.info(line);
64
+ }
90
65
  log.info(`[fastagent] routes: ${Object.keys(service.routes).join(", ") || "(none)"}`);
91
66
  if (service.channels.longConnections.length > 0) {
92
67
  log.info(`[fastagent] long connections: ${service.channels.longConnections.join(", ")}`);
93
68
  }
94
69
  }
70
+ /** The line that names WHERE the serve is — every posture reports it, including AgentCore's own surface. */
71
+ export function bindLine(host, boundPort) {
72
+ return `[fastagent] http host on ${classifyBind(host) === "wildcard" ? `:${boundPort} (all interfaces)` : bindLabel(host, boundPort)}`;
73
+ }
95
74
  /**
96
- * The startup lines that name WHERE the serve is: the bind report, and the curl the reader copies.
97
- * ONE function because they are one message — they were two, and `--bind` updated the first while the
98
- * second went on dialing `localhost`, which is precisely what a non-wildcard bind stops answering. Now
99
- * neither can be changed without the other in view, and the address has a single derivation.
75
+ * The startup lines for a serve of OUR surface: the bind report, and the curl the reader copies.
100
76
  *
101
- * A wildcard bind is every interface, and naming one address there would understate it — but the curl
102
- * still needs one to dial, which is what `clientHost` gives (loopback for a wildcard, itself otherwise).
77
+ * `servesInvoke` is `AgentService.unverifiedRoutes`, never a guess from the route table: `http.invoke: false` leaves no
78
+ * `/invoke` to curl, and a channel may serve that path with a protocol of its own — both would turn this line into
79
+ * a copyable request that fails.
103
80
  */
104
- export function readyAddressLines(host, boundPort, builtinInvoke) {
81
+ export function readyAddressLines(host, boundPort, servesInvoke) {
105
82
  const dial = `${clientHost(host)}:${boundPort}`;
106
- const lines = [
107
- `[fastagent] http host on ${classifyBind(host) === "wildcard" ? `:${boundPort} (all interfaces)` : bindLabel(host, boundPort)}`,
83
+ return [
84
+ bindLine(host, boundPort),
85
+ ...(servesInvoke
86
+ ? [
87
+ `[fastagent] try it: curl -s ${dial}/invoke -X POST -H 'content-type: application/json' -d '${INVOKE_EXAMPLE_BODY}'`,
88
+ ]
89
+ : []),
108
90
  ];
109
- if (builtinInvoke) {
110
- lines.push(`[fastagent] try it: curl -s ${dial}/invoke -X POST -H 'content-type: application/json' -d '${INVOKE_EXAMPLE_BODY}'`);
111
- }
112
- return lines;
113
91
  }
114
92
  /**
115
- * Write `<stateRoot>/control.json` so a LOCAL client (`fastagent attach`) can find the control plane
116
- * once the port is known, and say what reaches it. Returns the file's removal — wired into the
117
- * shutdown so a stale file cannot point a client at a dead port (`attach` then fails with "cannot
118
- * read", accurate, instead of a stale token's misleading 401/ECONNREFUSED). A hard exit leaves the
119
- * file behind: advisory, overwritten by the next boot.
93
+ * Say what this port exposes and how far it reaches.
94
+ *
95
+ * NOTHING fastagent serves is authenticated — authentication belongs to the deployment (a gateway, a private
96
+ * network, AgentCore's IAM, an embedder's middleware). Two of the three warnings fire at a REACH the operator did
97
+ * not get by default: a bind off this machine, and `--tunnel`'s public URL.
120
98
  *
121
- * Here and not in the assembly: the file, its permissions and the warnings are how THIS process's
122
- * operator finds and protects the plane. An embedder distributes `service.control` itself.
99
+ * The cross-origin one is UNCONDITIONAL, including on a loopback `dev`, because the grant is. `*` is the default
100
+ * (`channels/serve.ts`), so a page the developer merely visits can drive this port from their browser and read the
101
+ * reply, loopback bind or not. Nobody opts into a default, so the one posture the decision costs is the one that
102
+ * has to hear about it.
103
+ *
104
+ * WHAT IS EXPOSED is read off `AgentService.unverifiedRoutes`, never assumed and never guessed from the route table.
105
+ * `POST /invoke` is on most serves but not all: AgentCore answers the Runtime's `/invocations` behind IAM,
106
+ * `http.invoke: false` withholds it, and a channel may serve that path itself — in which case the caller it is
107
+ * open to is the platform that signs its requests, not anyone at all. A warning naming an endpoint this process
108
+ * does not serve is how an operator learns to skim past all of them — the same reason `preflightDeploy` takes
109
+ * `publicUrl`.
123
110
  */
124
- export function announceControl(control, stateRoot, bind, boundPort) {
125
- if (!control)
126
- return () => { };
127
- mkdirSync(stateRoot, { recursive: true, mode: 0o700 });
128
- const path = join(stateRoot, "control.json");
129
- const url = `http://${clientHost(bind.host)}:${boundPort}`;
130
- writeFileAtomic(path, `${JSON.stringify({ url, token: control.token })}\n`, 0o600);
131
- log.info(`[fastagent] session control on ${control.prefix}/* (token in ${path})`);
132
- // LAN-reachable with the bearer token as the only protection — the tunnel and deploy paths warn
133
- // loudly, and the LAN path must not be the silent third way past the local trust story. A
134
- // loopback bind closes exactly that reach, so it earns silence.
111
+ export function announceControl(service, bind) {
112
+ const { controlPrefix, corsOrigins } = service;
113
+ if (controlPrefix)
114
+ log.info(`[fastagent] session control on ${controlPrefix}/*`);
115
+ // What an unauthenticated caller of this port can do, worst first. From `unverifiedRoutes`, so a channel that serves
116
+ // `/invoke` itself is not described as our unauthenticated data plane — it has its own signature check.
117
+ const exposed = describeAnonymousSurface({
118
+ invoke: service.unverifiedRoutes.includes("POST /invoke"),
119
+ run: service.unverifiedRoutes.includes("POST /run"),
120
+ ...(controlPrefix ? { controlPrefix } : {}),
121
+ });
122
+ if (exposed.length === 0)
123
+ return; // nothing of ours answers here (the AgentCore adapter's surface)
124
+ const what = `${exposed.join(" and ")} ${exposed.length > 1 ? "answer" : "answers"}`;
125
+ if (corsOrigins === undefined || corsOrigins.includes("*")) {
126
+ log.warn(`[fastagent] any web page your browser visits can call this serve cross-origin and read the reply: ${what} ` +
127
+ "with no credential. That is the default (`*`); pin the origins you actually use with http.cors " +
128
+ "(docs/design/session-control.md §14)");
129
+ }
135
130
  const reach = classifyBind(bind.host);
136
131
  if (reach !== "loopback") {
137
132
  log.warn(`[fastagent] the port binds ${reach === "wildcard" ? "all interfaces" : `${bind.host} (off this machine)`}: ` +
138
- "/control/* is reachable on your LAN, protected only by the bearer token — bind loopback " +
139
- "(--bind 127.0.0.1), firewall the port, or wrap it for real exposure (docs/design/session-control.md §14)");
133
+ `${what} UNAUTHENTICATED to anyone who can reach it — bind loopback (--bind 127.0.0.1), ` +
134
+ "firewall the port, or front it with a gateway (docs/design/session-control.md §14)");
140
135
  }
141
136
  if (bind.tunnel) {
142
- // Local trust = the token + its file permissions; --tunnel takes the whole port PUBLIC.
143
- log.warn("[fastagent] --tunnel exposes /control/* (steer, stop, rewrite or delete a session) at the public tunnel URL, " +
144
- "protected ONLY by the bearer token — wrap it with real auth before sharing that URL (docs/design/session-control.md §14)");
137
+ log.warn(`[fastagent] --tunnel publishes this port at a public URL with NO authentication: ${what} to anyone with ` +
138
+ "that URL — put real auth in front before sharing it (docs/design/session-control.md §14)");
145
139
  }
146
- return () => {
147
- try {
148
- rmSync(path, { force: true });
149
- }
150
- catch {
151
- /* the file is advisory — shutdown must not fail on it */
152
- }
153
- };
154
140
  }
155
- /** What the CLI gives a service to stop in, and the hard exit that follows it. The order matters:
156
- * a forced exit before the service answers would report a clean shutdown over a stuck channel. */
141
+ /** What the CLI gives a service to stop in, and the hard exit that follows it. */
157
142
  const SHUTDOWN_GRACE_MS = 800;
158
143
  const FORCED_EXIT_MS = 1_500;
159
- /**
160
- * Bind HTTP and report ready — but only once the SERVICE is, which is not the same moment: a bound
161
- * socket is not a serving agent while a declared long-connection channel is still dialling, so this
162
- * awaits `hooks.ready` (mountAgentService owns the connections themselves) before announcing
163
- * anything. Signals are the sole clean-shutdown command; `host` unset binds all interfaces.
164
- */
165
- function serve(handler, bind, hooks = {}) {
144
+ /** Bind HTTP and report ready — but only once the SERVICE is, which is not the same moment. */
145
+ export function serve(handler, bind, hooks = {}) {
166
146
  const { port, host } = bind;
167
147
  const hosted = serveNode(handler, { port, host });
168
148
  let stopping = false;
@@ -170,21 +150,15 @@ function serve(handler, bind, hooks = {}) {
170
150
  if (stopping)
171
151
  return;
172
152
  stopping = true;
173
- // Bounded: shutdown must not hang on a channel that will not close, so the deadline fires
174
- // regardless. No drain — an in-flight turn is cut, which is the existing contract.
175
- // Later than the service's own close deadline (SHUTDOWN_GRACE_MS below), or the process leaves
176
- // at 0 before `close()` has said a channel would not stop.
153
+ // Bounded: shutdown must not hang on a channel that will not close, so the deadline fires regardless.
177
154
  const deadline = setTimeout(() => {
178
155
  log.error(`[fastagent] shutdown did not finish within ${FORCED_EXIT_MS}ms; exiting`);
179
156
  process.exit(1);
180
157
  }, FORCED_EXIT_MS);
181
- // Stop accepting FIRST, before anything is awaited. `onShutdown` waits for long connections to
182
- // close, and a socket still listening through that wait would dispatch new work into channels
183
- // and a scheduler that are already shutting down.
158
+ // Stop accepting FIRST, before anything is awaited.
184
159
  const closingServer = hosted.close();
185
160
  hosted.closeAllConnections();
186
- // A cleanup that failed is not a clean exit: `close()` reports a channel that would not stop,
187
- // and swallowing it here would end the process at 0 over a resource still holding on.
161
+ // A cleanup that failed is not a clean exit.
188
162
  void Promise.allSettled([closingServer, Promise.resolve(hooks.onShutdown?.())]).then((outcomes) => {
189
163
  let code = exitCode;
190
164
  for (const outcome of outcomes) {
@@ -201,9 +175,9 @@ function serve(handler, bind, hooks = {}) {
201
175
  process.once("SIGTERM", () => stop(0));
202
176
  hosted.listening.then(async (boundPort) => {
203
177
  try {
204
- // A bound socket is NOT a serving agent: a declared socket-mode channel still has to come
205
- // up, and reporting ready before it does tells the supervisor (and --tunnel, and the
206
- // operator) that a surface is live while a channel is dead.
178
+ // A bound socket is NOT a serving agent: a declared socket-mode channel still has to come up, and reporting
179
+ // ready before it does tells the supervisor (and --tunnel, and the operator) that a surface is live while a
180
+ // channel is dead.
207
181
  await hooks.ready;
208
182
  if (stopping)
209
183
  return;
@@ -214,13 +188,12 @@ function serve(handler, bind, hooks = {}) {
214
188
  }
215
189
  }, (error) => {
216
190
  if (error.code === "EADDRINUSE") {
217
- // With a bind address the port is only taken ON THAT interface, so moving the bind is as valid
218
- // a fix as moving the port.
191
+ // With a bind address the port is only taken ON THAT interface, so moving the bind is as valid a fix as
192
+ // moving the port.
219
193
  failStartup(new Error(`${bindLabel(host, port)} is already in use; choose another with ` +
220
194
  `--port${classifyBind(host) === "wildcard" ? "" : " or --bind"}`));
221
195
  }
222
- // Through `bindLabel`, like every other message about a bind: hand-concatenating gives `:::8787`
223
- // for an IPv6 bind and a bare `:8787` for the wildcard, which reads as an explicit bind of nothing.
196
+ // Through `bindLabel`, like every other message about a bind.
224
197
  failStartup(new Error(`cannot bind http channel on ${bindLabel(host, port)}: ${error.message}`));
225
198
  });
226
199
  }
@@ -1,26 +1,19 @@
1
- import { type LoginIO, type LoginMethod, type LoginResult } from "../engines/pi/login.ts";
1
+ import { type AuthLayers } from "../engines/pi/config.ts";
2
+ import { type LoginIO } from "../engines/pi/login.ts";
2
3
  import type { LoadedDefinition } from "../engines/pi/definition.ts";
3
- import { type ModuleLoadFailure } from "../loader.ts";
4
4
  import type { ToolCollision } from "../engines/pi/tool.ts";
5
- import { type ResolvedPlacement } from "../paths.ts";
6
- /**
7
- * How every command that runs the model enters its agent directory, in the one order that works:
8
- * placement decides whose `.env` to read; `.env` may carry the proxy and the provider keys the
9
- * picker's auth probe needs; the picker runs last. Six commands wrote these steps out by hand, and
10
- * one carried the order as a comment. The result is the placement every later step reads.
11
- */
5
+ import type { ResolvedPlacement } from "../paths.ts";
6
+ /** How every command that runs the model enters its agent directory, in the one order that works. */
12
7
  export declare function enterAgentCommand(dirArg: string, opts: {
13
8
  model?: string;
14
- authPath?: string;
15
9
  input?: boolean;
16
10
  }): Promise<ResolvedPlacement>;
17
- /** What the startup report reads off an opened directory — a structural subset of the opener's return,
18
- * spelled out so this module does not depend on that function's whole shape. */
11
+ /** What the startup report reads off an opened directory. */
19
12
  export interface ReportableAssembly {
20
13
  agentDir: string;
21
14
  workspace: string;
22
15
  modelSpec: string;
23
- authPath: string;
16
+ auth: AuthLayers;
24
17
  config: {
25
18
  thinkingLevel?: string;
26
19
  };
@@ -28,63 +21,24 @@ export interface ReportableAssembly {
28
21
  toolNames: string[];
29
22
  deferredToolNames: string[];
30
23
  toolCollisions: ToolCollision[];
31
- toolFailures: ModuleLoadFailure[];
32
24
  }
33
- /**
34
- * What `dev` and `start` say about the directory they just opened, in the order they say it.
35
- *
36
- * ONE function because it is one report: the two commands wrote it out line by line, and the copies
37
- * had already diverged over which lines exist at all — `dev` naming the config file, `start` naming
38
- * state and sessions. A line added to one of two hand-written copies is invisible in the other.
39
- *
40
- * The divergence itself is PRESERVED, not resolved: `start`'s `state:`/`sessions:` pair introduces the
41
- * persistence warnings that follow it in production posture, and `dev`'s `config:` has no counterpart
42
- * there. Both are passed as explicit extras by the caller, so the asymmetry is visible at the call
43
- * site rather than buried in two copies of a list. Whether it is RIGHT is a separate question from
44
- * whether it has one owner.
45
- *
46
- * Findings (skill collisions, definition diagnostics) CLOSE the report — they are about the assembly
47
- * just printed. What a command says next is its own posture talk, not report: `start`'s persistence
48
- * notes now follow them rather than precede them.
49
- */
25
+ /** What `dev` and `start` say about the directory they just opened, in the order they say it. */
50
26
  export declare function reportAssembly(a: ReportableAssembly, extras?: {
51
- /** Printed between `workspace:`/`hint:` and `model:` (`dev` names the config file here). */
27
+ /** Printed between `workspace:` and `model:` (`dev` names the config file here). */
52
28
  beforeModel?: [label: string, value: string][];
53
29
  /** Printed after the tool lines, before findings (`start` names state + sessions here). */
54
30
  afterTools?: [label: string, value: string][];
55
31
  }): Promise<void>;
56
32
  /** Both stdin and stdout are a terminal — the precondition for an interactive prompt. */
57
33
  export declare function isInteractive(): boolean;
58
- /**
59
- * Parse + range-check a port string (CLI flag or env). Empty/whitespace is "not set" → undefined, so
60
- * the `??` chain falls through instead of binding port 0 (`Number("")` is 0). The exit code follows
61
- * RESPONSIBILITY, not the layer that discovers the problem: a bad `--port` is a usage error (2), a
62
- * bad `PORT` env is broken runtime configuration (1).
63
- */
34
+ /** Parse + range-check a port string (CLI flag or env). */
64
35
  export declare function parsePort(value: string | undefined, source: string, from: "flag" | "env"): number | undefined;
65
36
  /**
66
- * Parse a `--bind` address: empty/whitespace is "not set" → undefined (the `??` chain falls through to
67
- * config, then all interfaces). An unbindable string is a USAGE error (2) — caught here rather than as
68
- * a node bind failure, or worse, as a "the interface you bound" diagnostic downstream.
37
+ * Parse a `--bind` address: empty/whitespace is "not set" → undefined (the `??` chain falls through to config, then
38
+ * all interfaces).
69
39
  */
70
40
  export declare function parseBind(value: string | undefined): string | undefined;
71
- /** Report which source provides the model's credentials, surfacing a remediation hint at startup. Non-blocking.
72
- * Probes through the AGENT's model surface (`agentDir` carries its models.json), so a custom endpoint is
73
- * reported like any built-in rather than as an unknown provider. */
74
- export declare function reportAuth(agentDir: string, modelSpec: string, authPath: string): Promise<void>;
75
- /**
76
- * Interactive login with the api_key quick-fail probe closed into a LOOP: a definitively rejected key
77
- * (HTTP 401) deletes the bad credential and RE-PROMPTS immediately — the user's hands are on the
78
- * keyboard NOW; parking the failure for a later `fastagent login` would waste that. The loop exits on
79
- * a verified/unverifiable key (kept), an OAuth login (completing the flow already proved the
80
- * credential), or cancel (LoginCancelled propagates to the caller's cancel policy). Used by both the
81
- * `login` command and the first-run picker's inline login.
82
- */
83
- export declare function loginWithKeyCheck(provider: string | undefined, authPath: string, spec?: string, seams?: {
84
- flow?: (io: LoginIO, options: {
85
- provider?: string;
86
- authPath?: string;
87
- method?: LoginMethod;
88
- }) => Promise<LoginResult>;
89
- verify?: (provider: string, authPath: string, spec?: string) => Promise<"ok" | "rejected" | "unknown">;
90
- }): Promise<LoginResult>;
41
+ /** Report which source provides the model's credentials, surfacing a remediation hint at startup. */
42
+ export declare function reportAuth(agentDir: string, modelSpec: string, auth: AuthLayers): Promise<void>;
43
+ /** Login terminal IO via @clack/prompts: a searchable list once long, a hidden prompt for keys. */
44
+ export declare function terminalLoginIO(): LoginIO;