@fastagent-sh/fastagent 0.24.4 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -82
- package/dist/agent-api.d.ts +452 -0
- package/dist/agent-api.js +201 -0
- package/dist/answer-text.d.ts +8 -0
- package/dist/answer-text.js +18 -0
- package/dist/atomic-write.d.ts +2 -2
- package/dist/atomic-write.js +2 -2
- package/dist/authoring.d.ts +77 -0
- package/dist/authoring.js +238 -0
- package/dist/channel.d.ts +29 -15
- package/dist/channel.js +4 -1
- package/dist/channels/agentcore-protocol.d.ts +36 -50
- package/dist/channels/agentcore-protocol.js +3 -3
- package/dist/channels/agentcore-service.d.ts +8 -18
- package/dist/channels/agentcore-service.js +108 -127
- package/dist/channels/agentcore.d.ts +8 -24
- package/dist/channels/agentcore.js +32 -65
- package/dist/channels/body.d.ts +0 -16
- package/dist/channels/body.js +0 -25
- package/dist/channels/busy.js +6 -1
- package/dist/channels/context.d.ts +4 -0
- package/dist/channels/context.js +35 -0
- package/dist/channels/discover.d.ts +18 -20
- package/dist/channels/discover.js +41 -99
- package/dist/channels/feishu/feishu-api.d.ts +54 -4
- package/dist/channels/feishu/feishu-api.js +192 -149
- package/dist/channels/feishu/feishu.d.ts +3 -0
- package/dist/channels/feishu/feishu.js +117 -106
- package/dist/channels/feishu/history.d.ts +55 -0
- package/dist/channels/feishu/history.js +199 -0
- package/dist/channels/feishu/invoke-turn.d.ts +13 -11
- package/dist/channels/feishu/invoke-turn.js +9 -10
- package/dist/channels/feishu/model.d.ts +2 -1
- package/dist/channels/feishu/normalize.js +100 -0
- package/dist/channels/feishu/preview.d.ts +2 -2
- package/dist/channels/feishu/register-webhook.d.ts +1 -0
- package/dist/channels/feishu/register-webhook.js +3 -2
- package/dist/channels/feishu/scaffold/channel.ts +65 -46
- package/dist/channels/feishu/scaffold/feishu-send.ts +38 -33
- package/dist/channels/feishu/scaffold/feishu-threads.ts +25 -0
- package/dist/channels/feishu/setup-mode.d.ts +45 -25
- package/dist/channels/feishu/setup-mode.js +74 -23
- package/dist/channels/feishu/shared-api.d.ts +24 -6
- package/dist/channels/feishu/shared-api.js +30 -24
- package/dist/channels/kit/context-buffer.d.ts +11 -2
- package/dist/channels/kit/context-buffer.js +7 -4
- package/dist/channels/kit/delivery.d.ts +19 -3
- package/dist/channels/kit/delivery.js +74 -15
- package/dist/channels/kit/event-stream.js +2 -1
- package/dist/channels/kit/invoke-turn-kit.d.ts +41 -41
- package/dist/channels/kit/invoke-turn-kit.js +62 -71
- package/dist/channels/kit/place-history.d.ts +107 -0
- package/dist/channels/kit/place-history.js +182 -0
- package/dist/channels/kit/preview-kit.d.ts +9 -5
- package/dist/channels/kit/preview-kit.js +36 -15
- package/dist/channels/kit/room-threads.d.ts +46 -0
- package/dist/channels/kit/room-threads.js +81 -0
- package/dist/channels/kit/seen.js +1 -1
- package/dist/channels/kit/stop-command.d.ts +6 -3
- package/dist/channels/kit/stop-command.js +20 -18
- package/dist/channels/kit/thread-fork.d.ts +17 -0
- package/dist/channels/kit/thread-fork.js +43 -0
- package/dist/channels/kit/thread-participants.js +1 -1
- package/dist/channels/kit/transport.d.ts +5 -0
- package/dist/channels/kit/transport.js +5 -0
- package/dist/channels/kit/turn-runner.d.ts +10 -9
- package/dist/channels/kit/turn-runner.js +17 -19
- package/dist/channels/kit/turn-store.d.ts +5 -4
- package/dist/channels/kit/turn-store.js +5 -5
- package/dist/channels/lark/lark.d.ts +3 -0
- package/dist/channels/lark/lark.js +5 -0
- package/dist/channels/lark/onboard.d.ts +5 -3
- package/dist/channels/lark/onboard.js +14 -14
- package/dist/channels/lark/scaffold/channel.ts +67 -44
- package/dist/channels/lark/scaffold/lark-send.ts +38 -33
- package/dist/channels/lark/scaffold/lark-threads.ts +25 -0
- package/dist/channels/respond.d.ts +0 -4
- package/dist/channels/respond.js +1 -1
- package/dist/channels/router.d.ts +18 -0
- package/dist/channels/router.js +68 -0
- package/dist/channels/serve.d.ts +5 -70
- package/dist/channels/serve.js +105 -287
- package/dist/channels/slack/history.d.ts +42 -0
- package/dist/channels/slack/history.js +282 -0
- package/dist/channels/slack/invoke-turn.d.ts +12 -5
- package/dist/channels/slack/invoke-turn.js +7 -5
- package/dist/channels/slack/manifest.d.ts +1 -4
- package/dist/channels/slack/manifest.js +22 -10
- package/dist/channels/slack/model.d.ts +2 -1
- package/dist/channels/slack/onboard.d.ts +0 -2
- package/dist/channels/slack/onboard.js +2 -4
- package/dist/channels/slack/onboarding-state.d.ts +0 -2
- package/dist/channels/slack/onboarding-state.js +0 -1
- package/dist/channels/slack/parse.d.ts +0 -5
- package/dist/channels/slack/parse.js +1 -16
- package/dist/channels/slack/preview.d.ts +2 -3
- package/dist/channels/slack/preview.js +78 -52
- package/dist/channels/slack/register-webhook.d.ts +1 -0
- package/dist/channels/slack/register-webhook.js +6 -5
- package/dist/channels/slack/scaffold/channel.ts +23 -24
- package/dist/channels/slack/scaffold/slack-send.ts +50 -43
- package/dist/channels/slack/scaffold/slack-threads.ts +29 -0
- package/dist/channels/slack/setup-server.d.ts +19 -0
- package/dist/channels/slack/setup-server.js +113 -11
- package/dist/channels/slack/shared-api.d.ts +15 -4
- package/dist/channels/slack/shared-api.js +19 -14
- package/dist/channels/slack/slack-api.d.ts +61 -2
- package/dist/channels/slack/slack-api.js +28 -5
- package/dist/channels/slack/slack.js +97 -52
- package/dist/channels/slack/welcomed.js +1 -1
- package/dist/channels/telegram/context-buffer.d.ts +6 -1
- package/dist/channels/telegram/context-buffer.js +19 -0
- package/dist/channels/telegram/invoke-turn.d.ts +8 -4
- package/dist/channels/telegram/invoke-turn.js +7 -7
- package/dist/channels/telegram/parse.d.ts +7 -2
- package/dist/channels/telegram/parse.js +7 -0
- package/dist/channels/telegram/preview.d.ts +2 -2
- package/dist/channels/telegram/register-webhook.d.ts +1 -0
- package/dist/channels/telegram/register-webhook.js +3 -2
- package/dist/channels/telegram/scaffold/channel.ts +27 -28
- package/dist/channels/telegram/scaffold/telegram-send.ts +61 -108
- package/dist/channels/telegram/shared-api.d.ts +34 -0
- package/dist/channels/telegram/shared-api.js +79 -0
- package/dist/channels/telegram/telegram-api.d.ts +15 -5
- package/dist/channels/telegram/telegram-api.js +10 -6
- package/dist/channels/telegram/telegram.js +27 -21
- package/dist/channels/telegram/turn-store.js +1 -1
- package/dist/channels/{kit/turn-queue.d.ts → turn-queue.d.ts} +2 -2
- package/dist/channels/{kit/turn-queue.js → turn-queue.js} +10 -10
- package/dist/cli/add-feishu.d.ts +42 -12
- package/dist/cli/add-feishu.js +177 -124
- package/dist/cli/add-slack.d.ts +8 -3
- package/dist/cli/add-slack.js +115 -63
- package/dist/cli/auth-view.d.ts +10 -3
- package/dist/cli/auth-view.js +8 -6
- package/dist/cli/box-login.d.ts +17 -7
- package/dist/cli/box-login.js +46 -12
- package/dist/cli/commands/add.d.ts +15 -4
- package/dist/cli/commands/add.js +252 -143
- package/dist/cli/commands/auth.d.ts +6 -0
- package/dist/cli/commands/auth.js +50 -0
- package/dist/cli/commands/content.d.ts +6 -0
- package/dist/cli/commands/content.js +45 -0
- package/dist/cli/commands/deploy/agentcore.js +50 -77
- package/dist/cli/commands/deploy/docker.js +38 -39
- package/dist/cli/commands/deploy/fly.js +21 -18
- package/dist/cli/commands/deploy/host-login.d.ts +26 -0
- package/dist/cli/commands/deploy/host-login.js +90 -0
- package/dist/cli/commands/deploy/railway.js +21 -26
- package/dist/cli/commands/deploy/shared.d.ts +45 -17
- package/dist/cli/commands/deploy/shared.js +34 -15
- package/dist/cli/commands/deploy.d.ts +0 -4
- package/dist/cli/commands/deploy.js +237 -50
- package/dist/cli/commands/destroy.js +8 -6
- package/dist/cli/commands/dev.d.ts +0 -2
- package/dist/cli/commands/dev.js +20 -19
- package/dist/cli/commands/env.d.ts +12 -0
- package/dist/cli/commands/env.js +190 -0
- package/dist/cli/commands/info.js +95 -156
- package/dist/cli/commands/init.d.ts +2 -2
- package/dist/cli/commands/init.js +35 -33
- package/dist/cli/commands/invoke.d.ts +6 -0
- package/dist/cli/commands/invoke.js +131 -16
- package/dist/cli/commands/login.d.ts +31 -2
- package/dist/cli/commands/login.js +413 -64
- package/dist/cli/commands/logout.d.ts +4 -0
- package/dist/cli/commands/logout.js +53 -0
- package/dist/cli/commands/logs.js +8 -6
- package/dist/cli/commands/models.d.ts +2 -1
- package/dist/cli/commands/models.js +39 -37
- package/dist/cli/commands/schedules.d.ts +21 -0
- package/dist/cli/commands/schedules.js +143 -0
- package/dist/cli/commands/start.d.ts +11 -10
- package/dist/cli/commands/start.js +35 -62
- package/dist/cli/content-view.d.ts +9 -0
- package/dist/cli/content-view.js +26 -0
- package/dist/cli/fail.d.ts +9 -12
- package/dist/cli/fail.js +17 -14
- package/dist/cli/invoke-stream.d.ts +12 -3
- package/dist/cli/invoke-stream.js +85 -23
- package/dist/cli/kernel.d.ts +9 -2
- package/dist/cli/kernel.js +15 -6
- package/dist/cli/login-relay.d.ts +3 -2
- package/dist/cli/login-relay.js +18 -6
- package/dist/cli/models-view.d.ts +5 -1
- package/dist/cli/models-view.js +1 -1
- package/dist/cli/person.d.ts +10 -0
- package/dist/cli/person.js +23 -0
- package/dist/cli/program.js +421 -203
- package/dist/cli/serve.d.ts +13 -63
- package/dist/cli/serve.js +31 -121
- package/dist/cli/shared.d.ts +21 -48
- package/dist/cli/shared.js +68 -89
- package/dist/cli/ticket.d.ts +136 -0
- package/dist/cli/ticket.js +476 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +2 -0
- package/dist/content/declare.d.ts +70 -0
- package/dist/content/declare.js +163 -0
- package/dist/content/file.d.ts +32 -0
- package/dist/content/file.js +119 -0
- package/dist/content/git.d.ts +41 -0
- package/dist/content/git.js +217 -0
- package/dist/content/mount.d.ts +2 -0
- package/dist/content/mount.js +15 -0
- package/dist/content/resolve.d.ts +52 -0
- package/dist/content/resolve.js +151 -0
- package/dist/content/source.d.ts +27 -0
- package/dist/content/source.js +53 -0
- package/dist/conversation-sessions.d.ts +26 -0
- package/dist/conversation-sessions.js +99 -0
- package/dist/declared-secrets.d.ts +19 -37
- package/dist/declared-secrets.js +16 -58
- package/dist/deploy/agentcore/destroy.d.ts +3 -3
- package/dist/deploy/agentcore/destroy.js +46 -28
- package/dist/deploy/agentcore/forwarder.js +105 -22
- package/dist/deploy/agentcore/logs.js +1 -1
- package/dist/deploy/agentcore/plan.d.ts +10 -24
- package/dist/deploy/agentcore/plan.js +31 -135
- package/dist/deploy/agentcore/run.d.ts +1 -1
- package/dist/deploy/agentcore/run.js +8 -5
- package/dist/deploy/agentcore/shell.d.ts +1 -1
- package/dist/deploy/agentcore/shell.js +5 -5
- package/dist/deploy/api.d.ts +34 -0
- package/dist/deploy/api.js +50 -0
- package/dist/deploy/box-shell.d.ts +6 -0
- package/dist/deploy/box-shell.js +7 -0
- package/dist/deploy/build-context.d.ts +7 -5
- package/dist/deploy/build-context.js +41 -35
- package/dist/deploy/channel-ingress.d.ts +6 -1
- package/dist/deploy/channel-ingress.js +18 -5
- package/dist/deploy/container.d.ts +22 -9
- package/dist/deploy/container.js +96 -55
- package/dist/deploy/docker/plan.d.ts +3 -2
- package/dist/deploy/docker/plan.js +13 -14
- package/dist/deploy/docker/run.d.ts +2 -2
- package/dist/deploy/docker/run.js +8 -4
- package/dist/deploy/fly/plan.d.ts +1 -1
- package/dist/deploy/fly/plan.js +12 -21
- package/dist/deploy/fly/run.d.ts +10 -6
- package/dist/deploy/fly/run.js +11 -6
- package/dist/deploy/hosts.d.ts +2 -1
- package/dist/deploy/hosts.js +2 -1
- package/dist/deploy/preflight.d.ts +21 -23
- package/dist/deploy/preflight.js +222 -201
- package/dist/deploy/railway/plan.d.ts +8 -6
- package/dist/deploy/railway/plan.js +15 -58
- package/dist/deploy/railway/run.d.ts +8 -3
- package/dist/deploy/railway/run.js +12 -8
- package/dist/deploy/residency.d.ts +5 -11
- package/dist/deploy/residency.js +0 -6
- package/dist/deploy/runner.d.ts +1 -1
- package/dist/deploy/runner.js +1 -1
- package/dist/deploy/secrets.d.ts +16 -2
- package/dist/deploy/secrets.js +33 -6
- package/dist/deploy/workspace.d.ts +11 -6
- package/dist/deploy/workspace.js +55 -38
- package/dist/dev-supervisor.d.ts +11 -2
- package/dist/dev-supervisor.js +51 -26
- package/dist/effect-port.d.ts +4 -4
- package/dist/effect-port.js +4 -4
- package/dist/environment/apt.d.ts +4 -0
- package/dist/environment/apt.js +32 -0
- package/dist/environment/declare.d.ts +59 -0
- package/dist/environment/declare.js +210 -0
- package/dist/environment/mise.d.ts +50 -0
- package/dist/environment/mise.js +268 -0
- package/dist/feishu.d.ts +2 -2
- package/dist/feishu.js +2 -2
- package/dist/git.d.ts +13 -0
- package/dist/git.js +55 -0
- package/dist/harnesses/models/catalog.d.ts +20 -0
- package/dist/harnesses/models/catalog.js +254 -0
- package/dist/{engines/pi/auth.d.ts → harnesses/models/credentials.d.ts} +3 -3
- package/dist/{engines/pi/auth.js → harnesses/models/credentials.js} +3 -3
- package/dist/harnesses/models/environment.d.ts +43 -0
- package/dist/harnesses/models/environment.js +82 -0
- package/dist/{engines/pi → harnesses/models}/login.d.ts +57 -26
- package/dist/{engines/pi → harnesses/models}/login.js +187 -79
- package/dist/harnesses/models/models.d.ts +83 -0
- package/dist/harnesses/models/models.js +158 -0
- package/dist/harnesses/pi-durable/agent.d.ts +42 -0
- package/dist/harnesses/pi-durable/agent.js +579 -0
- package/dist/harnesses/pi-durable/defaults.d.ts +28 -0
- package/dist/harnesses/pi-durable/defaults.js +26 -0
- package/dist/harnesses/pi-durable/define.d.ts +77 -0
- package/dist/harnesses/pi-durable/define.js +28 -0
- package/dist/harnesses/pi-durable/entries.d.ts +32 -0
- package/dist/harnesses/pi-durable/entries.js +126 -0
- package/dist/harnesses/pi-durable/events.d.ts +25 -0
- package/dist/harnesses/pi-durable/events.js +238 -0
- package/dist/harnesses/pi-durable/ids.d.ts +16 -0
- package/dist/harnesses/pi-durable/ids.js +55 -0
- package/dist/harnesses/pi-durable/messages.d.ts +41 -0
- package/dist/harnesses/pi-durable/messages.js +116 -0
- package/dist/harnesses/pi-durable/open.d.ts +88 -0
- package/dist/harnesses/pi-durable/open.js +329 -0
- package/dist/harnesses/pi-durable/reads.d.ts +30 -0
- package/dist/harnesses/pi-durable/reads.js +94 -0
- package/dist/harnesses/pi-durable/registry.d.ts +18 -0
- package/dist/harnesses/pi-durable/registry.js +56 -0
- package/dist/harnesses/pi-durable/release.d.ts +13 -0
- package/dist/harnesses/pi-durable/release.js +40 -0
- package/dist/harnesses/pi-durable/serve.d.ts +80 -0
- package/dist/harnesses/pi-durable/serve.js +156 -0
- package/dist/harnesses/pi-durable/sessions.d.ts +27 -0
- package/dist/harnesses/pi-durable/sessions.js +47 -0
- package/dist/harnesses/pi-durable/storage.d.ts +4 -0
- package/dist/harnesses/pi-durable/storage.js +49 -0
- package/dist/harnesses/pi-durable/stream.d.ts +20 -0
- package/dist/harnesses/pi-durable/stream.js +221 -0
- package/dist/harnesses/pi-durable/text.d.ts +30 -0
- package/dist/harnesses/pi-durable/text.js +292 -0
- package/dist/harnesses/pi-durable/wake.d.ts +4 -0
- package/dist/harnesses/pi-durable/wake.js +81 -0
- package/dist/http/client.d.ts +6 -0
- package/dist/http/client.js +256 -0
- package/dist/http/contract.d.ts +541 -0
- package/dist/http/contract.js +179 -0
- package/dist/http/server.d.ts +34 -0
- package/dist/http/server.js +194 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +10 -5
- package/dist/lark.d.ts +2 -2
- package/dist/lark.js +2 -2
- package/dist/locked-file.d.ts +17 -0
- package/dist/{engines/pi/locked-file.js → locked-file.js} +16 -10
- package/dist/once.d.ts +6 -0
- package/dist/once.js +23 -0
- package/dist/paths.d.ts +36 -52
- package/dist/paths.js +66 -182
- package/dist/runtime.d.ts +25 -2
- package/dist/runtime.js +27 -0
- package/dist/scaffold/add-channel.d.ts +14 -27
- package/dist/scaffold/add-channel.js +82 -180
- package/dist/scaffold/init.d.ts +17 -18
- package/dist/scaffold/init.js +87 -99
- package/dist/scaffold/templates/SYSTEM.md +12 -0
- package/dist/scaffold/templates/env.example +4 -10
- package/dist/scaffold/templates/fastagent.config.ts +21 -33
- package/dist/scaffold/templates/gitignore +8 -1
- package/dist/scaffold/templates/skills/writing-great-skills/SKILL.md +1 -2
- package/dist/scaffold/templates.d.ts +9 -4
- package/dist/scaffold/templates.js +7 -5
- package/dist/scaffold/vendor-skill.d.ts +1 -4
- package/dist/scaffold/vendor-skill.js +5 -6
- package/dist/schedule/cron.d.ts +13 -0
- package/dist/schedule/cron.js +52 -0
- package/dist/schedule/eventbridge-cron.d.ts +17 -0
- package/dist/schedule/eventbridge-cron.js +88 -0
- package/dist/schedule/schedule.d.ts +23 -0
- package/dist/schedule/schedule.js +34 -0
- package/dist/schedule/scheduler.d.ts +34 -33
- package/dist/schedule/scheduler.js +251 -137
- package/dist/schedule/state.d.ts +4 -14
- package/dist/schedule/state.js +7 -7
- package/dist/schedule/wake-alarm.d.ts +22 -2
- package/dist/schedule/wake-alarm.js +66 -20
- package/dist/schedule/wakeups.d.ts +16 -15
- package/dist/schedule/wakeups.js +47 -45
- package/dist/service.d.ts +56 -169
- package/dist/service.js +91 -187
- package/dist/serving-command.d.ts +10 -0
- package/dist/serving-command.js +16 -0
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js +1 -1
- package/dist/{channels/kit/state.js → state-file.js} +6 -6
- package/dist/telegram.d.ts +1 -0
- package/dist/telegram.js +1 -0
- package/dist/tunnel.d.ts +3 -0
- package/dist/tunnel.js +12 -4
- package/dist/value-file.d.ts +21 -0
- package/dist/value-file.js +108 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +14 -1
- package/package.json +18 -28
- package/dist/agent.d.ts +0 -106
- package/dist/agent.js +0 -21
- package/dist/channels/control.d.ts +0 -31
- package/dist/channels/control.js +0 -329
- package/dist/channels/define-channel.d.ts +0 -39
- package/dist/channels/define-channel.js +0 -9
- package/dist/channels/feishu/context-buffer.d.ts +0 -35
- package/dist/channels/feishu/context-buffer.js +0 -65
- package/dist/channels/feishu/scaffold/channel.websocket.ts +0 -31
- package/dist/channels/http.d.ts +0 -23
- package/dist/channels/http.js +0 -57
- package/dist/channels/lark/scaffold/channel.websocket.ts +0 -31
- package/dist/channels/slack/context-buffer.d.ts +0 -23
- package/dist/channels/slack/context-buffer.js +0 -37
- package/dist/channels/sse.d.ts +0 -4
- package/dist/channels/sse.js +0 -66
- package/dist/cli/commands/chat.d.ts +0 -3
- package/dist/cli/commands/chat.js +0 -14
- package/dist/cli/commands/routine-run.d.ts +0 -6
- package/dist/cli/commands/routine-run.js +0 -46
- package/dist/cli/commands/routine.d.ts +0 -25
- package/dist/cli/commands/routine.js +0 -122
- package/dist/cli/commands/tool.d.ts +0 -1
- package/dist/cli/commands/tool.js +0 -57
- package/dist/collect.d.ts +0 -63
- package/dist/collect.js +0 -90
- package/dist/core.d.ts +0 -13
- package/dist/core.js +0 -15
- package/dist/engines/pi/agent-models.d.ts +0 -83
- package/dist/engines/pi/agent-models.js +0 -120
- package/dist/engines/pi/agent-session-factory.d.ts +0 -121
- package/dist/engines/pi/agent-session-factory.js +0 -535
- package/dist/engines/pi/chat.d.ts +0 -3
- package/dist/engines/pi/chat.js +0 -8
- package/dist/engines/pi/config.d.ts +0 -71
- package/dist/engines/pi/config.js +0 -199
- package/dist/engines/pi/create.d.ts +0 -170
- package/dist/engines/pi/create.js +0 -343
- package/dist/engines/pi/definition.d.ts +0 -74
- package/dist/engines/pi/definition.js +0 -236
- package/dist/engines/pi/entry-images.d.ts +0 -14
- package/dist/engines/pi/entry-images.js +0 -23
- package/dist/engines/pi/invoke-session.d.ts +0 -18
- package/dist/engines/pi/invoke-session.js +0 -403
- package/dist/engines/pi/locked-file.d.ts +0 -9
- package/dist/engines/pi/machine.d.ts +0 -53
- package/dist/engines/pi/machine.js +0 -137
- package/dist/engines/pi/models.d.ts +0 -200
- package/dist/engines/pi/models.js +0 -533
- package/dist/engines/pi/open.d.ts +0 -180
- package/dist/engines/pi/open.js +0 -270
- package/dist/engines/pi/openai-account-models.d.ts +0 -35
- package/dist/engines/pi/openai-account-models.js +0 -116
- package/dist/engines/pi/report.d.ts +0 -18
- package/dist/engines/pi/report.js +0 -59
- package/dist/engines/pi/retry-event.d.ts +0 -6
- package/dist/engines/pi/retry-event.js +0 -15
- package/dist/engines/pi/service.d.ts +0 -9
- package/dist/engines/pi/service.js +0 -14
- package/dist/engines/pi/session-builder.d.ts +0 -13
- package/dist/engines/pi/session-builder.js +0 -117
- package/dist/engines/pi/session-control.d.ts +0 -77
- package/dist/engines/pi/session-control.js +0 -908
- package/dist/engines/pi/session-effects.d.ts +0 -14
- package/dist/engines/pi/session-effects.js +0 -30
- package/dist/engines/pi/session-inheritance.d.ts +0 -21
- package/dist/engines/pi/session-inheritance.js +0 -204
- package/dist/engines/pi/session-markers.d.ts +0 -49
- package/dist/engines/pi/session-markers.js +0 -60
- package/dist/engines/pi/session-settings.d.ts +0 -67
- package/dist/engines/pi/session-settings.js +0 -119
- package/dist/engines/pi/session-store.d.ts +0 -69
- package/dist/engines/pi/session-store.js +0 -430
- package/dist/engines/pi/tool-context.d.ts +0 -45
- package/dist/engines/pi/tool-context.js +0 -31
- package/dist/engines/pi/tool.d.ts +0 -99
- package/dist/engines/pi/tool.js +0 -118
- package/dist/engines/pi/turn-kit.d.ts +0 -92
- package/dist/engines/pi/turn-kit.js +0 -288
- package/dist/engines/pi/wake-tool.d.ts +0 -9
- package/dist/engines/pi/wake-tool.js +0 -92
- package/dist/loader.d.ts +0 -41
- package/dist/loader.js +0 -116
- package/dist/node.d.ts +0 -3
- package/dist/node.js +0 -4
- package/dist/observe.d.ts +0 -6
- package/dist/observe.js +0 -47
- package/dist/pi.d.ts +0 -25
- package/dist/pi.js +0 -15
- package/dist/scaffold/templates/APPEND_SYSTEM.md +0 -12
- package/dist/scaffold/templates/tools/fetch-url.ts +0 -25
- package/dist/schedule/discover.d.ts +0 -17
- package/dist/schedule/discover.js +0 -61
- package/dist/schedule/routine.d.ts +0 -43
- package/dist/schedule/routine.js +0 -32
- package/dist/schedule/run.d.ts +0 -55
- package/dist/schedule/run.js +0 -146
- package/dist/secrets-gate.d.ts +0 -32
- package/dist/secrets-gate.js +0 -33
- package/dist/session-remote.d.ts +0 -47
- package/dist/session-remote.js +0 -460
- package/dist/session.d.ts +0 -466
- package/dist/session.js +0 -57
- /package/dist/{channels/kit/state.d.ts → state-file.d.ts} +0 -0
package/dist/cli/add-feishu.js
CHANGED
|
@@ -5,137 +5,97 @@
|
|
|
5
5
|
import { readFile } from "node:fs/promises";
|
|
6
6
|
import { isCancel, log as clackLog, password, text as clackText } from "@clack/prompts";
|
|
7
7
|
import { bootstrapFeishuVerificationToken } from "../channels/feishu/bootstrap-token.js";
|
|
8
|
-
import {
|
|
8
|
+
import { FEISHU_APP_CONFIG_SCOPE, feishuAppAddons, feishuAppScopes, feishuScopeRequestUrl, scopeSatisfied, } from "../channels/feishu/setup-mode.js";
|
|
9
9
|
import { cloudFor } from "../channels/feishu/cloud.js";
|
|
10
10
|
import { createFeishuApi, isFeishuConfigApiMissing, isTransientFeishuRegistrationError, } from "../channels/feishu/feishu-api.js";
|
|
11
11
|
import { registerFeishuApp } from "../channels/feishu/register-app.js";
|
|
12
|
-
import { onboardLarkApp } from "../channels/lark/onboard.js";
|
|
13
|
-
import { dotEnvPath, parseEnvContent } from "../env.js";
|
|
12
|
+
import { LARK_CONSOLE_URL, onboardLarkApp } from "../channels/lark/onboard.js";
|
|
13
|
+
import { dotEnvPath, loadEnvValues, parseEnvContent } from "../env.js";
|
|
14
14
|
import { openExternalUrl } from "../open-url.js";
|
|
15
|
+
import { terminalPerson } from "./person.js";
|
|
16
|
+
import { AGENT_ENVIRONMENT_ENV } from "../paths.js";
|
|
15
17
|
import { appendChannelDotEnv } from "../scaffold/add-channel.js";
|
|
16
18
|
import { startCloudflareTunnel } from "../tunnel.js";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Check that the app holds what an app of this ingress needs ({@link feishuAppScopes}). A created app asks for them on
|
|
21
|
+
* its confirm page, and a tenant may still withhold some (its approval policy, or an app made by hand): those are
|
|
22
|
+
* NAMED, with what each one costs, and the console page that requests them is opened pre-filled. Nothing is requested
|
|
23
|
+
* through the config API — that needs a scope of its own, which a tenant can withhold just the same.
|
|
24
|
+
*/
|
|
25
|
+
export async function checkAgentScopes(input) {
|
|
26
|
+
const { kind, appId, apiBase, api } = input;
|
|
19
27
|
const note = input.note ?? ((message) => console.error(message));
|
|
20
|
-
const
|
|
28
|
+
const person = input.person ?? terminalPerson;
|
|
29
|
+
const needed = feishuAppScopes(input.ingress);
|
|
30
|
+
const requested = needed.map((entry) => entry.request);
|
|
21
31
|
let scopes;
|
|
22
|
-
let inspected = true;
|
|
23
32
|
try {
|
|
24
33
|
scopes = await api.listAppScopes();
|
|
25
34
|
}
|
|
26
35
|
catch (error) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const granted = (name) => scopes.some((scope) => scope.name === name && scope.grantStatus === 1 && (scope.type === undefined || scope.type === "tenant"));
|
|
32
|
-
// Same type filter as `granted`: a user-type entry is not the tenant scope this path needs, so treating one as "on
|
|
33
|
-
// the app" would report an approval that can never arrive and skip the PATCH that would actually add it.
|
|
34
|
-
const onApp = (name) => scopes.some((scope) => scope.name === name && (scope.type === undefined || scope.type === "tenant"));
|
|
35
|
-
// Both halves of the recommended path: delivery (the platform pushes un-mentioned group messages) and reading a
|
|
36
|
-
// quoted message (so a thread's opening ask carries what it replies to).
|
|
37
|
-
const missing = FEISHU_CONTEXT_ONBOARDING_SCOPES.filter((entry) => !scopeSatisfied(entry, granted));
|
|
38
|
-
const missingNames = missing.map((entry) => entry.request);
|
|
39
|
-
if (behavior === "mentions") {
|
|
40
|
-
if (!inspected) {
|
|
41
|
-
const permissionUrl = `${apiBase}/app/${encodeURIComponent(appId)}/permission`;
|
|
42
|
-
note(`[fastagent] mention-only scope state could not be verified — check Permissions before publishing. Opening ${permissionUrl}`);
|
|
43
|
-
openUrl(permissionUrl);
|
|
44
|
-
return { publishReady: false };
|
|
45
|
-
}
|
|
46
|
-
if (granted(FEISHU_GROUP_CONTEXT_SCOPE)) {
|
|
47
|
-
const permissionUrl = `${apiBase}/app/${encodeURIComponent(appId)}/permission`;
|
|
48
|
-
note(`[fastagent] warn: mention-only was selected, but ${FEISHU_GROUP_CONTEXT_SCOPE} is already granted — remove it before publishing a new version to restore least-privilege platform delivery. Opening ${permissionUrl}`);
|
|
49
|
-
openUrl(permissionUrl);
|
|
50
|
-
return { publishReady: false };
|
|
51
|
-
}
|
|
52
|
-
note(`[fastagent] group behavior: mention-only — bare replies in the Agent's threads and group context buffering are disabled. ` +
|
|
53
|
-
`Add ${FEISHU_MESSAGE_READ_SCOPE} by hand if you want an @mention to carry the message it quotes`);
|
|
54
|
-
return { publishReady: true };
|
|
36
|
+
const url = feishuScopeRequestUrl(apiBase, appId, requested);
|
|
37
|
+
note(`[fastagent] warn: could not read the ${kind} app's permissions: ${String(error)}`);
|
|
38
|
+
person.afterwards(`make sure the ${kind} app holds ${requested.join(", ")} before publishing`, url);
|
|
39
|
+
return { publishReady: false, missing: [] };
|
|
55
40
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
// A user-type entry is not the tenant scope the app acts with.
|
|
42
|
+
const tenant = scopes.filter((scope) => scope.type === undefined || scope.type === "tenant");
|
|
43
|
+
const granted = (name) => tenant.some((scope) => scope.name === name && scope.grantStatus === 1);
|
|
44
|
+
const missing = needed.filter((entry) => !scopeSatisfied(entry, granted));
|
|
60
45
|
if (missing.length === 0) {
|
|
61
|
-
note(`[fastagent] ${
|
|
62
|
-
return { publishReady: true };
|
|
63
|
-
}
|
|
64
|
-
const permissionUrl = `${apiBase}/app/${encodeURIComponent(appId)}/permission`;
|
|
65
|
-
// A missing scope is in one of two states, and they need different actions.
|
|
66
|
-
const awaitingApproval = missing.filter((entry) => scopeSatisfied(entry, onApp)).map((entry) => entry.request);
|
|
67
|
-
const toRequest = missing.filter((entry) => !scopeSatisfied(entry, onApp)).map((entry) => entry.request);
|
|
68
|
-
if (toRequest.length === 0) {
|
|
69
|
-
note(`[fastagent] ${awaitingApproval.join(" + ")} awaiting approval — complete tenant-admin approval before publishing. Opening ${permissionUrl}`);
|
|
70
|
-
openUrl(permissionUrl);
|
|
71
|
-
return { publishReady: false };
|
|
72
|
-
}
|
|
73
|
-
if (!explicit) {
|
|
74
|
-
// Defaulted, not chosen: report the gap and how to opt in, but leave the app's requested permission set untouched
|
|
75
|
-
// (a scripted re-run must not silently escalate a mention-only app).
|
|
76
|
-
note(`[fastagent] ${missingNames.join(" + ")} not granted (or could not be verified) — group behavior was ` +
|
|
77
|
-
`defaulted, so nothing was requested. Re-run with --group-behavior context to add ${missing.length > 1 ? "them" : "it"} ` +
|
|
78
|
-
`to the app draft, or --group-behavior mentions to stay least-privilege: ${permissionUrl}`);
|
|
79
|
-
return { publishReady: false };
|
|
80
|
-
}
|
|
81
|
-
try {
|
|
82
|
-
await api.addAppScopes(appId, toRequest);
|
|
83
|
-
note(`[fastagent] added ${toRequest.join(" + ")} to the app draft — complete tenant-admin approval before publishing. Opening ${permissionUrl}`);
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
note(`[fastagent] warn: could not add ${toRequest.join(" + ")} automatically: ${String(error)} — add it manually before publishing. Opening ${permissionUrl}`);
|
|
46
|
+
note(`[fastagent] ${kind} app permissions: ${requested.join(", ")} granted`);
|
|
47
|
+
return { publishReady: true, missing: [] };
|
|
87
48
|
}
|
|
88
|
-
|
|
89
|
-
|
|
49
|
+
// "Not granted", not "not requested": the list omits a scope still under review (measured), so the two look alike.
|
|
50
|
+
const describe = (entry) => `\n ${entry.request}: without it ${entry.withoutIt}`;
|
|
51
|
+
const url = feishuScopeRequestUrl(apiBase, appId, missing.map((entry) => entry.request));
|
|
52
|
+
person.afterwards(`the ${kind} app is not granted:${missing.map(describe).join("")}\n` +
|
|
53
|
+
`Tick and enable them on that page (one may already be awaiting a tenant admin's approval), before publishing`, url);
|
|
54
|
+
return { publishReady: false, missing: missing.map((entry) => entry.request) };
|
|
90
55
|
}
|
|
91
56
|
/** Create or resume the platform app behind `add feishu` / `add lark`. */
|
|
92
|
-
export async function onboardFeishuCloudApp(target, kind, ingress
|
|
57
|
+
export async function onboardFeishuCloudApp(target, kind, ingress,
|
|
58
|
+
/** The command that continues an interrupted setup: the one that started it. */
|
|
59
|
+
rerun = `fastagent add ${kind}${ingress === "webhook" ? " --ingress webhook" : ""}`,
|
|
60
|
+
/** Who takes the steps only a person can: at this terminal, or a coding agent's person through a ticket. */
|
|
61
|
+
person = terminalPerson) {
|
|
93
62
|
const env = dotEnvPath(target); // the file actually written — never the default spelling
|
|
94
63
|
const { envPrefix, apiBase, capabilities } = cloudFor(kind);
|
|
95
|
-
const requiredNames =
|
|
96
|
-
`${envPrefix}_APP_ID`,
|
|
97
|
-
`${envPrefix}_APP_SECRET`,
|
|
98
|
-
...(ingress === "webhook" ? [`${envPrefix}_VERIFICATION_TOKEN`] : []),
|
|
99
|
-
];
|
|
64
|
+
const requiredNames = feishuAppSecretNames(kind, ingress);
|
|
100
65
|
const existing = await activeDotEnvValues(target, requiredNames);
|
|
66
|
+
if (process.env[AGENT_ENVIRONMENT_ENV] === "production") {
|
|
67
|
+
assertIndependentFeishuApps(target, [kind], new Map(Object.entries(existing)));
|
|
68
|
+
}
|
|
101
69
|
if (Object.keys(existing).length === requiredNames.length) {
|
|
102
70
|
console.error(`[fastagent] ${requiredNames.join("/")} already set in ${env} — keeping them`);
|
|
103
71
|
// WebSocket still needs its console mode/publish guidance.
|
|
104
72
|
if (ingress === "webhook") {
|
|
105
73
|
const appId = existing[`${envPrefix}_APP_ID`];
|
|
106
74
|
const appSecret = existing[`${envPrefix}_APP_SECRET`];
|
|
107
|
-
await
|
|
75
|
+
await checkAgentScopes({
|
|
108
76
|
kind,
|
|
109
77
|
appId,
|
|
110
78
|
apiBase,
|
|
79
|
+
ingress,
|
|
111
80
|
api: createFeishuApi({ kind, baseUrl: apiBase, appId, appSecret }),
|
|
112
|
-
|
|
113
|
-
explicit: groupBehavior.explicit,
|
|
81
|
+
person,
|
|
114
82
|
});
|
|
115
83
|
return undefined;
|
|
116
84
|
}
|
|
117
85
|
}
|
|
118
86
|
if (capabilities.appCreation === "scan-to-create") {
|
|
119
|
-
await createFeishuAppFlow(target, existing, ingress,
|
|
87
|
+
await createFeishuAppFlow(target, existing, ingress, rerun, person);
|
|
120
88
|
return undefined;
|
|
121
89
|
}
|
|
122
90
|
// guided-console (lark): the intl cloud cannot complete the bound device flow — collect + validate.
|
|
123
|
-
|
|
124
|
-
!(existing[`${envPrefix}_APP_ID`] && existing[`${envPrefix}_APP_SECRET`])) {
|
|
125
|
-
throw new Error("`add lark` needs an interactive terminal to onboard the Lark app credentials — re-run it in a terminal");
|
|
126
|
-
}
|
|
127
|
-
const credentials = await onboardLarkApp({
|
|
128
|
-
openUrl: openExternalUrl,
|
|
129
|
-
note: (message) => clackLog.info(message),
|
|
130
|
-
async prompt(message, opts) {
|
|
131
|
-
const result = opts?.hidden ? await password({ message }) : await clackText({ message });
|
|
132
|
-
return isCancel(result) ? undefined : result;
|
|
133
|
-
},
|
|
134
|
-
}, {
|
|
91
|
+
const credentials = await onboardLarkApp(person === terminalPerson ? larkAtTerminal : larkThrough(person, env, rerun), {
|
|
135
92
|
existing,
|
|
136
93
|
ingress,
|
|
137
|
-
|
|
94
|
+
rerun,
|
|
138
95
|
verifyCredentials: async (appId, appSecret) => {
|
|
96
|
+
if (process.env[AGENT_ENVIRONMENT_ENV] === "production") {
|
|
97
|
+
assertIndependentFeishuApps(target, ["lark"], new Map([["LARK_APP_ID", appId]]));
|
|
98
|
+
}
|
|
139
99
|
await createFeishuApi({ kind: "lark", baseUrl: apiBase, appId, appSecret }).verifyCredentials();
|
|
140
100
|
console.error(`[fastagent] Lark App ID / Secret verified`);
|
|
141
101
|
},
|
|
@@ -165,23 +125,48 @@ export async function onboardFeishuCloudApp(target, kind, ingress = "webhook", g
|
|
|
165
125
|
}
|
|
166
126
|
},
|
|
167
127
|
});
|
|
168
|
-
await
|
|
128
|
+
await checkAgentScopes({
|
|
169
129
|
kind: "lark",
|
|
170
130
|
appId: credentials.LARK_APP_ID,
|
|
171
131
|
apiBase,
|
|
132
|
+
ingress,
|
|
133
|
+
person,
|
|
172
134
|
api: createFeishuApi({
|
|
173
135
|
kind: "lark",
|
|
174
136
|
baseUrl: apiBase,
|
|
175
137
|
appId: credentials.LARK_APP_ID,
|
|
176
138
|
appSecret: credentials.LARK_APP_SECRET,
|
|
177
139
|
}),
|
|
178
|
-
behavior: groupBehavior.behavior,
|
|
179
|
-
explicit: groupBehavior.explicit,
|
|
180
140
|
});
|
|
181
141
|
return Object.fromEntries(Object.entries(credentials).filter((entry) => typeof entry[1] === "string"));
|
|
182
142
|
}
|
|
143
|
+
/** Lark's guided console at a terminal: what to open, and the values asked for there. */
|
|
144
|
+
const larkAtTerminal = {
|
|
145
|
+
openUrl(url, action) {
|
|
146
|
+
clackLog.info(`${action}. Opening ${url}`);
|
|
147
|
+
openExternalUrl(url);
|
|
148
|
+
},
|
|
149
|
+
note: (message) => clackLog.info(message),
|
|
150
|
+
async prompt(message, opts) {
|
|
151
|
+
const result = opts?.hidden ? await password({ message }) : await clackText({ message });
|
|
152
|
+
return isCancel(result) ? undefined : result;
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Lark's guided console through a coding agent's person: a page is a step left to them, with what they do there; a
|
|
157
|
+
* value it would ask for is theirs to set in the value file, and the setup continues when run again.
|
|
158
|
+
*/
|
|
159
|
+
function larkThrough(person, env, rerun) {
|
|
160
|
+
return {
|
|
161
|
+
note: (message) => console.error(`[fastagent] ${message}`),
|
|
162
|
+
openUrl: (url, action) => person.afterwards(action, url),
|
|
163
|
+
async prompt(message) {
|
|
164
|
+
throw new Error(`${message} is needed: ask the user to set it in ${env}, then run \`${rerun}\` again`);
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
183
168
|
/** The scan-to-create flow `add feishu` runs by default. */
|
|
184
|
-
async function createFeishuAppFlow(target, existing, ingress,
|
|
169
|
+
async function createFeishuAppFlow(target, existing, ingress, rerun, person) {
|
|
185
170
|
const env = dotEnvPath(target); // the file actually written — never the default spelling
|
|
186
171
|
const { apiBase } = cloudFor("feishu");
|
|
187
172
|
let appId = existing.FEISHU_APP_ID;
|
|
@@ -194,15 +179,13 @@ async function createFeishuAppFlow(target, existing, ingress, groupBehavior) {
|
|
|
194
179
|
else {
|
|
195
180
|
console.error(`[fastagent] creating the Feishu app (confirm in the app)…`);
|
|
196
181
|
const app = await registerFeishuApp({
|
|
197
|
-
name: "{user}'s agent"
|
|
182
|
+
name: process.env[AGENT_ENVIRONMENT_ENV] === "production" ? "{user}'s production agent" : "{user}'s agent",
|
|
198
183
|
desc: "Served by fastagent",
|
|
199
|
-
// The agent template alone is not enough to SERVE (see feishuAppAddons).
|
|
200
|
-
addons: feishuAppAddons(),
|
|
201
|
-
onVerificationUrl: ({ url, expiresInS }) =>
|
|
202
|
-
console.error(`\n Opening the confirmation link in your browser (or open it in Feishu / render it as a QR code) — valid for ${Math.round(expiresInS / 60)} minutes:\n\n ${url}\n\n waiting for confirmation… (keep this running — the credentials are delivered here)`);
|
|
203
|
-
openExternalUrl(url); // best-effort, like `login` — the URL above is the fallback
|
|
204
|
-
},
|
|
184
|
+
// The agent template alone is not enough to SERVE, nor to hear a group (see feishuAppAddons).
|
|
185
|
+
addons: feishuAppAddons(ingress),
|
|
186
|
+
onVerificationUrl: ({ url, expiresInS }) => person.waitsOn(url, "confirm the new Feishu app (in a browser, or in Feishu, or as a QR code)", Date.now() + expiresInS * 1000),
|
|
205
187
|
});
|
|
188
|
+
person.carriesOn();
|
|
206
189
|
console.error(`[fastagent] app created: ${app.appId}${app.tenantBrand ? ` (${app.tenantBrand} tenant)` : ""}`);
|
|
207
190
|
// A cross-brand confirmation should be impossible (each confirm page refuses the other brand's code).
|
|
208
191
|
if (app.tenantBrand && app.tenantBrand !== "feishu") {
|
|
@@ -221,25 +204,22 @@ async function createFeishuAppFlow(target, existing, ingress, groupBehavior) {
|
|
|
221
204
|
? `[fastagent] wrote FEISHU_APP_ID, FEISHU_APP_SECRET to ${env} before Token bootstrap`
|
|
222
205
|
: `[fastagent] wrote FEISHU_APP_ID, FEISHU_APP_SECRET to ${env}`);
|
|
223
206
|
}
|
|
224
|
-
const groupSetup = await
|
|
207
|
+
const groupSetup = await checkAgentScopes({
|
|
225
208
|
kind: "feishu",
|
|
226
209
|
appId,
|
|
227
210
|
apiBase,
|
|
211
|
+
ingress,
|
|
228
212
|
api: createFeishuApi({ kind: "feishu", baseUrl: apiBase, appId, appSecret }),
|
|
229
|
-
|
|
230
|
-
explicit: groupBehavior.explicit,
|
|
213
|
+
person,
|
|
231
214
|
});
|
|
232
215
|
if (ingress === "websocket") {
|
|
233
216
|
const versionUrl = `${apiBase}/app/${appId}/version`;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
console.error(`[fastagent] WebSocket ingress needs no Verification Token, Encrypt Key, Request URL, or tunnel. ` +
|
|
241
|
-
`Choose long connection in Events & Callbacks, finish the permission work opened above, then CREATE + PUBLISH: ${versionUrl}`);
|
|
242
|
-
}
|
|
217
|
+
const choose = "WebSocket ingress needs no Verification Token, Encrypt Key, Request URL, or tunnel: choose long connection in " +
|
|
218
|
+
"Events & Callbacks";
|
|
219
|
+
if (groupSetup.publishReady)
|
|
220
|
+
person.afterwards(`${choose}, then CREATE + PUBLISH a version`, versionUrl);
|
|
221
|
+
else
|
|
222
|
+
person.afterwards(`${choose}, finish the permission work above, then CREATE + PUBLISH a version: ${versionUrl}`);
|
|
243
223
|
return;
|
|
244
224
|
}
|
|
245
225
|
// The webhook channel authenticates plaintext events by the platform-generated Verification Token.
|
|
@@ -256,20 +236,29 @@ async function createFeishuAppFlow(target, existing, ingress, groupBehavior) {
|
|
|
256
236
|
// it was needed would otherwise be invisible.
|
|
257
237
|
console.error(`[fastagent] could not read the app's Verification Token directly: ${error.message}`);
|
|
258
238
|
}
|
|
259
|
-
|
|
239
|
+
// The bootstrap registers a Request URL through the config scope; without it every attempt is refused, so it is not
|
|
240
|
+
// tried, and the reason is the one the permission check above already named.
|
|
241
|
+
const configWithheld = groupSetup.missing.includes(FEISHU_APP_CONFIG_SCOPE);
|
|
242
|
+
if (!token && configWithheld) {
|
|
243
|
+
console.error(`[fastagent] not capturing the Verification Token: the app is not granted ${FEISHU_APP_CONFIG_SCOPE}. Choose webhook ` +
|
|
244
|
+
`in Events & Callbacks and set the Request URL there yourself (dev --tunnel and deploy --run cannot ` +
|
|
245
|
+
`either), or have the permission approved and re-run \`${rerun}\`.`);
|
|
246
|
+
}
|
|
247
|
+
else if (!token) {
|
|
260
248
|
console.error(`[fastagent] capturing the Verification Token — a throwaway webhook registration delivers it (spinning up a temporary tunnel; can take a few minutes on a slow edge)…`);
|
|
261
249
|
try {
|
|
262
250
|
token = await bootstrapFeishuVerificationToken({
|
|
263
251
|
api,
|
|
264
252
|
appId,
|
|
265
253
|
startTunnel: (port) => startCloudflareTunnel(port),
|
|
254
|
+
// Only edge weather is retried; a refusal (scope, auth, app under review) is reported as itself.
|
|
255
|
+
shouldRetryPatch: isTransientFeishuRegistrationError,
|
|
266
256
|
});
|
|
267
257
|
webhookModeChanged = true;
|
|
268
258
|
console.error(`[fastagent] Verification Token captured`);
|
|
269
259
|
}
|
|
270
260
|
catch (e) {
|
|
271
|
-
|
|
272
|
-
console.error(`[fastagent] warn: could not capture the Verification Token: ${String(e)} — usually a transient tunnel issue; finish this app with the manual copy below`);
|
|
261
|
+
console.error(`[fastagent] warn: could not capture the Verification Token: ${String(e)} — finish this app with the manual copy below`);
|
|
273
262
|
}
|
|
274
263
|
}
|
|
275
264
|
if (token) {
|
|
@@ -278,20 +267,47 @@ async function createFeishuAppFlow(target, existing, ingress, groupBehavior) {
|
|
|
278
267
|
console.error(`[fastagent] wrote ${staged.written.join(", ")} to ${env}`);
|
|
279
268
|
}
|
|
280
269
|
else {
|
|
281
|
-
|
|
270
|
+
person.afterwards(`copy the Verification Token: developer console → Events & Callbacks → Encryption Strategy → Verification ` +
|
|
271
|
+
`Token → ${tokenVar} in ${env}`);
|
|
282
272
|
}
|
|
283
273
|
if (webhookModeChanged) {
|
|
284
274
|
// The bootstrap's PATCH flipped event mode in the DRAFT.
|
|
285
275
|
const versionUrl = `${apiBase}/app/${appId}/version`;
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
console.error(`[fastagent] after the permission work opened above, CREATE + PUBLISH a version — the switch to webhook mode takes effect on publish: ${versionUrl}`);
|
|
292
|
-
}
|
|
276
|
+
const publish = "CREATE + PUBLISH a version (self-approved): the switch to webhook mode takes effect on publish";
|
|
277
|
+
if (groupSetup.publishReady)
|
|
278
|
+
person.afterwards(publish, versionUrl);
|
|
279
|
+
else
|
|
280
|
+
person.afterwards(`after the permission work above, ${publish}: ${versionUrl}`);
|
|
293
281
|
}
|
|
294
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Lark's app credentials, which only the person can get, from the app they create in Lark's console: with no one at a
|
|
285
|
+
* terminal to type them, the report naming where they set them (the selected environment's file), when either is
|
|
286
|
+
* absent. `again` is the command that continues once they have.
|
|
287
|
+
*/
|
|
288
|
+
export async function larkCredentialsNeeded(agentDir, again) {
|
|
289
|
+
const held = await activeDotEnvValues(agentDir, ["LARK_APP_ID", "LARK_APP_SECRET"]);
|
|
290
|
+
if (held.LARK_APP_ID && held.LARK_APP_SECRET)
|
|
291
|
+
return undefined;
|
|
292
|
+
const valueFile = dotEnvPath(agentDir);
|
|
293
|
+
return {
|
|
294
|
+
json: {
|
|
295
|
+
status: "need_user_action",
|
|
296
|
+
url: LARK_CONSOLE_URL,
|
|
297
|
+
variables: ["LARK_APP_ID", "LARK_APP_SECRET"],
|
|
298
|
+
value_file: valueFile,
|
|
299
|
+
check_command: `${again} --json`,
|
|
300
|
+
agent_next_steps: "Give the URL to the user so they can create the Lark app there, and ask them to set LARK_APP_ID and " +
|
|
301
|
+
`LARK_APP_SECRET (from its Credentials & Basic Info) in ${valueFile} themselves, not in this ` +
|
|
302
|
+
"conversation. Once they say they have, run check_command.",
|
|
303
|
+
},
|
|
304
|
+
text: [
|
|
305
|
+
`need_user_action: create the Lark app at ${LARK_CONSOLE_URL}`,
|
|
306
|
+
` and set LARK_APP_ID and LARK_APP_SECRET in ${valueFile}`,
|
|
307
|
+
`then run: ${again}`,
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
}
|
|
295
311
|
/**
|
|
296
312
|
* Active agent `.env` (`.secrets/.env`) values for the requested names — decided by THE .env parser, so this check can
|
|
297
313
|
* never disagree with what `loadDotEnv` reads.
|
|
@@ -312,3 +328,40 @@ async function activeDotEnvValues(dir, names) {
|
|
|
312
328
|
return value ? [[name, value]] : [];
|
|
313
329
|
}));
|
|
314
330
|
}
|
|
331
|
+
export function feishuAppSecretNames(kind, ingress) {
|
|
332
|
+
const prefix = cloudFor(kind).envPrefix;
|
|
333
|
+
return [
|
|
334
|
+
`${prefix}_APP_ID`,
|
|
335
|
+
`${prefix}_APP_SECRET`,
|
|
336
|
+
...(ingress === "webhook" ? [`${prefix}_VERIFICATION_TOKEN`] : []),
|
|
337
|
+
];
|
|
338
|
+
}
|
|
339
|
+
export function unpreparedFeishuApps(channels, values) {
|
|
340
|
+
return ["feishu", "lark"].flatMap((kind) => {
|
|
341
|
+
const channel = channels.find((entry) => entry.name === kind);
|
|
342
|
+
if (!channel)
|
|
343
|
+
return [];
|
|
344
|
+
const ingress = channel.ingress === "webhook" ? "webhook" : "websocket";
|
|
345
|
+
return feishuAppSecretNames(kind, ingress).some((name) => !values.get(name)?.trim()) ? [{ kind, ingress }] : [];
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
export function assertIndependentFeishuApps(agentDir, kinds, values) {
|
|
349
|
+
const devFile = dotEnvPath(agentDir, {});
|
|
350
|
+
const devValues = loadEnvValues(devFile);
|
|
351
|
+
for (const kind of kinds) {
|
|
352
|
+
const name = `${cloudFor(kind).envPrefix}_APP_ID`;
|
|
353
|
+
const appId = values.get(name)?.trim();
|
|
354
|
+
if (appId && appId === devValues.get(name)?.trim()) {
|
|
355
|
+
throw new Error(`${kind}: dev and production use the same app (${name}) — create a separate production app in ` +
|
|
356
|
+
`${dotEnvPath(agentDir)}; copying dev credentials would take its messages away`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
export async function prepareFeishuApps(agentDir, apps, rerun, person, onboard = onboardFeishuCloudApp) {
|
|
361
|
+
for (const { kind, ingress } of apps) {
|
|
362
|
+
console.error(`[fastagent] ${kind}: preparing the production app for ${ingress} in ${dotEnvPath(agentDir)}`);
|
|
363
|
+
const created = await onboard(agentDir, kind, ingress, rerun, person);
|
|
364
|
+
if (created)
|
|
365
|
+
await appendChannelDotEnv(agentDir, kind, created, Object.keys(created), ingress);
|
|
366
|
+
}
|
|
367
|
+
}
|
package/dist/cli/add-slack.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
1
|
+
import type { Person } from "./person.ts";
|
|
2
|
+
/** Single-workspace internal-app creation + installation. */
|
|
3
3
|
export declare function onboardSlackInternalApp(input: {
|
|
4
4
|
/**
|
|
5
5
|
* The AGENT DIR — credentials land in its `.env` ({@link dotEnvPath}: `FASTAGENT_SECRETS_DIR` moves it, so messages
|
|
@@ -7,7 +7,12 @@ export declare function onboardSlackInternalApp(input: {
|
|
|
7
7
|
*/
|
|
8
8
|
target: string;
|
|
9
9
|
stateRoot: string;
|
|
10
|
-
groupBehavior: GroupBehaviorChoice;
|
|
11
10
|
/** `--replace-config`: go straight to replacing the local App Configuration token pair. */
|
|
12
11
|
replaceConfig?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* A coding agent's person, through a ticket: nothing is asked at a terminal. The token pair is pasted on a page the
|
|
14
|
+
* setup server shows, which then takes the browser on to Slack's install page; the app takes its default name, and
|
|
15
|
+
* a saved pair is kept. Absent: the terminal asks.
|
|
16
|
+
*/
|
|
17
|
+
person?: Person;
|
|
13
18
|
}): Promise<void>;
|