@fastagent-sh/fastagent 0.29.0 → 0.30.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 (310) hide show
  1. package/README.md +9 -4
  2. package/dist/atomic-write.d.ts +4 -5
  3. package/dist/atomic-write.js +4 -5
  4. package/dist/authoring.d.ts +32 -15
  5. package/dist/authoring.js +147 -127
  6. package/dist/channels/agentcore-protocol.d.ts +8 -3
  7. package/dist/channels/agentcore-protocol.js +3 -1
  8. package/dist/channels/agentcore-service.d.ts +1 -0
  9. package/dist/channels/agentcore-service.js +14 -4
  10. package/dist/channels/agentcore.d.ts +9 -0
  11. package/dist/channels/agentcore.js +29 -4
  12. package/dist/channels/context.d.ts +2 -0
  13. package/dist/channels/context.js +5 -1
  14. package/dist/channels/feishu/feishu-api.d.ts +2 -1
  15. package/dist/channels/feishu/feishu.d.ts +0 -3
  16. package/dist/channels/feishu/feishu.js +10 -10
  17. package/dist/channels/feishu/register-app.js +3 -5
  18. package/dist/channels/feishu/scaffold/channel.ts +32 -34
  19. package/dist/channels/feishu/scaffold/feishu-send.ts +5 -5
  20. package/dist/channels/feishu/scaffold/feishu-threads.ts +3 -3
  21. package/dist/channels/feishu/setup-mode.d.ts +2 -12
  22. package/dist/channels/feishu/setup-mode.js +2 -22
  23. package/dist/channels/feishu/setup.d.ts +12 -0
  24. package/dist/channels/feishu/setup.js +197 -0
  25. package/dist/channels/kit/abortable.d.ts +8 -0
  26. package/dist/channels/kit/abortable.js +22 -0
  27. package/dist/channels/lark/lark.d.ts +0 -3
  28. package/dist/channels/lark/lark.js +0 -5
  29. package/dist/channels/lark/scaffold/channel.ts +33 -35
  30. package/dist/channels/lark/scaffold/lark-send.ts +5 -5
  31. package/dist/channels/lark/scaffold/lark-threads.ts +3 -3
  32. package/dist/channels/lark/setup.d.ts +9 -0
  33. package/dist/channels/lark/setup.js +57 -0
  34. package/dist/channels/setup.d.ts +112 -0
  35. package/dist/channels/setup.js +31 -0
  36. package/dist/channels/slack/history.js +1 -1
  37. package/dist/channels/slack/manifest.d.ts +17 -7
  38. package/dist/channels/slack/manifest.js +12 -16
  39. package/dist/channels/slack/scaffold/channel.ts +44 -30
  40. package/dist/channels/slack/scaffold/slack-send.ts +8 -8
  41. package/dist/channels/slack/scaffold/slack-threads.ts +4 -4
  42. package/dist/channels/slack/setup.d.ts +7 -0
  43. package/dist/channels/slack/setup.js +119 -0
  44. package/dist/channels/slack/slack-api.d.ts +2 -0
  45. package/dist/channels/slack/slack-api.js +4 -0
  46. package/dist/channels/slack/slack.d.ts +21 -2
  47. package/dist/channels/slack/slack.js +398 -338
  48. package/dist/channels/slack/socket.d.ts +57 -0
  49. package/dist/channels/slack/socket.js +305 -0
  50. package/dist/channels/telegram/polling.d.ts +27 -0
  51. package/dist/channels/telegram/polling.js +105 -0
  52. package/dist/channels/telegram/scaffold/channel.ts +52 -32
  53. package/dist/channels/telegram/scaffold/telegram-send.ts +9 -9
  54. package/dist/channels/telegram/setup.d.ts +2 -0
  55. package/dist/channels/telegram/setup.js +42 -0
  56. package/dist/channels/telegram/telegram-api.d.ts +27 -1
  57. package/dist/channels/telegram/telegram-api.js +7 -6
  58. package/dist/channels/telegram/telegram.d.ts +11 -3
  59. package/dist/channels/telegram/telegram.js +184 -157
  60. package/dist/channels/webhook-evidence.d.ts +11 -0
  61. package/dist/channels/webhook-evidence.js +71 -0
  62. package/dist/channels/webhooks.d.ts +37 -0
  63. package/dist/channels/webhooks.js +70 -0
  64. package/dist/child-env.d.ts +16 -0
  65. package/dist/child-env.js +30 -0
  66. package/dist/cli/box-login.js +4 -1
  67. package/dist/cli/channel-app.d.ts +3 -0
  68. package/dist/cli/channel-app.js +35 -0
  69. package/dist/cli/channel-setup.d.ts +38 -0
  70. package/dist/cli/channel-setup.js +195 -0
  71. package/dist/cli/commands/add.d.ts +6 -14
  72. package/dist/cli/commands/add.js +45 -303
  73. package/dist/cli/commands/auth.js +8 -2
  74. package/dist/cli/commands/build.d.ts +5 -0
  75. package/dist/cli/commands/build.js +16 -0
  76. package/dist/cli/commands/channels.d.ts +19 -0
  77. package/dist/cli/commands/channels.js +230 -0
  78. package/dist/cli/commands/content.d.ts +7 -3
  79. package/dist/cli/commands/content.js +16 -10
  80. package/dist/cli/commands/deploy/agentcore.js +55 -23
  81. package/dist/cli/commands/deploy/channel-apps.d.ts +17 -0
  82. package/dist/cli/commands/deploy/channel-apps.js +30 -0
  83. package/dist/cli/commands/deploy/docker.js +32 -65
  84. package/dist/cli/commands/deploy/fly.js +28 -12
  85. package/dist/cli/commands/deploy/railway.js +38 -13
  86. package/dist/cli/commands/deploy/secrets-step.d.ts +19 -0
  87. package/dist/cli/commands/deploy/secrets-step.js +66 -0
  88. package/dist/cli/commands/deploy/shared.d.ts +16 -5
  89. package/dist/cli/commands/deploy/shared.js +25 -8
  90. package/dist/cli/commands/deploy.js +53 -60
  91. package/dist/cli/commands/dev.d.ts +2 -0
  92. package/dist/cli/commands/dev.js +15 -3
  93. package/dist/cli/commands/env.js +1 -1
  94. package/dist/cli/commands/info.d.ts +2 -0
  95. package/dist/cli/commands/info.js +60 -25
  96. package/dist/cli/commands/init.js +3 -1
  97. package/dist/cli/commands/invoke.d.ts +2 -0
  98. package/dist/cli/commands/invoke.js +20 -7
  99. package/dist/cli/commands/login.d.ts +0 -7
  100. package/dist/cli/commands/login.js +22 -10
  101. package/dist/cli/commands/logout.js +1 -1
  102. package/dist/cli/commands/mcp.js +14 -6
  103. package/dist/cli/commands/models.js +3 -2
  104. package/dist/cli/commands/schedules.d.ts +4 -2
  105. package/dist/cli/commands/schedules.js +14 -10
  106. package/dist/cli/commands/secrets.d.ts +14 -0
  107. package/dist/cli/commands/secrets.js +213 -0
  108. package/dist/cli/commands/start.d.ts +14 -14
  109. package/dist/cli/commands/start.js +46 -60
  110. package/dist/cli/content-view.d.ts +4 -6
  111. package/dist/cli/content-view.js +5 -11
  112. package/dist/cli/first-run-channels.d.ts +3 -0
  113. package/dist/cli/first-run-channels.js +63 -0
  114. package/dist/cli/instance.d.ts +41 -0
  115. package/dist/cli/instance.js +155 -0
  116. package/dist/cli/invoke-stream.d.ts +5 -2
  117. package/dist/cli/invoke-stream.js +7 -2
  118. package/dist/cli/program.js +282 -110
  119. package/dist/cli/serve.d.ts +4 -5
  120. package/dist/cli/serve.js +4 -7
  121. package/dist/cli/shared.d.ts +11 -2
  122. package/dist/cli/shared.js +32 -19
  123. package/dist/cli/ticket.js +50 -6
  124. package/dist/content/declare.d.ts +31 -37
  125. package/dist/content/declare.js +59 -60
  126. package/dist/content/file.d.ts +23 -12
  127. package/dist/content/file.js +48 -35
  128. package/dist/content/git.d.ts +0 -10
  129. package/dist/content/git.js +5 -39
  130. package/dist/content/resolve.d.ts +18 -22
  131. package/dist/content/resolve.js +32 -66
  132. package/dist/content/source.d.ts +7 -8
  133. package/dist/content/source.js +10 -28
  134. package/dist/credentials-page.d.ts +26 -0
  135. package/dist/credentials-page.js +185 -0
  136. package/dist/declared-secrets.d.ts +10 -3
  137. package/dist/declared-secrets.js +8 -4
  138. package/dist/deploy/agentcore/destroy.d.ts +4 -1
  139. package/dist/deploy/agentcore/destroy.js +25 -1
  140. package/dist/deploy/agentcore/forwarder.js +1 -1
  141. package/dist/deploy/agentcore/plan.d.ts +7 -21
  142. package/dist/deploy/agentcore/plan.js +47 -49
  143. package/dist/deploy/agentcore/run.d.ts +18 -10
  144. package/dist/deploy/agentcore/run.js +93 -70
  145. package/dist/deploy/agentcore/runtime-secrets.d.ts +7 -0
  146. package/dist/deploy/agentcore/runtime-secrets.js +108 -0
  147. package/dist/deploy/agentcore/shell.js +12 -19
  148. package/dist/deploy/agentcore/sigv4.d.ts +7 -0
  149. package/dist/deploy/agentcore/sigv4.js +15 -0
  150. package/dist/deploy/agentcore/slr.d.ts +18 -0
  151. package/dist/deploy/agentcore/slr.js +27 -0
  152. package/dist/deploy/agentcore/store.d.ts +7 -0
  153. package/dist/deploy/agentcore/store.js +115 -0
  154. package/dist/deploy/api.d.ts +14 -14
  155. package/dist/deploy/api.js +26 -24
  156. package/dist/deploy/box-shell.d.ts +3 -1
  157. package/dist/deploy/build-context.d.ts +4 -4
  158. package/dist/deploy/build-context.js +11 -15
  159. package/dist/deploy/channel-ingress.d.ts +35 -9
  160. package/dist/deploy/channel-ingress.js +119 -22
  161. package/dist/deploy/container.d.ts +35 -10
  162. package/dist/deploy/container.js +79 -37
  163. package/dist/deploy/delivered-text.d.ts +13 -0
  164. package/dist/deploy/delivered-text.js +86 -0
  165. package/dist/deploy/docker/plan.d.ts +7 -8
  166. package/dist/deploy/docker/plan.js +31 -52
  167. package/dist/deploy/docker/run.d.ts +5 -43
  168. package/dist/deploy/docker/run.js +9 -84
  169. package/dist/deploy/file-store.d.ts +2 -0
  170. package/dist/deploy/file-store.js +17 -0
  171. package/dist/deploy/fly/plan.d.ts +3 -2
  172. package/dist/deploy/fly/plan.js +20 -9
  173. package/dist/deploy/fly/run.d.ts +18 -8
  174. package/dist/deploy/fly/run.js +24 -42
  175. package/dist/deploy/fly/store.d.ts +12 -0
  176. package/dist/deploy/fly/store.js +83 -0
  177. package/dist/deploy/hosts.d.ts +1 -2
  178. package/dist/deploy/hosts.js +1 -2
  179. package/dist/deploy/preflight.d.ts +18 -5
  180. package/dist/deploy/preflight.js +135 -63
  181. package/dist/deploy/railway/ignore.d.ts +8 -0
  182. package/dist/deploy/railway/ignore.js +57 -0
  183. package/dist/deploy/railway/plan.d.ts +1 -2
  184. package/dist/deploy/railway/plan.js +8 -6
  185. package/dist/deploy/railway/run.d.ts +21 -15
  186. package/dist/deploy/railway/run.js +32 -78
  187. package/dist/deploy/railway/store.d.ts +29 -0
  188. package/dist/deploy/railway/store.js +143 -0
  189. package/dist/deploy/runner.d.ts +5 -2
  190. package/dist/deploy/runner.js +4 -3
  191. package/dist/deploy/secret-store.d.ts +63 -0
  192. package/dist/deploy/secret-store.js +98 -0
  193. package/dist/deploy/secrets.d.ts +29 -46
  194. package/dist/deploy/secrets.js +49 -122
  195. package/dist/deploy/workspace.d.ts +6 -12
  196. package/dist/deploy/workspace.js +18 -94
  197. package/dist/dev-supervisor.js +6 -8
  198. package/dist/environment/declare.js +3 -2
  199. package/dist/environment/mise.d.ts +3 -1
  200. package/dist/environment/mise.js +4 -2
  201. package/dist/feishu.d.ts +1 -1
  202. package/dist/feishu.js +1 -1
  203. package/dist/harnesses/models/catalog.d.ts +1 -0
  204. package/dist/harnesses/models/catalog.js +1 -2
  205. package/dist/harnesses/models/environment.d.ts +7 -2
  206. package/dist/harnesses/models/environment.js +9 -5
  207. package/dist/harnesses/models/host.d.ts +0 -7
  208. package/dist/harnesses/models/host.js +10 -1
  209. package/dist/harnesses/models/login.d.ts +0 -8
  210. package/dist/harnesses/models/login.js +5 -4
  211. package/dist/harnesses/models/models.d.ts +7 -2
  212. package/dist/harnesses/models/models.js +28 -4
  213. package/dist/harnesses/pi-durable/agent.js +59 -38
  214. package/dist/harnesses/pi-durable/build.d.ts +12 -0
  215. package/dist/harnesses/pi-durable/build.js +270 -0
  216. package/dist/harnesses/pi-durable/built.d.ts +24 -0
  217. package/dist/harnesses/pi-durable/built.js +136 -0
  218. package/dist/harnesses/pi-durable/config.d.ts +81 -0
  219. package/dist/harnesses/pi-durable/config.js +266 -0
  220. package/dist/harnesses/pi-durable/define.d.ts +63 -13
  221. package/dist/harnesses/pi-durable/define.js +23 -2
  222. package/dist/harnesses/pi-durable/definition.d.ts +72 -0
  223. package/dist/harnesses/pi-durable/definition.js +143 -0
  224. package/dist/harnesses/pi-durable/events.d.ts +4 -3
  225. package/dist/harnesses/pi-durable/events.js +179 -136
  226. package/dist/harnesses/pi-durable/execution-env.d.ts +17 -0
  227. package/dist/harnesses/pi-durable/execution-env.js +11 -0
  228. package/dist/harnesses/pi-durable/mcp.js +1 -3
  229. package/dist/harnesses/pi-durable/open.d.ts +35 -37
  230. package/dist/harnesses/pi-durable/open.js +91 -153
  231. package/dist/harnesses/pi-durable/reads.d.ts +0 -1
  232. package/dist/harnesses/pi-durable/reads.js +1 -3
  233. package/dist/harnesses/pi-durable/registry.d.ts +4 -6
  234. package/dist/harnesses/pi-durable/registry.js +29 -26
  235. package/dist/harnesses/pi-durable/release.d.ts +2 -2
  236. package/dist/harnesses/pi-durable/release.js +10 -7
  237. package/dist/harnesses/pi-durable/serve.d.ts +91 -15
  238. package/dist/harnesses/pi-durable/serve.js +109 -47
  239. package/dist/harnesses/pi-durable/sessions.js +15 -12
  240. package/dist/harnesses/pi-durable/text-sources.d.ts +30 -0
  241. package/dist/harnesses/pi-durable/text-sources.js +55 -0
  242. package/dist/harnesses/pi-durable/text.d.ts +16 -4
  243. package/dist/harnesses/pi-durable/text.js +115 -59
  244. package/dist/harnesses/pi-durable/wake.js +8 -8
  245. package/dist/http/client.js +9 -3
  246. package/dist/http/contract.d.ts +3 -3
  247. package/dist/http/server.d.ts +1 -1
  248. package/dist/http/server.js +1 -1
  249. package/dist/index.d.ts +8 -5
  250. package/dist/index.js +4 -1
  251. package/dist/instance-name.d.ts +7 -0
  252. package/dist/instance-name.js +26 -0
  253. package/dist/lark.d.ts +1 -1
  254. package/dist/lark.js +1 -1
  255. package/dist/mcp/client.js +11 -2
  256. package/dist/mcp/config.d.ts +70 -18
  257. package/dist/mcp/config.js +136 -53
  258. package/dist/mcp/host.d.ts +5 -2
  259. package/dist/mcp/host.js +14 -6
  260. package/dist/mcp/sign-in.js +2 -2
  261. package/dist/mcp-api.d.ts +14 -0
  262. package/dist/paths.d.ts +22 -8
  263. package/dist/paths.js +44 -11
  264. package/dist/runtime-websocket.d.ts +14 -0
  265. package/dist/runtime-websocket.js +39 -0
  266. package/dist/scaffold/add-channel.d.ts +9 -16
  267. package/dist/scaffold/add-channel.js +13 -83
  268. package/dist/scaffold/templates/env.example +4 -5
  269. package/dist/scaffold/templates/fastagent.config.ts +20 -14
  270. package/dist/scaffold/templates/gitignore +9 -6
  271. package/dist/scaffold/templates.d.ts +6 -2
  272. package/dist/scaffold/templates.js +7 -2
  273. package/dist/scaffold/vendor-skill.js +4 -2
  274. package/dist/service.d.ts +44 -6
  275. package/dist/service.js +110 -10
  276. package/dist/serving-command.d.ts +10 -0
  277. package/dist/serving-command.js +1 -0
  278. package/dist/slack.d.ts +1 -1
  279. package/dist/slack.js +1 -1
  280. package/dist/strip-edges.d.ts +10 -0
  281. package/dist/strip-edges.js +22 -0
  282. package/dist/telegram.d.ts +1 -1
  283. package/dist/telegram.js +1 -1
  284. package/dist/tunnel.d.ts +0 -1
  285. package/dist/tunnel.js +2 -8
  286. package/dist/value-file.d.ts +11 -6
  287. package/dist/value-file.js +21 -9
  288. package/dist/version.d.ts +7 -1
  289. package/dist/version.js +9 -3
  290. package/package.json +6 -5
  291. package/dist/channels/lark/credentials-page.d.ts +0 -25
  292. package/dist/channels/lark/credentials-page.js +0 -206
  293. package/dist/channels/lark/onboard.d.ts +0 -52
  294. package/dist/channels/lark/onboard.js +0 -86
  295. package/dist/channels/slack/config-api.d.ts +0 -69
  296. package/dist/channels/slack/config-api.js +0 -162
  297. package/dist/channels/slack/onboard.d.ts +0 -40
  298. package/dist/channels/slack/onboard.js +0 -136
  299. package/dist/channels/slack/onboarding-state.d.ts +0 -31
  300. package/dist/channels/slack/onboarding-state.js +0 -64
  301. package/dist/channels/slack/register-webhook.d.ts +0 -12
  302. package/dist/channels/slack/register-webhook.js +0 -67
  303. package/dist/channels/slack/setup-server.d.ts +0 -32
  304. package/dist/channels/slack/setup-server.js +0 -246
  305. package/dist/cli/add-feishu.d.ts +0 -41
  306. package/dist/cli/add-feishu.js +0 -391
  307. package/dist/cli/add-slack.d.ts +0 -18
  308. package/dist/cli/add-slack.js +0 -216
  309. package/dist/harnesses/pi-durable/parked.d.ts +0 -18
  310. package/dist/harnesses/pi-durable/parked.js +0 -27
@@ -7,6 +7,7 @@ import { buildProgram } from "./kernel.js";
7
7
  import { DEPLOY_HOSTS } from "../deploy/hosts.js";
8
8
  import { unsupportedRuntime } from "../runtime.js";
9
9
  import { failStartup } from "./fail.js";
10
+ import { CONFIG_FLAG, CONTENT_FLAGS, ENV_FILE_FLAG, INSTANCE_FLAGS, instanceFlags } from "./instance.js";
10
11
  // Help groups (clig: most common commands first) — the authoring loop leads, operations close.
11
12
  const AGENT_ARG = {
12
13
  name: "[agent]",
@@ -44,7 +45,7 @@ const init = {
44
45
  {
45
46
  flags: "--content <source>",
46
47
  description: "a directory or github:owner/repo the agent works on (repeatable): a repository in context.json, a " +
47
- "directory of this machine in context.local.json",
48
+ "directory of this machine in fastagent.json",
48
49
  repeatable: true,
49
50
  },
50
51
  { flags: "--no-install", description: "scaffold everything but skip npm install" },
@@ -70,7 +71,17 @@ const dev = {
70
71
  "(src/, fastagent.config.ts, package.json, .secrets/.env) restart the worker once its running messages finish. " +
71
72
  "Files the agent writes as work product never trigger a restart.",
72
73
  args: [AGENT_ARG],
73
- flags: [PORT, BIND, MODEL, { flags: "--no-watch", description: "serve once, no file-watching" }, TUNNEL, NO_INPUT],
74
+ flags: [
75
+ PORT,
76
+ BIND,
77
+ MODEL,
78
+ { flags: "--no-watch", description: "serve once, no file-watching" },
79
+ TUNNEL,
80
+ NO_INPUT,
81
+ ...INSTANCE_FLAGS,
82
+ CONFIG_FLAG,
83
+ ENV_FILE_FLAG,
84
+ ],
74
85
  examples: [
75
86
  { cmd: "fastagent dev" },
76
87
  { cmd: "fastagent dev --tunnel", note: "public URL + registered/guided webhooks" },
@@ -82,6 +93,7 @@ const dev = {
82
93
  watch: f.watch !== false,
83
94
  tunnel: f.tunnel === true,
84
95
  input: f.input !== false,
96
+ instance: instanceFlags(f),
85
97
  }),
86
98
  };
87
99
  const info = {
@@ -91,11 +103,27 @@ const info = {
91
103
  "secrets, content — WITHOUT opening or serving it. An unset model or secret is reported, not fatal. " +
92
104
  "Run it first when something looks off.",
93
105
  args: [AGENT_ARG],
94
- flags: [JSON_FLAG, MODEL],
106
+ flags: [JSON_FLAG, MODEL, ...INSTANCE_FLAGS, CONFIG_FLAG, ENV_FILE_FLAG],
95
107
  examples: [{ cmd: "fastagent info" }, { cmd: "fastagent info --json", note: "for CI" }],
96
108
  run: async (args, f) => (await import("./commands/info.js")).runInfo(args[0], {
97
109
  json: f.json === true,
98
110
  model: f.model,
111
+ instance: instanceFlags(f),
112
+ }),
113
+ };
114
+ const build = {
115
+ name: "build",
116
+ summary: "compile the agent into dist/, the package an app or a host opens",
117
+ description: "Compile the agent (default .) into dist/: its code with the project's TypeScript (type-checked, per file), its " +
118
+ "text, skills, prompts, assets and the resources beside its code, and a generated entry (index.js) whose default " +
119
+ "export is the definition. It refuses what dev refuses, and a type error. dist/ is replaced whole; it holds no " +
120
+ "secret, state or clone.",
121
+ args: [AGENT_ARG],
122
+ flags: [{ flags: "--no-check", description: "emit without type-checking (tsc --noCheck)" }, JSON_FLAG],
123
+ examples: [{ cmd: "fastagent build" }, { cmd: "fastagent build --json", note: "for CI" }],
124
+ run: async (args, f) => (await import("./commands/build.js")).runBuild(args[0], {
125
+ check: f.check !== false,
126
+ json: f.json === true,
99
127
  }),
100
128
  };
101
129
  const invoke = {
@@ -118,6 +146,9 @@ const invoke = {
118
146
  { flags: "--session <id>", description: "continue the session an earlier invoke printed" },
119
147
  { flags: "--url <base>", description: "send to the agent served at <base>, over its Agent API" },
120
148
  { flags: "--key <key>", description: "the API key for --url (default: the agent's production one)" },
149
+ ...INSTANCE_FLAGS,
150
+ CONFIG_FLAG,
151
+ ENV_FILE_FLAG,
121
152
  ],
122
153
  examples: [
123
154
  { cmd: `fastagent invoke "summarize today's inbox"` },
@@ -132,6 +163,7 @@ const invoke = {
132
163
  ...(typeof f.session === "string" ? { session: f.session } : {}),
133
164
  ...(typeof f.url === "string" ? { url: f.url } : {}),
134
165
  ...(typeof f.key === "string" ? { key: f.key } : {}),
166
+ instance: instanceFlags(f),
135
167
  }),
136
168
  };
137
169
  const models = {
@@ -139,7 +171,7 @@ const models = {
139
171
  summary: 'list the available "provider/modelId" model specs',
140
172
  description: 'List every "provider/modelId" spec the agent in this directory can name (pi-ai\'s built-ins, with the models ' +
141
173
  "pi's published catalog adds to them, and the providers its fastagent.config.ts declares) — use one with " +
142
- "--model or as `model` in fastagent.config.ts. Outside an agent, or with -g, list the built-ins without the " +
174
+ "--model or as `defaults.model` in fastagent.config.ts. Outside an agent, or with -g, list the built-ins without the " +
143
175
  "agent's providers. Every command that opens the agent refreshes the lists, asking at most every 4 hours once " +
144
176
  "one is kept; --refresh asks now, and exits 1 when it cannot.",
145
177
  args: [{ name: "[search]", description: "case-insensitive substring filter" }],
@@ -161,24 +193,40 @@ const models = {
161
193
  };
162
194
  const start = {
163
195
  name: "start",
164
- summary: "run the agent in production posture (opened as dev opens it, no watching)",
165
- description: "Run the agent (default .) in production posture — opened as dev opens it (your directory " +
166
- "is the agent), just no file-watching. model and http.port come from fastagent.config.ts.",
196
+ summary: "serve the built dist/ in production posture (no watching)",
197
+ description: "Serve the agent's dist/ (default .) in production posture, just no file-watching; refuses a " +
198
+ "missing or stale dist/, naming `fastagent build`. model and http.port come from " +
199
+ "defaults in fastagent.config.ts, over which --config's fastagent.json sets the instance's own.",
167
200
  args: [AGENT_ARG],
168
- flags: [PORT, BIND, MODEL, TUNNEL, NO_INPUT],
201
+ flags: [
202
+ PORT,
203
+ BIND,
204
+ MODEL,
205
+ TUNNEL,
206
+ NO_INPUT,
207
+ ...INSTANCE_FLAGS,
208
+ {
209
+ ...CONFIG_FLAG,
210
+ description: "the instance configuration, a fastagent.json (FASTAGENT_CONFIG); start never reads the project's",
211
+ },
212
+ ENV_FILE_FLAG,
213
+ ],
169
214
  examples: [
170
- { cmd: "fastagent start" },
215
+ { cmd: "fastagent start", note: "after fastagent build" },
171
216
  { cmd: "fastagent start --tunnel", note: "host a bot from your own box, no deploy" },
172
217
  ],
173
218
  notes: "Precedence chains:\n" +
174
219
  " port: --port > PORT env > fastagent.config.ts http.port > 8787\n" +
175
220
  " bind: --bind > all interfaces (dev: 127.0.0.1)\n" +
176
- " state: FASTAGENT_STATE_DIR > <agent dir>/.state/production\n" +
221
+ " state: --state > FASTAGENT_STATE_DIR > <root>/.state >\n" +
222
+ " <agent dir>/.state/production\n" +
177
223
  " the agent's storage (agent.sqlite), channels, schedules; use a\n" +
178
224
  " mounted volume so a redeploy never wipes it\n" +
179
- " secrets: FASTAGENT_SECRETS_DIR > <agent dir>/.secrets/production\n" +
225
+ " workdir: --workdir > FASTAGENT_WORKDIR > --root > <agent dir>\n" +
226
+ " config: --config > FASTAGENT_CONFIG > none (never fastagent.json)\n" +
227
+ " secrets: --env-file > FASTAGENT_SECRETS_DIR > <agent dir>/.secrets/production\n" +
180
228
  " .env + auth.json\n" +
181
- " content: <agent dir>/content/<name> — a clone of github content; a\n" +
229
+ " content: <workdir>/content/<name> — a clone of github content; a\n" +
182
230
  " deployment links content/ to its volume\n" +
183
231
  " auth: FASTAGENT_AUTH_PATH > <secrets>/auth.json\n" +
184
232
  " (project-level; point it at ~/.fastagent/.secrets/auth.json to\n" +
@@ -189,86 +237,45 @@ const start = {
189
237
  model: f.model,
190
238
  tunnel: f.tunnel === true,
191
239
  input: f.input !== false,
240
+ instance: instanceFlags(f),
192
241
  }),
193
242
  };
194
- const INGRESS = {
195
- flags: "--ingress <mode>",
196
- description: "Feishu/Lark: set websocket or webhook in the selected environment; webhook also prepares its app now " +
197
- "(unset: dev uses websocket, production uses webhook)",
198
- };
199
243
  const CHANNEL_ENVIRONMENT = {
200
244
  flags: "--env <environment>",
201
- description: "select independent app credentials and onboarding state (default: dev; production uses .secrets/production/.env)",
202
- };
203
- const NO_ONBOARD = {
204
- flags: "--no-onboard",
205
- description: "scaffold only: write the channel file (if missing) and its tools, and skip the app onboarding " +
206
- "(Slack: internal-app creation/OAuth; Feishu/Lark: app creation and credential capture)",
207
- };
208
- const REPLACE_CONFIG = {
209
- flags: "--replace-config",
210
- description: "Slack: replace the local App Configuration token pair (repairs automatic dev/deploy Request URL " +
211
- "updates after the tokens expire or are revoked; runs on the machine that onboarded the app)",
245
+ description: "select independent credentials and state (default: dev; production uses .secrets/production/.env)",
212
246
  };
213
247
  const channelSub = (kind, summary, description, notes) => ({
214
248
  name: kind,
215
249
  summary,
216
250
  description,
217
251
  args: [AGENT_ARG],
218
- flags: kind === "feishu" || kind === "lark"
219
- ? [CHANNEL_ENVIRONMENT, INGRESS, NO_ONBOARD, ...UNATTENDED_SETUP]
220
- : kind === "slack"
221
- ? [CHANNEL_ENVIRONMENT, NO_ONBOARD, REPLACE_CONFIG, ...UNATTENDED_SETUP]
222
- : [CHANNEL_ENVIRONMENT, JSON_FLAG],
223
- examples: [
224
- { cmd: `fastagent add ${kind}` },
225
- ...(kind === "telegram" ? [] : [{ cmd: `fastagent add ${kind} --json`, note: "a coding agent" }]),
226
- ],
252
+ flags: [JSON_FLAG],
253
+ examples: [{ cmd: `fastagent add ${kind}` }],
227
254
  ...(notes ? { notes } : {}),
228
- run: async (args, f) => (await import("./commands/add.js")).runAddChannel(kind, args[0], {
229
- ingress: f.ingress,
230
- environment: f.env,
231
- onboard: f.onboard !== false,
232
- replaceConfig: f.replaceConfig === true,
233
- input: f.input !== false,
234
- json: f.json === true,
235
- ...(f.check !== undefined ? { check: f.check } : {}),
236
- ...(f.timeout !== undefined ? { timeout: f.timeout } : {}),
237
- ...(f.ticket !== undefined ? { ticket: f.ticket } : {}),
238
- }),
255
+ run: async (args, f) => (await import("./commands/add.js")).runAddChannel(kind, args[0], { json: f.json === true }),
239
256
  });
240
- /**
241
- * How an app's setup runs with no one at a terminal: what the person provides is named, and their steps come back with
242
- * a ticket to check (`add` in docs/cli.md).
243
- */
244
- const UNATTENDED_SETUP = [
245
- { flags: "--json", description: "the outcome as one JSON object, with what to do next (agent_next_steps)" },
246
- { flags: "--check <ticket>", description: "where a setup started without a terminal stands" },
247
- { flags: "--timeout <seconds>", description: "how long that setup stays open (default 900)" },
248
- { flags: "--ticket <id>", description: "the process that runs a ticket's setup", hidden: true },
249
- NO_INPUT,
250
- ];
251
257
  const add = {
252
258
  name: "add",
253
259
  summary: "connect a channel (telegram, slack, feishu, lark) or vendor a skill",
254
260
  description: "Scaffold channels/<kind>.ts — first-party adapter glue with the policy to edit in the optional " +
255
261
  "route() — or vendor an Agent Skills skill into skills/<name>/.",
256
262
  subcommands: [
257
- channelSub("telegram", "scaffold the Telegram bot channel (durable turns, live preview)", "Scaffold src/channels/telegram.ts — the Telegram bot channel with durable turns, a live-preview " +
258
- "message pump, and an optional route() policy."),
259
- channelSub("slack", "scaffold the Slack Events API channel (files, threads, context, live preview)", "Scaffold src/channels/slack.ts plus its tools (src/tools/slack-send.ts, slack-threads.ts), create a single-workspace " +
260
- "internal Slack app from a manifest, and install it through OAuth. The channel provides signed " +
261
- "Events API ingress, durable turns, files, threads, context, and an edited live preview.", "Automated onboarding requires Slack App Configuration access + refresh tokens and a temporary " +
262
- "cloudflared tunnel. They stay in owner-readable local state and are never deployed; --no-onboard " +
263
- "keeps the explicit manual/scaffold-only path."),
264
- channelSub("feishu", "scaffold the Feishu channel AND create/configure the platform app", "Scaffold src/channels/feishu.ts and create/configure the Feishu app through scan-to-create, writing its " +
265
- "credentials to the selected environment. Dev uses WebSocket; deploy --run creates a separate production app for webhook.", "Feishu (open.feishu.cn) is the canonical implementation. WebSocket needs only App ID/Secret and " +
266
- "no public URL; webhook additionally captures the Verification Token through a temporary tunnel. " +
267
- "The app asks for the scopes that let the agent hear its group chats; any your tenant withholds are named."),
268
- channelSub("lark", "scaffold the Lark (international) channel with guided credential setup", "Scaffold src/channels/lark.ts and guide credential setup against the international developer console. " +
269
- "Dev uses WebSocket; deploy --run guides setup of a separate production app for webhook.", "Lark international (open.larksuite.com) is Feishu's compatibility profile. WebSocket stops after " +
270
- "App ID/Secret validation and a permission check; webhook setup probes config automation and falls " +
271
- "back to explicit manual steps on the international config-route 404."),
263
+ channelSub("telegram", "scaffold the Telegram bot channel (long polling or webhook, durable turns, live preview)", "Scaffold src/channels/telegram.ts — the Telegram bot channel with durable turns, a live-preview " +
264
+ "message pump, and an optional route() policy — and its send tool. Changes the program only: " +
265
+ "`fastagent channels setup telegram` sets up the bot and keeps its token."),
266
+ channelSub("slack", "scaffold the Slack channel (Socket Mode or Events API, files, threads, context, live preview)", "Scaffold src/channels/slack.ts plus its tools (src/tools/slack-send.ts, slack-threads.ts): durable turns, " +
267
+ "files, threads, context, and an edited live preview, received over Socket Mode or the Events API. Changes " +
268
+ "the program only: `fastagent channels setup slack` creates the app from a manifest link and keeps its tokens."),
269
+ channelSub("feishu", "scaffold the Feishu channel (long connection or webhook, durable turns, streaming card)", "Scaffold src/channels/feishu.ts plus its tools (src/tools/feishu-send.ts, feishu-threads.ts). Changes the " +
270
+ "program only: `fastagent channels setup feishu` creates the app by scan-to-create and keeps its credentials.", "Feishu (open.feishu.cn) is the canonical implementation. A long connection needs only App ID/Secret and " +
271
+ "no public URL; a webhook additionally needs the Verification Token, which setup captures through a " +
272
+ "temporary tunnel. The app asks for the scopes that let the agent hear its group chats; any your tenant " +
273
+ "withholds are named."),
274
+ channelSub("lark", "scaffold the Lark (international) channel", "Scaffold src/channels/lark.ts plus its tools (src/tools/lark-send.ts, lark-threads.ts). Changes the program " +
275
+ "only: `fastagent channels setup lark` guides the app's creation on Lark's launcher, checks the App ID " +
276
+ "and Secret, and keeps them.", "Lark international (open.larksuite.com) is Feishu's compatibility profile. A long connection stops after " +
277
+ "App ID/Secret validation and a permission check; a webhook tries to capture the Verification Token " +
278
+ "and asks for it when the international config API answers 404."),
272
279
  {
273
280
  name: "skill",
274
281
  summary: "vendor an Agent Skills skill into skills/<name>/ (copied in, git-tracked)",
@@ -312,24 +319,24 @@ const deploy = {
312
319
  flags: [
313
320
  {
314
321
  flags: "--run",
315
- description: "drive the target CLI to completion. Docker builds (pulling the base image) and runs `docker compose up -d`; with a tunnel " +
316
- "service, reads its URL and registers webhooks. Fly/Railway provision app/service + volume + " +
322
+ description: "drive the target CLI to completion. Docker builds (pulling the base image) and runs `docker compose up -d`. Fly/Railway provision app/service + volume + " +
317
323
  "secrets + deploy + webhook setup. AgentCore builds/pushes the arm64 image and deploys the " +
318
- "stack (aws + docker CLIs). A model key in the value file travels; any other credential is a login on " +
324
+ "stack (aws + docker CLIs). A model key is a value of the target (fastagent secrets); any other credential is a login on " +
319
325
  "the deployment itself, which --run starts once the box is up (fastagent login --deployment). " +
320
326
  "Stops at a gate (missing CLI/daemon/login/secret) with one actionable line. Without it: prints " +
321
327
  "the runbook",
322
328
  },
329
+ { flags: "--force", description: "overwrite existing target config/Dockerfile/.dockerignore (else kept)" },
323
330
  {
324
- flags: "--tunnel",
325
- description: "(docker only) add a Quick Tunnel service to generated Compose; generation-only unless combined " +
326
- "with --run. Existing Compose stays authoritative",
331
+ flags: "--config <file>",
332
+ description: "the instance configuration (a fastagent.json) the deployment runs with, carried in the image; without it, " +
333
+ "the program's defaults (the project's fastagent.json is the development instance's)",
327
334
  },
328
- { flags: "--force", description: "overwrite existing target config/Dockerfile/.dockerignore (else kept)" },
329
335
  {
330
336
  flags: "--into-linked",
331
- description: "(railway --run) provision INTO the project this dir is already linked to (skip create); by " +
332
- "default --run refuses a pre-existing link (could be unrelated/production)",
337
+ description: "(railway --run) provision INTO the project this dir is linked to even when it is not the agent's " +
338
+ "(it holds no service of this name and is not named for it); by default --run refuses that link " +
339
+ "(could be unrelated/production)",
333
340
  },
334
341
  {
335
342
  flags: "--json",
@@ -350,18 +357,17 @@ const deploy = {
350
357
  examples: [
351
358
  { cmd: "fastagent deploy fly --run", note: "provision + deploy + webhooks" },
352
359
  { cmd: "fastagent deploy fly --run --json", note: "a coding agent" },
353
- { cmd: "fastagent deploy docker --tunnel --run", note: "Compose + a public URL" },
360
+ { cmd: "fastagent deploy docker --run", note: "Compose on this machine" },
354
361
  { cmd: "fastagent deploy railway", note: "print the runbook only" },
355
362
  { cmd: "fastagent deploy agentcore --run", note: "arm64 image + stack + webhooks" },
356
363
  ],
357
- notes: "Definition-read-only: the only writes are generated artifacts (never clobbered without " +
358
- "--force). A plain redeploy of an already-provisioned agent is just the host's own command " +
359
- "(e.g. `railway up`).",
364
+ notes: "Definition-read-only: the only writes are generated artifacts (never clobbered without --force). A plain " +
365
+ "redeploy of an already-provisioned agent is just the host's own command (e.g. `railway up`).",
360
366
  run: async (args, f) => (await import("./commands/deploy.js")).runDeploy(args[0], args[1], {
361
367
  run: f.run === true,
362
- tunnel: f.tunnel === true,
363
368
  force: f.force === true,
364
369
  intoLinked: f.intoLinked === true,
370
+ ...(typeof f.config === "string" ? { config: f.config } : {}),
365
371
  input: f.input !== false,
366
372
  json: f.json === true,
367
373
  ...(f.check !== undefined ? { check: f.check } : {}),
@@ -435,49 +441,58 @@ const env = {
435
441
  const content = {
436
442
  name: "content",
437
443
  summary: "list, add or remove what the agent works on",
438
- description: "Content is a directory the agent works on: a GitHub repository declared " +
439
- "by name in context.json, shared with the agent and cloned at content/<name>, or a directory of this " +
440
- "machine bound in context.local.json, which never leaves it.",
444
+ description: "Content is a directory the agent works on: a GitHub repository, cloned at content/<name> in the instance's " +
445
+ "working directory, or a directory of this machine. The program's context.json declares repositories every " +
446
+ "instance reaches; an instance's fastagent.json adds its own, repositories and directories, and only adds: a " +
447
+ "name the program declares is not one it may take.",
441
448
  subcommands: [
442
449
  {
443
450
  name: "list",
444
451
  summary: "each content entry and where it is",
445
452
  args: [AGENT_ARG],
446
- flags: [JSON_FLAG],
453
+ flags: [JSON_FLAG, ...CONTENT_FLAGS],
447
454
  examples: [{ cmd: "fastagent content list" }],
448
- run: async (args, f) => (await import("./commands/content.js")).runContentList(args[0], f.json === true),
455
+ run: async (args, f) => (await import("./commands/content.js")).runContentList(args[0], f.json === true, instanceFlags(f)),
449
456
  },
450
457
  {
451
458
  name: "add",
452
- summary: "add a GitHub repository, or bind a directory of this machine, as content",
459
+ summary: "add a GitHub repository or a directory of this machine as content",
453
460
  args: [{ name: "<source>", description: "a directory, or github:owner/repo" }, AGENT_ARG],
454
461
  flags: [
455
462
  { flags: "--ref <ref>", description: "a repository: the branch, tag or commit to clone" },
456
463
  { flags: "--name <name>", description: "its name (default: the directory's or repository's)" },
457
464
  { flags: "--description <text>", description: "one sentence for the agent: what it is, how to treat it" },
465
+ {
466
+ flags: "--program",
467
+ description: "declare a repository in context.json, for every instance of the program, not in fastagent.json",
468
+ },
469
+ ...CONTENT_FLAGS,
458
470
  ],
459
471
  examples: [
460
- { cmd: "fastagent content add ~/code/app", note: "a directory of this machine" },
472
+ { cmd: "fastagent content add ~/code/app", note: "a directory" },
461
473
  { cmd: "fastagent content add github:acme/docs", note: "a clone" },
474
+ { cmd: "fastagent content add --program github:acme/docs", note: "for every instance" },
462
475
  ],
463
- notes: "The root of a GitHub checkout is declared in context.json as that repository, and bound in " +
464
- "context.local.json to the checkout, used as it is on this machine. github:owner/repo is cloned into " +
476
+ notes: "Without --program the entry is written to the instance's fastagent.json (the project's, or the file " +
477
+ "--config or FASTAGENT_CONFIG names); a deploy does not carry it yet. github:owner/repo is cloned into " +
465
478
  "content/<name> when the agent starts, and brought up to date in place at each start where git can do so " +
466
- "without touching the agent's work; so is a declared repository on any machine with no checkout bound. " +
467
- "Any other directory is bound in context.local.json only: a deployed instance works without it. A bound " +
468
- "directory may not contain the agent directory, nor sit inside it.",
479
+ "without touching the agent's work. A directory is used as it is, and may not contain the agent directory " +
480
+ "nor sit inside it.",
469
481
  run: async (args, f) => (await import("./commands/content.js")).runContentAdd(args[0], args[1], {
470
482
  ...(typeof f.ref === "string" ? { ref: f.ref } : {}),
471
483
  ...(typeof f.name === "string" ? { name: f.name } : {}),
472
484
  ...(typeof f.description === "string" ? { description: f.description } : {}),
485
+ ...(f.program === true ? { program: true } : {}),
486
+ instance: instanceFlags(f),
473
487
  }),
474
488
  },
475
489
  {
476
490
  name: "remove",
477
- summary: "remove a content entry from both files (a bound directory, and a clone, are left as they are)",
491
+ summary: "remove a content entry (a directory, and a clone, are left as they are)",
478
492
  args: [{ name: "<name>", description: "the entry's name" }, AGENT_ARG],
493
+ flags: [...CONTENT_FLAGS],
479
494
  examples: [{ cmd: "fastagent content remove app" }],
480
- run: async (args) => (await import("./commands/content.js")).runContentRemove(args[0], args[1]),
495
+ run: async (args, f) => (await import("./commands/content.js")).runContentRemove(args[0], args[1], instanceFlags(f)),
481
496
  },
482
497
  ],
483
498
  };
@@ -491,12 +506,11 @@ const schedules = {
491
506
  description: "List the schedules this definition declares (defineSchedule in src/schedules/<name>.ts): the next cron " +
492
507
  "instant, how the last run ended and the session its runs continue. The agent's own pending wake-ups are listed too, prefixed " +
493
508
  "`wake`: a different owner (the STATE, not the definition), cancelled by the agent's `unwake` tool or " +
494
- "`schedules unwake`. --json adds each schedule's retained fire history. It changes no state; like every " +
495
- "command that reads the definition, it regenerates .fastagent/.",
509
+ "`schedules unwake`. --json adds each schedule's retained fire history. It changes no state.",
496
510
  args: [AGENT_ARG],
497
- flags: [JSON_FLAG],
511
+ flags: [JSON_FLAG, ...INSTANCE_FLAGS],
498
512
  examples: [{ cmd: "fastagent schedules list" }],
499
- run: async (args, flags) => (await import("./commands/schedules.js")).runSchedulesList(args[0], flags.json === true),
513
+ run: async (args, flags) => (await import("./commands/schedules.js")).runSchedulesList(args[0], flags.json === true, instanceFlags(flags)),
500
514
  },
501
515
  {
502
516
  name: "run",
@@ -514,11 +528,15 @@ const schedules = {
514
528
  "it took after that",
515
529
  },
516
530
  NO_INPUT,
531
+ ...INSTANCE_FLAGS,
532
+ CONFIG_FLAG,
533
+ ENV_FILE_FLAG,
517
534
  ],
518
535
  examples: [{ cmd: "fastagent schedules run daily-digest" }],
519
536
  run: async (args, f) => (await import("./commands/schedules.js")).runScheduleNow(args[0], args[1], {
520
537
  model: f.model,
521
538
  input: f.input !== false,
539
+ instance: instanceFlags(f),
522
540
  }),
523
541
  },
524
542
  {
@@ -528,8 +546,156 @@ const schedules = {
528
546
  "one set where nobody can message the agent, such as a schedule's own session. It is refused while `dev` " +
529
547
  "or `start` serves this agent, since a serve's clock writes the same store.",
530
548
  args: [{ name: "<id>", description: "the wake-up's id" }, AGENT_ARG],
549
+ flags: [...INSTANCE_FLAGS],
531
550
  examples: [{ cmd: "fastagent schedules unwake 3f1c…" }],
532
- run: async (args) => (await import("./commands/schedules.js")).runUnwake(args[0], args[1]),
551
+ run: async (args, f) => (await import("./commands/schedules.js")).runUnwake(args[0], args[1], instanceFlags(f)),
552
+ },
553
+ ],
554
+ };
555
+ /**
556
+ * How an app's setup runs with no one at a terminal: what the person provides is named, and their steps come back with
557
+ * a ticket to check (`channels setup` in docs/cli.md).
558
+ */
559
+ const UNATTENDED_SETUP = [
560
+ { flags: "--json", description: "the outcome as one JSON object, with what to do next (agent_next_steps)" },
561
+ { flags: "--check <ticket>", description: "where a setup started without a terminal stands" },
562
+ { flags: "--timeout <seconds>", description: "how long that setup stays open (default 900)" },
563
+ { flags: "--ticket <id>", description: "the process that runs a ticket's setup", hidden: true },
564
+ NO_INPUT,
565
+ ];
566
+ const channels = {
567
+ name: "channels",
568
+ summary: "a channel's platform app, for one instance",
569
+ subcommands: [
570
+ {
571
+ name: "setup",
572
+ summary: "set up a channel's platform app for one instance, and keep its credentials",
573
+ description: "Guide a person through creating the platform app (a Slack app from a manifest link, a Telegram bot from " +
574
+ "BotFather, a Feishu app by scan-to-create, a Lark app on its launcher), ask for the values only they can " +
575
+ "read off its pages, check each with the platform, and keep them in the instance's value file. Safe to run again: a value already there that the platform still accepts is " +
576
+ "kept. How the channel receives (webhook or connection) decides which values it needs: --ingress, else what " +
577
+ "the configuration says, else connection for the development instance and webhook for any other. With no " +
578
+ "terminal (--json), the values are pasted on a page on this machine for the person a coding agent hands the " +
579
+ "step to, never in its conversation. With --record-url: read the deployment's /health, and once <name> (slack, " +
580
+ "or lark where its config API answers 404) is registered there, the platform having reached it at the URL a " +
581
+ "person saved on its app's page, write that URL into the binding (channels.<name>.app.url) of the " +
582
+ "configuration --config names, so every later deploy of it reports it registered from the start.",
583
+ args: [{ name: "<name>", description: "the channel: telegram, slack, feishu or lark" }, AGENT_ARG],
584
+ flags: [
585
+ {
586
+ flags: "--ingress <mode>",
587
+ description: "webhook or connection: set the app up for it, and write it to the configuration",
588
+ },
589
+ {
590
+ flags: "--config <file>",
591
+ description: "the instance configuration: how the channel receives is read from it, and --ingress written to it " +
592
+ "(default: the project's fastagent.json, the development instance's)",
593
+ },
594
+ {
595
+ flags: "--env-file <file>",
596
+ description: "the value file the credentials are kept in, which must exist; naming it or --config makes this " +
597
+ "another instance than the development one (default: .secrets/.env for dev, else " +
598
+ ".secrets/production/.env, created when missing)",
599
+ },
600
+ {
601
+ flags: "--record-url",
602
+ description: "record the URL the deployment confirms, in the configuration --config names",
603
+ },
604
+ {
605
+ flags: "--url <url>",
606
+ description: "with --record-url: where to read its /health (default: the configuration's http.publicUrl)",
607
+ },
608
+ ...UNATTENDED_SETUP,
609
+ ],
610
+ examples: [
611
+ { cmd: "fastagent channels setup telegram" },
612
+ { cmd: "fastagent channels setup slack --json", note: "an agent" },
613
+ { cmd: "fastagent channels setup slack --config prod.json", note: "a deployment" },
614
+ { cmd: "fastagent channels setup slack --record-url --config c.json" },
615
+ ],
616
+ run: async (args, f) => (await import("./commands/channels.js")).runChannelsSetup(args[0], args[1], {
617
+ recordUrl: f.recordUrl === true,
618
+ ...(typeof f.ingress === "string" ? { ingress: f.ingress } : {}),
619
+ ...(typeof f.config === "string" ? { config: f.config } : {}),
620
+ ...(typeof f.envFile === "string" ? { envFile: f.envFile } : {}),
621
+ ...(typeof f.url === "string" ? { url: f.url } : {}),
622
+ json: f.json === true,
623
+ input: f.input !== false,
624
+ ...(f.check !== undefined ? { check: f.check } : {}),
625
+ ...(f.timeout !== undefined ? { timeout: f.timeout } : {}),
626
+ ...(f.ticket !== undefined ? { ticket: f.ticket } : {}),
627
+ }),
628
+ },
629
+ ],
630
+ };
631
+ const SECRETS_HOST = {
632
+ name: "<host>",
633
+ description: "the target that keeps the values",
634
+ choices: ["docker", "fly", "railway", "agentcore"],
635
+ };
636
+ const secrets = {
637
+ name: "secrets",
638
+ summary: "a deployment's values, on the target that keeps them",
639
+ subcommands: [
640
+ {
641
+ name: "list",
642
+ summary: "the names the definition declares, and which the target holds",
643
+ description: "Print every name the deployment declares (the model's key, `needs()`, `context.json`'s variables, MCP " +
644
+ "references, for the channels its configuration chooses) with whether the target holds a value for it. A value " +
645
+ "is never read back.",
646
+ args: [SECRETS_HOST, AGENT_ARG],
647
+ flags: [
648
+ { flags: "--config <file>", description: "the configuration the deployment delivers (`deploy --config`)" },
649
+ JSON_FLAG,
650
+ ],
651
+ examples: [{ cmd: "fastagent secrets list fly" }],
652
+ run: async (args, f) => (await import("./commands/secrets.js")).runSecrets("list", args[0], undefined, args[1], {
653
+ ...(typeof f.config === "string" ? { config: f.config } : {}),
654
+ json: f.json === true,
655
+ }),
656
+ },
657
+ {
658
+ name: "set",
659
+ summary: "set one value: typed without echo, from standard input, or generated",
660
+ description: "Set one value on the target, creating the app or service when it does not exist. The value is typed without " +
661
+ "echo at a terminal, else read from standard input; it is never an argument. --generate sets a random value " +
662
+ "and prints it once, for what FastAgent makes itself (FASTAGENT_API_KEY).",
663
+ args: [SECRETS_HOST, { name: "<name>", description: "the environment variable" }, AGENT_ARG],
664
+ flags: [
665
+ { flags: "--config <file>", description: "the configuration the deployment delivers (`deploy --config`)" },
666
+ { flags: "--generate", description: "a random value, printed once" },
667
+ ],
668
+ examples: [
669
+ { cmd: "fastagent secrets set fly OPENAI_API_KEY" },
670
+ { cmd: "fastagent secrets set fly FASTAGENT_API_KEY --generate" },
671
+ ],
672
+ run: async (args, f) => (await import("./commands/secrets.js")).runSecrets("set", args[0], args[1], args[2], {
673
+ ...(typeof f.config === "string" ? { config: f.config } : {}),
674
+ generate: f.generate === true,
675
+ }),
676
+ },
677
+ {
678
+ name: "push",
679
+ summary: "set every declared value a value file or the environment holds",
680
+ description: "Set, in one batch, every declared name the source holds a value for, creating the app or service when it does " +
681
+ "not exist. The source is --env-file, else --from-env (the environment of a command that injected the values: " +
682
+ "`op run`, `doppler run`, `infisical run`, `dotenvx run`, a CI job), else the production value file " +
683
+ "(.secrets/production/.env). Names the definition does not declare are not pushed.",
684
+ args: [SECRETS_HOST, AGENT_ARG],
685
+ flags: [
686
+ { flags: "--config <file>", description: "the configuration the deployment delivers (`deploy --config`)" },
687
+ { flags: "--env-file <file>", description: "the value file to push from, which must exist" },
688
+ { flags: "--from-env", description: "push from this command's environment" },
689
+ ],
690
+ examples: [
691
+ { cmd: "fastagent secrets push fly" },
692
+ { cmd: "doppler run -- fastagent secrets push fly --from-env", note: "a secret manager" },
693
+ ],
694
+ run: async (args, f) => (await import("./commands/secrets.js")).runSecrets("push", args[0], undefined, args[1], {
695
+ ...(typeof f.config === "string" ? { config: f.config } : {}),
696
+ ...(typeof f.envFile === "string" ? { envFile: f.envFile } : {}),
697
+ fromEnv: f.fromEnv === true,
698
+ }),
533
699
  },
534
700
  ],
535
701
  };
@@ -537,7 +703,7 @@ const destroy = {
537
703
  name: "destroy",
538
704
  summary: "delete every AWS resource `deploy agentcore` created for an agent",
539
705
  description: "AgentCore only, and it exists because `aws cloudformation delete-stack` is not enough: the S3 " +
540
- "artifact bucket and the ECR repository have to exist BEFORE the stack that reads from them, BOTH " +
706
+ "artifact bucket, the ECR repository and the values secret have to exist BEFORE the stack that reads from them, BOTH " +
541
707
  "log groups (the forwarder's and the runtime's own stdout) are created by AWS on first write so no " +
542
708
  "template mentions them, and the EventBridge schedules (one per schedule, one per pending wake-up) " +
543
709
  "are minted at runtime by the container — left behind, they keep firing into a deleted Lambda. " +
@@ -710,7 +876,7 @@ const mcp = {
710
876
  {
711
877
  name: "list",
712
878
  summary: "inspect declarations and local auth",
713
- description: "Read .mcp.json and local grant metadata without contacting servers.",
879
+ description: "Read the declared MCP servers and local grant metadata without contacting servers.",
714
880
  examples: [{ cmd: "fastagent mcp list --json" }],
715
881
  args: [AGENT_ARG],
716
882
  flags: [CHANNEL_ENVIRONMENT, JSON_FLAG],
@@ -727,7 +893,10 @@ const mcp = {
727
893
  { cmd: "fastagent mcp login linear --scopes read --json" },
728
894
  { cmd: "fastagent mcp login --check <ticket> --json" },
729
895
  ],
730
- args: [{ name: "[server]", description: "the server name in .mcp.json" }, AGENT_ARG],
896
+ args: [
897
+ { name: "[server]", description: "the name of an MCP server the program or the instance declares" },
898
+ AGENT_ARG,
899
+ ],
731
900
  flags: [
732
901
  CHANNEL_ENVIRONMENT,
733
902
  ...UNATTENDED_SETUP,
@@ -770,6 +939,7 @@ export const specs = [
770
939
  models,
771
940
  mcp,
772
941
  info,
942
+ build,
773
943
  content,
774
944
  env,
775
945
  invoke,
@@ -777,6 +947,8 @@ export const specs = [
777
947
  dev,
778
948
  start,
779
949
  add,
950
+ channels,
951
+ secrets,
780
952
  deploy,
781
953
  logs,
782
954
  destroy,