@fastagent-sh/fastagent 0.29.0 → 0.30.1
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 -4
- package/dist/atomic-write.d.ts +4 -5
- package/dist/atomic-write.js +4 -5
- package/dist/authoring.d.ts +32 -15
- package/dist/authoring.js +147 -127
- package/dist/channels/agentcore-protocol.d.ts +8 -3
- package/dist/channels/agentcore-protocol.js +3 -1
- package/dist/channels/agentcore-service.d.ts +1 -0
- package/dist/channels/agentcore-service.js +14 -4
- package/dist/channels/agentcore.d.ts +9 -0
- package/dist/channels/agentcore.js +29 -4
- package/dist/channels/context.d.ts +2 -0
- package/dist/channels/context.js +5 -1
- package/dist/channels/feishu/feishu-api.d.ts +2 -1
- package/dist/channels/feishu/feishu.d.ts +0 -3
- package/dist/channels/feishu/feishu.js +10 -10
- package/dist/channels/feishu/register-app.js +3 -5
- package/dist/channels/feishu/scaffold/channel.ts +32 -34
- package/dist/channels/feishu/scaffold/feishu-send.ts +5 -5
- package/dist/channels/feishu/scaffold/feishu-threads.ts +3 -3
- package/dist/channels/feishu/setup-mode.d.ts +2 -12
- package/dist/channels/feishu/setup-mode.js +2 -22
- package/dist/channels/feishu/setup.d.ts +12 -0
- package/dist/channels/feishu/setup.js +197 -0
- package/dist/channels/kit/abortable.d.ts +8 -0
- package/dist/channels/kit/abortable.js +22 -0
- package/dist/channels/lark/lark.d.ts +0 -3
- package/dist/channels/lark/lark.js +0 -5
- package/dist/channels/lark/scaffold/channel.ts +33 -35
- package/dist/channels/lark/scaffold/lark-send.ts +5 -5
- package/dist/channels/lark/scaffold/lark-threads.ts +3 -3
- package/dist/channels/lark/setup.d.ts +9 -0
- package/dist/channels/lark/setup.js +57 -0
- package/dist/channels/setup.d.ts +112 -0
- package/dist/channels/setup.js +31 -0
- package/dist/channels/slack/history.js +1 -1
- package/dist/channels/slack/manifest.d.ts +17 -7
- package/dist/channels/slack/manifest.js +12 -16
- package/dist/channels/slack/scaffold/channel.ts +44 -30
- package/dist/channels/slack/scaffold/slack-send.ts +8 -8
- package/dist/channels/slack/scaffold/slack-threads.ts +4 -4
- package/dist/channels/slack/setup.d.ts +7 -0
- package/dist/channels/slack/setup.js +119 -0
- package/dist/channels/slack/slack-api.d.ts +2 -0
- package/dist/channels/slack/slack-api.js +4 -0
- package/dist/channels/slack/slack.d.ts +21 -2
- package/dist/channels/slack/slack.js +398 -338
- package/dist/channels/slack/socket.d.ts +57 -0
- package/dist/channels/slack/socket.js +305 -0
- package/dist/channels/telegram/polling.d.ts +27 -0
- package/dist/channels/telegram/polling.js +105 -0
- package/dist/channels/telegram/scaffold/channel.ts +52 -32
- package/dist/channels/telegram/scaffold/telegram-send.ts +9 -9
- package/dist/channels/telegram/setup.d.ts +2 -0
- package/dist/channels/telegram/setup.js +42 -0
- package/dist/channels/telegram/telegram-api.d.ts +27 -1
- package/dist/channels/telegram/telegram-api.js +7 -6
- package/dist/channels/telegram/telegram.d.ts +11 -3
- package/dist/channels/telegram/telegram.js +184 -157
- package/dist/channels/webhook-evidence.d.ts +11 -0
- package/dist/channels/webhook-evidence.js +71 -0
- package/dist/channels/webhooks.d.ts +37 -0
- package/dist/channels/webhooks.js +70 -0
- package/dist/child-env.d.ts +16 -0
- package/dist/child-env.js +30 -0
- package/dist/cli/box-login.js +4 -1
- package/dist/cli/channel-app.d.ts +3 -0
- package/dist/cli/channel-app.js +35 -0
- package/dist/cli/channel-setup.d.ts +38 -0
- package/dist/cli/channel-setup.js +195 -0
- package/dist/cli/commands/add.d.ts +6 -14
- package/dist/cli/commands/add.js +45 -303
- package/dist/cli/commands/auth.js +8 -2
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.js +16 -0
- package/dist/cli/commands/channels.d.ts +19 -0
- package/dist/cli/commands/channels.js +230 -0
- package/dist/cli/commands/content.d.ts +7 -3
- package/dist/cli/commands/content.js +16 -10
- package/dist/cli/commands/deploy/agentcore.js +55 -23
- package/dist/cli/commands/deploy/channel-apps.d.ts +17 -0
- package/dist/cli/commands/deploy/channel-apps.js +30 -0
- package/dist/cli/commands/deploy/docker.js +32 -65
- package/dist/cli/commands/deploy/fly.js +28 -12
- package/dist/cli/commands/deploy/railway.js +38 -13
- package/dist/cli/commands/deploy/secrets-step.d.ts +19 -0
- package/dist/cli/commands/deploy/secrets-step.js +66 -0
- package/dist/cli/commands/deploy/shared.d.ts +16 -5
- package/dist/cli/commands/deploy/shared.js +25 -8
- package/dist/cli/commands/deploy.js +53 -60
- package/dist/cli/commands/dev.d.ts +2 -0
- package/dist/cli/commands/dev.js +15 -3
- package/dist/cli/commands/env.js +1 -1
- package/dist/cli/commands/info.d.ts +2 -0
- package/dist/cli/commands/info.js +60 -25
- package/dist/cli/commands/init.js +3 -1
- package/dist/cli/commands/invoke.d.ts +2 -0
- package/dist/cli/commands/invoke.js +20 -7
- package/dist/cli/commands/login.d.ts +0 -7
- package/dist/cli/commands/login.js +22 -10
- package/dist/cli/commands/logout.js +1 -1
- package/dist/cli/commands/mcp.js +14 -6
- package/dist/cli/commands/models.js +3 -2
- package/dist/cli/commands/schedules.d.ts +4 -2
- package/dist/cli/commands/schedules.js +14 -10
- package/dist/cli/commands/secrets.d.ts +14 -0
- package/dist/cli/commands/secrets.js +213 -0
- package/dist/cli/commands/start.d.ts +14 -14
- package/dist/cli/commands/start.js +46 -60
- package/dist/cli/content-view.d.ts +4 -6
- package/dist/cli/content-view.js +5 -11
- package/dist/cli/first-run-channels.d.ts +3 -0
- package/dist/cli/first-run-channels.js +63 -0
- package/dist/cli/instance.d.ts +41 -0
- package/dist/cli/instance.js +155 -0
- package/dist/cli/invoke-stream.d.ts +5 -2
- package/dist/cli/invoke-stream.js +7 -2
- package/dist/cli/kernel.js +3 -0
- package/dist/cli/program.js +282 -110
- package/dist/cli/serve.d.ts +4 -5
- package/dist/cli/serve.js +4 -7
- package/dist/cli/shared.d.ts +11 -2
- package/dist/cli/shared.js +32 -19
- package/dist/cli/ticket.d.ts +7 -0
- package/dist/cli/ticket.js +106 -30
- package/dist/content/declare.d.ts +31 -37
- package/dist/content/declare.js +59 -60
- package/dist/content/file.d.ts +23 -12
- package/dist/content/file.js +48 -35
- package/dist/content/git.d.ts +0 -10
- package/dist/content/git.js +5 -39
- package/dist/content/resolve.d.ts +18 -22
- package/dist/content/resolve.js +32 -66
- package/dist/content/source.d.ts +7 -8
- package/dist/content/source.js +10 -28
- package/dist/credentials-page.d.ts +26 -0
- package/dist/credentials-page.js +185 -0
- package/dist/declared-secrets.d.ts +10 -3
- package/dist/declared-secrets.js +8 -4
- package/dist/deploy/agentcore/destroy.d.ts +4 -1
- package/dist/deploy/agentcore/destroy.js +25 -1
- package/dist/deploy/agentcore/forwarder.js +1 -1
- package/dist/deploy/agentcore/plan.d.ts +7 -21
- package/dist/deploy/agentcore/plan.js +47 -49
- package/dist/deploy/agentcore/run.d.ts +18 -10
- package/dist/deploy/agentcore/run.js +93 -70
- package/dist/deploy/agentcore/runtime-secrets.d.ts +7 -0
- package/dist/deploy/agentcore/runtime-secrets.js +108 -0
- package/dist/deploy/agentcore/shell.js +12 -19
- package/dist/deploy/agentcore/sigv4.d.ts +7 -0
- package/dist/deploy/agentcore/sigv4.js +15 -0
- package/dist/deploy/agentcore/slr.d.ts +18 -0
- package/dist/deploy/agentcore/slr.js +27 -0
- package/dist/deploy/agentcore/store.d.ts +7 -0
- package/dist/deploy/agentcore/store.js +115 -0
- package/dist/deploy/api.d.ts +14 -14
- package/dist/deploy/api.js +26 -24
- package/dist/deploy/box-shell.d.ts +3 -1
- package/dist/deploy/build-context.d.ts +4 -4
- package/dist/deploy/build-context.js +11 -15
- package/dist/deploy/channel-ingress.d.ts +35 -9
- package/dist/deploy/channel-ingress.js +119 -22
- package/dist/deploy/container.d.ts +35 -10
- package/dist/deploy/container.js +79 -37
- package/dist/deploy/delivered-text.d.ts +13 -0
- package/dist/deploy/delivered-text.js +86 -0
- package/dist/deploy/docker/plan.d.ts +7 -8
- package/dist/deploy/docker/plan.js +31 -52
- package/dist/deploy/docker/run.d.ts +5 -43
- package/dist/deploy/docker/run.js +9 -84
- package/dist/deploy/file-store.d.ts +2 -0
- package/dist/deploy/file-store.js +17 -0
- package/dist/deploy/fly/plan.d.ts +3 -2
- package/dist/deploy/fly/plan.js +20 -9
- package/dist/deploy/fly/run.d.ts +18 -8
- package/dist/deploy/fly/run.js +24 -42
- package/dist/deploy/fly/store.d.ts +12 -0
- package/dist/deploy/fly/store.js +83 -0
- package/dist/deploy/hosts.d.ts +1 -2
- package/dist/deploy/hosts.js +1 -2
- package/dist/deploy/preflight.d.ts +18 -5
- package/dist/deploy/preflight.js +135 -63
- package/dist/deploy/railway/ignore.d.ts +8 -0
- package/dist/deploy/railway/ignore.js +57 -0
- package/dist/deploy/railway/plan.d.ts +1 -2
- package/dist/deploy/railway/plan.js +8 -6
- package/dist/deploy/railway/run.d.ts +21 -15
- package/dist/deploy/railway/run.js +32 -78
- package/dist/deploy/railway/store.d.ts +29 -0
- package/dist/deploy/railway/store.js +143 -0
- package/dist/deploy/runner.d.ts +5 -2
- package/dist/deploy/runner.js +4 -3
- package/dist/deploy/secret-store.d.ts +63 -0
- package/dist/deploy/secret-store.js +98 -0
- package/dist/deploy/secrets.d.ts +29 -46
- package/dist/deploy/secrets.js +49 -122
- package/dist/deploy/workspace.d.ts +6 -12
- package/dist/deploy/workspace.js +18 -94
- package/dist/dev-supervisor.js +6 -8
- package/dist/environment/declare.js +3 -2
- package/dist/environment/mise.d.ts +3 -1
- package/dist/environment/mise.js +4 -2
- package/dist/feishu.d.ts +1 -1
- package/dist/feishu.js +1 -1
- package/dist/harnesses/models/catalog.d.ts +1 -0
- package/dist/harnesses/models/catalog.js +1 -2
- package/dist/harnesses/models/environment.d.ts +7 -2
- package/dist/harnesses/models/environment.js +9 -5
- package/dist/harnesses/models/host.d.ts +0 -7
- package/dist/harnesses/models/host.js +10 -1
- package/dist/harnesses/models/login.d.ts +0 -8
- package/dist/harnesses/models/login.js +5 -4
- package/dist/harnesses/models/models.d.ts +7 -2
- package/dist/harnesses/models/models.js +28 -4
- package/dist/harnesses/pi-durable/agent.js +59 -38
- package/dist/harnesses/pi-durable/build.d.ts +12 -0
- package/dist/harnesses/pi-durable/build.js +270 -0
- package/dist/harnesses/pi-durable/built.d.ts +24 -0
- package/dist/harnesses/pi-durable/built.js +136 -0
- package/dist/harnesses/pi-durable/config.d.ts +81 -0
- package/dist/harnesses/pi-durable/config.js +266 -0
- package/dist/harnesses/pi-durable/define.d.ts +63 -13
- package/dist/harnesses/pi-durable/define.js +23 -2
- package/dist/harnesses/pi-durable/definition.d.ts +72 -0
- package/dist/harnesses/pi-durable/definition.js +143 -0
- package/dist/harnesses/pi-durable/events.d.ts +4 -3
- package/dist/harnesses/pi-durable/events.js +179 -136
- package/dist/harnesses/pi-durable/execution-env.d.ts +17 -0
- package/dist/harnesses/pi-durable/execution-env.js +11 -0
- package/dist/harnesses/pi-durable/mcp.js +1 -3
- package/dist/harnesses/pi-durable/open.d.ts +35 -37
- package/dist/harnesses/pi-durable/open.js +91 -153
- package/dist/harnesses/pi-durable/reads.d.ts +0 -1
- package/dist/harnesses/pi-durable/reads.js +1 -3
- package/dist/harnesses/pi-durable/registry.d.ts +4 -6
- package/dist/harnesses/pi-durable/registry.js +29 -26
- package/dist/harnesses/pi-durable/release.d.ts +2 -2
- package/dist/harnesses/pi-durable/release.js +10 -7
- package/dist/harnesses/pi-durable/serve.d.ts +91 -15
- package/dist/harnesses/pi-durable/serve.js +109 -47
- package/dist/harnesses/pi-durable/sessions.js +15 -12
- package/dist/harnesses/pi-durable/text-sources.d.ts +30 -0
- package/dist/harnesses/pi-durable/text-sources.js +55 -0
- package/dist/harnesses/pi-durable/text.d.ts +16 -4
- package/dist/harnesses/pi-durable/text.js +115 -59
- package/dist/harnesses/pi-durable/wake.js +8 -8
- package/dist/http/client.js +9 -3
- package/dist/http/contract.d.ts +3 -3
- package/dist/http/server.d.ts +1 -1
- package/dist/http/server.js +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -1
- package/dist/instance-name.d.ts +7 -0
- package/dist/instance-name.js +26 -0
- package/dist/lark.d.ts +1 -1
- package/dist/lark.js +1 -1
- package/dist/mcp/client.js +11 -2
- package/dist/mcp/config.d.ts +70 -18
- package/dist/mcp/config.js +136 -53
- package/dist/mcp/host.d.ts +5 -2
- package/dist/mcp/host.js +14 -6
- package/dist/mcp/sign-in.js +2 -2
- package/dist/mcp-api.d.ts +14 -0
- package/dist/paths.d.ts +22 -8
- package/dist/paths.js +44 -11
- package/dist/runtime-websocket.d.ts +14 -0
- package/dist/runtime-websocket.js +39 -0
- package/dist/scaffold/add-channel.d.ts +9 -16
- package/dist/scaffold/add-channel.js +13 -83
- package/dist/scaffold/templates/env.example +4 -5
- package/dist/scaffold/templates/fastagent.config.ts +20 -14
- package/dist/scaffold/templates/gitignore +9 -6
- package/dist/scaffold/templates.d.ts +6 -2
- package/dist/scaffold/templates.js +7 -2
- package/dist/scaffold/vendor-skill.js +4 -2
- package/dist/service.d.ts +44 -6
- package/dist/service.js +110 -10
- package/dist/serving-command.d.ts +10 -0
- package/dist/serving-command.js +1 -0
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js +1 -1
- package/dist/strip-edges.d.ts +10 -0
- package/dist/strip-edges.js +22 -0
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +0 -1
- package/dist/tunnel.js +2 -8
- package/dist/value-file.d.ts +11 -6
- package/dist/value-file.js +21 -9
- package/dist/version.d.ts +7 -1
- package/dist/version.js +9 -3
- package/package.json +6 -5
- package/dist/channels/lark/credentials-page.d.ts +0 -25
- package/dist/channels/lark/credentials-page.js +0 -206
- package/dist/channels/lark/onboard.d.ts +0 -52
- package/dist/channels/lark/onboard.js +0 -86
- package/dist/channels/slack/config-api.d.ts +0 -69
- package/dist/channels/slack/config-api.js +0 -162
- package/dist/channels/slack/onboard.d.ts +0 -40
- package/dist/channels/slack/onboard.js +0 -136
- package/dist/channels/slack/onboarding-state.d.ts +0 -31
- package/dist/channels/slack/onboarding-state.js +0 -64
- package/dist/channels/slack/register-webhook.d.ts +0 -12
- package/dist/channels/slack/register-webhook.js +0 -67
- package/dist/channels/slack/setup-server.d.ts +0 -32
- package/dist/channels/slack/setup-server.js +0 -246
- package/dist/cli/add-feishu.d.ts +0 -41
- package/dist/cli/add-feishu.js +0 -391
- package/dist/cli/add-slack.d.ts +0 -18
- package/dist/cli/add-slack.js +0 -216
- package/dist/harnesses/pi-durable/parked.d.ts +0 -18
- package/dist/harnesses/pi-durable/parked.js +0 -27
package/dist/cli/add-slack.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Person } from "./person.ts";
|
|
2
|
-
/** Single-workspace internal-app creation + installation. */
|
|
3
|
-
export declare function onboardSlackInternalApp(input: {
|
|
4
|
-
/**
|
|
5
|
-
* The AGENT DIR — credentials land in its `.env` ({@link dotEnvPath}: `FASTAGENT_SECRETS_DIR` moves it, so messages
|
|
6
|
-
* print the resolved path rather than the default spelling).
|
|
7
|
-
*/
|
|
8
|
-
target: string;
|
|
9
|
-
stateRoot: string;
|
|
10
|
-
/** `--replace-config`: go straight to replacing the local App Configuration token pair. */
|
|
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;
|
|
18
|
-
}): Promise<void>;
|
package/dist/cli/add-slack.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { basename } from "node:path";
|
|
3
|
-
import { isCancel, log as clackLog, password, select, text as clackText } from "@clack/prompts";
|
|
4
|
-
import { dotEnvPath, parseEnvContent } from "../value-file.js";
|
|
5
|
-
import { openExternalUrl } from "../open-url.js";
|
|
6
|
-
import { appendChannelDotEnv } from "../scaffold/add-channel.js";
|
|
7
|
-
import { newSlackOnboardingState, onboardSlackApp } from "../channels/slack/onboard.js";
|
|
8
|
-
import { configTokenExpiry, readSlackOnboardingState, writeSlackOnboardingState, } from "../channels/slack/onboarding-state.js";
|
|
9
|
-
import { startSlackSetupServer } from "../channels/slack/setup-server.js";
|
|
10
|
-
import { startCloudflareTunnel } from "../tunnel.js";
|
|
11
|
-
/** Where an App Configuration token pair is generated. */
|
|
12
|
-
const SLACK_CONFIG_TOKEN_URL = "https://api.slack.com/apps";
|
|
13
|
-
async function promptValue(message, hidden = false, initialValue) {
|
|
14
|
-
const result = hidden ? await password({ message }) : await clackText({ message, initialValue });
|
|
15
|
-
if (isCancel(result))
|
|
16
|
-
throw new Error("Slack onboarding cancelled");
|
|
17
|
-
const value = String(result).trim();
|
|
18
|
-
if (!value)
|
|
19
|
-
throw new Error(`${message}: value is required`);
|
|
20
|
-
return value;
|
|
21
|
-
}
|
|
22
|
-
/** The one place an App Configuration token pair is asked for and validated. */
|
|
23
|
-
async function promptConfigTokens() {
|
|
24
|
-
console.error(`[fastagent] generate an App Configuration Token pair at ${SLACK_CONFIG_TOKEN_URL}`);
|
|
25
|
-
openExternalUrl(SLACK_CONFIG_TOKEN_URL);
|
|
26
|
-
const configToken = await promptValue("Slack configuration access token (xoxe.xoxp-…)", true);
|
|
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) {
|
|
32
|
-
if (!configToken.startsWith("xoxe.") || !configRefreshToken.startsWith("xoxe-")) {
|
|
33
|
-
throw new Error("invalid Slack configuration token prefix (expected xoxe. access + xoxe- refresh)");
|
|
34
|
-
}
|
|
35
|
-
return { configToken, configRefreshToken, configTokenExpiresAt: configTokenExpiry() };
|
|
36
|
-
}
|
|
37
|
-
/** Keep the saved token pair, or paste a fresh one? `--replace-config` answers without asking. */
|
|
38
|
-
async function chooseTokenAction(prompt) {
|
|
39
|
-
if (prompt.forced)
|
|
40
|
-
return "replace-config";
|
|
41
|
-
if (!prompt.asks)
|
|
42
|
-
return "keep";
|
|
43
|
-
const answer = await select({
|
|
44
|
-
message: prompt.message,
|
|
45
|
-
initialValue: "keep",
|
|
46
|
-
options: [
|
|
47
|
-
{ value: "keep", label: prompt.keepLabel },
|
|
48
|
-
{
|
|
49
|
-
value: "replace-config",
|
|
50
|
-
label: prompt.replaceLabel,
|
|
51
|
-
...(prompt.replaceHint ? { hint: prompt.replaceHint } : {}),
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
});
|
|
55
|
-
if (isCancel(answer))
|
|
56
|
-
throw new Error("Slack onboarding cancelled");
|
|
57
|
-
return answer;
|
|
58
|
-
}
|
|
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. */
|
|
90
|
-
export async function onboardSlackInternalApp(input) {
|
|
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();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async function onboard(input, freshTokens, endpoint) {
|
|
116
|
-
const { person } = input;
|
|
117
|
-
const asks = person === undefined;
|
|
118
|
-
let state = readSlackOnboardingState(input.stateRoot);
|
|
119
|
-
const resumed = state !== undefined;
|
|
120
|
-
if (input.replaceConfig && !state)
|
|
121
|
-
throw nothingToReplace();
|
|
122
|
-
if (state?.installedAt) {
|
|
123
|
-
const env = await readFile(dotEnvPath(input.target), "utf8")
|
|
124
|
-
.then(parseEnvContent)
|
|
125
|
-
.catch((error) => {
|
|
126
|
-
if (error.code === "ENOENT")
|
|
127
|
-
return new Map();
|
|
128
|
-
throw error;
|
|
129
|
-
});
|
|
130
|
-
const missingRuntime = ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"].filter((name) => !((process.env[name] ?? env.get(name))?.trim() ?? ""));
|
|
131
|
-
if (missingRuntime.length > 0) {
|
|
132
|
-
throw new Error(`Slack app ${state.appId ?? "(unknown)"} is installed but ${dotEnvPath(input.target)} is missing ` +
|
|
133
|
-
`${missingRuntime.join(", ")} — ` +
|
|
134
|
-
"restore them from the Slack app console, or delete the app + onboarding state and create a new one");
|
|
135
|
-
}
|
|
136
|
-
const action = await chooseTokenAction({
|
|
137
|
-
forced: input.replaceConfig === true,
|
|
138
|
-
asks,
|
|
139
|
-
message: `Slack app ${state.appId ?? "(unknown)"} is already installed${state.teamName ? ` in ${state.teamName}` : ""}`,
|
|
140
|
-
keepLabel: "Keep the installed app",
|
|
141
|
-
replaceLabel: "Replace App Configuration tokens",
|
|
142
|
-
replaceHint: "repair automatic dev/deploy Request URL updates",
|
|
143
|
-
});
|
|
144
|
-
if (action === "replace-config") {
|
|
145
|
-
writeSlackOnboardingState(input.stateRoot, { ...state, ...(await freshTokens()) });
|
|
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.");
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
console.error("[fastagent] keeping the installed Slack app and local configuration tokens");
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if (!state) {
|
|
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()) });
|
|
164
|
-
writeSlackOnboardingState(input.stateRoot, state);
|
|
165
|
-
}
|
|
166
|
-
if (state.createAttemptedAt && !state.appId) {
|
|
167
|
-
throw new Error(`a prior Slack app creation attempt at ${state.createAttemptedAt} returned no app ID — ` +
|
|
168
|
-
`inspect ${SLACK_CONFIG_TOKEN_URL}; delete any incomplete app and ${input.stateRoot}/channels/slack/onboarding.json before retrying`);
|
|
169
|
-
}
|
|
170
|
-
// `--replace-config` also covers the created-but-not-installed state, where a revoked token would otherwise strand
|
|
171
|
-
// the resume (rotation fails and no menu offers replacement).
|
|
172
|
-
if (resumed && (!state.appId || input.replaceConfig)) {
|
|
173
|
-
const action = await chooseTokenAction({
|
|
174
|
-
forced: input.replaceConfig === true,
|
|
175
|
-
asks,
|
|
176
|
-
message: "Resume Slack onboarding with which App Configuration tokens?",
|
|
177
|
-
keepLabel: "Use the saved token pair",
|
|
178
|
-
replaceLabel: "Paste a fresh token pair",
|
|
179
|
-
});
|
|
180
|
-
if (action === "replace-config") {
|
|
181
|
-
state = { ...state, ...(await freshTokens()) };
|
|
182
|
-
writeSlackOnboardingState(input.stateRoot, state);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
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)}`);
|
|
216
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What becomes of a task pi-durable's crash-loop guard parked (`settings.restartLimit`: cut off by a crash that many
|
|
3
|
-
* times in a row, with no progress between). Left parked, the message it was answering stays `running` for ever with
|
|
4
|
-
* nothing to say why (SPEC.md §5.4 ends a message that cannot be answered `failed`). Parked is a state the task keeps,
|
|
5
|
-
* which `inspect()` shows as blocked for `restart_limit`: it is read from there, and not from the one `task_parked`
|
|
6
|
-
* report an open makes, so a process that dies half way, or a step that fails, is finished by the next open.
|
|
7
|
-
*/
|
|
8
|
-
import type { Context } from "@earendil-works/chord/context";
|
|
9
|
-
import { type Harness } from "@earendil-works/pi-durable";
|
|
10
|
-
/**
|
|
11
|
-
* Settle the messages each parked task was answering `unanswered` for {@link RESTART_LIMIT_REASON}, and abort the task,
|
|
12
|
-
* which frees its session. The settlement comes first: an abort alone settles them `aborted`, which reads as a
|
|
13
|
-
* cancellation nobody asked for, and the first settlement of a submission stands (measured). Both steps can be run
|
|
14
|
-
* again over their own result: the run stays until the abort's handler ends it, so a task left half way is found
|
|
15
|
-
* parked, and finished, by the next open. A parked task that is not its conversation's run (a tool's, a compaction's)
|
|
16
|
-
* is only aborted: the run goes on without it.
|
|
17
|
-
*/
|
|
18
|
-
export declare function giveUpOnParked(harness: Harness, context: Context): Promise<void>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { LiveDoc } from "@earendil-works/pi-durable";
|
|
2
|
-
import { log } from "../../log.js";
|
|
3
|
-
const RESTART_LIMIT_REASON = "restart_limit";
|
|
4
|
-
const DETAIL = "The process was cut off repeatedly while answering this message, so it was given up on";
|
|
5
|
-
/**
|
|
6
|
-
* Settle the messages each parked task was answering `unanswered` for {@link RESTART_LIMIT_REASON}, and abort the task,
|
|
7
|
-
* which frees its session. The settlement comes first: an abort alone settles them `aborted`, which reads as a
|
|
8
|
-
* cancellation nobody asked for, and the first settlement of a submission stands (measured). Both steps can be run
|
|
9
|
-
* again over their own result: the run stays until the abort's handler ends it, so a task left half way is found
|
|
10
|
-
* parked, and finished, by the next open. A parked task that is not its conversation's run (a tool's, a compaction's)
|
|
11
|
-
* is only aborted: the run goes on without it.
|
|
12
|
-
*/
|
|
13
|
-
export async function giveUpOnParked(harness, context) {
|
|
14
|
-
const parked = (await harness.inspect(context)).tasks.filter(({ state }) => state.kind === "blocked" && state.reason === RESTART_LIMIT_REASON);
|
|
15
|
-
for (const { record } of parked) {
|
|
16
|
-
await harness.commit(async (tx) => {
|
|
17
|
-
const run = (await tx.doc(LiveDoc, record.conversationId))?.run;
|
|
18
|
-
if (run?.taskId !== record.id)
|
|
19
|
-
return;
|
|
20
|
-
for (const id of run.inputs) {
|
|
21
|
-
tx.settleSubmission(id, { status: "unanswered", reason: RESTART_LIMIT_REASON, detail: DETAIL });
|
|
22
|
-
}
|
|
23
|
-
}, context);
|
|
24
|
-
await harness.abortTask(record.id, context);
|
|
25
|
-
log.warn(`[fastagent] gave up on ${record.kind} task ${record.id} of conversation ${record.conversationId}: it was parked`);
|
|
26
|
-
}
|
|
27
|
-
}
|