@fastagent-sh/fastagent 0.24.4 → 0.25.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 (480) hide show
  1. package/README.md +53 -82
  2. package/dist/agent-api.d.ts +452 -0
  3. package/dist/agent-api.js +201 -0
  4. package/dist/answer-text.d.ts +8 -0
  5. package/dist/answer-text.js +18 -0
  6. package/dist/atomic-write.d.ts +2 -2
  7. package/dist/atomic-write.js +2 -2
  8. package/dist/authoring.d.ts +77 -0
  9. package/dist/authoring.js +238 -0
  10. package/dist/channel.d.ts +29 -15
  11. package/dist/channel.js +4 -1
  12. package/dist/channels/agentcore-protocol.d.ts +36 -50
  13. package/dist/channels/agentcore-protocol.js +3 -3
  14. package/dist/channels/agentcore-service.d.ts +8 -18
  15. package/dist/channels/agentcore-service.js +108 -127
  16. package/dist/channels/agentcore.d.ts +8 -24
  17. package/dist/channels/agentcore.js +32 -65
  18. package/dist/channels/body.d.ts +0 -16
  19. package/dist/channels/body.js +0 -25
  20. package/dist/channels/busy.js +6 -1
  21. package/dist/channels/context.d.ts +4 -0
  22. package/dist/channels/context.js +35 -0
  23. package/dist/channels/discover.d.ts +18 -20
  24. package/dist/channels/discover.js +41 -99
  25. package/dist/channels/feishu/feishu-api.d.ts +54 -4
  26. package/dist/channels/feishu/feishu-api.js +192 -149
  27. package/dist/channels/feishu/feishu.d.ts +3 -0
  28. package/dist/channels/feishu/feishu.js +117 -106
  29. package/dist/channels/feishu/history.d.ts +55 -0
  30. package/dist/channels/feishu/history.js +199 -0
  31. package/dist/channels/feishu/invoke-turn.d.ts +13 -11
  32. package/dist/channels/feishu/invoke-turn.js +9 -10
  33. package/dist/channels/feishu/model.d.ts +2 -1
  34. package/dist/channels/feishu/normalize.js +100 -0
  35. package/dist/channels/feishu/preview.d.ts +2 -2
  36. package/dist/channels/feishu/register-webhook.d.ts +1 -0
  37. package/dist/channels/feishu/register-webhook.js +3 -2
  38. package/dist/channels/feishu/scaffold/channel.ts +65 -46
  39. package/dist/channels/feishu/scaffold/feishu-send.ts +38 -33
  40. package/dist/channels/feishu/scaffold/feishu-threads.ts +25 -0
  41. package/dist/channels/feishu/setup-mode.d.ts +45 -25
  42. package/dist/channels/feishu/setup-mode.js +74 -23
  43. package/dist/channels/feishu/shared-api.d.ts +24 -6
  44. package/dist/channels/feishu/shared-api.js +30 -24
  45. package/dist/channels/kit/context-buffer.d.ts +11 -2
  46. package/dist/channels/kit/context-buffer.js +7 -4
  47. package/dist/channels/kit/delivery.d.ts +19 -3
  48. package/dist/channels/kit/delivery.js +74 -15
  49. package/dist/channels/kit/event-stream.js +2 -1
  50. package/dist/channels/kit/invoke-turn-kit.d.ts +41 -41
  51. package/dist/channels/kit/invoke-turn-kit.js +62 -71
  52. package/dist/channels/kit/place-history.d.ts +107 -0
  53. package/dist/channels/kit/place-history.js +182 -0
  54. package/dist/channels/kit/preview-kit.d.ts +9 -5
  55. package/dist/channels/kit/preview-kit.js +36 -15
  56. package/dist/channels/kit/room-threads.d.ts +46 -0
  57. package/dist/channels/kit/room-threads.js +81 -0
  58. package/dist/channels/kit/seen.js +1 -1
  59. package/dist/channels/kit/stop-command.d.ts +6 -3
  60. package/dist/channels/kit/stop-command.js +20 -18
  61. package/dist/channels/kit/thread-fork.d.ts +17 -0
  62. package/dist/channels/kit/thread-fork.js +43 -0
  63. package/dist/channels/kit/thread-participants.js +1 -1
  64. package/dist/channels/kit/transport.d.ts +5 -0
  65. package/dist/channels/kit/transport.js +5 -0
  66. package/dist/channels/kit/turn-runner.d.ts +10 -9
  67. package/dist/channels/kit/turn-runner.js +17 -19
  68. package/dist/channels/kit/turn-store.d.ts +5 -4
  69. package/dist/channels/kit/turn-store.js +5 -5
  70. package/dist/channels/lark/lark.d.ts +3 -0
  71. package/dist/channels/lark/lark.js +5 -0
  72. package/dist/channels/lark/onboard.d.ts +5 -3
  73. package/dist/channels/lark/onboard.js +14 -14
  74. package/dist/channels/lark/scaffold/channel.ts +67 -44
  75. package/dist/channels/lark/scaffold/lark-send.ts +38 -33
  76. package/dist/channels/lark/scaffold/lark-threads.ts +25 -0
  77. package/dist/channels/respond.d.ts +0 -4
  78. package/dist/channels/respond.js +1 -1
  79. package/dist/channels/router.d.ts +18 -0
  80. package/dist/channels/router.js +68 -0
  81. package/dist/channels/serve.d.ts +5 -70
  82. package/dist/channels/serve.js +105 -287
  83. package/dist/channels/slack/history.d.ts +42 -0
  84. package/dist/channels/slack/history.js +282 -0
  85. package/dist/channels/slack/invoke-turn.d.ts +12 -5
  86. package/dist/channels/slack/invoke-turn.js +7 -5
  87. package/dist/channels/slack/manifest.d.ts +1 -4
  88. package/dist/channels/slack/manifest.js +22 -10
  89. package/dist/channels/slack/model.d.ts +2 -1
  90. package/dist/channels/slack/onboard.d.ts +0 -2
  91. package/dist/channels/slack/onboard.js +2 -4
  92. package/dist/channels/slack/onboarding-state.d.ts +0 -2
  93. package/dist/channels/slack/onboarding-state.js +0 -1
  94. package/dist/channels/slack/parse.d.ts +0 -5
  95. package/dist/channels/slack/parse.js +1 -16
  96. package/dist/channels/slack/preview.d.ts +2 -3
  97. package/dist/channels/slack/preview.js +78 -52
  98. package/dist/channels/slack/register-webhook.d.ts +1 -0
  99. package/dist/channels/slack/register-webhook.js +6 -5
  100. package/dist/channels/slack/scaffold/channel.ts +23 -24
  101. package/dist/channels/slack/scaffold/slack-send.ts +50 -43
  102. package/dist/channels/slack/scaffold/slack-threads.ts +29 -0
  103. package/dist/channels/slack/setup-server.d.ts +19 -0
  104. package/dist/channels/slack/setup-server.js +113 -11
  105. package/dist/channels/slack/shared-api.d.ts +15 -4
  106. package/dist/channels/slack/shared-api.js +19 -14
  107. package/dist/channels/slack/slack-api.d.ts +61 -2
  108. package/dist/channels/slack/slack-api.js +28 -5
  109. package/dist/channels/slack/slack.js +97 -52
  110. package/dist/channels/slack/welcomed.js +1 -1
  111. package/dist/channels/telegram/context-buffer.d.ts +6 -1
  112. package/dist/channels/telegram/context-buffer.js +19 -0
  113. package/dist/channels/telegram/invoke-turn.d.ts +8 -4
  114. package/dist/channels/telegram/invoke-turn.js +7 -7
  115. package/dist/channels/telegram/parse.d.ts +7 -2
  116. package/dist/channels/telegram/parse.js +7 -0
  117. package/dist/channels/telegram/preview.d.ts +2 -2
  118. package/dist/channels/telegram/register-webhook.d.ts +1 -0
  119. package/dist/channels/telegram/register-webhook.js +3 -2
  120. package/dist/channels/telegram/scaffold/channel.ts +27 -28
  121. package/dist/channels/telegram/scaffold/telegram-send.ts +61 -108
  122. package/dist/channels/telegram/shared-api.d.ts +34 -0
  123. package/dist/channels/telegram/shared-api.js +79 -0
  124. package/dist/channels/telegram/telegram-api.d.ts +15 -5
  125. package/dist/channels/telegram/telegram-api.js +10 -6
  126. package/dist/channels/telegram/telegram.js +27 -21
  127. package/dist/channels/telegram/turn-store.js +1 -1
  128. package/dist/channels/{kit/turn-queue.d.ts → turn-queue.d.ts} +2 -2
  129. package/dist/channels/{kit/turn-queue.js → turn-queue.js} +10 -10
  130. package/dist/cli/add-feishu.d.ts +42 -12
  131. package/dist/cli/add-feishu.js +177 -124
  132. package/dist/cli/add-slack.d.ts +8 -3
  133. package/dist/cli/add-slack.js +115 -63
  134. package/dist/cli/auth-view.d.ts +10 -3
  135. package/dist/cli/auth-view.js +8 -6
  136. package/dist/cli/box-login.d.ts +17 -7
  137. package/dist/cli/box-login.js +46 -12
  138. package/dist/cli/commands/add.d.ts +15 -4
  139. package/dist/cli/commands/add.js +252 -143
  140. package/dist/cli/commands/auth.d.ts +6 -0
  141. package/dist/cli/commands/auth.js +50 -0
  142. package/dist/cli/commands/content.d.ts +6 -0
  143. package/dist/cli/commands/content.js +45 -0
  144. package/dist/cli/commands/deploy/agentcore.js +50 -77
  145. package/dist/cli/commands/deploy/docker.js +38 -39
  146. package/dist/cli/commands/deploy/fly.js +21 -18
  147. package/dist/cli/commands/deploy/host-login.d.ts +26 -0
  148. package/dist/cli/commands/deploy/host-login.js +90 -0
  149. package/dist/cli/commands/deploy/railway.js +21 -26
  150. package/dist/cli/commands/deploy/shared.d.ts +45 -17
  151. package/dist/cli/commands/deploy/shared.js +34 -15
  152. package/dist/cli/commands/deploy.d.ts +0 -4
  153. package/dist/cli/commands/deploy.js +237 -50
  154. package/dist/cli/commands/destroy.js +8 -6
  155. package/dist/cli/commands/dev.d.ts +0 -2
  156. package/dist/cli/commands/dev.js +20 -19
  157. package/dist/cli/commands/env.d.ts +12 -0
  158. package/dist/cli/commands/env.js +190 -0
  159. package/dist/cli/commands/info.js +95 -156
  160. package/dist/cli/commands/init.d.ts +2 -2
  161. package/dist/cli/commands/init.js +35 -33
  162. package/dist/cli/commands/invoke.d.ts +6 -0
  163. package/dist/cli/commands/invoke.js +131 -16
  164. package/dist/cli/commands/login.d.ts +31 -2
  165. package/dist/cli/commands/login.js +413 -64
  166. package/dist/cli/commands/logout.d.ts +4 -0
  167. package/dist/cli/commands/logout.js +53 -0
  168. package/dist/cli/commands/logs.js +8 -6
  169. package/dist/cli/commands/models.d.ts +2 -1
  170. package/dist/cli/commands/models.js +39 -37
  171. package/dist/cli/commands/schedules.d.ts +21 -0
  172. package/dist/cli/commands/schedules.js +143 -0
  173. package/dist/cli/commands/start.d.ts +11 -10
  174. package/dist/cli/commands/start.js +35 -62
  175. package/dist/cli/content-view.d.ts +9 -0
  176. package/dist/cli/content-view.js +26 -0
  177. package/dist/cli/fail.d.ts +9 -12
  178. package/dist/cli/fail.js +17 -14
  179. package/dist/cli/invoke-stream.d.ts +12 -3
  180. package/dist/cli/invoke-stream.js +85 -23
  181. package/dist/cli/kernel.d.ts +9 -2
  182. package/dist/cli/kernel.js +15 -6
  183. package/dist/cli/login-relay.d.ts +3 -2
  184. package/dist/cli/login-relay.js +18 -6
  185. package/dist/cli/models-view.d.ts +5 -1
  186. package/dist/cli/models-view.js +1 -1
  187. package/dist/cli/person.d.ts +10 -0
  188. package/dist/cli/person.js +23 -0
  189. package/dist/cli/program.js +421 -203
  190. package/dist/cli/serve.d.ts +13 -63
  191. package/dist/cli/serve.js +31 -121
  192. package/dist/cli/shared.d.ts +21 -48
  193. package/dist/cli/shared.js +68 -89
  194. package/dist/cli/ticket.d.ts +136 -0
  195. package/dist/cli/ticket.js +476 -0
  196. package/dist/client.d.ts +7 -0
  197. package/dist/client.js +2 -0
  198. package/dist/content/declare.d.ts +70 -0
  199. package/dist/content/declare.js +163 -0
  200. package/dist/content/file.d.ts +32 -0
  201. package/dist/content/file.js +119 -0
  202. package/dist/content/git.d.ts +41 -0
  203. package/dist/content/git.js +217 -0
  204. package/dist/content/mount.d.ts +2 -0
  205. package/dist/content/mount.js +15 -0
  206. package/dist/content/resolve.d.ts +52 -0
  207. package/dist/content/resolve.js +151 -0
  208. package/dist/content/source.d.ts +27 -0
  209. package/dist/content/source.js +53 -0
  210. package/dist/conversation-sessions.d.ts +26 -0
  211. package/dist/conversation-sessions.js +99 -0
  212. package/dist/declared-secrets.d.ts +19 -37
  213. package/dist/declared-secrets.js +16 -58
  214. package/dist/deploy/agentcore/destroy.d.ts +3 -3
  215. package/dist/deploy/agentcore/destroy.js +46 -28
  216. package/dist/deploy/agentcore/forwarder.js +105 -22
  217. package/dist/deploy/agentcore/logs.js +1 -1
  218. package/dist/deploy/agentcore/plan.d.ts +10 -24
  219. package/dist/deploy/agentcore/plan.js +31 -135
  220. package/dist/deploy/agentcore/run.d.ts +1 -1
  221. package/dist/deploy/agentcore/run.js +8 -5
  222. package/dist/deploy/agentcore/shell.d.ts +1 -1
  223. package/dist/deploy/agentcore/shell.js +5 -5
  224. package/dist/deploy/api.d.ts +34 -0
  225. package/dist/deploy/api.js +50 -0
  226. package/dist/deploy/box-shell.d.ts +6 -0
  227. package/dist/deploy/box-shell.js +7 -0
  228. package/dist/deploy/build-context.d.ts +7 -5
  229. package/dist/deploy/build-context.js +41 -35
  230. package/dist/deploy/channel-ingress.d.ts +6 -1
  231. package/dist/deploy/channel-ingress.js +18 -5
  232. package/dist/deploy/container.d.ts +22 -9
  233. package/dist/deploy/container.js +96 -55
  234. package/dist/deploy/docker/plan.d.ts +3 -2
  235. package/dist/deploy/docker/plan.js +13 -14
  236. package/dist/deploy/docker/run.d.ts +2 -2
  237. package/dist/deploy/docker/run.js +8 -4
  238. package/dist/deploy/fly/plan.d.ts +1 -1
  239. package/dist/deploy/fly/plan.js +12 -21
  240. package/dist/deploy/fly/run.d.ts +10 -6
  241. package/dist/deploy/fly/run.js +11 -6
  242. package/dist/deploy/hosts.d.ts +2 -1
  243. package/dist/deploy/hosts.js +2 -1
  244. package/dist/deploy/preflight.d.ts +21 -23
  245. package/dist/deploy/preflight.js +222 -201
  246. package/dist/deploy/railway/plan.d.ts +8 -6
  247. package/dist/deploy/railway/plan.js +15 -58
  248. package/dist/deploy/railway/run.d.ts +8 -3
  249. package/dist/deploy/railway/run.js +12 -8
  250. package/dist/deploy/residency.d.ts +5 -11
  251. package/dist/deploy/residency.js +0 -6
  252. package/dist/deploy/runner.d.ts +1 -1
  253. package/dist/deploy/runner.js +1 -1
  254. package/dist/deploy/secrets.d.ts +16 -2
  255. package/dist/deploy/secrets.js +33 -6
  256. package/dist/deploy/workspace.d.ts +11 -6
  257. package/dist/deploy/workspace.js +55 -38
  258. package/dist/dev-supervisor.d.ts +11 -2
  259. package/dist/dev-supervisor.js +51 -26
  260. package/dist/effect-port.d.ts +4 -4
  261. package/dist/effect-port.js +4 -4
  262. package/dist/environment/apt.d.ts +4 -0
  263. package/dist/environment/apt.js +32 -0
  264. package/dist/environment/declare.d.ts +59 -0
  265. package/dist/environment/declare.js +210 -0
  266. package/dist/environment/mise.d.ts +50 -0
  267. package/dist/environment/mise.js +268 -0
  268. package/dist/feishu.d.ts +2 -2
  269. package/dist/feishu.js +2 -2
  270. package/dist/git.d.ts +13 -0
  271. package/dist/git.js +55 -0
  272. package/dist/harnesses/models/catalog.d.ts +20 -0
  273. package/dist/harnesses/models/catalog.js +254 -0
  274. package/dist/{engines/pi/auth.d.ts → harnesses/models/credentials.d.ts} +3 -3
  275. package/dist/{engines/pi/auth.js → harnesses/models/credentials.js} +3 -3
  276. package/dist/harnesses/models/environment.d.ts +43 -0
  277. package/dist/harnesses/models/environment.js +82 -0
  278. package/dist/{engines/pi → harnesses/models}/login.d.ts +57 -26
  279. package/dist/{engines/pi → harnesses/models}/login.js +187 -79
  280. package/dist/harnesses/models/models.d.ts +83 -0
  281. package/dist/harnesses/models/models.js +158 -0
  282. package/dist/harnesses/pi-durable/agent.d.ts +42 -0
  283. package/dist/harnesses/pi-durable/agent.js +579 -0
  284. package/dist/harnesses/pi-durable/defaults.d.ts +28 -0
  285. package/dist/harnesses/pi-durable/defaults.js +26 -0
  286. package/dist/harnesses/pi-durable/define.d.ts +77 -0
  287. package/dist/harnesses/pi-durable/define.js +28 -0
  288. package/dist/harnesses/pi-durable/entries.d.ts +32 -0
  289. package/dist/harnesses/pi-durable/entries.js +126 -0
  290. package/dist/harnesses/pi-durable/events.d.ts +25 -0
  291. package/dist/harnesses/pi-durable/events.js +238 -0
  292. package/dist/harnesses/pi-durable/ids.d.ts +16 -0
  293. package/dist/harnesses/pi-durable/ids.js +55 -0
  294. package/dist/harnesses/pi-durable/messages.d.ts +41 -0
  295. package/dist/harnesses/pi-durable/messages.js +116 -0
  296. package/dist/harnesses/pi-durable/open.d.ts +88 -0
  297. package/dist/harnesses/pi-durable/open.js +329 -0
  298. package/dist/harnesses/pi-durable/reads.d.ts +30 -0
  299. package/dist/harnesses/pi-durable/reads.js +94 -0
  300. package/dist/harnesses/pi-durable/registry.d.ts +18 -0
  301. package/dist/harnesses/pi-durable/registry.js +56 -0
  302. package/dist/harnesses/pi-durable/release.d.ts +13 -0
  303. package/dist/harnesses/pi-durable/release.js +40 -0
  304. package/dist/harnesses/pi-durable/serve.d.ts +80 -0
  305. package/dist/harnesses/pi-durable/serve.js +156 -0
  306. package/dist/harnesses/pi-durable/sessions.d.ts +27 -0
  307. package/dist/harnesses/pi-durable/sessions.js +47 -0
  308. package/dist/harnesses/pi-durable/storage.d.ts +4 -0
  309. package/dist/harnesses/pi-durable/storage.js +49 -0
  310. package/dist/harnesses/pi-durable/stream.d.ts +20 -0
  311. package/dist/harnesses/pi-durable/stream.js +221 -0
  312. package/dist/harnesses/pi-durable/text.d.ts +30 -0
  313. package/dist/harnesses/pi-durable/text.js +292 -0
  314. package/dist/harnesses/pi-durable/wake.d.ts +4 -0
  315. package/dist/harnesses/pi-durable/wake.js +81 -0
  316. package/dist/http/client.d.ts +6 -0
  317. package/dist/http/client.js +256 -0
  318. package/dist/http/contract.d.ts +541 -0
  319. package/dist/http/contract.js +179 -0
  320. package/dist/http/server.d.ts +34 -0
  321. package/dist/http/server.js +194 -0
  322. package/dist/index.d.ts +17 -4
  323. package/dist/index.js +10 -5
  324. package/dist/lark.d.ts +2 -2
  325. package/dist/lark.js +2 -2
  326. package/dist/locked-file.d.ts +17 -0
  327. package/dist/{engines/pi/locked-file.js → locked-file.js} +16 -10
  328. package/dist/once.d.ts +6 -0
  329. package/dist/once.js +23 -0
  330. package/dist/paths.d.ts +36 -52
  331. package/dist/paths.js +66 -182
  332. package/dist/runtime.d.ts +25 -2
  333. package/dist/runtime.js +27 -0
  334. package/dist/scaffold/add-channel.d.ts +14 -27
  335. package/dist/scaffold/add-channel.js +82 -180
  336. package/dist/scaffold/init.d.ts +17 -18
  337. package/dist/scaffold/init.js +87 -99
  338. package/dist/scaffold/templates/SYSTEM.md +12 -0
  339. package/dist/scaffold/templates/env.example +4 -10
  340. package/dist/scaffold/templates/fastagent.config.ts +21 -33
  341. package/dist/scaffold/templates/gitignore +8 -1
  342. package/dist/scaffold/templates/skills/writing-great-skills/SKILL.md +1 -2
  343. package/dist/scaffold/templates.d.ts +9 -4
  344. package/dist/scaffold/templates.js +7 -5
  345. package/dist/scaffold/vendor-skill.d.ts +1 -4
  346. package/dist/scaffold/vendor-skill.js +5 -6
  347. package/dist/schedule/cron.d.ts +13 -0
  348. package/dist/schedule/cron.js +52 -0
  349. package/dist/schedule/eventbridge-cron.d.ts +17 -0
  350. package/dist/schedule/eventbridge-cron.js +88 -0
  351. package/dist/schedule/schedule.d.ts +23 -0
  352. package/dist/schedule/schedule.js +34 -0
  353. package/dist/schedule/scheduler.d.ts +34 -33
  354. package/dist/schedule/scheduler.js +251 -137
  355. package/dist/schedule/state.d.ts +4 -14
  356. package/dist/schedule/state.js +7 -7
  357. package/dist/schedule/wake-alarm.d.ts +22 -2
  358. package/dist/schedule/wake-alarm.js +66 -20
  359. package/dist/schedule/wakeups.d.ts +16 -15
  360. package/dist/schedule/wakeups.js +47 -45
  361. package/dist/service.d.ts +56 -169
  362. package/dist/service.js +91 -187
  363. package/dist/serving-command.d.ts +10 -0
  364. package/dist/serving-command.js +16 -0
  365. package/dist/slack.d.ts +1 -1
  366. package/dist/slack.js +1 -1
  367. package/dist/{channels/kit/state.js → state-file.js} +6 -6
  368. package/dist/telegram.d.ts +1 -0
  369. package/dist/telegram.js +1 -0
  370. package/dist/tunnel.d.ts +3 -0
  371. package/dist/tunnel.js +12 -4
  372. package/dist/value-file.d.ts +21 -0
  373. package/dist/value-file.js +108 -0
  374. package/dist/version.d.ts +5 -0
  375. package/dist/version.js +14 -1
  376. package/package.json +18 -28
  377. package/dist/agent.d.ts +0 -106
  378. package/dist/agent.js +0 -21
  379. package/dist/channels/control.d.ts +0 -31
  380. package/dist/channels/control.js +0 -329
  381. package/dist/channels/define-channel.d.ts +0 -39
  382. package/dist/channels/define-channel.js +0 -9
  383. package/dist/channels/feishu/context-buffer.d.ts +0 -35
  384. package/dist/channels/feishu/context-buffer.js +0 -65
  385. package/dist/channels/feishu/scaffold/channel.websocket.ts +0 -31
  386. package/dist/channels/http.d.ts +0 -23
  387. package/dist/channels/http.js +0 -57
  388. package/dist/channels/lark/scaffold/channel.websocket.ts +0 -31
  389. package/dist/channels/slack/context-buffer.d.ts +0 -23
  390. package/dist/channels/slack/context-buffer.js +0 -37
  391. package/dist/channels/sse.d.ts +0 -4
  392. package/dist/channels/sse.js +0 -66
  393. package/dist/cli/commands/chat.d.ts +0 -3
  394. package/dist/cli/commands/chat.js +0 -14
  395. package/dist/cli/commands/routine-run.d.ts +0 -6
  396. package/dist/cli/commands/routine-run.js +0 -46
  397. package/dist/cli/commands/routine.d.ts +0 -25
  398. package/dist/cli/commands/routine.js +0 -122
  399. package/dist/cli/commands/tool.d.ts +0 -1
  400. package/dist/cli/commands/tool.js +0 -57
  401. package/dist/collect.d.ts +0 -63
  402. package/dist/collect.js +0 -90
  403. package/dist/core.d.ts +0 -13
  404. package/dist/core.js +0 -15
  405. package/dist/engines/pi/agent-models.d.ts +0 -83
  406. package/dist/engines/pi/agent-models.js +0 -120
  407. package/dist/engines/pi/agent-session-factory.d.ts +0 -121
  408. package/dist/engines/pi/agent-session-factory.js +0 -535
  409. package/dist/engines/pi/chat.d.ts +0 -3
  410. package/dist/engines/pi/chat.js +0 -8
  411. package/dist/engines/pi/config.d.ts +0 -71
  412. package/dist/engines/pi/config.js +0 -199
  413. package/dist/engines/pi/create.d.ts +0 -170
  414. package/dist/engines/pi/create.js +0 -343
  415. package/dist/engines/pi/definition.d.ts +0 -74
  416. package/dist/engines/pi/definition.js +0 -236
  417. package/dist/engines/pi/entry-images.d.ts +0 -14
  418. package/dist/engines/pi/entry-images.js +0 -23
  419. package/dist/engines/pi/invoke-session.d.ts +0 -18
  420. package/dist/engines/pi/invoke-session.js +0 -403
  421. package/dist/engines/pi/locked-file.d.ts +0 -9
  422. package/dist/engines/pi/machine.d.ts +0 -53
  423. package/dist/engines/pi/machine.js +0 -137
  424. package/dist/engines/pi/models.d.ts +0 -200
  425. package/dist/engines/pi/models.js +0 -533
  426. package/dist/engines/pi/open.d.ts +0 -180
  427. package/dist/engines/pi/open.js +0 -270
  428. package/dist/engines/pi/openai-account-models.d.ts +0 -35
  429. package/dist/engines/pi/openai-account-models.js +0 -116
  430. package/dist/engines/pi/report.d.ts +0 -18
  431. package/dist/engines/pi/report.js +0 -59
  432. package/dist/engines/pi/retry-event.d.ts +0 -6
  433. package/dist/engines/pi/retry-event.js +0 -15
  434. package/dist/engines/pi/service.d.ts +0 -9
  435. package/dist/engines/pi/service.js +0 -14
  436. package/dist/engines/pi/session-builder.d.ts +0 -13
  437. package/dist/engines/pi/session-builder.js +0 -117
  438. package/dist/engines/pi/session-control.d.ts +0 -77
  439. package/dist/engines/pi/session-control.js +0 -908
  440. package/dist/engines/pi/session-effects.d.ts +0 -14
  441. package/dist/engines/pi/session-effects.js +0 -30
  442. package/dist/engines/pi/session-inheritance.d.ts +0 -21
  443. package/dist/engines/pi/session-inheritance.js +0 -204
  444. package/dist/engines/pi/session-markers.d.ts +0 -49
  445. package/dist/engines/pi/session-markers.js +0 -60
  446. package/dist/engines/pi/session-settings.d.ts +0 -67
  447. package/dist/engines/pi/session-settings.js +0 -119
  448. package/dist/engines/pi/session-store.d.ts +0 -69
  449. package/dist/engines/pi/session-store.js +0 -430
  450. package/dist/engines/pi/tool-context.d.ts +0 -45
  451. package/dist/engines/pi/tool-context.js +0 -31
  452. package/dist/engines/pi/tool.d.ts +0 -99
  453. package/dist/engines/pi/tool.js +0 -118
  454. package/dist/engines/pi/turn-kit.d.ts +0 -92
  455. package/dist/engines/pi/turn-kit.js +0 -288
  456. package/dist/engines/pi/wake-tool.d.ts +0 -9
  457. package/dist/engines/pi/wake-tool.js +0 -92
  458. package/dist/loader.d.ts +0 -41
  459. package/dist/loader.js +0 -116
  460. package/dist/node.d.ts +0 -3
  461. package/dist/node.js +0 -4
  462. package/dist/observe.d.ts +0 -6
  463. package/dist/observe.js +0 -47
  464. package/dist/pi.d.ts +0 -25
  465. package/dist/pi.js +0 -15
  466. package/dist/scaffold/templates/APPEND_SYSTEM.md +0 -12
  467. package/dist/scaffold/templates/tools/fetch-url.ts +0 -25
  468. package/dist/schedule/discover.d.ts +0 -17
  469. package/dist/schedule/discover.js +0 -61
  470. package/dist/schedule/routine.d.ts +0 -43
  471. package/dist/schedule/routine.js +0 -32
  472. package/dist/schedule/run.d.ts +0 -55
  473. package/dist/schedule/run.js +0 -146
  474. package/dist/secrets-gate.d.ts +0 -32
  475. package/dist/secrets-gate.js +0 -33
  476. package/dist/session-remote.d.ts +0 -47
  477. package/dist/session-remote.js +0 -460
  478. package/dist/session.d.ts +0 -466
  479. package/dist/session.js +0 -57
  480. /package/dist/{channels/kit/state.d.ts → state-file.d.ts} +0 -0
@@ -8,7 +8,8 @@ import { newSlackOnboardingState, onboardSlackApp } from "../channels/slack/onbo
8
8
  import { configTokenExpiry, readSlackOnboardingState, writeSlackOnboardingState, } from "../channels/slack/onboarding-state.js";
9
9
  import { startSlackSetupServer } from "../channels/slack/setup-server.js";
10
10
  import { startCloudflareTunnel } from "../tunnel.js";
11
- const CONFIG_TOKEN_URL = "https://api.slack.com/apps";
11
+ /** Where an App Configuration token pair is generated. */
12
+ const SLACK_CONFIG_TOKEN_URL = "https://api.slack.com/apps";
12
13
  async function promptValue(message, hidden = false, initialValue) {
13
14
  const result = hidden ? await password({ message }) : await clackText({ message, initialValue });
14
15
  if (isCancel(result))
@@ -20,10 +21,14 @@ async function promptValue(message, hidden = false, initialValue) {
20
21
  }
21
22
  /** The one place an App Configuration token pair is asked for and validated. */
22
23
  async function promptConfigTokens() {
23
- console.error(`[fastagent] generate an App Configuration Token pair at ${CONFIG_TOKEN_URL}`);
24
- openExternalUrl(CONFIG_TOKEN_URL);
24
+ console.error(`[fastagent] generate an App Configuration Token pair at ${SLACK_CONFIG_TOKEN_URL}`);
25
+ openExternalUrl(SLACK_CONFIG_TOKEN_URL);
25
26
  const configToken = await promptValue("Slack configuration access token (xoxe.xoxp-…)", true);
26
27
  const configRefreshToken = await promptValue("Slack configuration refresh token (xoxe-…)", true);
28
+ return checkedConfigTokens(configToken, configRefreshToken);
29
+ }
30
+ /** An App Configuration token pair, refused unless each is the kind Slack issues. */
31
+ function checkedConfigTokens(configToken, configRefreshToken) {
27
32
  if (!configToken.startsWith("xoxe.") || !configRefreshToken.startsWith("xoxe-")) {
28
33
  throw new Error("invalid Slack configuration token prefix (expected xoxe. access + xoxe- refresh)");
29
34
  }
@@ -33,6 +38,8 @@ async function promptConfigTokens() {
33
38
  async function chooseTokenAction(prompt) {
34
39
  if (prompt.forced)
35
40
  return "replace-config";
41
+ if (!prompt.asks)
42
+ return "keep";
36
43
  const answer = await select({
37
44
  message: prompt.message,
38
45
  initialValue: "keep",
@@ -49,18 +56,69 @@ async function chooseTokenAction(prompt) {
49
56
  throw new Error("Slack onboarding cancelled");
50
57
  return answer;
51
58
  }
52
- /** Interactive single-workspace internal-app creation + installation. */
59
+ const nothingToReplace = () => new Error("--replace-config found no local Slack onboarding state on this machine — nothing to replace. " +
60
+ "Run `fastagent add slack` to onboard, or update the Request URL manually in the Slack console");
61
+ /** The temporary setup server and the tunnel to it, started once something needs them. */
62
+ function setupEndpoint() {
63
+ let started;
64
+ return {
65
+ get: () => {
66
+ started ??= (async () => {
67
+ const server = await startSlackSetupServer();
68
+ const tunnel = await startCloudflareTunnel(server.port);
69
+ if (!tunnel) {
70
+ await server.close();
71
+ throw new Error("Slack onboarding needs a temporary HTTPS tunnel — install cloudflared and re-run");
72
+ }
73
+ console.error(`[fastagent] temporary Slack setup tunnel ready → ${tunnel.url}`);
74
+ return { server, tunnelUrl: tunnel.url, closeTunnel: () => tunnel.close() };
75
+ })();
76
+ return started;
77
+ },
78
+ /** The endpoint if something started it, never starting one. */
79
+ ifStarted: () => started?.catch(() => undefined),
80
+ async close() {
81
+ const endpoint = await started?.catch(() => undefined);
82
+ if (endpoint === undefined)
83
+ return;
84
+ endpoint.closeTunnel();
85
+ await endpoint.server.close().catch(() => { });
86
+ },
87
+ };
88
+ }
89
+ /** Single-workspace internal-app creation + installation. */
53
90
  export async function onboardSlackInternalApp(input) {
54
- if (!(process.stdin.isTTY && process.stdout.isTTY)) {
55
- throw new Error("`add slack` needs an interactive terminal for internal-app creation and OAuth — " +
56
- "re-run in a terminal, or pass --no-onboard to scaffold only");
91
+ const { person } = input;
92
+ const endpoint = setupEndpoint();
93
+ /** A fresh pair: at the terminal, or on the setup server's page. */
94
+ const freshTokens = async () => {
95
+ if (person === undefined)
96
+ return promptConfigTokens();
97
+ const { server, tunnelUrl } = await endpoint.get();
98
+ person.waitsOn(`${tunnelUrl}${server.tokensPath}`, `generate a Slack App Configuration Token at ${SLACK_CONFIG_TOKEN_URL} and paste it on this page`);
99
+ const tokens = await server.waitForTokens(({ access, refresh }) => checkedConfigTokens(access, refresh));
100
+ person.carriesOn();
101
+ return tokens;
102
+ };
103
+ try {
104
+ await onboard(input, freshTokens, endpoint);
105
+ }
106
+ catch (error) {
107
+ // The browser that pasted the pair waits on the next page: it says why, as the ticket does.
108
+ await (await endpoint.ifStarted())?.server.failed(error.message);
109
+ throw error;
110
+ }
111
+ finally {
112
+ await endpoint.close();
57
113
  }
114
+ }
115
+ async function onboard(input, freshTokens, endpoint) {
116
+ const { person } = input;
117
+ const asks = person === undefined;
58
118
  let state = readSlackOnboardingState(input.stateRoot);
59
119
  const resumed = state !== undefined;
60
- if (input.replaceConfig && !state) {
61
- throw new Error("--replace-config found no local Slack onboarding state on this machine — nothing to replace. " +
62
- "Run `fastagent add slack` to onboard, or update the Request URL manually in the Slack console");
63
- }
120
+ if (input.replaceConfig && !state)
121
+ throw nothingToReplace();
64
122
  if (state?.installedAt) {
65
123
  const env = await readFile(dotEnvPath(input.target), "utf8")
66
124
  .then(parseEnvContent)
@@ -75,20 +133,19 @@ export async function onboardSlackInternalApp(input) {
75
133
  `${missingRuntime.join(", ")} — ` +
76
134
  "restore them from the Slack app console, or delete the app + onboarding state and create a new one");
77
135
  }
78
- if (input.groupBehavior.explicit && state.groupBehavior !== input.groupBehavior.behavior) {
79
- throw new Error(`the onboarded Slack app uses group behavior ${state.groupBehavior}; changing an installed app's ` +
80
- "OAuth scopes is a migration. Keep the existing choice, or remove the app + Slack onboarding state and create a new app");
81
- }
82
136
  const action = await chooseTokenAction({
83
137
  forced: input.replaceConfig === true,
138
+ asks,
84
139
  message: `Slack app ${state.appId ?? "(unknown)"} is already installed${state.teamName ? ` in ${state.teamName}` : ""}`,
85
140
  keepLabel: "Keep the installed app",
86
141
  replaceLabel: "Replace App Configuration tokens",
87
142
  replaceHint: "repair automatic dev/deploy Request URL updates",
88
143
  });
89
144
  if (action === "replace-config") {
90
- writeSlackOnboardingState(input.stateRoot, { ...state, ...(await promptConfigTokens()) });
145
+ writeSlackOnboardingState(input.stateRoot, { ...state, ...(await freshTokens()) });
91
146
  console.error("[fastagent] replaced local Slack App Configuration tokens; runtime app credentials are unchanged");
147
+ // A browser that pasted the pair waits on the page after it: this is where the setup ends.
148
+ await (await endpoint.ifStarted())?.server.done("Slack App Configuration tokens replaced: you can close this page.");
92
149
  }
93
150
  else {
94
151
  console.error("[fastagent] keeping the installed Slack app and local configuration tokens");
@@ -96,69 +153,64 @@ export async function onboardSlackInternalApp(input) {
96
153
  return;
97
154
  }
98
155
  if (!state) {
99
- const appName = await promptValue("Slack app name", false, `FastAgent ${basename(input.target)}`);
100
- clackLog.info("Slack's configuration refresh token can manage apps owned by your user in this workspace. " +
101
- "FastAgent stores it only in owner-readable local state; it is never deployed.");
102
- state = newSlackOnboardingState({
103
- appName,
104
- groupBehavior: input.groupBehavior.behavior,
105
- ...(await promptConfigTokens()),
106
- });
107
- writeSlackOnboardingState(input.stateRoot, state);
108
- }
109
- else if (input.groupBehavior.explicit && !state.appId) {
110
- state = { ...state, groupBehavior: input.groupBehavior.behavior };
156
+ const appName = asks
157
+ ? await promptValue("Slack app name", false, `FastAgent ${basename(input.target)}`)
158
+ : `FastAgent ${basename(input.target)}`;
159
+ if (asks) {
160
+ clackLog.info("Slack's configuration refresh token can manage apps owned by your user in this workspace. " +
161
+ "FastAgent stores it only in owner-readable local state; it is never deployed.");
162
+ }
163
+ state = newSlackOnboardingState({ appName, ...(await freshTokens()) });
111
164
  writeSlackOnboardingState(input.stateRoot, state);
112
165
  }
113
166
  if (state.createAttemptedAt && !state.appId) {
114
167
  throw new Error(`a prior Slack app creation attempt at ${state.createAttemptedAt} returned no app ID — ` +
115
- `inspect ${CONFIG_TOKEN_URL}; delete any incomplete app and ${input.stateRoot}/channels/slack/onboarding.json before retrying`);
168
+ `inspect ${SLACK_CONFIG_TOKEN_URL}; delete any incomplete app and ${input.stateRoot}/channels/slack/onboarding.json before retrying`);
116
169
  }
117
170
  // `--replace-config` also covers the created-but-not-installed state, where a revoked token would otherwise strand
118
171
  // the resume (rotation fails and no menu offers replacement).
119
172
  if (resumed && (!state.appId || input.replaceConfig)) {
120
173
  const action = await chooseTokenAction({
121
174
  forced: input.replaceConfig === true,
175
+ asks,
122
176
  message: "Resume Slack onboarding with which App Configuration tokens?",
123
177
  keepLabel: "Use the saved token pair",
124
178
  replaceLabel: "Paste a fresh token pair",
125
179
  });
126
180
  if (action === "replace-config") {
127
- state = { ...state, ...(await promptConfigTokens()) };
181
+ state = { ...state, ...(await freshTokens()) };
128
182
  writeSlackOnboardingState(input.stateRoot, state);
129
183
  }
130
184
  }
131
- const server = await startSlackSetupServer();
132
- const tunnel = await startCloudflareTunnel(server.port);
133
- if (!tunnel) {
134
- await server.close();
135
- throw new Error("Slack onboarding needs a temporary HTTPS tunnel — install cloudflared and re-run");
136
- }
137
- const requestUrl = `${tunnel.url}${server.requestPath}`;
138
- const redirectUrl = `${tunnel.url}${server.redirectPath}`;
139
- console.error(`[fastagent] temporary Slack setup tunnel ready → ${tunnel.url}`);
140
- try {
141
- // No local readiness probe: Slack challenges requestUrl from ITS network during app creation, and that is the
142
- // reachability that matters (#421).
143
- await onboardSlackApp({ stateRoot: input.stateRoot, state, requestUrl, redirectUrl }, {
144
- note: (message) => clackLog.info(message),
145
- openUrl: openExternalUrl,
146
- waitForOAuth: () => server.waitForOAuth(),
147
- writeRuntimeSecrets: async ({ botToken, signingSecret }) => {
148
- const values = {
149
- ...(botToken ? { SLACK_BOT_TOKEN: botToken } : {}),
150
- ...(signingSecret ? { SLACK_SIGNING_SECRET: signingSecret } : {}),
151
- };
152
- if (Object.keys(values).length > 0) {
153
- await appendChannelDotEnv(input.target, "slack", values, Object.keys(values));
154
- }
155
- },
156
- });
157
- // What happened, once. What to do next is `add`'s "next steps" block.
158
- console.error(`[fastagent] Slack app installed; credentials written to ${dotEnvPath(input.target)}`);
159
- }
160
- finally {
161
- tunnel.close();
162
- await server.close().catch(() => { });
163
- }
185
+ const { server, tunnelUrl } = await endpoint.get();
186
+ const requestUrl = `${tunnelUrl}${server.requestPath}`;
187
+ const redirectUrl = `${tunnelUrl}${server.redirectPath}`;
188
+ // No local readiness probe: Slack challenges requestUrl from ITS network during app creation, and that is the
189
+ // reachability that matters (#421).
190
+ await onboardSlackApp({ stateRoot: input.stateRoot, state, requestUrl, redirectUrl }, {
191
+ note: (message) => (asks ? clackLog.info(message) : console.error(`[fastagent] ${message}`)),
192
+ openUrl: (url) => {
193
+ if (person === undefined)
194
+ return openExternalUrl(url);
195
+ // A browser that pasted the pair goes straight on; the ticket names the page for one that did not.
196
+ server.next(url);
197
+ person.waitsOn(url, "click Allow to install the Slack app in their workspace");
198
+ },
199
+ waitForOAuth: async () => {
200
+ const callback = await server.waitForOAuth();
201
+ person?.carriesOn();
202
+ return callback;
203
+ },
204
+ writeRuntimeSecrets: async ({ botToken, signingSecret }) => {
205
+ const values = {
206
+ ...(botToken ? { SLACK_BOT_TOKEN: botToken } : {}),
207
+ ...(signingSecret ? { SLACK_SIGNING_SECRET: signingSecret } : {}),
208
+ };
209
+ if (Object.keys(values).length > 0) {
210
+ await appendChannelDotEnv(input.target, "slack", values, Object.keys(values));
211
+ }
212
+ },
213
+ });
214
+ // What happened, once. What to do next is `add`'s "next steps" block.
215
+ console.error(`[fastagent] Slack app installed; credentials written to ${dotEnvPath(input.target)}`);
164
216
  }
@@ -1,8 +1,9 @@
1
1
  /** CLI presenter for the auth-status line `reportAuth` prints (invoke/dev/start). */
2
+ import type { DeployHost } from "../deploy/hosts.ts";
2
3
  /**
3
4
  * Format the auth status for a provider, from `AgentModels.authStatus`'s answer. `deployed`: this process is a
4
- * deployed box, which logs in from the owner's workspace (`fastagent login --deployment`), never by a login run on it
5
- * by hand.
5
+ * deployed box, which logs in from the owner's agent directory (`fastagent login --deployment <host>`), never by a
6
+ * login run on it by hand; `host` is which one, when the box can tell (`deployedHost`).
6
7
  */
7
8
  export declare function formatAuthReport(status: {
8
9
  provider: string;
@@ -12,7 +13,13 @@ export declare function formatAuthReport(status: {
12
13
  error?: string;
13
14
  stored?: string;
14
15
  shadowed?: string;
15
- deployed?: boolean;
16
+ deployed?: {
17
+ host: DeployHost | undefined;
18
+ };
19
+ local?: {
20
+ authPath: string;
21
+ valueFile: string;
22
+ };
16
23
  }): {
17
24
  line: string;
18
25
  warn?: string;
@@ -1,13 +1,15 @@
1
- /** CLI presenter for the auth-status line `reportAuth` prints (invoke/dev/start). */
2
1
  /**
3
2
  * Format the auth status for a provider, from `AgentModels.authStatus`'s answer. `deployed`: this process is a
4
- * deployed box, which logs in from the owner's workspace (`fastagent login --deployment`), never by a login run on it
5
- * by hand.
3
+ * deployed box, which logs in from the owner's agent directory (`fastagent login --deployment <host>`), never by a
4
+ * login run on it by hand; `host` is which one, when the box can tell (`deployedHost`).
6
5
  */
7
6
  export function formatAuthReport(status) {
8
- const { provider, path, source, error, stored, shadowed, deployed = false } = status;
7
+ const { provider, path, source, error, stored, shadowed, deployed, local } = status;
9
8
  const because = error === undefined ? "" : ` (${error})`;
10
- const login = (name) => deployed ? `\`${name} --deployment\` from the workspace this was deployed from` : `\`${name}\``;
9
+ const authOverride = local ? `FASTAGENT_AUTH_PATH='${local.authPath.replaceAll("'", "'\\''")}' ` : "";
10
+ const login = (name) => deployed
11
+ ? `\`${name} --deployment ${deployed.host ?? "<host>"}\` from the agent directory this was deployed from`
12
+ : `\`${authOverride}${name}\``;
11
13
  if (source !== undefined) {
12
14
  const line = `auth: ${source} (${provider}) — ${path}`;
13
15
  if (shadowed === undefined)
@@ -27,6 +29,6 @@ export function formatAuthReport(status) {
27
29
  }
28
30
  return {
29
31
  line: `auth: (none found) — ${path}`,
30
- warn: `no credentials for "${provider}"${because} — run ${login("fastagent login")}, or set the provider's API key in ${deployed ? "the deployment's value file" : ".env"}; invokes will fail until then`,
32
+ warn: `no credentials for "${provider}"${because} — run ${login("fastagent login")}, or set the provider's API key in ${deployed ? "the deployment's value file" : (local?.valueFile ?? ".env")}; invokes will fail until then`,
31
33
  };
32
34
  }
@@ -1,32 +1,42 @@
1
1
  import { type BoxShell } from "../deploy/box-shell.ts";
2
2
  import type { DeployHost } from "../deploy/hosts.ts";
3
- import type { LoginIO } from "../engines/pi/login.ts";
4
- import type { ResolvedPlacement } from "../paths.ts";
3
+ import type { LoginIO, LoginMethod } from "../harnesses/models/login.ts";
4
+ import type { TicketStep } from "./ticket.ts";
5
5
  export interface BoxLoginRequest {
6
6
  host: DeployHost;
7
7
  shell: BoxShell;
8
- placement: ResolvedPlacement;
9
8
  /** Skip the provider menu. */
10
9
  provider?: string;
10
+ /** Skip the method menu. */
11
+ method?: LoginMethod;
11
12
  /** Keep a credential the box already holds for `provider` (a redeploy), instead of replacing it. */
12
13
  ifMissing?: boolean;
13
14
  /** false: never ask; a box without the credential is a failure naming the command to run in a terminal. */
14
15
  input: boolean;
16
+ /** Who answers what the box asks: this terminal by default, or a ticket's process ({@link ticketLoginIO}). */
17
+ io?: LoginIO;
15
18
  }
16
19
  /**
17
20
  * Run the login on the box and report its outcome. Resolves `undefined` once the box reports a credential for the
18
21
  * provider (logged in now, or kept), else with the one line saying why not and what to run.
19
22
  */
20
23
  export declare function loginOnBox(request: BoxLoginRequest): Promise<string | undefined>;
24
+ /**
25
+ * A box's sign-in answered by a ticket's process, with no one at a terminal: what the person does is the ticket's
26
+ * (`need_user_action`), and what the box asks is answered as {@link signInInteraction} answers a local sign-in. A choice
27
+ * takes its first option, pi's default; a text question is left blank; the address the browser ended on comes from
28
+ * `login --check --code` (or the redirect {@link catchingRedirect} catches first); a secret it cannot take, and
29
+ * `refusal` says so, since the box only hears that the question was backed out of.
30
+ */
31
+ export declare function ticketLoginIO(step: TicketStep, retry: string): LoginIO & {
32
+ refusal(): string | undefined;
33
+ };
21
34
  /**
22
35
  * A browser OAuth flow sends the owner's browser back to its `redirect_uri`: a localhost address, which on the owner's
23
36
  * machine has nothing of the box behind it. So catch it here. While an authorization URL naming such a redirect is
24
37
  * open, listen on that address (the port the provider fixed, loopback only, as pi's own flows do), and answer the
25
- * next text prompt with the URL the browser brought back, exactly what the person would paste. The terminal prompt
38
+ * prompt for that address with the URL the browser brought back, exactly what the person would paste. The prompt
26
39
  * stays up meanwhile: a taken port, or a browser on another machine, still leaves pasting.
27
- *
28
- * ponytail: "the next text prompt" is the one after the URL. pi's browser flows (Anthropic, Codex) ask exactly one,
29
- * the paste; a flow that asked something else in between would get the URL as that answer and reject it.
30
40
  */
31
41
  export declare function catchingRedirect(io: LoginIO): LoginIO & {
32
42
  close(): void;
@@ -5,7 +5,6 @@
5
5
  * copied from this machine.
6
6
  */
7
7
  import { createServer } from "node:http";
8
- import { basename } from "node:path";
9
8
  import { deploymentLoginCommand } from "../deploy/box-shell.js";
10
9
  import { boxLoginCommand } from "../deploy/container.js";
11
10
  import { relayLogin } from "./login-relay.js";
@@ -15,16 +14,17 @@ import { terminalLoginIO } from "./shared.js";
15
14
  * provider (logged in now, or kept), else with the one line saying why not and what to run.
16
15
  */
17
16
  export async function loginOnBox(request) {
18
- const { host, shell, placement, provider } = request;
17
+ const { host, shell, provider } = request;
19
18
  const retry = deploymentLoginCommand(host, provider);
20
19
  const args = [
21
20
  ...(provider ? [provider] : []),
21
+ ...(request.method ? ["--method", request.method === "oauth" ? "account" : "api-key"] : []),
22
22
  ...(request.ifMissing ? ["--if-missing"] : []),
23
23
  ...(request.input ? [] : ["--no-input"]),
24
24
  ];
25
25
  let command;
26
26
  try {
27
- command = boxLoginCommand(basename(placement.agentDir), args, shell.storage);
27
+ command = boxLoginCommand(args, shell.storage);
28
28
  }
29
29
  catch (error) {
30
30
  return error.message;
@@ -36,7 +36,7 @@ export async function loginOnBox(request) {
36
36
  const channel = await shell.open(command).catch((error) => error);
37
37
  if (channel instanceof Error)
38
38
  return channel.message;
39
- const io = catchingRedirect(terminalLoginIO());
39
+ const io = catchingRedirect(request.io ?? terminalLoginIO());
40
40
  const result = await relayLogin(channel.output, channel.input, io, (line) => console.error(line)).finally(io.close);
41
41
  const closed = await channel.closed;
42
42
  if (!closed.opened)
@@ -51,23 +51,55 @@ export async function loginOnBox(request) {
51
51
  : `[fastagent] logged in to ${result.provider} (${result.method}) on the deployment — saved to ${result.path} there`);
52
52
  return undefined;
53
53
  }
54
- if (result.reason === "missing")
55
- return `not logged in: ${result.message} — run \`${retry}\` in a terminal`;
54
+ if (result.reason === "missing") {
55
+ const forAgent = provider
56
+ ? `fastagent login ${provider} --method account --deployment ${host} --json`
57
+ : `${retry} --json`;
58
+ return (`not logged in: ${result.message} — run \`${retry}\` in a terminal, or \`${forAgent}\` from a coding agent, ` +
59
+ `which hands the sign-in to its user`);
60
+ }
56
61
  if (result.reason === "cancelled")
57
62
  return `login on the deployment cancelled — run \`${retry}\` to log it in`;
58
63
  return `login on the deployment failed: ${result.message}`;
59
64
  }
60
65
  const CAUGHT_PAGE = "<!doctype html><meta charset=utf-8><title>fastagent</title>" +
61
66
  "<p>fastagent received the sign-in and sent it to your deployment. Return to your terminal.</p>";
67
+ /**
68
+ * A box's sign-in answered by a ticket's process, with no one at a terminal: what the person does is the ticket's
69
+ * (`need_user_action`), and what the box asks is answered as {@link signInInteraction} answers a local sign-in. A choice
70
+ * takes its first option, pi's default; a text question is left blank; the address the browser ended on comes from
71
+ * `login --check --code` (or the redirect {@link catchingRedirect} catches first); a secret it cannot take, and
72
+ * `refusal` says so, since the box only hears that the question was backed out of.
73
+ */
74
+ export function ticketLoginIO(step, retry) {
75
+ let refusal;
76
+ return {
77
+ refusal: () => refusal,
78
+ select: async (_message, options) => options[0]?.value,
79
+ async prompt(message, opts) {
80
+ if (opts?.hidden) {
81
+ refusal = `the sign-in asks "${message}", which only a terminal can answer: run \`${retry}\` in one`;
82
+ return undefined;
83
+ }
84
+ if (!opts?.redirect)
85
+ return "";
86
+ const address = await step
87
+ .address(opts.signal ? AbortSignal.any([opts.signal, step.signal]) : step.signal)
88
+ .catch(() => undefined);
89
+ if (address !== undefined)
90
+ step.person.carriesOn();
91
+ return address;
92
+ },
93
+ note: (message) => console.error(`[fastagent] ${message}`),
94
+ openUrl: (url, userCode) => step.waits(userCode ? { url, code: userCode } : { url, takesAddress: true }),
95
+ };
96
+ }
62
97
  /**
63
98
  * A browser OAuth flow sends the owner's browser back to its `redirect_uri`: a localhost address, which on the owner's
64
99
  * machine has nothing of the box behind it. So catch it here. While an authorization URL naming such a redirect is
65
100
  * open, listen on that address (the port the provider fixed, loopback only, as pi's own flows do), and answer the
66
- * next text prompt with the URL the browser brought back, exactly what the person would paste. The terminal prompt
101
+ * prompt for that address with the URL the browser brought back, exactly what the person would paste. The prompt
67
102
  * stays up meanwhile: a taken port, or a browser on another machine, still leaves pasting.
68
- *
69
- * ponytail: "the next text prompt" is the one after the URL. pi's browser flows (Anthropic, Codex) ask exactly one,
70
- * the paste; a flow that asked something else in between would get the URL as that answer and reject it.
71
103
  */
72
104
  export function catchingRedirect(io) {
73
105
  let server;
@@ -125,11 +157,13 @@ export function catchingRedirect(io) {
125
157
  select: io.select,
126
158
  note: io.note,
127
159
  close,
128
- openUrl(url) {
160
+ openUrl(url, userCode) {
129
161
  listen(url);
130
- io.openUrl(url);
162
+ io.openUrl(url, userCode);
131
163
  },
132
164
  async prompt(message, opts) {
165
+ if (!opts?.redirect)
166
+ return io.prompt(message, opts);
133
167
  if (caught !== undefined) {
134
168
  const url = caught;
135
169
  caught = undefined;
@@ -1,11 +1,22 @@
1
1
  import { type ChannelKind } from "../../scaffold/add-channel.ts";
2
- /** `fastagent add <kind> [dir]`: scaffold `channels/<kind>.ts` — the adapter import plus a starter `on()`. */
3
- export declare function runAddChannel(channelKind: ChannelKind, dirArg: string, opts: {
2
+ export interface AddChannelOptions {
4
3
  ingress?: string;
5
- groupBehavior?: string;
6
4
  onboard?: boolean;
7
5
  replaceConfig?: boolean;
8
- }): Promise<void>;
6
+ environment?: string;
7
+ /** false ⇔ `--no-input`. */
8
+ input?: boolean;
9
+ /** `--json`: the outcome as one JSON object on stdout. */
10
+ json?: boolean;
11
+ /** `--check <ticket>`: where an app's setup started without a terminal stands. */
12
+ check?: string;
13
+ /** `--timeout <seconds>`: how long a setup started without a terminal stays open. */
14
+ timeout?: string;
15
+ /** `--ticket <id>`: the process that runs a ticket's setup. */
16
+ ticket?: string;
17
+ }
18
+ /** `fastagent add <kind> [dir]`: scaffold `src/channels/<kind>.ts`, the adapter configured with a starter policy. */
19
+ export declare function runAddChannel(channelKind: ChannelKind, dirArg: string, opts: AddChannelOptions): Promise<void>;
9
20
  /** `fastagent add skill <source> [dir]`: vendor an Agent Skills skill into <dir>/skills/<name>/. */
10
21
  export declare function runAddSkill(source: string | undefined, dirArg: string, opts: {
11
22
  update?: boolean;