@fastagent-sh/fastagent 0.24.4 → 0.26.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 (487) hide show
  1. package/README.md +54 -82
  2. package/dist/agent-api.d.ts +460 -0
  3. package/dist/agent-api.js +209 -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 +81 -0
  9. package/dist/authoring.js +245 -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 +116 -64
  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 +18 -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 +253 -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 +191 -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 +132 -16
  164. package/dist/cli/commands/login.d.ts +31 -2
  165. package/dist/cli/commands/login.js +416 -65
  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 +6 -4
  184. package/dist/cli/login-relay.js +19 -7
  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 +70 -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 +220 -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 +223 -202
  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 +52 -27
  260. package/dist/effect-port.d.ts +4 -4
  261. package/dist/effect-port.js +4 -4
  262. package/dist/env.d.ts +0 -13
  263. package/dist/env.js +1 -44
  264. package/dist/environment/apt.d.ts +4 -0
  265. package/dist/environment/apt.js +32 -0
  266. package/dist/environment/declare.d.ts +59 -0
  267. package/dist/environment/declare.js +210 -0
  268. package/dist/environment/mise.d.ts +51 -0
  269. package/dist/environment/mise.js +272 -0
  270. package/dist/feishu.d.ts +2 -2
  271. package/dist/feishu.js +2 -2
  272. package/dist/git.d.ts +13 -0
  273. package/dist/git.js +55 -0
  274. package/dist/harnesses/models/catalog.d.ts +20 -0
  275. package/dist/harnesses/models/catalog.js +254 -0
  276. package/dist/{engines/pi/auth.d.ts → harnesses/models/credentials.d.ts} +3 -3
  277. package/dist/{engines/pi/auth.js → harnesses/models/credentials.js} +3 -3
  278. package/dist/harnesses/models/environment.d.ts +48 -0
  279. package/dist/harnesses/models/environment.js +88 -0
  280. package/dist/harnesses/models/host.d.ts +30 -0
  281. package/dist/harnesses/models/host.js +97 -0
  282. package/dist/{engines/pi → harnesses/models}/login.d.ts +66 -70
  283. package/dist/harnesses/models/login.js +439 -0
  284. package/dist/harnesses/models/models.d.ts +84 -0
  285. package/dist/harnesses/models/models.js +197 -0
  286. package/dist/harnesses/pi-durable/agent.d.ts +42 -0
  287. package/dist/harnesses/pi-durable/agent.js +581 -0
  288. package/dist/harnesses/pi-durable/defaults.d.ts +28 -0
  289. package/dist/harnesses/pi-durable/defaults.js +26 -0
  290. package/dist/harnesses/pi-durable/define.d.ts +77 -0
  291. package/dist/harnesses/pi-durable/define.js +28 -0
  292. package/dist/harnesses/pi-durable/entries.d.ts +32 -0
  293. package/dist/harnesses/pi-durable/entries.js +126 -0
  294. package/dist/harnesses/pi-durable/events.d.ts +25 -0
  295. package/dist/harnesses/pi-durable/events.js +238 -0
  296. package/dist/harnesses/pi-durable/ids.d.ts +16 -0
  297. package/dist/harnesses/pi-durable/ids.js +55 -0
  298. package/dist/harnesses/pi-durable/messages.d.ts +41 -0
  299. package/dist/harnesses/pi-durable/messages.js +116 -0
  300. package/dist/harnesses/pi-durable/open.d.ts +95 -0
  301. package/dist/harnesses/pi-durable/open.js +330 -0
  302. package/dist/harnesses/pi-durable/reads.d.ts +30 -0
  303. package/dist/harnesses/pi-durable/reads.js +94 -0
  304. package/dist/harnesses/pi-durable/registry.d.ts +18 -0
  305. package/dist/harnesses/pi-durable/registry.js +56 -0
  306. package/dist/harnesses/pi-durable/release.d.ts +13 -0
  307. package/dist/harnesses/pi-durable/release.js +40 -0
  308. package/dist/harnesses/pi-durable/serve.d.ts +90 -0
  309. package/dist/harnesses/pi-durable/serve.js +186 -0
  310. package/dist/harnesses/pi-durable/sessions.d.ts +27 -0
  311. package/dist/harnesses/pi-durable/sessions.js +47 -0
  312. package/dist/harnesses/pi-durable/storage.d.ts +4 -0
  313. package/dist/harnesses/pi-durable/storage.js +49 -0
  314. package/dist/harnesses/pi-durable/stream.d.ts +20 -0
  315. package/dist/harnesses/pi-durable/stream.js +221 -0
  316. package/dist/harnesses/pi-durable/text.d.ts +30 -0
  317. package/dist/harnesses/pi-durable/text.js +292 -0
  318. package/dist/harnesses/pi-durable/wake.d.ts +11 -0
  319. package/dist/harnesses/pi-durable/wake.js +90 -0
  320. package/dist/http/client.d.ts +6 -0
  321. package/dist/http/client.js +256 -0
  322. package/dist/http/contract.d.ts +541 -0
  323. package/dist/http/contract.js +179 -0
  324. package/dist/http/server.d.ts +34 -0
  325. package/dist/http/server.js +194 -0
  326. package/dist/index.d.ts +19 -4
  327. package/dist/index.js +13 -5
  328. package/dist/lark.d.ts +2 -2
  329. package/dist/lark.js +2 -2
  330. package/dist/locked-file.d.ts +17 -0
  331. package/dist/{engines/pi/locked-file.js → locked-file.js} +16 -10
  332. package/dist/once.d.ts +6 -0
  333. package/dist/once.js +23 -0
  334. package/dist/paths.d.ts +36 -52
  335. package/dist/paths.js +66 -182
  336. package/dist/runtime.d.ts +25 -2
  337. package/dist/runtime.js +27 -0
  338. package/dist/scaffold/add-channel.d.ts +14 -27
  339. package/dist/scaffold/add-channel.js +82 -180
  340. package/dist/scaffold/init.d.ts +17 -18
  341. package/dist/scaffold/init.js +87 -99
  342. package/dist/scaffold/templates/SYSTEM.md +12 -0
  343. package/dist/scaffold/templates/env.example +4 -10
  344. package/dist/scaffold/templates/fastagent.config.ts +21 -33
  345. package/dist/scaffold/templates/gitignore +8 -1
  346. package/dist/scaffold/templates/skills/writing-great-skills/SKILL.md +1 -2
  347. package/dist/scaffold/templates.d.ts +9 -4
  348. package/dist/scaffold/templates.js +7 -5
  349. package/dist/scaffold/vendor-skill.d.ts +1 -4
  350. package/dist/scaffold/vendor-skill.js +5 -6
  351. package/dist/schedule/cron.d.ts +13 -0
  352. package/dist/schedule/cron.js +52 -0
  353. package/dist/schedule/eventbridge-cron.d.ts +17 -0
  354. package/dist/schedule/eventbridge-cron.js +88 -0
  355. package/dist/schedule/schedule.d.ts +23 -0
  356. package/dist/schedule/schedule.js +34 -0
  357. package/dist/schedule/scheduler.d.ts +34 -33
  358. package/dist/schedule/scheduler.js +251 -137
  359. package/dist/schedule/state.d.ts +4 -14
  360. package/dist/schedule/state.js +7 -7
  361. package/dist/schedule/wake-alarm.d.ts +22 -2
  362. package/dist/schedule/wake-alarm.js +66 -20
  363. package/dist/schedule/wakeups.d.ts +16 -15
  364. package/dist/schedule/wakeups.js +47 -45
  365. package/dist/service.d.ts +56 -169
  366. package/dist/service.js +91 -187
  367. package/dist/serving-command.d.ts +10 -0
  368. package/dist/serving-command.js +16 -0
  369. package/dist/sign-in-api.d.ts +147 -0
  370. package/dist/sign-in-api.js +9 -0
  371. package/dist/slack.d.ts +1 -1
  372. package/dist/slack.js +1 -1
  373. package/dist/{channels/kit/state.js → state-file.js} +6 -6
  374. package/dist/telegram.d.ts +1 -0
  375. package/dist/telegram.js +1 -0
  376. package/dist/tunnel.d.ts +3 -0
  377. package/dist/tunnel.js +14 -5
  378. package/dist/value-file.d.ts +40 -0
  379. package/dist/value-file.js +164 -0
  380. package/dist/version.d.ts +5 -0
  381. package/dist/version.js +14 -1
  382. package/package.json +18 -28
  383. package/dist/agent.d.ts +0 -106
  384. package/dist/agent.js +0 -21
  385. package/dist/channels/control.d.ts +0 -31
  386. package/dist/channels/control.js +0 -329
  387. package/dist/channels/define-channel.d.ts +0 -39
  388. package/dist/channels/define-channel.js +0 -9
  389. package/dist/channels/feishu/context-buffer.d.ts +0 -35
  390. package/dist/channels/feishu/context-buffer.js +0 -65
  391. package/dist/channels/feishu/scaffold/channel.websocket.ts +0 -31
  392. package/dist/channels/http.d.ts +0 -23
  393. package/dist/channels/http.js +0 -57
  394. package/dist/channels/lark/scaffold/channel.websocket.ts +0 -31
  395. package/dist/channels/slack/context-buffer.d.ts +0 -23
  396. package/dist/channels/slack/context-buffer.js +0 -37
  397. package/dist/channels/sse.d.ts +0 -4
  398. package/dist/channels/sse.js +0 -66
  399. package/dist/cli/commands/chat.d.ts +0 -3
  400. package/dist/cli/commands/chat.js +0 -14
  401. package/dist/cli/commands/routine-run.d.ts +0 -6
  402. package/dist/cli/commands/routine-run.js +0 -46
  403. package/dist/cli/commands/routine.d.ts +0 -25
  404. package/dist/cli/commands/routine.js +0 -122
  405. package/dist/cli/commands/tool.d.ts +0 -1
  406. package/dist/cli/commands/tool.js +0 -57
  407. package/dist/collect.d.ts +0 -63
  408. package/dist/collect.js +0 -90
  409. package/dist/core.d.ts +0 -13
  410. package/dist/core.js +0 -15
  411. package/dist/engines/pi/agent-models.d.ts +0 -83
  412. package/dist/engines/pi/agent-models.js +0 -120
  413. package/dist/engines/pi/agent-session-factory.d.ts +0 -121
  414. package/dist/engines/pi/agent-session-factory.js +0 -535
  415. package/dist/engines/pi/chat.d.ts +0 -3
  416. package/dist/engines/pi/chat.js +0 -8
  417. package/dist/engines/pi/config.d.ts +0 -71
  418. package/dist/engines/pi/config.js +0 -199
  419. package/dist/engines/pi/create.d.ts +0 -170
  420. package/dist/engines/pi/create.js +0 -343
  421. package/dist/engines/pi/definition.d.ts +0 -74
  422. package/dist/engines/pi/definition.js +0 -236
  423. package/dist/engines/pi/entry-images.d.ts +0 -14
  424. package/dist/engines/pi/entry-images.js +0 -23
  425. package/dist/engines/pi/invoke-session.d.ts +0 -18
  426. package/dist/engines/pi/invoke-session.js +0 -403
  427. package/dist/engines/pi/locked-file.d.ts +0 -9
  428. package/dist/engines/pi/login.js +0 -331
  429. package/dist/engines/pi/machine.d.ts +0 -53
  430. package/dist/engines/pi/machine.js +0 -137
  431. package/dist/engines/pi/models.d.ts +0 -200
  432. package/dist/engines/pi/models.js +0 -533
  433. package/dist/engines/pi/open.d.ts +0 -180
  434. package/dist/engines/pi/open.js +0 -270
  435. package/dist/engines/pi/openai-account-models.d.ts +0 -35
  436. package/dist/engines/pi/openai-account-models.js +0 -116
  437. package/dist/engines/pi/report.d.ts +0 -18
  438. package/dist/engines/pi/report.js +0 -59
  439. package/dist/engines/pi/retry-event.d.ts +0 -6
  440. package/dist/engines/pi/retry-event.js +0 -15
  441. package/dist/engines/pi/service.d.ts +0 -9
  442. package/dist/engines/pi/service.js +0 -14
  443. package/dist/engines/pi/session-builder.d.ts +0 -13
  444. package/dist/engines/pi/session-builder.js +0 -117
  445. package/dist/engines/pi/session-control.d.ts +0 -77
  446. package/dist/engines/pi/session-control.js +0 -908
  447. package/dist/engines/pi/session-effects.d.ts +0 -14
  448. package/dist/engines/pi/session-effects.js +0 -30
  449. package/dist/engines/pi/session-inheritance.d.ts +0 -21
  450. package/dist/engines/pi/session-inheritance.js +0 -204
  451. package/dist/engines/pi/session-markers.d.ts +0 -49
  452. package/dist/engines/pi/session-markers.js +0 -60
  453. package/dist/engines/pi/session-settings.d.ts +0 -67
  454. package/dist/engines/pi/session-settings.js +0 -119
  455. package/dist/engines/pi/session-store.d.ts +0 -69
  456. package/dist/engines/pi/session-store.js +0 -430
  457. package/dist/engines/pi/tool-context.d.ts +0 -45
  458. package/dist/engines/pi/tool-context.js +0 -31
  459. package/dist/engines/pi/tool.d.ts +0 -99
  460. package/dist/engines/pi/tool.js +0 -118
  461. package/dist/engines/pi/turn-kit.d.ts +0 -92
  462. package/dist/engines/pi/turn-kit.js +0 -288
  463. package/dist/engines/pi/wake-tool.d.ts +0 -9
  464. package/dist/engines/pi/wake-tool.js +0 -92
  465. package/dist/loader.d.ts +0 -41
  466. package/dist/loader.js +0 -116
  467. package/dist/node.d.ts +0 -3
  468. package/dist/node.js +0 -4
  469. package/dist/observe.d.ts +0 -6
  470. package/dist/observe.js +0 -47
  471. package/dist/pi.d.ts +0 -25
  472. package/dist/pi.js +0 -15
  473. package/dist/scaffold/templates/APPEND_SYSTEM.md +0 -12
  474. package/dist/scaffold/templates/tools/fetch-url.ts +0 -25
  475. package/dist/schedule/discover.d.ts +0 -17
  476. package/dist/schedule/discover.js +0 -61
  477. package/dist/schedule/routine.d.ts +0 -43
  478. package/dist/schedule/routine.js +0 -32
  479. package/dist/schedule/run.d.ts +0 -55
  480. package/dist/schedule/run.js +0 -146
  481. package/dist/secrets-gate.d.ts +0 -32
  482. package/dist/secrets-gate.js +0 -33
  483. package/dist/session-remote.d.ts +0 -47
  484. package/dist/session-remote.js +0 -460
  485. package/dist/session.d.ts +0 -466
  486. package/dist/session.js +0 -57
  487. /package/dist/{channels/kit/state.d.ts → state-file.d.ts} +0 -0
package/dist/paths.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- /** The directory name `init` gives an agent (`<workspace>/fastagent/`) unless `--agent-dir` names another. */
2
- export declare const DEFAULT_AGENT_DIRNAME = "fastagent";
3
- /** The user-global machinery home, `~/.fastagent`: the machine's credentials, models.json and model catalog. */
1
+ import type { DeployHost } from "./deploy/hosts.ts";
2
+ /** The user-global machinery home, `~/.fastagent`: the machine's model credentials. */
4
3
  export declare function globalHome(): string;
5
4
  /**
6
5
  * The secrets segment inside an agent dir (or the global home). Every path fastagent resolves — `.env`,
@@ -9,55 +8,37 @@ export declare function globalHome(): string;
9
8
  * ignore templates spell it out as literal text, so renaming this constant means editing them too.
10
9
  */
11
10
  export declare const SECRETS_DIRNAME = ".secrets";
11
+ export declare const AGENT_ENVIRONMENT_ENV = "FASTAGENT_ENVIRONMENT";
12
+ type AgentEnvironment = "dev" | "production";
13
+ export declare function selectAgentEnvironment(environment: AgentEnvironment, env?: NodeJS.ProcessEnv): void;
12
14
  /** The state segment inside an agent dir — same rule and same template caveat as {@link SECRETS_DIRNAME}. */
13
15
  export declare const STATE_DIRNAME = ".state";
16
+ /**
17
+ * Where fastagent clones the repositories `context.json` declares, `content/<name>` in the agent dir. Never an env
18
+ * override: a machine that has a checkout of its own binds it in {@link LOCAL_CONTEXT_FILE} instead.
19
+ */
20
+ export declare const CONTENT_DIRNAME = "content";
21
+ /** The agent's context declaration (`context.json`), beside its config: shared, so only what every instance reaches. */
22
+ export declare const CONTEXT_FILE = "context.json";
23
+ /** The directories of THIS machine the agent is bound to: never committed, never deployed. */
24
+ export declare const LOCAL_CONTEXT_FILE = "context.local.json";
14
25
  /**
15
26
  * THE config filename. One spelling, not a family: fastagent generates this file, so a choice of extension buys
16
27
  * an author nothing and costs a precedence order plus a "you have two of them" failure path. Everything else an
17
- * author writes (`tools/`, `channels/`, `routines/`) still accepts `.ts`/`.js`/`.mjs` — that is THEIR code.
28
+ * author writes (`tools/`, `channels/`) still accepts `.ts`/`.js`/`.mjs` — that is THEIR code.
18
29
  */
19
30
  export declare const AGENT_CONFIG_FILE = "fastagent.config.ts";
20
- /** The optional custom-model-endpoint file inside an agent dir (pi's models.json schema). */
21
- export declare const AGENT_MODELS_FILE = "models.json";
22
- /** The agent's model catalog: pi.dev's models newer than pi's bundled catalog, fetched by `models --refresh`. */
23
- export declare const AGENT_MODEL_CATALOG_FILE = "models-store.json";
24
- export interface ResolvedPlacement {
25
- /**
26
- * The AGENT directory — where the definition (SYSTEM.md/skills/tools/channels/routines), the config, and the
27
- * machinery dirs (`.secrets/`, `.state/`) live.
28
- */
29
- agentDir: string;
30
- /**
31
- * The WORKSPACE — what the agent works ON: its cwd, and the start of the ② context walk. Always the agent
32
- * directory's parent, whichever of the two the command was pointed at.
33
- */
34
- workspace: string;
35
- }
31
+ /** The agent `dir` sits INSIDE (the nearest proper ancestor that IS an agent dir), or undefined. */
32
+ export declare function enclosingAgentDir(dir: string): string | undefined;
36
33
  /**
37
- * The agents `dir` resolves over: ITSELF when it holds a config, else the ones directly inside it — never both,
38
- * because aiming at an agent can only mean that agent.
34
+ * The agent directory `dir` names, for a command that also works without one (`login`, `models`): `dir` itself when it
35
+ * holds the config, undefined when it is no agent and inside none. Inside an agent is refused, naming its root —
36
+ * answering for the enclosing agent would act on a directory the caller did not name, and answering "no agent" would
37
+ * send a login to the machine's store.
39
38
  */
40
- export declare function agentsAt(dir: string): string[];
41
- /** The agent dir for `dir`, or undefined when there is none — {@link findPlacement} without the pair or the throw. */
42
39
  export declare function findAgentDir(dir: string): string | undefined;
43
- /**
44
- * The agent whose DEFINITION contains `dir` — scaffolding there would make the new agent part of the outer one's
45
- * loaded surface rather than an agent of its own.
46
- */
47
- export declare function agentDefinitionOwner(dir: string): string | undefined;
48
- /** Why `dir` is not an agent, when it has its OWN way out — or undefined when it is simply not near one. */
49
- export declare function placementDeadEnd(dir: string, env?: NodeJS.ProcessEnv): string | undefined;
50
- /**
51
- * Resolve a directory into its placement — the ONE owner of the rule ({@link findPlacement}).
52
- *
53
- * WHERE AN UNREADABLE CANDIDATE IS SPENT, and only here: this caller MUST produce an agent, so a directory it
54
- * could not look into is the difference between "there is none" and "there might be". `placementDeadEnd` is
55
- * asked a weaker question — is this place a dead end with its own way out — by callers like `login`, for which
56
- * a neighbour it may not enter is environment noise, not a reason to exit instead of logging in globally. It
57
- * also comes AFTER that call: with two agents to choose between, a permission problem in a third directory is
58
- * not the message that gets the caller moving.
59
- */
60
- export declare function resolvePlacement(dir: string, env?: NodeJS.ProcessEnv): ResolvedPlacement;
40
+ /** The agent directory `dir` names ({@link findAgentDir}), refusing when there is none. */
41
+ export declare function resolveAgentDir(dir: string): string;
61
42
  /** How to WRITE a path for someone standing in `cwd`. */
62
43
  export declare function displayPath(cwd: string, dir: string): string | undefined;
63
44
  export declare function exists(p: string): Promise<boolean>;
@@ -70,20 +51,14 @@ export declare function readTextIfExists(p: string): Promise<string | undefined>
70
51
  export declare function resolveOverridePath(raw: string | undefined): string | undefined;
71
52
  /**
72
53
  * The resolved state root — the durable machine-state home (sessions/, channels/<kind>/, schedule/):
73
- * `FASTAGENT_STATE_DIR` env > `<agentDir>/.state`.
54
+ * Explicit paths win; production otherwise uses `.state/production`, dev uses `.state`.
74
55
  */
75
56
  export declare function resolveStateRoot(dir: string, env?: NodeJS.ProcessEnv): string;
76
- /**
77
- * WHERE an agent's session records live: `<state root>/sessions`, always. Records are machine state like channel
78
- * state and schedule claims, so they move with the ONE knob that moves all of it rather than with a second one that
79
- * moves only them — a split every reader would then have to agree about, and which left channel state behind anyway.
80
- * An embedder that really wants the records elsewhere passes `sessionsDir` to `createAgentService`; there is no env
81
- * or flag spelling of it, for the reason `resolveAuthPathOverride` states.
82
- */
83
- export declare function resolveSessionsDir(dir: string, env?: NodeJS.ProcessEnv): string;
57
+ /** Where fastagent clones the content entry `name` of the agent in `dir`. */
58
+ export declare function contentEntryPath(dir: string, name: string): string;
84
59
  /**
85
60
  * The resolved secrets dir — everything fastagent manages that must NEVER leave the machine (the agent's `.env` +
86
- * auth.json).
61
+ * auth.json). Explicit paths win; production otherwise uses `.secrets/production`, dev uses `.secrets`.
87
62
  */
88
63
  export declare function resolveSecretsDir(dir: string, env?: NodeJS.ProcessEnv): string;
89
64
  /** Is this process the deployed container the generated artifacts describe? ONE reading of the
@@ -91,6 +66,14 @@ export declare function resolveSecretsDir(dir: string, env?: NodeJS.ProcessEnv):
91
66
  export declare function isDeployedWorkspace(): boolean;
92
67
  /** Is this process running inside the AgentCore Runtime? Set by the generated deploy artifacts. */
93
68
  export declare function isAgentcoreRuntime(): boolean;
69
+ /**
70
+ * Which host this deployed box runs on, for the command that logs it in (`login --deployment <host>`). Read from what
71
+ * each platform puts in a box's environment (`FLY_APP_NAME`, `RAILWAY_SERVICE_ID`) or what our AgentCore template
72
+ * sets, because the artifacts in the agent directory cannot say it: a Railway deploy leaves no file of its own, and a
73
+ * directory can hold several hosts' files. Undefined where nothing says (Docker sets nothing, nor would a host
74
+ * fastagent did not deploy to): the caller then asks for the host by name.
75
+ */
76
+ export declare function deployedHost(env?: NodeJS.ProcessEnv): DeployHost | undefined;
94
77
  /**
95
78
  * The mode of a file fastagent CREATES to hold a secret: `auth.json`, a `.env` it makes itself,
96
79
  * a host's parameter file. That is the whole extent of its opinion about permissions — a file it did not create
@@ -110,3 +93,4 @@ export declare const SECRET_FILE_MODE = 384;
110
93
  export declare function assertInsideAgentDir(agentDir: string, name: string): Promise<void>;
111
94
  /** Whether `targetPath` lives inside `baseDir` (same path counts). */
112
95
  export declare function isUnderDir(targetPath: string, baseDir: string): boolean;
96
+ export {};
package/dist/paths.js CHANGED
@@ -1,14 +1,13 @@
1
1
  /**
2
- * PLACEMENT: which directory holds the agent, and which directory the agent works ON — plus the machinery paths that
3
- * follow from it.
2
+ * ADDRESSING: which directory is the agent — the one holding `fastagent.config.ts`, named by the caller — plus the
3
+ * machinery paths that follow from it. Nothing about what the agent works on is derived from where it sits; that is
4
+ * its declared content (src/content/).
4
5
  */
5
- import { readdirSync, statSync } from "node:fs";
6
+ import { statSync } from "node:fs";
6
7
  import { access, readFile, realpath } from "node:fs/promises";
7
8
  import { homedir } from "node:os";
8
- import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
9
- /** The directory name `init` gives an agent (`<workspace>/fastagent/`) unless `--agent-dir` names another. */
10
- export const DEFAULT_AGENT_DIRNAME = "fastagent";
11
- /** The user-global machinery home, `~/.fastagent`: the machine's credentials, models.json and model catalog. */
9
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
10
+ /** The user-global machinery home, `~/.fastagent`: the machine's model credentials. */
12
11
  export function globalHome() {
13
12
  return join(homedir(), ".fastagent");
14
13
  }
@@ -19,39 +18,35 @@ export function globalHome() {
19
18
  * ignore templates spell it out as literal text, so renaming this constant means editing them too.
20
19
  */
21
20
  export const SECRETS_DIRNAME = ".secrets";
21
+ export const AGENT_ENVIRONMENT_ENV = "FASTAGENT_ENVIRONMENT";
22
+ export function selectAgentEnvironment(environment, env = process.env) {
23
+ env[AGENT_ENVIRONMENT_ENV] = environment;
24
+ }
25
+ function environmentPath(dir, segment, env) {
26
+ const root = join(resolve(dir), segment);
27
+ return env[AGENT_ENVIRONMENT_ENV] === "production" ? join(root, "production") : root;
28
+ }
22
29
  /** The state segment inside an agent dir — same rule and same template caveat as {@link SECRETS_DIRNAME}. */
23
30
  export const STATE_DIRNAME = ".state";
31
+ /**
32
+ * Where fastagent clones the repositories `context.json` declares, `content/<name>` in the agent dir. Never an env
33
+ * override: a machine that has a checkout of its own binds it in {@link LOCAL_CONTEXT_FILE} instead.
34
+ */
35
+ export const CONTENT_DIRNAME = "content";
36
+ /** The agent's context declaration (`context.json`), beside its config: shared, so only what every instance reaches. */
37
+ export const CONTEXT_FILE = "context.json";
38
+ /** The directories of THIS machine the agent is bound to: never committed, never deployed. */
39
+ export const LOCAL_CONTEXT_FILE = "context.local.json";
24
40
  /**
25
41
  * THE config filename. One spelling, not a family: fastagent generates this file, so a choice of extension buys
26
42
  * an author nothing and costs a precedence order plus a "you have two of them" failure path. Everything else an
27
- * author writes (`tools/`, `channels/`, `routines/`) still accepts `.ts`/`.js`/`.mjs` — that is THEIR code.
43
+ * author writes (`tools/`, `channels/`) still accepts `.ts`/`.js`/`.mjs` — that is THEIR code.
28
44
  */
29
45
  export const AGENT_CONFIG_FILE = "fastagent.config.ts";
30
- /** The optional custom-model-endpoint file inside an agent dir (pi's models.json schema). */
31
- export const AGENT_MODELS_FILE = "models.json";
32
- /** The agent's model catalog: pi.dev's models newer than pi's bundled catalog, fetched by `models --refresh`. */
33
- export const AGENT_MODEL_CATALOG_FILE = "models-store.json";
34
- /**
35
- * The definition paths an agent LOADS content from — the surface a second agent must not be scaffolded inside
36
- * ({@link agentDefinitionOwner}), because the outer agent would read it as its own skills/tools.
37
- */
38
- const LOADED_SURFACE = [
39
- "SYSTEM.md",
40
- "APPEND_SYSTEM.md",
41
- "skills",
42
- "prompts",
43
- "tools",
44
- "channels",
45
- "routines",
46
- // pi's and the standard spellings the definition also reads: `.pi/skills`, `.pi/prompts`, `.agents/skills`.
47
- ".pi",
48
- ".agents",
49
- ];
50
46
  /**
51
47
  * "Not there" and "could not look" are different answers, and only the first may read as an absence: an agent
52
- * directory the caller cannot enter (EACCES) reported as no-agent-here ends in `run \`fastagent init\` to
53
- * scaffold one` — over a definition that exists. So ENOENT/ENOTDIR are absence, and every other errno travels
54
- * with its path, as {@link agentChildren} already did for the scan itself.
48
+ * directory the caller cannot enter (EACCES) reported as no-agent-here ends in `run \`fastagent init\`` — over a
49
+ * definition that exists. So ENOENT/ENOTDIR are absence, and every other errno travels with its path.
55
50
  */
56
51
  function statOrAbsent(p) {
57
52
  try {
@@ -64,84 +59,12 @@ function statOrAbsent(p) {
64
59
  throw e;
65
60
  }
66
61
  }
67
- function isDir(p) {
68
- return statOrAbsent(p)?.isDirectory() === true;
69
- }
70
62
  /** THE marker: a directory that declares itself an agent with a {@link AGENT_CONFIG_FILE}. */
71
63
  function hasConfig(p) {
72
- return isDir(p) && statOrAbsent(join(p, AGENT_CONFIG_FILE)) !== undefined;
73
- }
74
- /**
75
- * DIRECTLY inside `dir`: the agent directories, and the ones the answer is missing for.
76
- *
77
- * A NAMED directory and a SCANNED one are different questions. `hasConfig` throws for the first, because the
78
- * caller pointed at it. Here it cannot: every machine has directories this process may not enter, and one of
79
- * them sitting next to the agent must not fail a command that found the agent — `workspaceHint` scans the
80
- * PARENT for a hint, which on a CI runner means scanning `/tmp` and its `snap-private-tmp`. So an unreadable
81
- * candidate is carried, not thrown, and {@link resolvePlacement} spends it where it is the answer: a caller
82
- * that must produce an agent and found none says "I could not look at these", never `fastagent init`.
83
- */
84
- function agentChildren(dir) {
85
- let entries;
86
- try {
87
- entries = readdirSync(dir, { withFileTypes: true });
88
- }
89
- catch (e) {
90
- const code = e.code;
91
- if (code === "ENOENT" || code === "ENOTDIR")
92
- return { agents: [], unreadable: [] };
93
- throw e;
94
- }
95
- const agents = [];
96
- const unreadable = [];
97
- for (const entry of entries.filter((e) => !e.isFile())) {
98
- const child = join(dir, entry.name);
99
- try {
100
- if (hasConfig(child))
101
- agents.push(child);
102
- }
103
- catch (e) {
104
- // PERMISSION ONLY. "Someone else's 0700 directory sits next to mine" is the normal case this carrying
105
- // exists for, and it is the one an operator can act on. EIO, ELOOP, a non-errno throw: those are real
106
- // failures with different fixes, and a scan has no business turning them into a line of prose.
107
- const code = e.code;
108
- if (code !== "EACCES" && code !== "EPERM")
109
- throw e;
110
- unreadable.push(entry.name);
111
- }
112
- }
113
- return { agents: agents.sort(), unreadable: unreadable.sort() };
114
- }
115
- /**
116
- * The agents `dir` resolves over: ITSELF when it holds a config, else the ones directly inside it — never both,
117
- * because aiming at an agent can only mean that agent.
118
- */
119
- export function agentsAt(dir) {
120
- return scanAgents(resolve(dir)).agents;
121
- }
122
- /** {@link agentsAt} plus what the scan could not look at — one readdir answering both questions. */
123
- function scanAgents(base) {
124
- return hasConfig(base) ? { agents: [base], unreadable: [] } : agentChildren(base);
125
- }
126
- /** WHICH agent is meant, when a directory holds several. */
127
- function selectAgent(agents, env) {
128
- const wanted = env.FASTAGENT_AGENT;
129
- if (wanted)
130
- return agents.find((a) => basename(a) === wanted);
131
- const [only, ...rest] = agents;
132
- return rest.length === 0 ? only : agents.find((a) => basename(a) === DEFAULT_AGENT_DIRNAME);
133
- }
134
- /** Resolve `dir` into its placement, or undefined when nothing selects one agent. */
135
- function findPlacement(dir, env = process.env) {
136
- const agentDir = selectAgent(agentsAt(resolve(dir)), env);
137
- return agentDir === undefined ? undefined : { agentDir, workspace: dirname(agentDir) };
138
- }
139
- /** The agent dir for `dir`, or undefined when there is none — {@link findPlacement} without the pair or the throw. */
140
- export function findAgentDir(dir) {
141
- return findPlacement(dir)?.agentDir;
64
+ return statOrAbsent(p)?.isDirectory() === true && statOrAbsent(join(p, AGENT_CONFIG_FILE)) !== undefined;
142
65
  }
143
66
  /** The agent `dir` sits INSIDE (the nearest proper ancestor that IS an agent dir), or undefined. */
144
- function enclosingAgentDir(dir) {
67
+ export function enclosingAgentDir(dir) {
145
68
  let candidate = dirname(resolve(dir));
146
69
  for (let prev = ""; candidate !== prev; prev = candidate, candidate = dirname(candidate)) {
147
70
  if (hasConfig(candidate))
@@ -150,78 +73,29 @@ function enclosingAgentDir(dir) {
150
73
  return undefined;
151
74
  }
152
75
  /**
153
- * The agent whose DEFINITION contains `dir` — scaffolding there would make the new agent part of the outer one's
154
- * loaded surface rather than an agent of its own.
76
+ * The agent directory `dir` names, for a command that also works without one (`login`, `models`): `dir` itself when it
77
+ * holds the config, undefined when it is no agent and inside none. Inside an agent is refused, naming its root —
78
+ * answering for the enclosing agent would act on a directory the caller did not name, and answering "no agent" would
79
+ * send a login to the machine's store.
155
80
  */
156
- export function agentDefinitionOwner(dir) {
157
- const base = resolve(dir);
158
- const agent = enclosingAgentDir(base);
159
- if (!agent)
160
- return undefined;
161
- const [head] = relative(agent, base).split(sep);
162
- return head && LOADED_SURFACE.includes(head) ? agent : undefined;
163
- }
164
- /** Why `dir` is not an agent, when it has its OWN way out — or undefined when it is simply not near one. */
165
- export function placementDeadEnd(dir, env = process.env) {
81
+ export function findAgentDir(dir) {
166
82
  const base = resolve(dir);
83
+ if (hasConfig(base))
84
+ return base;
167
85
  const enclosing = enclosingAgentDir(base);
168
86
  if (enclosing) {
169
- return `${base} is inside the agent ${enclosing} but is not its root — \`cd\` there (or to its workspace) and re-run`;
170
- }
171
- const agents = agentsAt(base).map((a) => basename(a));
172
- const listed = `${base} holds ${agents.length} agent${agents.length === 1 ? "" : "s"} (${agents.join(", ")})`;
173
- // Asserting a name that is not here is a different mistake from asserting none, and it is worth its own message at
174
- // ANY count.
175
- if (env.FASTAGENT_AGENT && agents.length > 0) {
176
- return (`${listed}, and FASTAGENT_AGENT asserts "${env.FASTAGENT_AGENT}", which is not one of them — set it ` +
177
- `to one of those, unset it, or scope it to the repository that needs it (an .envrc)`);
178
- }
179
- if (agents.length > 1) {
180
- return (`${listed} and none of them is named "${DEFAULT_AGENT_DIRNAME}" (the default) — pick one with ` +
181
- `FASTAGENT_AGENT=<name>, or point fastagent at the one you want`);
87
+ throw new Error(`${base} is inside the agent ${enclosing} — run from ${enclosing}, or pass it as the agent`);
182
88
  }
183
89
  return undefined;
184
90
  }
185
- /**
186
- * Resolve a directory into its placement — the ONE owner of the rule ({@link findPlacement}).
187
- *
188
- * WHERE AN UNREADABLE CANDIDATE IS SPENT, and only here: this caller MUST produce an agent, so a directory it
189
- * could not look into is the difference between "there is none" and "there might be". `placementDeadEnd` is
190
- * asked a weaker question — is this place a dead end with its own way out — by callers like `login`, for which
191
- * a neighbour it may not enter is environment noise, not a reason to exit instead of logging in globally. It
192
- * also comes AFTER that call: with two agents to choose between, a permission problem in a third directory is
193
- * not the message that gets the caller moving.
194
- */
195
- export function resolvePlacement(dir, env = process.env) {
196
- const placement = findPlacement(dir, env);
197
- if (!placement) {
198
- const base = resolve(dir);
199
- throw new Error(placementDeadEnd(base, env) ?? `${base} is not a fastagent agent${noAgentHere(base)}`);
91
+ /** The agent directory `dir` names ({@link findAgentDir}), refusing when there is none. */
92
+ export function resolveAgentDir(dir) {
93
+ const agentDir = findAgentDir(dir);
94
+ if (agentDir === undefined) {
95
+ throw new Error(`${resolve(dir)} is not a fastagent agent — it holds no ${AGENT_CONFIG_FILE}; pass the agent's directory, ` +
96
+ "or create one with `fastagent init <dir>`");
200
97
  }
201
- return placement;
202
- }
203
- /** At most this many names before the rest become a count — `/tmp` on a shared machine has plenty. */
204
- const LISTED_UNREADABLE = 3;
205
- /**
206
- * The rest of the "not an agent" refusal: the way out, plus what could not be looked at.
207
- *
208
- * BOTH, never one or the other. `fastagent init` is the only line that tells the caller what to do, and a
209
- * directory it cannot enter is exactly why that advice can be wrong (#571: scaffolding over a definition that
210
- * is there but invisible). Substituting the second for the first sends anyone running in `/tmp`, or on a
211
- * shared machine, to fix permissions on directories that were never theirs and hold no agent.
212
- */
213
- function noAgentHere(base) {
214
- const { unreadable } = scanAgents(base);
215
- const noConfig = ` — no fastagent.config.ts here, and no readable directory holding one directly inside`;
216
- const scaffold = "run `fastagent init` to scaffold one";
217
- if (unreadable.length === 0)
218
- return `${noConfig}; ${scaffold}`;
219
- const shown = unreadable.slice(0, LISTED_UNREADABLE).join(", ");
220
- const rest = unreadable.length - LISTED_UNREADABLE;
221
- // The unknown FIRST, because it is the one thing that can make the advice wrong.
222
- return (`${noConfig}. ${unreadable.length} director${unreadable.length === 1 ? "y" : "ies"} here could not be ` +
223
- `read (permission), so an agent may be inside one: ${shown}${rest > 0 ? `, +${rest} more` : ""}. Check ` +
224
- `those first; ${scaffold} only if none of them holds an agent`);
98
+ return agentDir;
225
99
  }
226
100
  /** How to WRITE a path for someone standing in `cwd`. */
227
101
  export function displayPath(cwd, dir) {
@@ -258,27 +132,21 @@ export function resolveOverridePath(raw) {
258
132
  }
259
133
  /**
260
134
  * The resolved state root — the durable machine-state home (sessions/, channels/<kind>/, schedule/):
261
- * `FASTAGENT_STATE_DIR` env > `<agentDir>/.state`.
135
+ * Explicit paths win; production otherwise uses `.state/production`, dev uses `.state`.
262
136
  */
263
137
  export function resolveStateRoot(dir, env = process.env) {
264
- return resolveOverridePath(env.FASTAGENT_STATE_DIR) ?? join(resolve(dir), STATE_DIRNAME);
138
+ return resolveOverridePath(env.FASTAGENT_STATE_DIR) ?? environmentPath(dir, STATE_DIRNAME, env);
265
139
  }
266
- /**
267
- * WHERE an agent's session records live: `<state root>/sessions`, always. Records are machine state like channel
268
- * state and schedule claims, so they move with the ONE knob that moves all of it rather than with a second one that
269
- * moves only them — a split every reader would then have to agree about, and which left channel state behind anyway.
270
- * An embedder that really wants the records elsewhere passes `sessionsDir` to `createAgentService`; there is no env
271
- * or flag spelling of it, for the reason `resolveAuthPathOverride` states.
272
- */
273
- export function resolveSessionsDir(dir, env = process.env) {
274
- return join(resolveStateRoot(dir, env), "sessions");
140
+ /** Where fastagent clones the content entry `name` of the agent in `dir`. */
141
+ export function contentEntryPath(dir, name) {
142
+ return join(resolve(dir), CONTENT_DIRNAME, name);
275
143
  }
276
144
  /**
277
145
  * The resolved secrets dir — everything fastagent manages that must NEVER leave the machine (the agent's `.env` +
278
- * auth.json).
146
+ * auth.json). Explicit paths win; production otherwise uses `.secrets/production`, dev uses `.secrets`.
279
147
  */
280
148
  export function resolveSecretsDir(dir, env = process.env) {
281
- return resolveOverridePath(env.FASTAGENT_SECRETS_DIR) ?? join(resolve(dir), SECRETS_DIRNAME);
149
+ return resolveOverridePath(env.FASTAGENT_SECRETS_DIR) ?? environmentPath(dir, SECRETS_DIRNAME, env);
282
150
  }
283
151
  /** Is this process the deployed container the generated artifacts describe? ONE reading of the
284
152
  * environment fact the image states, so a second spelling cannot drift from it. */
@@ -289,6 +157,22 @@ export function isDeployedWorkspace() {
289
157
  export function isAgentcoreRuntime() {
290
158
  return process.env.FASTAGENT_AGENTCORE === "1";
291
159
  }
160
+ /**
161
+ * Which host this deployed box runs on, for the command that logs it in (`login --deployment <host>`). Read from what
162
+ * each platform puts in a box's environment (`FLY_APP_NAME`, `RAILWAY_SERVICE_ID`) or what our AgentCore template
163
+ * sets, because the artifacts in the agent directory cannot say it: a Railway deploy leaves no file of its own, and a
164
+ * directory can hold several hosts' files. Undefined where nothing says (Docker sets nothing, nor would a host
165
+ * fastagent did not deploy to): the caller then asks for the host by name.
166
+ */
167
+ export function deployedHost(env = process.env) {
168
+ if (env.FASTAGENT_AGENTCORE === "1")
169
+ return "agentcore";
170
+ if (env.FLY_APP_NAME)
171
+ return "fly";
172
+ if (env.RAILWAY_SERVICE_ID)
173
+ return "railway";
174
+ return undefined;
175
+ }
292
176
  /**
293
177
  * The mode of a file fastagent CREATES to hold a secret: `auth.json`, a `.env` it makes itself,
294
178
  * a host's parameter file. That is the whole extent of its opinion about permissions — a file it did not create
package/dist/runtime.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  /**
2
- * How to install and run the AGENT: its package.json + lockfile decide, never the surrounding workspace's (whose
3
- * toolchain is the agent's runtime concern, not fastagent's).
2
+ * How to install and run the AGENT: its own package.json + lockfile decide.
4
3
  */
5
4
  export interface AgentRuntime {
6
5
  /**
@@ -23,6 +22,29 @@ export interface AgentRuntime {
23
22
  export declare function detectRuntime(dir: string, pkg: {
24
23
  packageManager?: unknown;
25
24
  }): AgentRuntime;
25
+ /**
26
+ * The oldest runtimes that run an agent, both set by the instance's storage, `node:sqlite`: Bun ships it from 1.4.0,
27
+ * and Node stops calling it experimental, and printing so on every start, from 24.15.0.
28
+ */
29
+ export declare const RUNTIME_FLOOR: {
30
+ readonly node: "24.15.0";
31
+ readonly bun: "1.4.0";
32
+ };
33
+ /** Whether `version` (`1.3.13`, `24.4`) is older than `floor`; false for one that names no version (`canary`). */
34
+ export declare function belowFloor(version: string, floor: string): boolean;
35
+ /** Why this process's runtime cannot run fastagent, or undefined when it can. Bun reports a Node version too. */
36
+ export declare function unsupportedRuntime(versions?: {
37
+ node: string;
38
+ bun?: string;
39
+ }): string | undefined;
40
+ /**
41
+ * Whether a manifest lists FastAgent, which the image of an agent with a `package.json` runs from its own
42
+ * `node_modules`: without it, the container cannot start.
43
+ */
44
+ export declare function listsFastagent(pkg: {
45
+ dependencies?: Record<string, unknown>;
46
+ devDependencies?: Record<string, unknown>;
47
+ }): boolean;
26
48
  /**
27
49
  * Parse `<dir>/package.json`, or `{}` when there is none (a markdown-only agent). A file that does not parse throws,
28
50
  * naming itself: read as `{}` it became "does not list @fastagent-sh/fastagent" and an npm-based image, both wrong.
@@ -31,4 +53,5 @@ export declare function readPackageJson(dir: string): Promise<{
31
53
  packageManager?: unknown;
32
54
  dependencies?: Record<string, unknown>;
33
55
  devDependencies?: Record<string, unknown>;
56
+ optionalDependencies?: Record<string, unknown>;
34
57
  }>;
package/dist/runtime.js CHANGED
@@ -14,6 +14,33 @@ export function detectRuntime(dir, pkg) {
14
14
  }
15
15
  return { runtime: "node", hasLockfile: existsSync(join(dir, "package-lock.json")) };
16
16
  }
17
+ /**
18
+ * The oldest runtimes that run an agent, both set by the instance's storage, `node:sqlite`: Bun ships it from 1.4.0,
19
+ * and Node stops calling it experimental, and printing so on every start, from 24.15.0.
20
+ */
21
+ export const RUNTIME_FLOOR = { node: "24.15.0", bun: "1.4.0" };
22
+ /** Whether `version` (`1.3.13`, `24.4`) is older than `floor`; false for one that names no version (`canary`). */
23
+ export function belowFloor(version, floor) {
24
+ const match = /^v?(\d+)\.(\d+)(?:\.(\d+))?/.exec(version);
25
+ if (match === null)
26
+ return false;
27
+ const given = [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];
28
+ const least = floor.split(".").map(Number);
29
+ const differs = given.findIndex((part, i) => part !== least[i]);
30
+ return differs !== -1 && given[differs] < least[differs];
31
+ }
32
+ /** Why this process's runtime cannot run fastagent, or undefined when it can. Bun reports a Node version too. */
33
+ export function unsupportedRuntime(versions = process.versions) {
34
+ const [name, version, floor] = versions.bun === undefined ? ["Node", versions.node, RUNTIME_FLOOR.node] : ["Bun", versions.bun, RUNTIME_FLOOR.bun];
35
+ return belowFloor(version, floor) ? `fastagent needs ${name} ${floor} or later; this is ${version}` : undefined;
36
+ }
37
+ /**
38
+ * Whether a manifest lists FastAgent, which the image of an agent with a `package.json` runs from its own
39
+ * `node_modules`: without it, the container cannot start.
40
+ */
41
+ export function listsFastagent(pkg) {
42
+ return "@fastagent-sh/fastagent" in { ...pkg.dependencies, ...pkg.devDependencies };
43
+ }
17
44
  /**
18
45
  * Parse `<dir>/package.json`, or `{}` when there is none (a markdown-only agent). A file that does not parse throws,
19
46
  * naming itself: read as `{}` it became "does not list @fastagent-sh/fastagent" and an npm-based image, both wrong.
@@ -1,12 +1,6 @@
1
- import type { FeishuSubscriptionMode } from "../channels/feishu/setup-mode.ts";
1
+ import { type ValueWriteResult } from "../value-file.ts";
2
+ import { type FeishuSubscriptionMode } from "../channels/feishu/setup-mode.ts";
2
3
  export type ChannelKind = "telegram" | "slack" | "feishu" | "lark";
3
- /** Group-visibility choice shared by the slack/feishu/lark onboarding flows. */
4
- export type GroupBehavior = "context" | "mentions";
5
- /** A resolved group-behavior decision plus whether the author actually chose it (flag or prompt). */
6
- export interface GroupBehaviorChoice {
7
- behavior: GroupBehavior;
8
- explicit: boolean;
9
- }
10
4
  /** An env var a scaffolded channel reads. */
11
5
  export interface ChannelEnv {
12
6
  name: string;
@@ -18,35 +12,28 @@ export interface ChannelEnv {
18
12
  /** The channel kinds `fastagent add <kind>` can scaffold. */
19
13
  export declare const CHANNEL_KINDS: ChannelKind[];
20
14
  /** The mode-specific env vars + next-step lines a scaffolded channel needs. */
21
- export declare function channelSetup(kind: ChannelKind, ingress?: FeishuSubscriptionMode, groupBehavior?: GroupBehavior): {
15
+ export declare function channelSetup(kind: ChannelKind, ingress?: FeishuSubscriptionMode,
16
+ /** Whether `<PREFIX>_INGRESS` is explicitly set in this environment. */
17
+ pinned?: boolean): {
22
18
  env: ChannelEnv[];
23
19
  steps: string[];
24
20
  };
25
21
  /**
26
22
  * Append a channel's env vars (commented placeholders + hints) to `.env.example`, so a developer who copies it to
27
- * `.env` finds the vars already there.
23
+ * `.env` finds the vars already there. Every var the channel can declare, whichever way this machine receives it:
24
+ * the file is what a collaborator or CI fills for a deployment, which receives Feishu/Lark by webhook.
28
25
  */
29
- export declare function appendChannelEnv(dir: string, kind: ChannelKind, ingress?: FeishuSubscriptionMode): Promise<boolean>;
30
- export interface DotEnvWriteResult {
31
- /** Generated secret vars written as active `KEY=value` lines. */
32
- written: string[];
33
- /** Vars already present with a non-empty active value; left untouched and omitted from next steps. */
34
- alreadySet: string[];
35
- /** Set when the secrets dir is an operator-chosen one (`FASTAGENT_SECRETS_DIR`) carrying no `.gitignore`. */
36
- unprotectedSecretsDir?: string;
37
- }
26
+ export declare function appendChannelEnv(dir: string, kind: ChannelKind): Promise<boolean>;
38
27
  /**
39
- * Append generated channel secrets to the agent's `.env` (`.secrets/.env` — never `.env.example`) Existing non-empty
40
- * values are kept.
28
+ * Append generated channel secrets to the selected environment's value file, and a placeholder for each the channel
29
+ * reads that nothing generated. Existing non-empty values are kept.
41
30
  */
42
- export declare function appendChannelDotEnv(dir: string, kind: ChannelKind, generated: Record<string, string>, overwrite?: readonly string[], ingress?: FeishuSubscriptionMode): Promise<DotEnvWriteResult>;
31
+ export declare function appendChannelDotEnv(dir: string, kind: ChannelKind, generated: Record<string, string>, overwrite?: readonly string[], ingress?: FeishuSubscriptionMode): Promise<ValueWriteResult>;
43
32
  /** Whether a channel file already exists — checked before any mutation, so a no-clobber re-add is side-effect-free. */
44
33
  export declare function channelExists(dir: string, kind: ChannelKind): Promise<boolean>;
45
- /** Scaffold `channels/<kind>.ts` into {@link dir}. */
46
- export declare function scaffoldChannel(dir: string, kind: ChannelKind, options?: {
47
- ingress?: FeishuSubscriptionMode;
48
- }): Promise<string>;
49
- /** The bundle's companion tools (every `.ts` beside `channel.ts` → `tools/<name>`). */
34
+ /** Scaffold `src/channels/<kind>.ts` into {@link dir}. */
35
+ export declare function scaffoldChannel(dir: string, kind: ChannelKind): Promise<string>;
36
+ /** The bundle's companion tools (every `.ts` beside `channel.ts` → `src/tools/<name>`). */
50
37
  export declare function scaffoldCompanionTools(dir: string, kind: ChannelKind): Promise<string[]>;
51
38
  /**
52
39
  * Verify the AGENT DIR is ready to host a channel: an ESM package.json that declares `@fastagent-sh/fastagent` (the