@fastagent-sh/fastagent 0.21.1 → 0.22.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 +9 -12
- package/dist/agent.d.ts +24 -37
- package/dist/agent.js +7 -15
- package/dist/atomic-write.d.ts +13 -17
- package/dist/atomic-write.js +18 -29
- package/dist/bind.d.ts +12 -22
- package/dist/bind.js +18 -27
- package/dist/channel.d.ts +11 -33
- package/dist/channels/agentcore-limits.d.ts +2 -13
- package/dist/channels/agentcore-limits.js +2 -13
- package/dist/channels/agentcore-protocol.d.ts +67 -58
- package/dist/channels/agentcore-protocol.js +23 -15
- package/dist/channels/agentcore-service.d.ts +19 -33
- package/dist/channels/agentcore-service.js +176 -59
- package/dist/channels/agentcore.d.ts +39 -33
- package/dist/channels/agentcore.js +90 -224
- package/dist/channels/body.d.ts +15 -2
- package/dist/channels/body.js +24 -2
- package/dist/channels/busy.d.ts +1 -21
- package/dist/channels/busy.js +2 -39
- package/dist/channels/control.d.ts +17 -62
- package/dist/channels/control.js +74 -182
- package/dist/channels/define-channel.d.ts +39 -0
- package/dist/channels/define-channel.js +9 -0
- package/dist/channels/discover.d.ts +10 -31
- package/dist/channels/discover.js +37 -31
- package/dist/channels/feishu/bootstrap-token.d.ts +1 -8
- package/dist/channels/feishu/bootstrap-token.js +7 -23
- package/dist/channels/feishu/card.d.ts +14 -28
- package/dist/channels/feishu/card.js +16 -30
- package/dist/channels/feishu/cloud.d.ts +1 -5
- package/dist/channels/feishu/context-buffer.d.ts +4 -23
- package/dist/channels/feishu/context-buffer.js +8 -31
- package/dist/channels/feishu/crypto.d.ts +10 -5
- package/dist/channels/feishu/crypto.js +12 -19
- package/dist/channels/feishu/feishu-api.d.ts +2 -1
- package/dist/channels/feishu/feishu-api.js +5 -4
- package/dist/channels/feishu/feishu.d.ts +4 -10
- package/dist/channels/feishu/feishu.js +113 -227
- package/dist/channels/feishu/invoke-turn.d.ts +5 -4
- package/dist/channels/feishu/invoke-turn.js +36 -54
- package/dist/channels/feishu/model.d.ts +4 -21
- package/dist/channels/feishu/model.js +1 -8
- package/dist/channels/feishu/normalize.d.ts +2 -10
- package/dist/channels/feishu/normalize.js +7 -42
- package/dist/channels/feishu/parse.d.ts +9 -29
- package/dist/channels/feishu/parse.js +8 -26
- package/dist/channels/feishu/preview.d.ts +12 -14
- package/dist/channels/feishu/preview.js +108 -207
- package/dist/channels/feishu/register-app.d.ts +8 -23
- package/dist/channels/feishu/register-app.js +7 -20
- package/dist/channels/feishu/register-webhook.d.ts +2 -9
- package/dist/channels/feishu/register-webhook.js +9 -33
- package/dist/channels/feishu/scaffold/channel.ts +27 -19
- package/dist/channels/feishu/scaffold/channel.websocket.ts +31 -0
- package/dist/channels/feishu/setup-mode.d.ts +11 -36
- package/dist/channels/feishu/setup-mode.js +7 -26
- package/dist/channels/feishu/ws-ingress.d.ts +1 -2
- package/dist/channels/feishu/ws-ingress.js +6 -8
- package/dist/channels/http.d.ts +15 -15
- package/dist/channels/http.js +19 -9
- package/dist/channels/kit/attachment-path.d.ts +4 -5
- package/dist/channels/kit/attachment-path.js +10 -34
- package/dist/channels/kit/context-buffer.d.ts +14 -21
- package/dist/channels/kit/context-buffer.js +25 -38
- package/dist/channels/kit/delivery.d.ts +35 -0
- package/dist/channels/kit/delivery.js +129 -0
- package/dist/channels/kit/event-stream.d.ts +5 -0
- package/dist/channels/kit/event-stream.js +29 -0
- package/dist/channels/kit/invoke-turn-kit.d.ts +53 -26
- package/dist/channels/kit/invoke-turn-kit.js +89 -32
- package/dist/channels/kit/preview-kit.d.ts +18 -72
- package/dist/channels/kit/preview-kit.js +22 -88
- package/dist/channels/kit/signature.d.ts +3 -9
- package/dist/channels/kit/signature.js +3 -9
- package/dist/channels/kit/state.d.ts +1 -2
- package/dist/channels/kit/state.js +5 -14
- package/dist/channels/kit/stop-command.d.ts +1 -2
- package/dist/channels/kit/stop-command.js +6 -9
- package/dist/channels/kit/tasks.d.ts +1 -1
- package/dist/channels/kit/tasks.js +8 -21
- package/dist/channels/kit/text.d.ts +2 -16
- package/dist/channels/kit/text.js +23 -31
- package/dist/channels/kit/thread-participants.d.ts +4 -17
- package/dist/channels/kit/thread-participants.js +8 -55
- package/dist/channels/kit/transport.d.ts +26 -0
- package/dist/channels/kit/transport.js +20 -0
- package/dist/channels/kit/turn-queue.d.ts +7 -11
- package/dist/channels/kit/turn-queue.js +21 -39
- package/dist/channels/kit/turn-runner.d.ts +32 -18
- package/dist/channels/kit/turn-runner.js +98 -53
- package/dist/channels/kit/turn-store.d.ts +32 -32
- package/dist/channels/kit/turn-store.js +45 -88
- package/dist/channels/lark/lark.d.ts +1 -5
- package/dist/channels/lark/onboard.d.ts +3 -12
- package/dist/channels/lark/onboard.js +3 -13
- package/dist/channels/lark/scaffold/channel.ts +27 -19
- package/dist/channels/lark/scaffold/channel.websocket.ts +31 -0
- package/dist/channels/registration.d.ts +9 -35
- package/dist/channels/registration.js +6 -37
- package/dist/channels/secret.js +2 -5
- package/dist/channels/serve.d.ts +47 -44
- package/dist/channels/serve.js +165 -101
- package/dist/channels/slack/config-api.d.ts +4 -27
- package/dist/channels/slack/config-api.js +5 -34
- package/dist/channels/slack/context-buffer.d.ts +2 -3
- package/dist/channels/slack/context-buffer.js +5 -5
- package/dist/channels/slack/invoke-turn.d.ts +3 -1
- package/dist/channels/slack/invoke-turn.js +25 -34
- package/dist/channels/slack/manifest.js +1 -3
- package/dist/channels/slack/model.d.ts +1 -2
- package/dist/channels/slack/model.js +1 -1
- package/dist/channels/slack/onboard.d.ts +4 -3
- package/dist/channels/slack/onboard.js +8 -11
- package/dist/channels/slack/onboarding-state.d.ts +3 -5
- package/dist/channels/slack/onboarding-state.js +9 -6
- package/dist/channels/slack/parse.d.ts +4 -13
- package/dist/channels/slack/parse.js +7 -28
- package/dist/channels/slack/preview.d.ts +12 -2
- package/dist/channels/slack/preview.js +292 -269
- package/dist/channels/slack/reaction.d.ts +11 -3
- package/dist/channels/slack/reaction.js +19 -8
- package/dist/channels/slack/register-webhook.js +4 -7
- package/dist/channels/slack/scaffold/channel.ts +20 -13
- package/dist/channels/slack/scaffold/slack-send.ts +2 -2
- package/dist/channels/slack/setup-server.d.ts +1 -5
- package/dist/channels/slack/setup-server.js +1 -5
- package/dist/channels/slack/shared-api.d.ts +1 -4
- package/dist/channels/slack/shared-api.js +2 -13
- package/dist/channels/slack/slack-api.d.ts +2 -1
- package/dist/channels/slack/slack-api.js +6 -4
- package/dist/channels/slack/slack.d.ts +11 -14
- package/dist/channels/slack/slack.js +121 -122
- package/dist/channels/sse.d.ts +1 -1
- package/dist/channels/sse.js +1 -1
- package/dist/channels/telegram/context-buffer.d.ts +7 -22
- package/dist/channels/telegram/context-buffer.js +6 -23
- package/dist/channels/telegram/invoke-turn.d.ts +7 -7
- package/dist/channels/telegram/invoke-turn.js +24 -43
- package/dist/channels/telegram/parse.d.ts +24 -51
- package/dist/channels/telegram/parse.js +32 -84
- package/dist/channels/telegram/preview.d.ts +10 -1
- package/dist/channels/telegram/preview.js +79 -100
- package/dist/channels/telegram/register-webhook.js +5 -23
- package/dist/channels/telegram/scaffold/channel.ts +25 -18
- package/dist/channels/telegram/scaffold/telegram-send.ts +6 -4
- package/dist/channels/telegram/telegram-api.d.ts +4 -3
- package/dist/channels/telegram/telegram-api.js +9 -7
- package/dist/channels/telegram/telegram.d.ts +4 -18
- package/dist/channels/telegram/telegram.js +38 -94
- package/dist/channels/telegram/turn-store.d.ts +11 -14
- package/dist/channels/telegram/turn-store.js +8 -6
- package/dist/channels/wait-health.d.ts +4 -6
- package/dist/channels/wait-health.js +10 -14
- package/dist/cli/add-feishu.d.ts +2 -12
- package/dist/cli/add-feishu.js +24 -71
- package/dist/cli/add-slack.d.ts +5 -3
- package/dist/cli/add-slack.js +53 -76
- package/dist/cli/auth-view.d.ts +2 -16
- package/dist/cli/auth-view.js +2 -16
- package/dist/cli/commands/add.js +25 -40
- package/dist/cli/commands/chat.d.ts +0 -1
- package/dist/cli/commands/chat.js +5 -6
- package/dist/cli/commands/deploy/agentcore.js +60 -65
- package/dist/cli/commands/deploy/docker.js +50 -23
- package/dist/cli/commands/deploy/fly.js +23 -61
- package/dist/cli/commands/deploy/railway.js +23 -18
- package/dist/cli/commands/deploy/shared.d.ts +38 -57
- package/dist/cli/commands/deploy/shared.js +40 -59
- package/dist/cli/commands/deploy.d.ts +10 -27
- package/dist/cli/commands/deploy.js +38 -60
- package/dist/cli/commands/destroy.d.ts +4 -0
- package/dist/cli/commands/destroy.js +56 -0
- package/dist/cli/commands/dev.d.ts +2 -1
- package/dist/cli/commands/dev.js +20 -23
- package/dist/cli/commands/info.d.ts +0 -2
- package/dist/cli/commands/info.js +83 -49
- package/dist/cli/commands/init.d.ts +1 -2
- package/dist/cli/commands/init.js +16 -55
- package/dist/cli/commands/invoke.d.ts +0 -1
- package/dist/cli/commands/invoke.js +5 -7
- package/dist/cli/commands/login.d.ts +2 -1
- package/dist/cli/commands/login.js +33 -38
- package/dist/cli/commands/logs.js +3 -4
- package/dist/cli/commands/models.js +1 -5
- package/dist/cli/commands/routine-run.d.ts +6 -0
- package/dist/cli/commands/routine-run.js +47 -0
- package/dist/cli/commands/routine.d.ts +25 -0
- package/dist/cli/commands/routine.js +122 -0
- package/dist/cli/commands/start.d.ts +31 -3
- package/dist/cli/commands/start.js +131 -81
- package/dist/cli/commands/tool.js +26 -12
- package/dist/cli/fail.d.ts +13 -23
- package/dist/cli/fail.js +20 -23
- package/dist/cli/invoke-stream.d.ts +1 -8
- package/dist/cli/kernel.d.ts +6 -38
- package/dist/cli/kernel.js +14 -77
- package/dist/cli/models-view.d.ts +1 -9
- package/dist/cli/models-view.js +11 -22
- package/dist/cli/program.d.ts +5 -6
- package/dist/cli/program.js +120 -157
- package/dist/cli/serve.d.ts +57 -41
- package/dist/cli/serve.js +94 -121
- package/dist/cli/shared.d.ts +15 -61
- package/dist/cli/shared.js +55 -181
- package/dist/cli.js +1 -8
- package/dist/collect.d.ts +6 -0
- package/dist/collect.js +6 -0
- package/dist/core.d.ts +4 -1
- package/dist/core.js +9 -7
- package/dist/declared-secrets.d.ts +55 -0
- package/dist/declared-secrets.js +88 -0
- package/dist/deploy/agentcore/aws-cli.d.ts +91 -0
- package/dist/deploy/agentcore/aws-cli.js +64 -0
- package/dist/deploy/agentcore/destroy.d.ts +51 -0
- package/dist/deploy/agentcore/destroy.js +273 -0
- package/dist/deploy/agentcore/forwarder.js +28 -79
- package/dist/deploy/agentcore/logs.d.ts +2 -18
- package/dist/deploy/agentcore/logs.js +27 -51
- package/dist/deploy/agentcore/plan.d.ts +85 -105
- package/dist/deploy/agentcore/plan.js +152 -314
- package/dist/deploy/agentcore/run.d.ts +28 -28
- package/dist/deploy/agentcore/run.js +227 -306
- package/dist/deploy/agentcore/zip.d.ts +2 -15
- package/dist/deploy/agentcore/zip.js +3 -17
- package/dist/deploy/build-context.d.ts +21 -0
- package/dist/deploy/build-context.js +137 -0
- package/dist/deploy/channel-ingress.d.ts +26 -39
- package/dist/deploy/channel-ingress.js +57 -28
- package/dist/deploy/container.d.ts +20 -34
- package/dist/deploy/container.js +49 -100
- package/dist/deploy/docker/plan.d.ts +12 -11
- package/dist/deploy/docker/plan.js +43 -24
- package/dist/deploy/docker/run.d.ts +22 -25
- package/dist/deploy/docker/run.js +39 -37
- package/dist/deploy/fly/plan.d.ts +15 -44
- package/dist/deploy/fly/plan.js +41 -73
- package/dist/deploy/fly/run.d.ts +16 -51
- package/dist/deploy/fly/run.js +42 -95
- package/dist/deploy/hosts.d.ts +24 -3
- package/dist/deploy/hosts.js +24 -3
- package/dist/deploy/preflight.d.ts +47 -41
- package/dist/deploy/preflight.js +282 -383
- package/dist/deploy/railway/plan.d.ts +16 -42
- package/dist/deploy/railway/plan.js +42 -60
- package/dist/deploy/railway/run.d.ts +30 -68
- package/dist/deploy/railway/run.js +86 -100
- package/dist/deploy/registration-gate.d.ts +6 -13
- package/dist/deploy/residency.d.ts +37 -0
- package/dist/deploy/residency.js +24 -0
- package/dist/deploy/runner.d.ts +10 -9
- package/dist/deploy/runner.js +7 -18
- package/dist/deploy/secrets.d.ts +40 -41
- package/dist/deploy/secrets.js +117 -103
- package/dist/deploy/workspace.d.ts +50 -0
- package/dist/deploy/workspace.js +197 -0
- package/dist/dev-supervisor.d.ts +1 -9
- package/dist/dev-supervisor.js +21 -64
- package/dist/effect-port.d.ts +50 -0
- package/dist/effect-port.js +77 -0
- package/dist/engines/pi/agent-session-factory.d.ts +50 -69
- package/dist/engines/pi/agent-session-factory.js +249 -146
- package/dist/engines/pi/auth.d.ts +15 -11
- package/dist/engines/pi/auth.js +96 -99
- package/dist/engines/pi/chat.d.ts +1 -5
- package/dist/engines/pi/chat.js +2 -14
- package/dist/engines/pi/config.d.ts +53 -51
- package/dist/engines/pi/config.js +83 -92
- package/dist/engines/pi/create.d.ts +60 -75
- package/dist/engines/pi/create.js +108 -141
- package/dist/engines/pi/definition.d.ts +14 -58
- package/dist/engines/pi/definition.js +21 -85
- package/dist/engines/pi/invoke-session.d.ts +5 -25
- package/dist/engines/pi/invoke-session.js +209 -244
- package/dist/engines/pi/login.d.ts +95 -35
- package/dist/engines/pi/login.js +259 -107
- package/dist/engines/pi/machine.d.ts +31 -0
- package/dist/engines/pi/machine.js +106 -0
- package/dist/engines/pi/models.d.ts +70 -89
- package/dist/engines/pi/models.js +188 -81
- package/dist/engines/pi/open.d.ts +65 -53
- package/dist/engines/pi/open.js +129 -69
- package/dist/engines/pi/report.d.ts +3 -12
- package/dist/engines/pi/report.js +2 -16
- package/dist/engines/pi/search-tools.d.ts +1 -9
- package/dist/engines/pi/search-tools.js +26 -57
- package/dist/engines/pi/service.d.ts +2 -16
- package/dist/engines/pi/service.js +2 -16
- package/dist/engines/pi/session-builder.d.ts +5 -9
- package/dist/engines/pi/session-builder.js +44 -82
- package/dist/engines/pi/session-control.js +286 -269
- package/dist/engines/pi/session-effects.d.ts +14 -0
- package/dist/engines/pi/session-effects.js +30 -0
- package/dist/engines/pi/session-inheritance.d.ts +9 -18
- package/dist/engines/pi/session-inheritance.js +103 -160
- package/dist/engines/pi/session-markers.d.ts +31 -30
- package/dist/engines/pi/session-markers.js +26 -25
- package/dist/engines/pi/session-settings.d.ts +6 -22
- package/dist/engines/pi/session-settings.js +10 -21
- package/dist/engines/pi/session-store.d.ts +26 -92
- package/dist/engines/pi/session-store.js +96 -310
- package/dist/engines/pi/tool-context.d.ts +17 -45
- package/dist/engines/pi/tool-context.js +7 -26
- package/dist/engines/pi/tool.d.ts +45 -36
- package/dist/engines/pi/tool.js +43 -57
- package/dist/engines/pi/turn-kit.d.ts +14 -52
- package/dist/engines/pi/turn-kit.js +18 -67
- package/dist/engines/pi/wake-tool.d.ts +2 -10
- package/dist/engines/pi/wake-tool.js +7 -27
- package/dist/env.d.ts +27 -28
- package/dist/env.js +45 -50
- package/dist/index.js +0 -2
- package/dist/lark.d.ts +1 -2
- package/dist/lark.js +1 -2
- package/dist/loader.d.ts +14 -55
- package/dist/loader.js +24 -43
- package/dist/log.d.ts +2 -12
- package/dist/log.js +3 -24
- package/dist/node.d.ts +2 -15
- package/dist/node.js +2 -18
- package/dist/observe.d.ts +2 -8
- package/dist/open-url.d.ts +1 -1
- package/dist/open-url.js +1 -1
- package/dist/paths.d.ts +70 -134
- package/dist/paths.js +165 -232
- package/dist/pi.d.ts +4 -6
- package/dist/pi.js +3 -3
- package/dist/proxy.d.ts +16 -6
- package/dist/proxy.js +52 -16
- package/dist/runtime.d.ts +18 -12
- package/dist/runtime.js +18 -11
- package/dist/scaffold/add-channel.d.ts +14 -31
- package/dist/scaffold/add-channel.js +48 -112
- package/dist/scaffold/init.d.ts +9 -31
- package/dist/scaffold/init.js +45 -138
- package/dist/scaffold/templates/env.example +6 -4
- package/dist/scaffold/templates/fastagent.config.ts +36 -0
- package/dist/scaffold/templates.d.ts +3 -3
- package/dist/scaffold/templates.js +5 -8
- package/dist/scaffold/vendor-skill.d.ts +2 -5
- package/dist/scaffold/vendor-skill.js +19 -29
- package/dist/schedule/cron.d.ts +9 -5
- package/dist/schedule/cron.js +9 -11
- package/dist/schedule/discover.d.ts +12 -12
- package/dist/schedule/discover.js +43 -34
- package/dist/schedule/routine.d.ts +43 -0
- package/dist/schedule/routine.js +32 -0
- package/dist/schedule/run.d.ts +55 -0
- package/dist/schedule/run.js +146 -0
- package/dist/schedule/scheduler.d.ts +44 -55
- package/dist/schedule/scheduler.js +291 -265
- package/dist/schedule/state.d.ts +105 -10
- package/dist/schedule/state.js +293 -19
- package/dist/schedule/wake-alarm.d.ts +10 -23
- package/dist/schedule/wake-alarm.js +91 -121
- package/dist/schedule/wakeups.d.ts +23 -39
- package/dist/schedule/wakeups.js +33 -75
- package/dist/secrets-gate.d.ts +32 -0
- package/dist/secrets-gate.js +33 -0
- package/dist/service.d.ts +137 -98
- package/dist/service.js +250 -252
- package/dist/session-remote.d.ts +33 -44
- package/dist/session-remote.js +203 -192
- package/dist/session.d.ts +153 -228
- package/dist/session.js +33 -55
- package/dist/tunnel.d.ts +8 -36
- package/dist/tunnel.js +24 -65
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/package.json +10 -16
- package/dist/channels/agentcore-state.d.ts +0 -77
- package/dist/channels/agentcore-state.js +0 -276
- package/dist/channels/github/github.d.ts +0 -31
- package/dist/channels/github/github.js +0 -89
- package/dist/channels/github/scaffold/channel.ts +0 -25
- package/dist/cli/commands/attach.d.ts +0 -108
- package/dist/cli/commands/attach.js +0 -637
- package/dist/cli/commands/fire.d.ts +0 -7
- package/dist/cli/commands/fire.js +0 -38
- package/dist/cli/commands/schedule.d.ts +0 -12
- package/dist/cli/commands/schedule.js +0 -87
- package/dist/github.d.ts +0 -3
- package/dist/github.js +0 -2
- package/dist/scaffold/templates/fastagent.config.mjs +0 -23
- package/dist/schedule/audit.d.ts +0 -18
- package/dist/schedule/audit.js +0 -57
- package/dist/schedule/schedule.d.ts +0 -35
- package/dist/schedule/schedule.js +0 -23
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Minimal Slack Events/Web API shapes used by the first-party channel.
|
|
1
|
+
/** Minimal Slack Events/Web API shapes used by the first-party channel. */
|
|
2
2
|
export interface SlackFile {
|
|
3
3
|
id?: string;
|
|
4
4
|
name?: string;
|
|
@@ -57,7 +57,6 @@ export interface SlackEventEnvelope {
|
|
|
57
57
|
is_bot?: boolean;
|
|
58
58
|
}>;
|
|
59
59
|
}
|
|
60
|
-
/** A routed Slack turn. `threadTs:null` explicitly sends at channel top level. */
|
|
61
60
|
export interface SlackRoute {
|
|
62
61
|
session?: string;
|
|
63
62
|
channelId?: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/** Minimal Slack Events/Web API shapes used by the first-party channel.
|
|
1
|
+
/** Minimal Slack Events/Web API shapes used by the first-party channel. */
|
|
2
2
|
export {};
|
|
@@ -4,14 +4,13 @@ import { type SlackOnboardingState } from "./onboarding-state.ts";
|
|
|
4
4
|
export interface SlackOnboardIO {
|
|
5
5
|
note(message: string): void;
|
|
6
6
|
openUrl(url: string): void;
|
|
7
|
-
/** Wait for the one OAuth redirect.
|
|
7
|
+
/** Wait for the one OAuth redirect. */
|
|
8
8
|
waitForOAuth(): Promise<{
|
|
9
9
|
code?: string;
|
|
10
10
|
state?: string;
|
|
11
11
|
error?: string;
|
|
12
12
|
}>;
|
|
13
|
-
/** Stage the runtime secrets into the gitignored .env
|
|
14
|
-
* else: the client credentials are setup-only (the OAuth code exchange) and stay in onboarding state. */
|
|
13
|
+
/** Stage the runtime secrets into the gitignored .env. */
|
|
15
14
|
writeRuntimeSecrets(values: {
|
|
16
15
|
botToken?: string;
|
|
17
16
|
signingSecret?: string;
|
|
@@ -37,5 +36,7 @@ export declare function newSlackOnboardingState(input: {
|
|
|
37
36
|
groupBehavior: SlackGroupBehavior;
|
|
38
37
|
configToken: string;
|
|
39
38
|
configRefreshToken: string;
|
|
39
|
+
/** When the pair was captured; pass it through rather than re-deriving the same expiry twice. */
|
|
40
|
+
configTokenExpiresAt?: number;
|
|
40
41
|
now?: number;
|
|
41
42
|
}): SlackOnboardingState;
|
|
@@ -2,14 +2,16 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { retryWhile } from "../registration.js";
|
|
3
3
|
import { createSlackApp, exchangeSlackOAuthCode, isSlackRequestUrlUnverified, isSlackRotationLocked, SLACK_ROTATING_APP_UPGRADE, SlackConfigApiError, updateSlackAppManifest, } from "./config-api.js";
|
|
4
4
|
import { buildSlackManifest, slackBotScopes } from "./manifest.js";
|
|
5
|
-
import { currentSlackConfigToken, writeSlackOnboardingState } from "./onboarding-state.js";
|
|
5
|
+
import { configTokenExpiry, currentSlackConfigToken, writeSlackOnboardingState, } from "./onboarding-state.js";
|
|
6
6
|
/** Create/resume one internal Slack app and complete its workspace OAuth installation. */
|
|
7
7
|
export async function onboardSlackApp(input, io, deps = {}) {
|
|
8
8
|
let state = input.state;
|
|
9
9
|
const current = await currentSlackConfigToken(input.stateRoot, state);
|
|
10
10
|
state = current.state;
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
11
|
+
/**
|
|
12
|
+
* Slack challenges request_url from ITS network during a manifest call and validates the whole manifest before
|
|
13
|
+
* acting, so an unverifiable URL created nothing and the call is safe to repeat.
|
|
14
|
+
*/
|
|
13
15
|
const whileUnverified = (call, onRetry) => retryWhile(call, isSlackRequestUrlUnverified, {
|
|
14
16
|
attempts: deps.attempts,
|
|
15
17
|
retryMs: deps.retryMs,
|
|
@@ -37,10 +39,7 @@ export async function onboardSlackApp(input, io, deps = {}) {
|
|
|
37
39
|
let created;
|
|
38
40
|
try {
|
|
39
41
|
created = await whileUnverified(() => {
|
|
40
|
-
// Record BEFORE the non-idempotent API call.
|
|
41
|
-
// app; refusing a blind retry is safer than silently producing duplicates. The marker spans
|
|
42
|
-
// exactly one in-flight call: an unverifiable URL created nothing, so it comes off again before
|
|
43
|
-
// the wait — a Ctrl-C during that wait must not wedge the next run on an app that never existed.
|
|
42
|
+
// Record BEFORE the non-idempotent API call.
|
|
44
43
|
setMarker(new Date().toISOString());
|
|
45
44
|
return (deps.createApp ?? createSlackApp)(current.token, manifest);
|
|
46
45
|
}, () => setMarker(undefined));
|
|
@@ -95,8 +94,7 @@ export async function onboardSlackApp(input, io, deps = {}) {
|
|
|
95
94
|
authorize.searchParams.set("scope", slackBotScopes(state.groupBehavior).join(","));
|
|
96
95
|
authorize.searchParams.set("redirect_uri", input.redirectUrl);
|
|
97
96
|
authorize.searchParams.set("state", oauthState);
|
|
98
|
-
// The redirect lands on the tunnel hostname, which THIS machine may not resolve yet (#421)
|
|
99
|
-
// page beside a terminal that looks hung, unless the reload is named before it happens.
|
|
97
|
+
// The redirect lands on the tunnel hostname, which THIS machine may not resolve yet (#421).
|
|
100
98
|
io.note(`Click Allow in Slack to install the app: ${authorize}\nIf the page it returns to does not load, reload it.`);
|
|
101
99
|
io.openUrl(authorize.toString());
|
|
102
100
|
const callback = await io.waitForOAuth();
|
|
@@ -135,7 +133,6 @@ export function newSlackOnboardingState(input) {
|
|
|
135
133
|
groupBehavior: input.groupBehavior,
|
|
136
134
|
configToken: input.configToken,
|
|
137
135
|
configRefreshToken: input.configRefreshToken,
|
|
138
|
-
|
|
139
|
-
configTokenExpiresAt: (input.now ?? Date.now()) + 11 * 60 * 60_000,
|
|
136
|
+
configTokenExpiresAt: input.configTokenExpiresAt ?? configTokenExpiry(input.now),
|
|
140
137
|
};
|
|
141
138
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { SlackGroupBehavior } from "./manifest.ts";
|
|
2
|
+
/** When a token pair captured `now` stops being usable — the ONE place that answers it. */
|
|
3
|
+
export declare function configTokenExpiry(now?: number): number;
|
|
2
4
|
export interface SlackOnboardingState {
|
|
3
5
|
version: 1;
|
|
4
6
|
appName: string;
|
|
@@ -19,11 +21,7 @@ export interface SlackOnboardingState {
|
|
|
19
21
|
installedAt?: string;
|
|
20
22
|
}
|
|
21
23
|
export declare function readSlackOnboardingState(stateRoot: string): SlackOnboardingState | undefined;
|
|
22
|
-
/** Atomic replacement with owner-only permissions: this file carries a workspace-wide config refresh
|
|
23
|
-
* token. Synchronous, through the shared writer, like every other piece of state this repo keeps
|
|
24
|
-
* (kit/state.ts): the file is ~1 KB and its writers are `fastagent add slack` and one config-token
|
|
25
|
-
* rotation at tunnel startup, so the async spelling bought nothing and cost a fifth set of temp-name
|
|
26
|
-
* and permission rules to keep true. */
|
|
24
|
+
/** Atomic replacement with owner-only permissions: this file carries a workspace-wide config refresh token. */
|
|
27
25
|
export declare function writeSlackOnboardingState(stateRoot: string, state: SlackOnboardingState): void;
|
|
28
26
|
export declare function currentSlackConfigToken(stateRoot: string, state: SlackOnboardingState, options?: {
|
|
29
27
|
now?: number;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writeFileAtomic } from "../../atomic-write.js";
|
|
4
|
+
import { SECRET_FILE_MODE } from "../../paths.js";
|
|
4
5
|
import { rotateSlackConfigToken } from "./config-api.js";
|
|
6
|
+
/** Slack config access tokens expire in 12 hours; use 11h so registration rotates before the edge. */
|
|
7
|
+
const CONFIG_TOKEN_TTL_MS = 11 * 60 * 60_000;
|
|
8
|
+
/** When a token pair captured `now` stops being usable — the ONE place that answers it. */
|
|
9
|
+
export function configTokenExpiry(now = Date.now()) {
|
|
10
|
+
return now + CONFIG_TOKEN_TTL_MS;
|
|
11
|
+
}
|
|
5
12
|
function slackOnboardingStatePath(stateRoot) {
|
|
6
13
|
return join(stateRoot, "channels", "slack", "onboarding.json");
|
|
7
14
|
}
|
|
@@ -37,13 +44,9 @@ export function readSlackOnboardingState(stateRoot) {
|
|
|
37
44
|
throw new Error(`invalid Slack onboarding state ${file}: ${error.message}`);
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
|
-
/** Atomic replacement with owner-only permissions: this file carries a workspace-wide config refresh
|
|
41
|
-
* token. Synchronous, through the shared writer, like every other piece of state this repo keeps
|
|
42
|
-
* (kit/state.ts): the file is ~1 KB and its writers are `fastagent add slack` and one config-token
|
|
43
|
-
* rotation at tunnel startup, so the async spelling bought nothing and cost a fifth set of temp-name
|
|
44
|
-
* and permission rules to keep true. */
|
|
47
|
+
/** Atomic replacement with owner-only permissions: this file carries a workspace-wide config refresh token. */
|
|
45
48
|
export function writeSlackOnboardingState(stateRoot, state) {
|
|
46
|
-
writeFileAtomic(slackOnboardingStatePath(stateRoot), `${JSON.stringify(state, null, 2)}\n`,
|
|
49
|
+
writeFileAtomic(slackOnboardingStatePath(stateRoot), `${JSON.stringify(state, null, 2)}\n`, SECRET_FILE_MODE);
|
|
47
50
|
}
|
|
48
51
|
export async function currentSlackConfigToken(stateRoot, state, options = {}) {
|
|
49
52
|
const now = options.now ?? Date.now();
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { SlackEventEnvelope, SlackMessageEvent, SlackRoute } from "./model.ts";
|
|
2
2
|
export type { SlackEventEnvelope, SlackFile, SlackMessageEvent, SlackRoute } from "./model.ts";
|
|
3
|
-
/** Does this text address ANYONE — a user, a broadcast, or a user group?
|
|
3
|
+
/** Does this text address ANYONE — a user, a broadcast, or a user group? */
|
|
4
4
|
export declare function hasSlackMention(text: string): boolean;
|
|
5
|
-
/** Does this text mention a USER? Distinct from the above because only a user mention can be the bot:
|
|
6
|
-
* a broadcast never is, so it must not make a message look like a possible summon. */
|
|
7
5
|
export declare function hasSlackUserMention(text: string): boolean;
|
|
8
|
-
/** Does this text mention this specific user (either form)?
|
|
6
|
+
/** Does this text mention this specific user (either form)? */
|
|
9
7
|
export declare function mentionsSlackUser(text: string, userId: string): boolean;
|
|
10
8
|
/** Strip every mention, e.g. before matching a bare command word or building a title. */
|
|
11
9
|
export declare function stripSlackMentions(text: string, replacement?: string): string;
|
|
@@ -17,22 +15,15 @@ export declare function isSlackHumanMessage(event: SlackMessageEvent | undefined
|
|
|
17
15
|
};
|
|
18
16
|
export declare function isSlackDirectMessage(event: SlackMessageEvent): boolean;
|
|
19
17
|
export declare function isSlackGroupMessage(event: SlackMessageEvent): boolean;
|
|
20
|
-
/** Stable install identity.
|
|
18
|
+
/** Stable install identity. */
|
|
21
19
|
export declare function slackTeamId(envelope: SlackEventEnvelope): string | undefined;
|
|
22
20
|
export declare function slackFileIds(event: SlackMessageEvent): string[];
|
|
23
21
|
/** Text plus a structural marker for file-only or captioned file shares. */
|
|
24
22
|
export declare function slackMessageText(event: SlackMessageEvent): string;
|
|
25
23
|
export declare function slackSenderLabel(event: SlackMessageEvent): string;
|
|
26
|
-
/** Main-channel discussion and each concrete thread are independent context buckets.
|
|
27
|
-
*
|
|
28
|
-
* The `:root:` segment carries `thread_ts`, which in Slack IS the thread's parent message and is
|
|
29
|
-
* stable for the life of the thread — unrelated to the `<chat>:root:<root_id>` shape Feishu retired
|
|
30
|
-
* (its `root_id` moves with the reply chain, so it could not identify a side conversation at all).
|
|
31
|
-
* Same token, different platform meaning; the key is left as-is because renaming it would discard
|
|
32
|
-
* live context buckets for no semantic gain. */
|
|
24
|
+
/** Main-channel discussion and each concrete thread are independent context buckets. */
|
|
33
25
|
export declare function slackPlaceKey(teamId: string, event: Pick<SlackMessageEvent, "channel" | "thread_ts">): string;
|
|
34
26
|
export declare function slackBufferText(text: string): string;
|
|
35
|
-
/** Canonical prompt envelope. The channel/thread ids also give slack-send an explicit delivery target. */
|
|
36
27
|
export declare function slackEnvelope(envelope: SlackEventEnvelope): string;
|
|
37
28
|
/** Default explicit-summon policy: DMs and app_mention events only. */
|
|
38
29
|
export declare function defaultSlackRoute(envelope: SlackEventEnvelope): SlackRoute | null;
|
|
@@ -1,35 +1,21 @@
|
|
|
1
1
|
import { BUFFER_LINE_MAX_CHARS } from "../kit/context-buffer.js";
|
|
2
2
|
import { codePointPrefix, truncateCodePointPrefix } from "../kit/text.js";
|
|
3
3
|
const HUMAN_MESSAGE_SUBTYPES = new Set(["file_share", "thread_broadcast"]);
|
|
4
|
-
/**
|
|
5
|
-
* Both forms Slack writes a mention in: `<@U123>` and the labelled `<@U123|name>`. ONE definition,
|
|
6
|
-
* because the forms have to agree across every site that reads them — the "@-mentions only other
|
|
7
|
-
* people is discussion" guard, the structural bot-summon check, the stop-command strip, and the
|
|
8
|
-
* assistant-thread title. They drifted once: widening the first two while the strip still matched only
|
|
9
|
-
* the bare form turned `<@bot|name> stop` into an ordinary turn, queued behind the run it meant to stop.
|
|
10
|
-
*/
|
|
4
|
+
/** Both forms Slack writes a mention in: `<@U123>` and the labelled `<@U123|name>`. */
|
|
11
5
|
const mentionSource = (idPattern) => String.raw `<@${idPattern}(?:\|[^>]*)?>`;
|
|
12
6
|
const USER_MENTION = mentionSource("[A-Z0-9]+");
|
|
13
|
-
/** Broadcasts and user groups address people too: `<!here>`, `<!channel>`, `<!everyone>`,
|
|
14
|
-
* `<!subteam^S123|@team>`. Feishu's twin guard counts every mention, and the summon rule is supposed
|
|
15
|
-
* to be the same on both — without these, "@here can someone look at this" in a thread the agent takes
|
|
16
|
-
* part in reads as a bare message addressed to IT, and gets answered. */
|
|
7
|
+
/** Broadcasts and user groups address people too: `<!here>`, `<!channel>`, `<!everyone>`, `<!subteam^S123|@team>`. */
|
|
17
8
|
const ANY_MENTION = String.raw `(?:${USER_MENTION}|<!(?:here|channel|everyone)(?:\|[^>]*)?>|<!subteam\^[^>]*>)`;
|
|
18
|
-
/** Does this text address ANYONE — a user, a broadcast, or a user group?
|
|
9
|
+
/** Does this text address ANYONE — a user, a broadcast, or a user group? */
|
|
19
10
|
export function hasSlackMention(text) {
|
|
20
11
|
return new RegExp(ANY_MENTION, "i").test(text);
|
|
21
12
|
}
|
|
22
|
-
/** Does this text mention a USER? Distinct from the above because only a user mention can be the bot:
|
|
23
|
-
* a broadcast never is, so it must not make a message look like a possible summon. */
|
|
24
13
|
export function hasSlackUserMention(text) {
|
|
25
14
|
return new RegExp(USER_MENTION, "i").test(text);
|
|
26
15
|
}
|
|
27
|
-
/** Escape a platform-supplied id before it becomes part of a pattern.
|
|
28
|
-
* practice, but `auth.test`'s value is not validated here, and this runs on every group message: an
|
|
29
|
-
* unescaped metacharacter would either mis-answer the summon question or throw on the acceptance
|
|
30
|
-
* path, which Slack answers with an endless redelivery. */
|
|
16
|
+
/** Escape a platform-supplied id before it becomes part of a pattern. */
|
|
31
17
|
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
32
|
-
/** Does this text mention this specific user (either form)?
|
|
18
|
+
/** Does this text mention this specific user (either form)? */
|
|
33
19
|
export function mentionsSlackUser(text, userId) {
|
|
34
20
|
return new RegExp(mentionSource(escapeRegExp(userId)), "i").test(text);
|
|
35
21
|
}
|
|
@@ -51,7 +37,7 @@ export function isSlackDirectMessage(event) {
|
|
|
51
37
|
export function isSlackGroupMessage(event) {
|
|
52
38
|
return !isSlackDirectMessage(event) && (event.type === "app_mention" || event.channel_type !== undefined);
|
|
53
39
|
}
|
|
54
|
-
/** Stable install identity.
|
|
40
|
+
/** Stable install identity. */
|
|
55
41
|
export function slackTeamId(envelope) {
|
|
56
42
|
return (envelope.team_id ??
|
|
57
43
|
envelope.event?.team ??
|
|
@@ -75,13 +61,7 @@ export function slackMessageText(event) {
|
|
|
75
61
|
export function slackSenderLabel(event) {
|
|
76
62
|
return `user ${event.user ?? "unknown"}`;
|
|
77
63
|
}
|
|
78
|
-
/** Main-channel discussion and each concrete thread are independent context buckets.
|
|
79
|
-
*
|
|
80
|
-
* The `:root:` segment carries `thread_ts`, which in Slack IS the thread's parent message and is
|
|
81
|
-
* stable for the life of the thread — unrelated to the `<chat>:root:<root_id>` shape Feishu retired
|
|
82
|
-
* (its `root_id` moves with the reply chain, so it could not identify a side conversation at all).
|
|
83
|
-
* Same token, different platform meaning; the key is left as-is because renaming it would discard
|
|
84
|
-
* live context buckets for no semantic gain. */
|
|
64
|
+
/** Main-channel discussion and each concrete thread are independent context buckets. */
|
|
85
65
|
export function slackPlaceKey(teamId, event) {
|
|
86
66
|
const base = `${teamId}:${event.channel ?? "unknown-channel"}`;
|
|
87
67
|
return event.thread_ts ? `${base}:root:${event.thread_ts}` : base;
|
|
@@ -89,7 +69,6 @@ export function slackPlaceKey(teamId, event) {
|
|
|
89
69
|
export function slackBufferText(text) {
|
|
90
70
|
return truncateCodePointPrefix(text.replace(/\s+/g, " ").trim(), BUFFER_LINE_MAX_CHARS);
|
|
91
71
|
}
|
|
92
|
-
/** Canonical prompt envelope. The channel/thread ids also give slack-send an explicit delivery target. */
|
|
93
72
|
export function slackEnvelope(envelope) {
|
|
94
73
|
const event = envelope.event;
|
|
95
74
|
if (!event?.channel)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/** Slack reply rendering: native Agent streams first, rate-safe edited-message compatibility second. */
|
|
2
2
|
import type { AgentEvent } from "../../agent.ts";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Stream from "effect/Stream";
|
|
5
|
+
import { PortFailure } from "../../effect-port.ts";
|
|
3
6
|
import { type ChannelFailure, defaultErrorMessage } from "../kit/preview-kit.ts";
|
|
4
7
|
import { type SlackApi, type SlackTarget } from "./slack-api.ts";
|
|
5
8
|
export type SlackFailure = ChannelFailure;
|
|
@@ -12,12 +15,19 @@ export { defaultErrorMessage };
|
|
|
12
15
|
* across the many `<` start positions), while still neutralizing every `<@…>` / `<!…>` control sequence
|
|
13
16
|
* (real Slack controls never contain a `<`). */
|
|
14
17
|
export declare function sanitizeSlackMarkdown(markdown: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Deliver a reply this process did not generate: a recovered answer. The stream it was written for is gone with its
|
|
20
|
+
* process, so there is none to resume — but a compatibility queue message THIS process posted while the record
|
|
21
|
+
* waited its turn is taken over rather than left above the answer.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deliverSlackAnswer(api: SlackApi, target: SlackTarget, markdown: string, previewTs?: string): Promise<void>;
|
|
15
24
|
/** Settle a queue/drop/defer notice. These are authored plain strings, so the basic text API is enough. */
|
|
16
25
|
export declare function settleSlackPreview(api: SlackApi, target: SlackTarget, previewTs: string | undefined, text: string): Promise<void>;
|
|
17
|
-
export declare function
|
|
26
|
+
export declare function slackReply(events: Stream.Stream<AgentEvent, PortFailure>, api: SlackApi, target: SlackTarget, formatError: (failure: SlackFailure) => string | undefined, options?: {
|
|
18
27
|
rendering?: SlackRendering;
|
|
19
28
|
initialPreviewTs?: string;
|
|
20
29
|
threadTitle?: string;
|
|
21
30
|
disclaimer?: string | false;
|
|
22
31
|
label?: string;
|
|
23
|
-
|
|
32
|
+
onAnswered?: (answer: string) => void;
|
|
33
|
+
}): Effect.Effect<void, PortFailure, import("effect/Scope").Scope>;
|