@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-slack.js
CHANGED
|
@@ -8,7 +8,8 @@ import { newSlackOnboardingState, onboardSlackApp } from "../channels/slack/onbo
|
|
|
8
8
|
import { configTokenExpiry, readSlackOnboardingState, writeSlackOnboardingState, } from "../channels/slack/onboarding-state.js";
|
|
9
9
|
import { startSlackSetupServer } from "../channels/slack/setup-server.js";
|
|
10
10
|
import { startCloudflareTunnel } from "../tunnel.js";
|
|
11
|
-
|
|
11
|
+
/** Where an App Configuration token pair is generated. */
|
|
12
|
+
const SLACK_CONFIG_TOKEN_URL = "https://api.slack.com/apps";
|
|
12
13
|
async function promptValue(message, hidden = false, initialValue) {
|
|
13
14
|
const result = hidden ? await password({ message }) : await clackText({ message, initialValue });
|
|
14
15
|
if (isCancel(result))
|
|
@@ -20,10 +21,14 @@ async function promptValue(message, hidden = false, initialValue) {
|
|
|
20
21
|
}
|
|
21
22
|
/** The one place an App Configuration token pair is asked for and validated. */
|
|
22
23
|
async function promptConfigTokens() {
|
|
23
|
-
console.error(`[fastagent] generate an App Configuration Token pair at ${
|
|
24
|
-
openExternalUrl(
|
|
24
|
+
console.error(`[fastagent] generate an App Configuration Token pair at ${SLACK_CONFIG_TOKEN_URL}`);
|
|
25
|
+
openExternalUrl(SLACK_CONFIG_TOKEN_URL);
|
|
25
26
|
const configToken = await promptValue("Slack configuration access token (xoxe.xoxp-…)", true);
|
|
26
27
|
const configRefreshToken = await promptValue("Slack configuration refresh token (xoxe-…)", true);
|
|
28
|
+
return checkedConfigTokens(configToken, configRefreshToken);
|
|
29
|
+
}
|
|
30
|
+
/** An App Configuration token pair, refused unless each is the kind Slack issues. */
|
|
31
|
+
function checkedConfigTokens(configToken, configRefreshToken) {
|
|
27
32
|
if (!configToken.startsWith("xoxe.") || !configRefreshToken.startsWith("xoxe-")) {
|
|
28
33
|
throw new Error("invalid Slack configuration token prefix (expected xoxe. access + xoxe- refresh)");
|
|
29
34
|
}
|
|
@@ -33,6 +38,8 @@ async function promptConfigTokens() {
|
|
|
33
38
|
async function chooseTokenAction(prompt) {
|
|
34
39
|
if (prompt.forced)
|
|
35
40
|
return "replace-config";
|
|
41
|
+
if (!prompt.asks)
|
|
42
|
+
return "keep";
|
|
36
43
|
const answer = await select({
|
|
37
44
|
message: prompt.message,
|
|
38
45
|
initialValue: "keep",
|
|
@@ -49,18 +56,69 @@ async function chooseTokenAction(prompt) {
|
|
|
49
56
|
throw new Error("Slack onboarding cancelled");
|
|
50
57
|
return answer;
|
|
51
58
|
}
|
|
52
|
-
|
|
59
|
+
const nothingToReplace = () => new Error("--replace-config found no local Slack onboarding state on this machine — nothing to replace. " +
|
|
60
|
+
"Run `fastagent add slack` to onboard, or update the Request URL manually in the Slack console");
|
|
61
|
+
/** The temporary setup server and the tunnel to it, started once something needs them. */
|
|
62
|
+
function setupEndpoint() {
|
|
63
|
+
let started;
|
|
64
|
+
return {
|
|
65
|
+
get: () => {
|
|
66
|
+
started ??= (async () => {
|
|
67
|
+
const server = await startSlackSetupServer();
|
|
68
|
+
const tunnel = await startCloudflareTunnel(server.port);
|
|
69
|
+
if (!tunnel) {
|
|
70
|
+
await server.close();
|
|
71
|
+
throw new Error("Slack onboarding needs a temporary HTTPS tunnel — install cloudflared and re-run");
|
|
72
|
+
}
|
|
73
|
+
console.error(`[fastagent] temporary Slack setup tunnel ready → ${tunnel.url}`);
|
|
74
|
+
return { server, tunnelUrl: tunnel.url, closeTunnel: () => tunnel.close() };
|
|
75
|
+
})();
|
|
76
|
+
return started;
|
|
77
|
+
},
|
|
78
|
+
/** The endpoint if something started it, never starting one. */
|
|
79
|
+
ifStarted: () => started?.catch(() => undefined),
|
|
80
|
+
async close() {
|
|
81
|
+
const endpoint = await started?.catch(() => undefined);
|
|
82
|
+
if (endpoint === undefined)
|
|
83
|
+
return;
|
|
84
|
+
endpoint.closeTunnel();
|
|
85
|
+
await endpoint.server.close().catch(() => { });
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Single-workspace internal-app creation + installation. */
|
|
53
90
|
export async function onboardSlackInternalApp(input) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
91
|
+
const { person } = input;
|
|
92
|
+
const endpoint = setupEndpoint();
|
|
93
|
+
/** A fresh pair: at the terminal, or on the setup server's page. */
|
|
94
|
+
const freshTokens = async () => {
|
|
95
|
+
if (person === undefined)
|
|
96
|
+
return promptConfigTokens();
|
|
97
|
+
const { server, tunnelUrl } = await endpoint.get();
|
|
98
|
+
person.waitsOn(`${tunnelUrl}${server.tokensPath}`, `generate a Slack App Configuration Token at ${SLACK_CONFIG_TOKEN_URL} and paste it on this page`);
|
|
99
|
+
const tokens = await server.waitForTokens(({ access, refresh }) => checkedConfigTokens(access, refresh));
|
|
100
|
+
person.carriesOn();
|
|
101
|
+
return tokens;
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
await onboard(input, freshTokens, endpoint);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// The browser that pasted the pair waits on the next page: it says why, as the ticket does.
|
|
108
|
+
await (await endpoint.ifStarted())?.server.failed(error.message);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
await endpoint.close();
|
|
57
113
|
}
|
|
114
|
+
}
|
|
115
|
+
async function onboard(input, freshTokens, endpoint) {
|
|
116
|
+
const { person } = input;
|
|
117
|
+
const asks = person === undefined;
|
|
58
118
|
let state = readSlackOnboardingState(input.stateRoot);
|
|
59
119
|
const resumed = state !== undefined;
|
|
60
|
-
if (input.replaceConfig && !state)
|
|
61
|
-
throw
|
|
62
|
-
"Run `fastagent add slack` to onboard, or update the Request URL manually in the Slack console");
|
|
63
|
-
}
|
|
120
|
+
if (input.replaceConfig && !state)
|
|
121
|
+
throw nothingToReplace();
|
|
64
122
|
if (state?.installedAt) {
|
|
65
123
|
const env = await readFile(dotEnvPath(input.target), "utf8")
|
|
66
124
|
.then(parseEnvContent)
|
|
@@ -75,20 +133,19 @@ export async function onboardSlackInternalApp(input) {
|
|
|
75
133
|
`${missingRuntime.join(", ")} — ` +
|
|
76
134
|
"restore them from the Slack app console, or delete the app + onboarding state and create a new one");
|
|
77
135
|
}
|
|
78
|
-
if (input.groupBehavior.explicit && state.groupBehavior !== input.groupBehavior.behavior) {
|
|
79
|
-
throw new Error(`the onboarded Slack app uses group behavior ${state.groupBehavior}; changing an installed app's ` +
|
|
80
|
-
"OAuth scopes is a migration. Keep the existing choice, or remove the app + Slack onboarding state and create a new app");
|
|
81
|
-
}
|
|
82
136
|
const action = await chooseTokenAction({
|
|
83
137
|
forced: input.replaceConfig === true,
|
|
138
|
+
asks,
|
|
84
139
|
message: `Slack app ${state.appId ?? "(unknown)"} is already installed${state.teamName ? ` in ${state.teamName}` : ""}`,
|
|
85
140
|
keepLabel: "Keep the installed app",
|
|
86
141
|
replaceLabel: "Replace App Configuration tokens",
|
|
87
142
|
replaceHint: "repair automatic dev/deploy Request URL updates",
|
|
88
143
|
});
|
|
89
144
|
if (action === "replace-config") {
|
|
90
|
-
writeSlackOnboardingState(input.stateRoot, { ...state, ...(await
|
|
145
|
+
writeSlackOnboardingState(input.stateRoot, { ...state, ...(await freshTokens()) });
|
|
91
146
|
console.error("[fastagent] replaced local Slack App Configuration tokens; runtime app credentials are unchanged");
|
|
147
|
+
// A browser that pasted the pair waits on the page after it: this is where the setup ends.
|
|
148
|
+
await (await endpoint.ifStarted())?.server.done("Slack App Configuration tokens replaced: you can close this page.");
|
|
92
149
|
}
|
|
93
150
|
else {
|
|
94
151
|
console.error("[fastagent] keeping the installed Slack app and local configuration tokens");
|
|
@@ -96,69 +153,64 @@ export async function onboardSlackInternalApp(input) {
|
|
|
96
153
|
return;
|
|
97
154
|
}
|
|
98
155
|
if (!state) {
|
|
99
|
-
const appName =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
writeSlackOnboardingState(input.stateRoot, state);
|
|
108
|
-
}
|
|
109
|
-
else if (input.groupBehavior.explicit && !state.appId) {
|
|
110
|
-
state = { ...state, groupBehavior: input.groupBehavior.behavior };
|
|
156
|
+
const appName = asks
|
|
157
|
+
? await promptValue("Slack app name", false, `FastAgent ${basename(input.target)}`)
|
|
158
|
+
: `FastAgent ${basename(input.target)}`;
|
|
159
|
+
if (asks) {
|
|
160
|
+
clackLog.info("Slack's configuration refresh token can manage apps owned by your user in this workspace. " +
|
|
161
|
+
"FastAgent stores it only in owner-readable local state; it is never deployed.");
|
|
162
|
+
}
|
|
163
|
+
state = newSlackOnboardingState({ appName, ...(await freshTokens()) });
|
|
111
164
|
writeSlackOnboardingState(input.stateRoot, state);
|
|
112
165
|
}
|
|
113
166
|
if (state.createAttemptedAt && !state.appId) {
|
|
114
167
|
throw new Error(`a prior Slack app creation attempt at ${state.createAttemptedAt} returned no app ID — ` +
|
|
115
|
-
`inspect ${
|
|
168
|
+
`inspect ${SLACK_CONFIG_TOKEN_URL}; delete any incomplete app and ${input.stateRoot}/channels/slack/onboarding.json before retrying`);
|
|
116
169
|
}
|
|
117
170
|
// `--replace-config` also covers the created-but-not-installed state, where a revoked token would otherwise strand
|
|
118
171
|
// the resume (rotation fails and no menu offers replacement).
|
|
119
172
|
if (resumed && (!state.appId || input.replaceConfig)) {
|
|
120
173
|
const action = await chooseTokenAction({
|
|
121
174
|
forced: input.replaceConfig === true,
|
|
175
|
+
asks,
|
|
122
176
|
message: "Resume Slack onboarding with which App Configuration tokens?",
|
|
123
177
|
keepLabel: "Use the saved token pair",
|
|
124
178
|
replaceLabel: "Paste a fresh token pair",
|
|
125
179
|
});
|
|
126
180
|
if (action === "replace-config") {
|
|
127
|
-
state = { ...state, ...(await
|
|
181
|
+
state = { ...state, ...(await freshTokens()) };
|
|
128
182
|
writeSlackOnboardingState(input.stateRoot, state);
|
|
129
183
|
}
|
|
130
184
|
}
|
|
131
|
-
const server = await
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
await server.close().catch(() => { });
|
|
163
|
-
}
|
|
185
|
+
const { server, tunnelUrl } = await endpoint.get();
|
|
186
|
+
const requestUrl = `${tunnelUrl}${server.requestPath}`;
|
|
187
|
+
const redirectUrl = `${tunnelUrl}${server.redirectPath}`;
|
|
188
|
+
// No local readiness probe: Slack challenges requestUrl from ITS network during app creation, and that is the
|
|
189
|
+
// reachability that matters (#421).
|
|
190
|
+
await onboardSlackApp({ stateRoot: input.stateRoot, state, requestUrl, redirectUrl }, {
|
|
191
|
+
note: (message) => (asks ? clackLog.info(message) : console.error(`[fastagent] ${message}`)),
|
|
192
|
+
openUrl: (url) => {
|
|
193
|
+
if (person === undefined)
|
|
194
|
+
return openExternalUrl(url);
|
|
195
|
+
// A browser that pasted the pair goes straight on; the ticket names the page for one that did not.
|
|
196
|
+
server.next(url);
|
|
197
|
+
person.waitsOn(url, "click Allow to install the Slack app in their workspace");
|
|
198
|
+
},
|
|
199
|
+
waitForOAuth: async () => {
|
|
200
|
+
const callback = await server.waitForOAuth();
|
|
201
|
+
person?.carriesOn();
|
|
202
|
+
return callback;
|
|
203
|
+
},
|
|
204
|
+
writeRuntimeSecrets: async ({ botToken, signingSecret }) => {
|
|
205
|
+
const values = {
|
|
206
|
+
...(botToken ? { SLACK_BOT_TOKEN: botToken } : {}),
|
|
207
|
+
...(signingSecret ? { SLACK_SIGNING_SECRET: signingSecret } : {}),
|
|
208
|
+
};
|
|
209
|
+
if (Object.keys(values).length > 0) {
|
|
210
|
+
await appendChannelDotEnv(input.target, "slack", values, Object.keys(values));
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
// What happened, once. What to do next is `add`'s "next steps" block.
|
|
215
|
+
console.error(`[fastagent] Slack app installed; credentials written to ${dotEnvPath(input.target)}`);
|
|
164
216
|
}
|
package/dist/cli/auth-view.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** CLI presenter for the auth-status line `reportAuth` prints (invoke/dev/start). */
|
|
2
|
+
import type { DeployHost } from "../deploy/hosts.ts";
|
|
2
3
|
/**
|
|
3
4
|
* Format the auth status for a provider, from `AgentModels.authStatus`'s answer. `deployed`: this process is a
|
|
4
|
-
* deployed box, which logs in from the owner's
|
|
5
|
-
* by hand.
|
|
5
|
+
* deployed box, which logs in from the owner's agent directory (`fastagent login --deployment <host>`), never by a
|
|
6
|
+
* login run on it by hand; `host` is which one, when the box can tell (`deployedHost`).
|
|
6
7
|
*/
|
|
7
8
|
export declare function formatAuthReport(status: {
|
|
8
9
|
provider: string;
|
|
@@ -12,7 +13,13 @@ export declare function formatAuthReport(status: {
|
|
|
12
13
|
error?: string;
|
|
13
14
|
stored?: string;
|
|
14
15
|
shadowed?: string;
|
|
15
|
-
deployed?:
|
|
16
|
+
deployed?: {
|
|
17
|
+
host: DeployHost | undefined;
|
|
18
|
+
};
|
|
19
|
+
local?: {
|
|
20
|
+
authPath: string;
|
|
21
|
+
valueFile: string;
|
|
22
|
+
};
|
|
16
23
|
}): {
|
|
17
24
|
line: string;
|
|
18
25
|
warn?: string;
|
package/dist/cli/auth-view.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
/** CLI presenter for the auth-status line `reportAuth` prints (invoke/dev/start). */
|
|
2
1
|
/**
|
|
3
2
|
* Format the auth status for a provider, from `AgentModels.authStatus`'s answer. `deployed`: this process is a
|
|
4
|
-
* deployed box, which logs in from the owner's
|
|
5
|
-
* by hand.
|
|
3
|
+
* deployed box, which logs in from the owner's agent directory (`fastagent login --deployment <host>`), never by a
|
|
4
|
+
* login run on it by hand; `host` is which one, when the box can tell (`deployedHost`).
|
|
6
5
|
*/
|
|
7
6
|
export function formatAuthReport(status) {
|
|
8
|
-
const { provider, path, source, error, stored, shadowed, deployed
|
|
7
|
+
const { provider, path, source, error, stored, shadowed, deployed, local } = status;
|
|
9
8
|
const because = error === undefined ? "" : ` (${error})`;
|
|
10
|
-
const
|
|
9
|
+
const authOverride = local ? `FASTAGENT_AUTH_PATH='${local.authPath.replaceAll("'", "'\\''")}' ` : "";
|
|
10
|
+
const login = (name) => deployed
|
|
11
|
+
? `\`${name} --deployment ${deployed.host ?? "<host>"}\` from the agent directory this was deployed from`
|
|
12
|
+
: `\`${authOverride}${name}\``;
|
|
11
13
|
if (source !== undefined) {
|
|
12
14
|
const line = `auth: ${source} (${provider}) — ${path}`;
|
|
13
15
|
if (shadowed === undefined)
|
|
@@ -27,6 +29,6 @@ export function formatAuthReport(status) {
|
|
|
27
29
|
}
|
|
28
30
|
return {
|
|
29
31
|
line: `auth: (none found) — ${path}`,
|
|
30
|
-
warn: `no credentials for "${provider}"${because} — run ${login("fastagent login")}, or set the provider's API key in ${deployed ? "the deployment's value file" : ".env"}; invokes will fail until then`,
|
|
32
|
+
warn: `no credentials for "${provider}"${because} — run ${login("fastagent login")}, or set the provider's API key in ${deployed ? "the deployment's value file" : (local?.valueFile ?? ".env")}; invokes will fail until then`,
|
|
31
33
|
};
|
|
32
34
|
}
|
package/dist/cli/box-login.d.ts
CHANGED
|
@@ -1,32 +1,42 @@
|
|
|
1
1
|
import { type BoxShell } from "../deploy/box-shell.ts";
|
|
2
2
|
import type { DeployHost } from "../deploy/hosts.ts";
|
|
3
|
-
import type { LoginIO } from "../
|
|
4
|
-
import type {
|
|
3
|
+
import type { LoginIO, LoginMethod } from "../harnesses/models/login.ts";
|
|
4
|
+
import type { TicketStep } from "./ticket.ts";
|
|
5
5
|
export interface BoxLoginRequest {
|
|
6
6
|
host: DeployHost;
|
|
7
7
|
shell: BoxShell;
|
|
8
|
-
placement: ResolvedPlacement;
|
|
9
8
|
/** Skip the provider menu. */
|
|
10
9
|
provider?: string;
|
|
10
|
+
/** Skip the method menu. */
|
|
11
|
+
method?: LoginMethod;
|
|
11
12
|
/** Keep a credential the box already holds for `provider` (a redeploy), instead of replacing it. */
|
|
12
13
|
ifMissing?: boolean;
|
|
13
14
|
/** false: never ask; a box without the credential is a failure naming the command to run in a terminal. */
|
|
14
15
|
input: boolean;
|
|
16
|
+
/** Who answers what the box asks: this terminal by default, or a ticket's process ({@link ticketLoginIO}). */
|
|
17
|
+
io?: LoginIO;
|
|
15
18
|
}
|
|
16
19
|
/**
|
|
17
20
|
* Run the login on the box and report its outcome. Resolves `undefined` once the box reports a credential for the
|
|
18
21
|
* provider (logged in now, or kept), else with the one line saying why not and what to run.
|
|
19
22
|
*/
|
|
20
23
|
export declare function loginOnBox(request: BoxLoginRequest): Promise<string | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* A box's sign-in answered by a ticket's process, with no one at a terminal: what the person does is the ticket's
|
|
26
|
+
* (`need_user_action`), and what the box asks is answered as {@link signInInteraction} answers a local sign-in. A choice
|
|
27
|
+
* takes its first option, pi's default; a text question is left blank; the address the browser ended on comes from
|
|
28
|
+
* `login --check --code` (or the redirect {@link catchingRedirect} catches first); a secret it cannot take, and
|
|
29
|
+
* `refusal` says so, since the box only hears that the question was backed out of.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ticketLoginIO(step: TicketStep, retry: string): LoginIO & {
|
|
32
|
+
refusal(): string | undefined;
|
|
33
|
+
};
|
|
21
34
|
/**
|
|
22
35
|
* A browser OAuth flow sends the owner's browser back to its `redirect_uri`: a localhost address, which on the owner's
|
|
23
36
|
* machine has nothing of the box behind it. So catch it here. While an authorization URL naming such a redirect is
|
|
24
37
|
* open, listen on that address (the port the provider fixed, loopback only, as pi's own flows do), and answer the
|
|
25
|
-
*
|
|
38
|
+
* prompt for that address with the URL the browser brought back, exactly what the person would paste. The prompt
|
|
26
39
|
* stays up meanwhile: a taken port, or a browser on another machine, still leaves pasting.
|
|
27
|
-
*
|
|
28
|
-
* ponytail: "the next text prompt" is the one after the URL. pi's browser flows (Anthropic, Codex) ask exactly one,
|
|
29
|
-
* the paste; a flow that asked something else in between would get the URL as that answer and reject it.
|
|
30
40
|
*/
|
|
31
41
|
export declare function catchingRedirect(io: LoginIO): LoginIO & {
|
|
32
42
|
close(): void;
|
package/dist/cli/box-login.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* copied from this machine.
|
|
6
6
|
*/
|
|
7
7
|
import { createServer } from "node:http";
|
|
8
|
-
import { basename } from "node:path";
|
|
9
8
|
import { deploymentLoginCommand } from "../deploy/box-shell.js";
|
|
10
9
|
import { boxLoginCommand } from "../deploy/container.js";
|
|
11
10
|
import { relayLogin } from "./login-relay.js";
|
|
@@ -15,16 +14,17 @@ import { terminalLoginIO } from "./shared.js";
|
|
|
15
14
|
* provider (logged in now, or kept), else with the one line saying why not and what to run.
|
|
16
15
|
*/
|
|
17
16
|
export async function loginOnBox(request) {
|
|
18
|
-
const { host, shell,
|
|
17
|
+
const { host, shell, provider } = request;
|
|
19
18
|
const retry = deploymentLoginCommand(host, provider);
|
|
20
19
|
const args = [
|
|
21
20
|
...(provider ? [provider] : []),
|
|
21
|
+
...(request.method ? ["--method", request.method === "oauth" ? "account" : "api-key"] : []),
|
|
22
22
|
...(request.ifMissing ? ["--if-missing"] : []),
|
|
23
23
|
...(request.input ? [] : ["--no-input"]),
|
|
24
24
|
];
|
|
25
25
|
let command;
|
|
26
26
|
try {
|
|
27
|
-
command = boxLoginCommand(
|
|
27
|
+
command = boxLoginCommand(args, shell.storage);
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
30
|
return error.message;
|
|
@@ -36,7 +36,7 @@ export async function loginOnBox(request) {
|
|
|
36
36
|
const channel = await shell.open(command).catch((error) => error);
|
|
37
37
|
if (channel instanceof Error)
|
|
38
38
|
return channel.message;
|
|
39
|
-
const io = catchingRedirect(terminalLoginIO());
|
|
39
|
+
const io = catchingRedirect(request.io ?? terminalLoginIO());
|
|
40
40
|
const result = await relayLogin(channel.output, channel.input, io, (line) => console.error(line)).finally(io.close);
|
|
41
41
|
const closed = await channel.closed;
|
|
42
42
|
if (!closed.opened)
|
|
@@ -51,23 +51,55 @@ export async function loginOnBox(request) {
|
|
|
51
51
|
: `[fastagent] logged in to ${result.provider} (${result.method}) on the deployment — saved to ${result.path} there`);
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
|
-
if (result.reason === "missing")
|
|
55
|
-
|
|
54
|
+
if (result.reason === "missing") {
|
|
55
|
+
const forAgent = provider
|
|
56
|
+
? `fastagent login ${provider} --method account --deployment ${host} --json`
|
|
57
|
+
: `${retry} --json`;
|
|
58
|
+
return (`not logged in: ${result.message} — run \`${retry}\` in a terminal, or \`${forAgent}\` from a coding agent, ` +
|
|
59
|
+
`which hands the sign-in to its user`);
|
|
60
|
+
}
|
|
56
61
|
if (result.reason === "cancelled")
|
|
57
62
|
return `login on the deployment cancelled — run \`${retry}\` to log it in`;
|
|
58
63
|
return `login on the deployment failed: ${result.message}`;
|
|
59
64
|
}
|
|
60
65
|
const CAUGHT_PAGE = "<!doctype html><meta charset=utf-8><title>fastagent</title>" +
|
|
61
66
|
"<p>fastagent received the sign-in and sent it to your deployment. Return to your terminal.</p>";
|
|
67
|
+
/**
|
|
68
|
+
* A box's sign-in answered by a ticket's process, with no one at a terminal: what the person does is the ticket's
|
|
69
|
+
* (`need_user_action`), and what the box asks is answered as {@link signInInteraction} answers a local sign-in. A choice
|
|
70
|
+
* takes its first option, pi's default; a text question is left blank; the address the browser ended on comes from
|
|
71
|
+
* `login --check --code` (or the redirect {@link catchingRedirect} catches first); a secret it cannot take, and
|
|
72
|
+
* `refusal` says so, since the box only hears that the question was backed out of.
|
|
73
|
+
*/
|
|
74
|
+
export function ticketLoginIO(step, retry) {
|
|
75
|
+
let refusal;
|
|
76
|
+
return {
|
|
77
|
+
refusal: () => refusal,
|
|
78
|
+
select: async (_message, options) => options[0]?.value,
|
|
79
|
+
async prompt(message, opts) {
|
|
80
|
+
if (opts?.hidden) {
|
|
81
|
+
refusal = `the sign-in asks "${message}", which only a terminal can answer: run \`${retry}\` in one`;
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if (!opts?.redirect)
|
|
85
|
+
return "";
|
|
86
|
+
const address = await step
|
|
87
|
+
.address(opts.signal ? AbortSignal.any([opts.signal, step.signal]) : step.signal)
|
|
88
|
+
.catch(() => undefined);
|
|
89
|
+
if (address !== undefined)
|
|
90
|
+
step.person.carriesOn();
|
|
91
|
+
return address;
|
|
92
|
+
},
|
|
93
|
+
note: (message) => console.error(`[fastagent] ${message}`),
|
|
94
|
+
openUrl: (url, userCode) => step.waits(userCode ? { url, code: userCode } : { url, takesAddress: true }),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
62
97
|
/**
|
|
63
98
|
* A browser OAuth flow sends the owner's browser back to its `redirect_uri`: a localhost address, which on the owner's
|
|
64
99
|
* machine has nothing of the box behind it. So catch it here. While an authorization URL naming such a redirect is
|
|
65
100
|
* open, listen on that address (the port the provider fixed, loopback only, as pi's own flows do), and answer the
|
|
66
|
-
*
|
|
101
|
+
* prompt for that address with the URL the browser brought back, exactly what the person would paste. The prompt
|
|
67
102
|
* stays up meanwhile: a taken port, or a browser on another machine, still leaves pasting.
|
|
68
|
-
*
|
|
69
|
-
* ponytail: "the next text prompt" is the one after the URL. pi's browser flows (Anthropic, Codex) ask exactly one,
|
|
70
|
-
* the paste; a flow that asked something else in between would get the URL as that answer and reject it.
|
|
71
103
|
*/
|
|
72
104
|
export function catchingRedirect(io) {
|
|
73
105
|
let server;
|
|
@@ -125,11 +157,13 @@ export function catchingRedirect(io) {
|
|
|
125
157
|
select: io.select,
|
|
126
158
|
note: io.note,
|
|
127
159
|
close,
|
|
128
|
-
openUrl(url) {
|
|
160
|
+
openUrl(url, userCode) {
|
|
129
161
|
listen(url);
|
|
130
|
-
io.openUrl(url);
|
|
162
|
+
io.openUrl(url, userCode);
|
|
131
163
|
},
|
|
132
164
|
async prompt(message, opts) {
|
|
165
|
+
if (!opts?.redirect)
|
|
166
|
+
return io.prompt(message, opts);
|
|
133
167
|
if (caught !== undefined) {
|
|
134
168
|
const url = caught;
|
|
135
169
|
caught = undefined;
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { type ChannelKind } from "../../scaffold/add-channel.ts";
|
|
2
|
-
|
|
3
|
-
export declare function runAddChannel(channelKind: ChannelKind, dirArg: string, opts: {
|
|
2
|
+
export interface AddChannelOptions {
|
|
4
3
|
ingress?: string;
|
|
5
|
-
groupBehavior?: string;
|
|
6
4
|
onboard?: boolean;
|
|
7
5
|
replaceConfig?: boolean;
|
|
8
|
-
|
|
6
|
+
environment?: string;
|
|
7
|
+
/** false ⇔ `--no-input`. */
|
|
8
|
+
input?: boolean;
|
|
9
|
+
/** `--json`: the outcome as one JSON object on stdout. */
|
|
10
|
+
json?: boolean;
|
|
11
|
+
/** `--check <ticket>`: where an app's setup started without a terminal stands. */
|
|
12
|
+
check?: string;
|
|
13
|
+
/** `--timeout <seconds>`: how long a setup started without a terminal stays open. */
|
|
14
|
+
timeout?: string;
|
|
15
|
+
/** `--ticket <id>`: the process that runs a ticket's setup. */
|
|
16
|
+
ticket?: string;
|
|
17
|
+
}
|
|
18
|
+
/** `fastagent add <kind> [dir]`: scaffold `src/channels/<kind>.ts`, the adapter configured with a starter policy. */
|
|
19
|
+
export declare function runAddChannel(channelKind: ChannelKind, dirArg: string, opts: AddChannelOptions): Promise<void>;
|
|
9
20
|
/** `fastagent add skill <source> [dir]`: vendor an Agent Skills skill into <dir>/skills/<name>/. */
|
|
10
21
|
export declare function runAddSkill(source: string | undefined, dirArg: string, opts: {
|
|
11
22
|
update?: boolean;
|