@andreprado/agentkit 0.1.1 → 0.2.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 +8 -77
- package/docs/guides/add-channel.md +14 -92
- package/docs/guides/add-knowledge.md +0 -21
- package/docs/guides/add-tool.md +5 -11
- package/docs/guides/channel-security.md +3 -207
- package/docs/guides/connect-discord.md +7 -172
- package/docs/guides/connect-slack.md +6 -121
- package/docs/guides/connect-telegram.md +6 -165
- package/docs/guides/connect-whatsapp-evolution.md +6 -116
- package/docs/guides/connect-whatsapp-uazapi.md +6 -134
- package/docs/guides/connect-whatsapp-zapster.md +6 -202
- package/docs/guides/create-agent.md +5 -14
- package/docs/guides/debug-channel.md +4 -156
- package/docs/guides/improve-local.md +13 -0
- package/docs/guides/local-only-migration.md +35 -0
- package/docs/guides/replay-local-traces.md +11 -0
- package/docs/guides/run-evals.md +2 -4
- package/docs/guides/security-rules.md +5 -154
- package/docs/guides/use-jev.md +3 -6
- package/docs/guides/use-provider.md +0 -3
- package/docs/guides/write-feedback.md +10 -0
- package/docs/llms-full.txt +27 -448
- package/docs/llms.txt +8 -44
- package/package.json +2 -4
- package/src/cli/commands/channels.ts +8 -1613
- package/src/cli/commands/feedback.ts +8 -86
- package/src/cli/constants.ts +0 -3
- package/src/cli/flags.ts +0 -28
- package/src/cli/help.ts +16 -92
- package/src/cli/index.ts +15 -1091
- package/src/index.ts +6 -158
- package/src/providers/pi.ts +2 -0
- package/src/runtime/channels/discord.ts +2 -2
- package/src/runtime/chat.ts +5 -3
- package/src/runtime/config.ts +14 -148
- package/src/runtime/database.ts +2 -2
- package/src/runtime/dev-server.ts +8 -8
- package/src/runtime/env.ts +11 -0
- package/src/runtime/improve.ts +2 -262
- package/src/runtime/inspect.ts +13 -73
- package/src/runtime/knowledge/ingest.ts +1 -1
- package/src/runtime/knowledge/tool.ts +16 -2
- package/src/runtime/knowledge/vector.ts +1 -1
- package/src/runtime/tool-runner.ts +5 -3
- package/src/runtime/tools.ts +10 -14
- package/src/storage/sqlite.ts +11 -32
- package/src/templates/blank.ts +15 -102
- package/src/templates/common.ts +60 -0
- package/src/templates/dentista.ts +7 -74
- package/src/templates/skills/agentkit-capsule/SKILL.md +5 -7
- package/src/templates/skills/agentkit-capsule/references/docs-router.md +2 -3
- package/src/templates/skills/agentkit-channels/SKILL.md +6 -119
- package/src/templates/skills/agentkit-channels/references/channel-buffering.md +0 -9
- package/src/templates/skills/agentkit-channels/references/channel-debugging.md +1 -64
- package/src/templates/skills/agentkit-channels/references/discord.md +2 -92
- package/src/templates/skills/agentkit-channels/references/slack.md +2 -55
- package/src/templates/skills/agentkit-channels/references/telegram.md +2 -71
- package/src/templates/skills/agentkit-channels/references/whatsapp-evolution.md +2 -56
- package/src/templates/skills/agentkit-channels/references/whatsapp-uazapi.md +2 -53
- package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +2 -70
- package/src/templates/skills/agentkit-database/SKILL.md +2 -4
- package/src/templates/skills/agentkit-evals/SKILL.md +1 -1
- package/src/templates/skills/agentkit-improve/SKILL.md +6 -85
- package/src/templates/skills/agentkit-improve/references/trace-packets.md +1 -1
- package/src/templates/skills/agentkit-provider/SKILL.md +0 -1
- package/src/templates/skills/agentkit-security/SKILL.md +1 -3
- package/src/templates/skills/agentkit-tools/SKILL.md +1 -1
- package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +1 -2
- package/src/templates/skills/agentkit-troubleshooting/SKILL.md +5 -11
- package/src/templates/support.ts +8 -92
- package/docs/guides/add-managed-composio.md +0 -165
- package/docs/guides/improve-from-production.md +0 -151
- package/docs/guides/prepare-deploy.md +0 -227
- package/docs/guides/replay-production-traces.md +0 -72
- package/docs/guides/send-feedback.md +0 -135
- package/src/cli/cloud-client.ts +0 -377
- package/src/cli/deploy-chat-ui.ts +0 -606
- package/src/cli/deploy-readiness.ts +0 -561
- package/src/cloud/artifact.ts +0 -139
- package/src/cloud/client.ts +0 -80
- package/src/cloud/contracts.ts +0 -63
- package/src/cloud/index.ts +0 -3
- package/src/runtime/build.ts +0 -43
- package/src/runtime/core/deploy-state.ts +0 -54
- package/src/runtime/core/manifest.ts +0 -283
- package/src/runtime/core/targets.ts +0 -133
- package/src/runtime/deploy-readiness.ts +0 -135
- package/src/runtime/deploy.ts +0 -1
- package/src/runtime/integrations/composio.ts +0 -425
- package/src/runtime/targets/cloudflare/build.ts +0 -3319
- package/src/runtime/targets/container/build.ts +0 -146
- package/src/runtime/targets/container/server.ts +0 -33
- package/src/runtime/targets/vps/deploy.ts +0 -223
- package/src/templates/skills/agentkit-deploy/SKILL.md +0 -52
- package/src/templates/skills/agentkit-integrations/SKILL.md +0 -98
package/src/cli/index.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { join, relative, resolve } from "node:path";
|
|
5
5
|
|
|
6
6
|
import { createProject } from "../create-project";
|
|
7
|
-
import { buildAgentCapsule } from "../runtime/build";
|
|
8
7
|
import { findAgentCapsuleRoot, loadAgentCapsule } from "../runtime/config";
|
|
9
|
-
import { readLocalDeployStateIfExists, type LocalDeployState } from "../runtime/core/deploy-state";
|
|
10
|
-
import { resolveBuildTarget, resolveDeployTarget } from "../runtime/core/targets";
|
|
11
8
|
import { getConversationFromCwd, listConversationsFromCwd } from "../runtime/conversations";
|
|
12
9
|
import { getConversationTraceFromCwd } from "../runtime/traces";
|
|
13
10
|
import { runAgentMessageFromCwd } from "../runtime/chat";
|
|
14
|
-
import { deployBuildToAgentKitCloud, writeLocalDeployState } from "../runtime/deploy";
|
|
15
11
|
import {
|
|
16
12
|
migrateLocalDatabase,
|
|
17
13
|
openLocalDatabaseShell,
|
|
@@ -21,57 +17,23 @@ import {
|
|
|
21
17
|
import { runEvalsFromCwd, writeEvalFromConversation } from "../runtime/evals";
|
|
22
18
|
import { findAgentKitDocs } from "../runtime/docs";
|
|
23
19
|
import { listCapsuleEnv, setCapsuleEnv, unsetCapsuleEnv } from "../runtime/env";
|
|
24
|
-
import {
|
|
20
|
+
import { collectLocalImproveBundle, generateImproveEvals, replayImproveBundle } from "../runtime/improve";
|
|
25
21
|
import { checkAgentSpec, initializeAgentSpec } from "../runtime/spec";
|
|
26
22
|
import { checkDefaultSkillStatus, syncDefaultSkillFiles } from "../runtime/skills";
|
|
27
23
|
import { initializeSyncScaffold, runCapsuleSync } from "../runtime/sync";
|
|
28
24
|
import { runToolFromCwd } from "../runtime/tool-runner";
|
|
29
25
|
import { startAgentDevServer } from "../runtime/dev-server";
|
|
30
26
|
import { inspectAgentCapsule } from "../runtime/inspect";
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import { parseArgs, isHelpRequested, type ParsedArgs } from "./args";
|
|
27
|
+
import { isAgentKitError } from "../runtime/errors";
|
|
28
|
+
import { parseArgs, isHelpRequested } from "./args";
|
|
34
29
|
import { resolveNewProjectName } from "./new-command";
|
|
35
30
|
import {
|
|
36
31
|
defaultAgentKitDevPort,
|
|
37
|
-
defaultDeployChatAccessTokenName,
|
|
38
|
-
defaultDeployChatAccessTokenPath,
|
|
39
32
|
} from "./constants";
|
|
40
33
|
import {
|
|
41
|
-
clearCloudAuth,
|
|
42
|
-
cloudApiRequest,
|
|
43
|
-
readCloudAuth,
|
|
44
|
-
readCloudAuthForApiUrl,
|
|
45
|
-
readCloudError,
|
|
46
|
-
resolveCloudApiUrl,
|
|
47
|
-
verifyCloudLogin,
|
|
48
|
-
writeCloudAuth,
|
|
49
|
-
type AccountApiTokenCreateResponse,
|
|
50
|
-
type AccountApiTokenListResponse,
|
|
51
|
-
type BillingCheckoutIntentResponse,
|
|
52
|
-
type BillingCheckoutResponse,
|
|
53
|
-
type BillingClaimResponse,
|
|
54
|
-
type BillingPortalResponse,
|
|
55
|
-
type CloudMeResponse,
|
|
56
|
-
type DeployAccessTokenCreateResponse,
|
|
57
|
-
type DeployAccessTokenListResponse,
|
|
58
|
-
} from "./cloud-client";
|
|
59
|
-
import {
|
|
60
|
-
checkDeployReadiness,
|
|
61
|
-
formatDeployCloudAuthSummary,
|
|
62
|
-
formatDeployOnlineCapacity,
|
|
63
|
-
formatReadinessError,
|
|
64
|
-
printDeployReadinessReport,
|
|
65
|
-
resolveProjectIdForSecretCommand,
|
|
66
|
-
syncHostedSecretsFromLocal,
|
|
67
|
-
} from "./deploy-readiness";
|
|
68
|
-
import { readDeployAccessTokenForUi, startDeployChatUiServer } from "./deploy-chat-ui";
|
|
69
|
-
import {
|
|
70
|
-
parseCloudApiUrl,
|
|
71
34
|
parseOptionalStringFlag,
|
|
72
35
|
parsePort,
|
|
73
36
|
parseRequiredStringFlag,
|
|
74
|
-
parseTargetFlag,
|
|
75
37
|
resolveSecretInputValue,
|
|
76
38
|
} from "./flags";
|
|
77
39
|
import { renderCommandHelp, renderCommandReference, renderHelp } from "./help";
|
|
@@ -82,7 +44,6 @@ import { handleFeedbackCommand } from "./commands/feedback";
|
|
|
82
44
|
import { handleKnowledgeCommand } from "./commands/knowledge";
|
|
83
45
|
import { handleTranscribeCommand } from "./commands/transcribe";
|
|
84
46
|
|
|
85
|
-
const hostedDeployEntitlement = "agentkit_cloud_deploy";
|
|
86
47
|
|
|
87
48
|
async function main() {
|
|
88
49
|
const args = parseArgs(process.argv.slice(2));
|
|
@@ -113,6 +74,10 @@ async function main() {
|
|
|
113
74
|
throw new Error("Usage: agentkit help [commands]");
|
|
114
75
|
}
|
|
115
76
|
|
|
77
|
+
if (args.flags.deploy !== undefined || args.flags.api !== undefined || args.flags.target !== undefined) {
|
|
78
|
+
throw new Error("AgentKit runs locally. Hosted --deploy, --api, and --target options are no longer supported.");
|
|
79
|
+
}
|
|
80
|
+
|
|
116
81
|
warnIfUnsupportedNode();
|
|
117
82
|
|
|
118
83
|
if (args.command === "provider") {
|
|
@@ -147,7 +112,6 @@ async function main() {
|
|
|
147
112
|
console.log(" Codex starts at skills/agentkit-capsule/SKILL.md and treats your request as the brief");
|
|
148
113
|
console.log(' npm run chat -- --message "hello"');
|
|
149
114
|
console.log(" npm run dev");
|
|
150
|
-
console.log(" npm run agentkit -- deploy");
|
|
151
115
|
console.log("");
|
|
152
116
|
console.log("Optional: manage local secrets with `printf %s \"$VALUE\" | npm run agentkit -- env set <NAME> --stdin`.");
|
|
153
117
|
return;
|
|
@@ -189,37 +153,6 @@ async function main() {
|
|
|
189
153
|
return;
|
|
190
154
|
}
|
|
191
155
|
|
|
192
|
-
if (args.command === "chat-ui") {
|
|
193
|
-
if (!args.flags.deploy) {
|
|
194
|
-
throw new Error("Usage: agentkit chat-ui --deploy [--port <number>] [--token-file <path>]");
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const requestedPort = parsePort(args.flags.port, "agentkit chat-ui --deploy --port <number>");
|
|
198
|
-
const port = requestedPort ?? 4124;
|
|
199
|
-
const tokenFile = parseOptionalStringFlag(
|
|
200
|
-
args.flags["token-file"],
|
|
201
|
-
"token-file",
|
|
202
|
-
"agentkit chat-ui --deploy --token-file <path>",
|
|
203
|
-
);
|
|
204
|
-
const server = await startDeployChatUiServer(process.cwd(), {
|
|
205
|
-
port,
|
|
206
|
-
tokenFile,
|
|
207
|
-
autoPort: requestedPort === undefined,
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
console.log("AgentKit hosted chat UI running");
|
|
211
|
-
console.log("");
|
|
212
|
-
if (server.portConflict) {
|
|
213
|
-
console.log(`Port ${server.portConflict.port} is already used. Started hosted chat UI at ${server.url}.`);
|
|
214
|
-
console.log("");
|
|
215
|
-
}
|
|
216
|
-
console.log(`Chat: ${server.url}`);
|
|
217
|
-
console.log(`Production: ${server.deployUrl}`);
|
|
218
|
-
console.log(`Token: ${server.tokenSource}`);
|
|
219
|
-
await waitForShutdown(server.stop);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
156
|
if (args.command === "chat") {
|
|
224
157
|
const message = args.flags.message;
|
|
225
158
|
const conversationId = parseOptionalStringFlag(
|
|
@@ -373,32 +306,7 @@ async function main() {
|
|
|
373
306
|
"agentkit improve collect --conversation-id <id>",
|
|
374
307
|
);
|
|
375
308
|
const out = parseOptionalStringFlag(args.flags.out, "out", "agentkit improve collect --out <directory>");
|
|
376
|
-
const
|
|
377
|
-
const apiUrl = args.flags.deploy === true ? await resolveCloudApiUrl(args.flags.api) : null;
|
|
378
|
-
const cloudAuth = apiUrl ? await readCloudAuthForApiUrl(apiUrl) : null;
|
|
379
|
-
const result = args.flags.deploy === true
|
|
380
|
-
? await collectDeployImproveBundle(process.cwd(), {
|
|
381
|
-
deployId: deployState?.deploy_id ?? "",
|
|
382
|
-
since,
|
|
383
|
-
conversationId,
|
|
384
|
-
out,
|
|
385
|
-
collector: {
|
|
386
|
-
...(cloudAuth && apiUrl && deployState
|
|
387
|
-
? {
|
|
388
|
-
exportEvidence: (input: { deployId: string; since?: string; conversationId?: string }) =>
|
|
389
|
-
fetchDeployImproveEvidence(apiUrl, input),
|
|
390
|
-
}
|
|
391
|
-
: {}),
|
|
392
|
-
listConversations: () => fetchDeployConversationJson(process.cwd(), "/v1/conversations"),
|
|
393
|
-
getTrace: (id: string) =>
|
|
394
|
-
fetchDeployConversationJson(process.cwd(), `/v1/conversations/${encodeURIComponent(id)}/trace`),
|
|
395
|
-
},
|
|
396
|
-
})
|
|
397
|
-
: await collectLocalImproveBundle(process.cwd(), {
|
|
398
|
-
since,
|
|
399
|
-
conversationId,
|
|
400
|
-
out,
|
|
401
|
-
});
|
|
309
|
+
const result = await collectLocalImproveBundle(process.cwd(), { since, conversationId, out });
|
|
402
310
|
|
|
403
311
|
console.log("Improve bundle collected");
|
|
404
312
|
console.log(`Source: ${result.source}`);
|
|
@@ -437,7 +345,7 @@ async function main() {
|
|
|
437
345
|
return;
|
|
438
346
|
}
|
|
439
347
|
|
|
440
|
-
throw new Error("Usage: agentkit improve collect [--
|
|
348
|
+
throw new Error("Usage: agentkit improve collect [--since <duration|iso>] [--conversation-id <id>] [--out <directory>] | agentkit improve evals <bundle-dir-or-json> [--force]");
|
|
441
349
|
}
|
|
442
350
|
|
|
443
351
|
if (args.command === "replay") {
|
|
@@ -479,14 +387,8 @@ async function main() {
|
|
|
479
387
|
|
|
480
388
|
if (args.command === "conversations") {
|
|
481
389
|
const [subcommand, conversationId] = args.positional;
|
|
482
|
-
const fromDeploy = args.flags.deploy === true;
|
|
483
390
|
|
|
484
391
|
if (subcommand === "list") {
|
|
485
|
-
if (fromDeploy) {
|
|
486
|
-
const payload = await fetchDeployConversationJson(process.cwd(), "/v1/conversations");
|
|
487
|
-
printJson(payload);
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
392
|
|
|
491
393
|
const conversations = await listConversationsFromCwd(process.cwd());
|
|
492
394
|
|
|
@@ -513,16 +415,7 @@ async function main() {
|
|
|
513
415
|
|
|
514
416
|
if (subcommand === "show") {
|
|
515
417
|
if (!conversationId) {
|
|
516
|
-
throw new Error("Missing conversation id. Usage: agentkit conversations show <conversation-id>
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
if (fromDeploy) {
|
|
520
|
-
const payload = await fetchDeployConversationJson(
|
|
521
|
-
process.cwd(),
|
|
522
|
-
`/v1/conversations/${encodeURIComponent(conversationId)}`,
|
|
523
|
-
);
|
|
524
|
-
printJson(payload);
|
|
525
|
-
return;
|
|
418
|
+
throw new Error("Missing conversation id. Usage: agentkit conversations show <conversation-id>");
|
|
526
419
|
}
|
|
527
420
|
|
|
528
421
|
const conversation = await getConversationFromCwd(process.cwd(), conversationId);
|
|
@@ -541,16 +434,7 @@ async function main() {
|
|
|
541
434
|
|
|
542
435
|
if (subcommand === "trace") {
|
|
543
436
|
if (!conversationId) {
|
|
544
|
-
throw new Error("Missing conversation id. Usage: agentkit conversations trace <conversation-id>
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
if (fromDeploy) {
|
|
548
|
-
const trace = await fetchDeployConversationJson(
|
|
549
|
-
process.cwd(),
|
|
550
|
-
`/v1/conversations/${encodeURIComponent(conversationId)}/trace`,
|
|
551
|
-
);
|
|
552
|
-
printJson(trace);
|
|
553
|
-
return;
|
|
437
|
+
throw new Error("Missing conversation id. Usage: agentkit conversations trace <conversation-id>");
|
|
554
438
|
}
|
|
555
439
|
|
|
556
440
|
const trace = await getConversationTraceFromCwd(process.cwd(), conversationId);
|
|
@@ -558,7 +442,7 @@ async function main() {
|
|
|
558
442
|
return;
|
|
559
443
|
}
|
|
560
444
|
|
|
561
|
-
throw new Error("Usage: agentkit conversations list
|
|
445
|
+
throw new Error("Usage: agentkit conversations list | agentkit conversations show <conversation-id> | agentkit conversations trace <conversation-id>");
|
|
562
446
|
}
|
|
563
447
|
|
|
564
448
|
if (args.command === "knowledge") {
|
|
@@ -648,505 +532,6 @@ async function main() {
|
|
|
648
532
|
return;
|
|
649
533
|
}
|
|
650
534
|
|
|
651
|
-
if (args.command === "build") {
|
|
652
|
-
const target = resolveBuildTarget(parseTargetFlag(args.flags.target, "build"));
|
|
653
|
-
const result = await buildAgentCapsule(process.cwd(), { target: target.id });
|
|
654
|
-
printBuildResult(result);
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
if (args.command === "login") {
|
|
659
|
-
const token = parseRequiredStringFlag(args.flags.token, "token", "agentkit login --token <token> [--api <url>]");
|
|
660
|
-
const apiUrl = parseCloudApiUrl(args.flags.api);
|
|
661
|
-
const verified = await verifyCloudLogin(apiUrl, token);
|
|
662
|
-
await writeCloudAuth({ apiUrl, token });
|
|
663
|
-
const email = verified.me.account?.email;
|
|
664
|
-
console.log(email ? `Logged in to AgentKit Cloud as ${email}.` : "AgentKit Cloud token verified and stored.");
|
|
665
|
-
|
|
666
|
-
const hasHostedDeploy = (verified.capabilities.capabilities ?? []).some(
|
|
667
|
-
(capability) =>
|
|
668
|
-
(capability.name === "cloudflare_deploy_alpha" || capability.name === hostedDeployEntitlement) &&
|
|
669
|
-
capability.status === "active",
|
|
670
|
-
);
|
|
671
|
-
console.log(
|
|
672
|
-
hasHostedDeploy
|
|
673
|
-
? "Entitlement: hosted deploy active."
|
|
674
|
-
: `Warning: cloudflare_deploy_alpha or ${hostedDeployEntitlement} entitlement was not found for this account.`,
|
|
675
|
-
);
|
|
676
|
-
|
|
677
|
-
if (process.env.AGENTKIT_CLOUD_API_TOKEN && process.env.AGENTKIT_CLOUD_API_TOKEN !== token) {
|
|
678
|
-
console.log("Warning: AGENTKIT_CLOUD_API_TOKEN is set and will override this saved login in the current shell.");
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
return;
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
if (args.command === "logout") {
|
|
685
|
-
await clearCloudAuth();
|
|
686
|
-
console.log("AgentKit Cloud token removed.");
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
if (args.command === "account") {
|
|
691
|
-
const [noun, verb, value] = args.positional;
|
|
692
|
-
|
|
693
|
-
if (noun !== "token") {
|
|
694
|
-
throw new Error("Usage: agentkit account token create <name> [--use] [--out <path>] | list | revoke <token-id> [--api <url>]");
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
698
|
-
|
|
699
|
-
if (verb === "create" && value) {
|
|
700
|
-
const payload = (await cloudApiRequest(apiUrl, "/v1/account/tokens", {
|
|
701
|
-
method: "POST",
|
|
702
|
-
body: JSON.stringify({ name: value }),
|
|
703
|
-
})) as AccountApiTokenCreateResponse;
|
|
704
|
-
const token = payload.token;
|
|
705
|
-
|
|
706
|
-
if (!token?.token || !token.id) {
|
|
707
|
-
throw new AgentKitError("account_token_invalid", "AgentKit Cloud returned an invalid account token payload.");
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
const outPath = parseOptionalStringFlag(
|
|
711
|
-
args.flags.out,
|
|
712
|
-
"out",
|
|
713
|
-
"agentkit account token create <name> [--api <url>] [--use] [--out <path>]",
|
|
714
|
-
);
|
|
715
|
-
|
|
716
|
-
if (outPath) {
|
|
717
|
-
const absolutePath = resolve(process.cwd(), outPath);
|
|
718
|
-
await writeSecretJson(absolutePath, payload);
|
|
719
|
-
console.log(`Account token written to ${absolutePath}`);
|
|
720
|
-
} else {
|
|
721
|
-
printJson(payload);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
if (args.flags.use === true) {
|
|
725
|
-
await writeCloudAuth({ apiUrl, token: token.token });
|
|
726
|
-
console.log(`Saved ${token.id} as the current AgentKit Cloud login.`);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
if (verb === "list" && !value) {
|
|
733
|
-
const payload = (await cloudApiRequest(apiUrl, "/v1/account/tokens", {
|
|
734
|
-
method: "GET",
|
|
735
|
-
})) as AccountApiTokenListResponse;
|
|
736
|
-
printJson(payload);
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
if (verb === "revoke" && value) {
|
|
741
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/account/tokens/${encodeURIComponent(value)}/revoke`, {
|
|
742
|
-
method: "POST",
|
|
743
|
-
});
|
|
744
|
-
printJson(payload);
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
throw new Error("Usage: agentkit account token create <name> [--use] [--out <path>] | list | revoke <token-id> [--api <url>]");
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
if (args.command === "billing") {
|
|
752
|
-
const [subcommand, intentId] = args.positional;
|
|
753
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
754
|
-
|
|
755
|
-
if (subcommand === "checkout") {
|
|
756
|
-
const slots = parsePositiveIntegerFlag(
|
|
757
|
-
args.flags.slots,
|
|
758
|
-
"slots",
|
|
759
|
-
"agentkit billing checkout --slots <count> [--email <email>] [--api <url>]",
|
|
760
|
-
);
|
|
761
|
-
const email = parseOptionalStringFlag(
|
|
762
|
-
args.flags.email,
|
|
763
|
-
"email",
|
|
764
|
-
"agentkit billing checkout --slots <count> --email <email>",
|
|
765
|
-
);
|
|
766
|
-
const payload = (await cloudApiRequest(apiUrl, "/v1/billing/checkout", {
|
|
767
|
-
method: "POST",
|
|
768
|
-
body: JSON.stringify({
|
|
769
|
-
slots,
|
|
770
|
-
...(email ? { email } : {}),
|
|
771
|
-
}),
|
|
772
|
-
})) as BillingCheckoutResponse;
|
|
773
|
-
const checkoutUrl = payload.checkout?.url;
|
|
774
|
-
const billingIntentId = payload.billing_intent?.id;
|
|
775
|
-
const secret = payload.billing_intent?.secret;
|
|
776
|
-
|
|
777
|
-
if (!checkoutUrl || !billingIntentId || !secret) {
|
|
778
|
-
throw new AgentKitError("billing_checkout_invalid", "AgentKit Cloud returned an invalid billing checkout payload.");
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
if (args.flags.json === true) {
|
|
782
|
-
printJson(payload);
|
|
783
|
-
} else {
|
|
784
|
-
console.log("AgentKit Cloud checkout");
|
|
785
|
-
console.log("");
|
|
786
|
-
console.log(`URL: ${checkoutUrl}`);
|
|
787
|
-
console.log(`Intent: ${billingIntentId}`);
|
|
788
|
-
console.log(`Secret: ${secret}`);
|
|
789
|
-
console.log("");
|
|
790
|
-
console.log(`After payment: agentkit billing claim ${billingIntentId} --secret ${secret} --api ${apiUrl}`);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
if (args.flags.open === true) {
|
|
794
|
-
await openLocalUrl(checkoutUrl);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
if (subcommand === "status" && intentId) {
|
|
801
|
-
const secret = parseRequiredStringFlag(
|
|
802
|
-
args.flags.secret,
|
|
803
|
-
"secret",
|
|
804
|
-
"agentkit billing status <billing-intent-id> --secret <secret> [--api <url>]",
|
|
805
|
-
);
|
|
806
|
-
const payload = (await cloudApiRequest(
|
|
807
|
-
apiUrl,
|
|
808
|
-
`/v1/billing/checkout-intents/${encodeURIComponent(intentId)}?secret=${encodeURIComponent(secret)}`,
|
|
809
|
-
{ method: "GET" },
|
|
810
|
-
)) as BillingCheckoutIntentResponse;
|
|
811
|
-
printJson(payload);
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (subcommand === "claim" && intentId) {
|
|
816
|
-
const secret = parseRequiredStringFlag(
|
|
817
|
-
args.flags.secret,
|
|
818
|
-
"secret",
|
|
819
|
-
"agentkit billing claim <billing-intent-id> --secret <secret> [--token-name <name>] [--api <url>]",
|
|
820
|
-
);
|
|
821
|
-
const tokenName = parseOptionalStringFlag(
|
|
822
|
-
args.flags["token-name"],
|
|
823
|
-
"token-name",
|
|
824
|
-
"agentkit billing claim <billing-intent-id> --secret <secret> --token-name <name>",
|
|
825
|
-
);
|
|
826
|
-
const payload = (await cloudApiRequest(apiUrl, `/v1/billing/checkout-intents/${encodeURIComponent(intentId)}/claim`, {
|
|
827
|
-
method: "POST",
|
|
828
|
-
body: JSON.stringify({
|
|
829
|
-
secret,
|
|
830
|
-
...(tokenName ? { token_name: tokenName } : {}),
|
|
831
|
-
}),
|
|
832
|
-
})) as BillingClaimResponse;
|
|
833
|
-
const token = payload.token;
|
|
834
|
-
|
|
835
|
-
if (!token?.token || !token.id) {
|
|
836
|
-
throw new AgentKitError("billing_claim_invalid", "AgentKit Cloud returned an invalid billing claim payload.");
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
await writeCloudAuth({ apiUrl, token: token.token });
|
|
840
|
-
|
|
841
|
-
const outPath = parseOptionalStringFlag(
|
|
842
|
-
args.flags.out,
|
|
843
|
-
"out",
|
|
844
|
-
"agentkit billing claim <billing-intent-id> --secret <secret> [--out <path>]",
|
|
845
|
-
);
|
|
846
|
-
|
|
847
|
-
if (outPath) {
|
|
848
|
-
const absolutePath = resolve(process.cwd(), outPath);
|
|
849
|
-
await writeSecretJson(absolutePath, payload);
|
|
850
|
-
console.log(`Account token written to ${absolutePath}`);
|
|
851
|
-
} else if (args.flags.json === true) {
|
|
852
|
-
printJson(payload);
|
|
853
|
-
} else {
|
|
854
|
-
console.log("AgentKit Cloud account token claimed and saved.");
|
|
855
|
-
console.log(`Token: ${token.id}`);
|
|
856
|
-
console.log(`API: ${apiUrl}`);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
return;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
if (subcommand === "portal") {
|
|
863
|
-
const payload = (await cloudApiRequest(apiUrl, "/v1/billing/portal", {
|
|
864
|
-
method: "POST",
|
|
865
|
-
body: JSON.stringify({}),
|
|
866
|
-
})) as BillingPortalResponse;
|
|
867
|
-
const portalUrl = payload.portal?.url;
|
|
868
|
-
|
|
869
|
-
if (!portalUrl) {
|
|
870
|
-
throw new AgentKitError("billing_portal_invalid", "AgentKit Cloud returned an invalid billing portal payload.");
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
if (args.flags.json === true) {
|
|
874
|
-
printJson(payload);
|
|
875
|
-
} else {
|
|
876
|
-
console.log("AgentKit Cloud billing portal");
|
|
877
|
-
console.log(`URL: ${portalUrl}`);
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
if (args.flags.open === true) {
|
|
881
|
-
await openLocalUrl(portalUrl);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
return;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
throw new Error(
|
|
888
|
-
"Usage: agentkit billing checkout --slots <count> [--email <email>] | status <intent-id> --secret <secret> | claim <intent-id> --secret <secret> | portal [--api <url>]",
|
|
889
|
-
);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (args.command === "deploy") {
|
|
893
|
-
const [deploySubcommand] = args.positional;
|
|
894
|
-
|
|
895
|
-
if (deploySubcommand === "smoke") {
|
|
896
|
-
const message =
|
|
897
|
-
parseOptionalStringFlag(args.flags.message ?? args.flags.smoke, "message", 'agentkit deploy smoke --message "hello"') ??
|
|
898
|
-
"hello";
|
|
899
|
-
const state = await requireLocalDeployState();
|
|
900
|
-
const token = await readDeployAccessTokenForHostedRequest(process.cwd());
|
|
901
|
-
await runDeploySmoke({
|
|
902
|
-
deployUrl: requireDeployUrl(state),
|
|
903
|
-
message,
|
|
904
|
-
token,
|
|
905
|
-
});
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
if (deploySubcommand === "doctor") {
|
|
910
|
-
const report = await checkDeployReadiness({
|
|
911
|
-
apiUrl: await resolveCloudApiUrl(args.flags.api),
|
|
912
|
-
requireLogin: !args.flags.anonymous,
|
|
913
|
-
});
|
|
914
|
-
printDeployReadinessReport(report);
|
|
915
|
-
|
|
916
|
-
if (!report.ok) {
|
|
917
|
-
process.exitCode = 1;
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
if (deploySubcommand === "status" || deploySubcommand === "pause" || deploySubcommand === "resume") {
|
|
924
|
-
const state = await requireLocalDeployState();
|
|
925
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
926
|
-
|
|
927
|
-
if (deploySubcommand === "status") {
|
|
928
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/deploys/${encodeURIComponent(state.deploy_id)}`, {
|
|
929
|
-
method: "GET",
|
|
930
|
-
});
|
|
931
|
-
printJson(payload);
|
|
932
|
-
return;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/deploys/${encodeURIComponent(state.deploy_id)}/${deploySubcommand}`, {
|
|
936
|
-
method: "POST",
|
|
937
|
-
});
|
|
938
|
-
printJson(payload);
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
const target = resolveDeployTarget(parseTargetFlag(args.flags.target, "deploy"));
|
|
943
|
-
const anonymous = Boolean(args.flags.anonymous);
|
|
944
|
-
const smokeMessage = parseOptionalStringFlag(args.flags.smoke, "smoke", 'agentkit deploy --smoke "hello"');
|
|
945
|
-
|
|
946
|
-
if (target.id === "vps") {
|
|
947
|
-
const host = parseRequiredStringFlag(args.flags.host, "host", "agentkit deploy --target vps --host <host>");
|
|
948
|
-
const container = await buildAgentCapsule(process.cwd(), { target: "container" });
|
|
949
|
-
const plan = await prepareVpsDeploy(container, { host, dryRun: Boolean(args.flags["dry-run"]) });
|
|
950
|
-
printBuildResult(container);
|
|
951
|
-
printVpsDeployPlan(plan);
|
|
952
|
-
return;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
let readinessReport: Awaited<ReturnType<typeof checkDeployReadiness>> | null = null;
|
|
956
|
-
|
|
957
|
-
if (!args.flags["dry-run"] && !args.flags["local-wrangler"]) {
|
|
958
|
-
readinessReport = await checkDeployReadiness({
|
|
959
|
-
apiUrl: await resolveCloudApiUrl(args.flags.api),
|
|
960
|
-
requireLogin: !anonymous,
|
|
961
|
-
});
|
|
962
|
-
|
|
963
|
-
if (!readinessReport.ok) {
|
|
964
|
-
printDeployReadinessReport(readinessReport);
|
|
965
|
-
throw new AgentKitError(
|
|
966
|
-
"deploy_readiness_failed",
|
|
967
|
-
"Fix deploy readiness failures before running agentkit deploy.",
|
|
968
|
-
);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
const result = await buildAgentCapsule(process.cwd(), { target: target.id });
|
|
973
|
-
if (result.target !== "cloudflare") {
|
|
974
|
-
throw new Error(`Unsupported AgentKit Cloud deploy target: ${result.target}`);
|
|
975
|
-
}
|
|
976
|
-
printBuildResult(result);
|
|
977
|
-
|
|
978
|
-
if (args.flags["dry-run"]) {
|
|
979
|
-
console.log("");
|
|
980
|
-
console.log("Dry run only. Artifact is ready for AgentKit Cloud.");
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
if (args.flags["local-wrangler"]) {
|
|
985
|
-
await deployCloudflare(result.wranglerPath, result.buildDir);
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
990
|
-
const auth = anonymous ? null : await readCloudAuthForApiUrl(apiUrl);
|
|
991
|
-
const deploy = await deployBuildToAgentKitCloud(result, {
|
|
992
|
-
apiUrl,
|
|
993
|
-
apiToken: anonymous ? null : auth?.token,
|
|
994
|
-
anonymous: anonymous || !auth?.token,
|
|
995
|
-
});
|
|
996
|
-
const statePath = await writeLocalDeployState(result.root, deploy);
|
|
997
|
-
const chatAccess = await ensureDeployChatAccessToken({
|
|
998
|
-
apiUrl,
|
|
999
|
-
root: result.root,
|
|
1000
|
-
deployId: deploy.deploy.id,
|
|
1001
|
-
skip: anonymous || !auth?.token,
|
|
1002
|
-
});
|
|
1003
|
-
|
|
1004
|
-
console.log("");
|
|
1005
|
-
console.log("Deploy ready");
|
|
1006
|
-
console.log(`URL: ${deploy.deploy.url}`);
|
|
1007
|
-
console.log(`Project: ${deploy.project.id}`);
|
|
1008
|
-
console.log(`Deploy: ${deploy.deploy.id}`);
|
|
1009
|
-
console.log(`State: ${statePath}`);
|
|
1010
|
-
printDeployCloudSummary(readinessReport);
|
|
1011
|
-
|
|
1012
|
-
if (chatAccess?.status === "ready") {
|
|
1013
|
-
console.log(`Chat auth: ${relativePath(process.cwd(), chatAccess.path)}`);
|
|
1014
|
-
} else if (chatAccess?.status === "skipped") {
|
|
1015
|
-
console.log("Chat auth: anonymous deploy; no local chat token was created.");
|
|
1016
|
-
} else if (chatAccess?.status === "failed") {
|
|
1017
|
-
console.log(`Chat auth: could not create local chat token. ${formatReadinessError(chatAccess.error)}`);
|
|
1018
|
-
console.log(`Run: agentkit access token create ${defaultDeployChatAccessTokenName} --out ${defaultDeployChatAccessTokenPath}`);
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
if (smokeMessage) {
|
|
1022
|
-
if (chatAccess?.status === "failed") {
|
|
1023
|
-
throw new AgentKitError("deploy_smoke_failed", "Could not run deploy smoke because chat access token creation failed.");
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
await runDeploySmoke({
|
|
1027
|
-
deployUrl: requireDeployUrl({
|
|
1028
|
-
deploy_id: deploy.deploy.id,
|
|
1029
|
-
url: deploy.deploy.url,
|
|
1030
|
-
}),
|
|
1031
|
-
message: smokeMessage,
|
|
1032
|
-
token:
|
|
1033
|
-
chatAccess?.status === "ready"
|
|
1034
|
-
? await readDeployAccessTokenForUi(chatAccess.path)
|
|
1035
|
-
: undefined,
|
|
1036
|
-
});
|
|
1037
|
-
}
|
|
1038
|
-
printDeployProductionHandoff({
|
|
1039
|
-
deployUrl: deploy.deploy.url,
|
|
1040
|
-
statePath,
|
|
1041
|
-
chatAccess,
|
|
1042
|
-
databaseSchemaPath: result.tursoSchemaPath,
|
|
1043
|
-
readinessReport,
|
|
1044
|
-
smokeMessage,
|
|
1045
|
-
});
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
if (args.command === "secret") {
|
|
1050
|
-
const [subcommand, name, ...valueParts] = args.positional;
|
|
1051
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
1052
|
-
const projectId = await resolveProjectIdForSecretCommand(process.cwd(), apiUrl);
|
|
1053
|
-
|
|
1054
|
-
if (subcommand === "list") {
|
|
1055
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/projects/${encodeURIComponent(projectId)}/secrets`, {
|
|
1056
|
-
method: "GET",
|
|
1057
|
-
});
|
|
1058
|
-
printJson(payload);
|
|
1059
|
-
return;
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
if (subcommand === "set") {
|
|
1063
|
-
const value = await resolveSecretInputValue({
|
|
1064
|
-
name,
|
|
1065
|
-
valueParts,
|
|
1066
|
-
stdinFlag: args.flags.stdin,
|
|
1067
|
-
fromEnvFlag: args.flags["from-env"],
|
|
1068
|
-
fromLocalEnvFlag: args.flags["from-local-env"],
|
|
1069
|
-
localEnvRoot: args.flags["from-local-env"] !== undefined ? await findAgentCapsuleRoot(process.cwd()) : undefined,
|
|
1070
|
-
usage: "agentkit secret set <NAME> <VALUE> | agentkit secret set <NAME> --stdin | agentkit secret set <NAME> --from-env [ENV_NAME] | agentkit secret set <NAME> --from-local-env [--api <url>]",
|
|
1071
|
-
inlineSensitiveHelp: "Prefer --stdin, --from-env, or --from-local-env so the value does not enter shell history.",
|
|
1072
|
-
});
|
|
1073
|
-
|
|
1074
|
-
if (!name) {
|
|
1075
|
-
throw new Error("Usage: agentkit secret set <NAME> <VALUE> | agentkit secret set <NAME> --stdin | agentkit secret set <NAME> --from-env [ENV_NAME] | agentkit secret set <NAME> --from-local-env [--api <url>]");
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(name)}`, {
|
|
1079
|
-
method: "PUT",
|
|
1080
|
-
body: JSON.stringify({ value }),
|
|
1081
|
-
});
|
|
1082
|
-
printJson(payload);
|
|
1083
|
-
return;
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
if (subcommand === "sync") {
|
|
1087
|
-
if (args.flags["from-local"] !== true) {
|
|
1088
|
-
throw new Error("Usage: agentkit secret sync --from-local [--api <url>]");
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
await syncHostedSecretsFromLocal({ apiUrl, projectId });
|
|
1092
|
-
return;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
if (subcommand === "unset") {
|
|
1096
|
-
if (!name) {
|
|
1097
|
-
throw new Error("Usage: agentkit secret unset <NAME> [--api <url>]");
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(name)}`, {
|
|
1101
|
-
method: "DELETE",
|
|
1102
|
-
});
|
|
1103
|
-
printJson(payload);
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
throw new Error("Usage: agentkit secret set <NAME> <VALUE> | agentkit secret set <NAME> --stdin | agentkit secret set <NAME> --from-env [ENV_NAME] | agentkit secret set <NAME> --from-local-env | agentkit secret sync --from-local | agentkit secret list | agentkit secret unset <NAME>");
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
if (args.command === "access") {
|
|
1111
|
-
const [subcommand, noun, name] = args.positional;
|
|
1112
|
-
|
|
1113
|
-
if (subcommand !== "token") {
|
|
1114
|
-
throw new Error("Usage: agentkit access token create <name> [--out <path>] | list | revoke <token-id> [--api <url>]");
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
const state = await requireLocalDeployState();
|
|
1118
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
1119
|
-
|
|
1120
|
-
if (noun === "create" && name) {
|
|
1121
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/deploys/${encodeURIComponent(state.deploy_id)}/access-tokens`, {
|
|
1122
|
-
method: "POST",
|
|
1123
|
-
body: JSON.stringify({ name }),
|
|
1124
|
-
});
|
|
1125
|
-
await printJsonOrWrite(payload, args.flags.out, "agentkit access token create <name> [--api <url>] [--out <path>]");
|
|
1126
|
-
return;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
if (noun === "list" && !name) {
|
|
1130
|
-
const payload = await cloudApiRequest(apiUrl, `/v1/deploys/${encodeURIComponent(state.deploy_id)}/access-tokens`, {
|
|
1131
|
-
method: "GET",
|
|
1132
|
-
});
|
|
1133
|
-
printJson(payload);
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
if (noun === "revoke" && name) {
|
|
1138
|
-
const payload = await cloudApiRequest(
|
|
1139
|
-
apiUrl,
|
|
1140
|
-
`/v1/deploys/${encodeURIComponent(state.deploy_id)}/access-tokens/${encodeURIComponent(name)}/revoke`,
|
|
1141
|
-
{ method: "POST" },
|
|
1142
|
-
);
|
|
1143
|
-
printJson(payload);
|
|
1144
|
-
return;
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
throw new Error("Usage: agentkit access token create <name> [--out <path>] | list | revoke <token-id> [--api <url>]");
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
535
|
if (args.command === "channels") {
|
|
1151
536
|
await handleChannelsCommand(args);
|
|
1152
537
|
return;
|
|
@@ -1180,93 +565,6 @@ async function main() {
|
|
|
1180
565
|
throw new Error("Usage: agentkit skills status | agentkit skills sync");
|
|
1181
566
|
}
|
|
1182
567
|
|
|
1183
|
-
if (args.command === "integrations") {
|
|
1184
|
-
const [subcommand, provider] = args.positional;
|
|
1185
|
-
|
|
1186
|
-
if (provider !== undefined && provider !== "composio") {
|
|
1187
|
-
throw new Error("Usage: agentkit integrations status | connect composio [--toolkit <slug>] [--callback-url <url>] [--api <url>]");
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
const state = await requireLocalDeployState();
|
|
1191
|
-
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
1192
|
-
|
|
1193
|
-
if (subcommand === "status") {
|
|
1194
|
-
const toolkit = parseOptionalStringFlag(
|
|
1195
|
-
args.flags.toolkit,
|
|
1196
|
-
"toolkit",
|
|
1197
|
-
"agentkit integrations status --toolkit <slug>",
|
|
1198
|
-
);
|
|
1199
|
-
const payload = await cloudApiRequest(
|
|
1200
|
-
apiUrl,
|
|
1201
|
-
`/v1/deploys/${encodeURIComponent(state.deploy_id)}/integrations/composio/status${
|
|
1202
|
-
toolkit ? `?toolkit=${encodeURIComponent(toolkit)}` : ""
|
|
1203
|
-
}`,
|
|
1204
|
-
{ method: "GET" },
|
|
1205
|
-
);
|
|
1206
|
-
printJson(payload);
|
|
1207
|
-
return;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
if (subcommand === "connect" && provider === "composio") {
|
|
1211
|
-
const toolkit = parseOptionalStringFlag(
|
|
1212
|
-
args.flags.toolkit,
|
|
1213
|
-
"toolkit",
|
|
1214
|
-
"agentkit integrations connect composio --toolkit <slug>",
|
|
1215
|
-
);
|
|
1216
|
-
const callbackUrl = parseOptionalStringFlag(
|
|
1217
|
-
args.flags["callback-url"],
|
|
1218
|
-
"callback-url",
|
|
1219
|
-
"agentkit integrations connect composio --callback-url <url>",
|
|
1220
|
-
);
|
|
1221
|
-
const payload = (await cloudApiRequest(
|
|
1222
|
-
apiUrl,
|
|
1223
|
-
`/v1/deploys/${encodeURIComponent(state.deploy_id)}/integrations/composio/connect-link`,
|
|
1224
|
-
{
|
|
1225
|
-
method: "POST",
|
|
1226
|
-
body: JSON.stringify({
|
|
1227
|
-
...(toolkit ? { toolkit } : {}),
|
|
1228
|
-
...(callbackUrl ? { callback_url: callbackUrl } : {}),
|
|
1229
|
-
}),
|
|
1230
|
-
},
|
|
1231
|
-
)) as {
|
|
1232
|
-
connect_link?: {
|
|
1233
|
-
toolkit?: string;
|
|
1234
|
-
user_id?: string;
|
|
1235
|
-
redirect_url?: string;
|
|
1236
|
-
expires_at?: string;
|
|
1237
|
-
connected_account_id?: string;
|
|
1238
|
-
auth_config_source?: string;
|
|
1239
|
-
};
|
|
1240
|
-
};
|
|
1241
|
-
|
|
1242
|
-
const link = payload.connect_link;
|
|
1243
|
-
|
|
1244
|
-
if (!link?.redirect_url) {
|
|
1245
|
-
throw new AgentKitError("integration_response_invalid", "AgentKit Cloud returned an invalid Composio connect-link payload.");
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
console.log("Composio connect link");
|
|
1249
|
-
console.log(`Toolkit: ${link.toolkit ?? toolkit ?? "unknown"}`);
|
|
1250
|
-
console.log(`User: ${link.user_id ?? "unknown"}`);
|
|
1251
|
-
if (link.auth_config_source) {
|
|
1252
|
-
console.log(`Auth: ${link.auth_config_source}`);
|
|
1253
|
-
}
|
|
1254
|
-
console.log(`URL: ${link.redirect_url}`);
|
|
1255
|
-
|
|
1256
|
-
if (link.expires_at) {
|
|
1257
|
-
console.log(`Expires: ${link.expires_at}`);
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
if (link.connected_account_id) {
|
|
1261
|
-
console.log(`Account: ${link.connected_account_id}`);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
throw new Error("Usage: agentkit integrations status | connect composio [--toolkit <slug>] [--callback-url <url>] [--api <url>]");
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
568
|
if (args.command === "env") {
|
|
1271
569
|
const [subcommand, name, ...valueParts] = args.positional;
|
|
1272
570
|
const root = await findAgentCapsuleRoot(process.cwd());
|
|
@@ -1413,7 +711,6 @@ npm run agentkit -- tool tool_name --input '{}'
|
|
|
1413
711
|
|
|
1414
712
|
UI testing:
|
|
1415
713
|
- For local UI testing, run \`npm run dev\`, open the printed \`Chat:\` URL, and tell the owner the exact URL.
|
|
1416
|
-
- For hosted UI testing after deploy, run \`npm run agentkit -- chat-ui --deploy\`, open the printed \`Chat:\` URL, and tell the owner it is connected to the hosted deploy.
|
|
1417
714
|
- If the provider is still \`test/fake\`, say the UI was tested only with the deterministic fake provider.
|
|
1418
715
|
|
|
1419
716
|
Final response:
|
|
@@ -1425,16 +722,12 @@ Final response:
|
|
|
1425
722
|
`;
|
|
1426
723
|
}
|
|
1427
724
|
|
|
1428
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
1429
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
725
|
function warnIfUnsupportedNode(): void {
|
|
1433
726
|
const major = majorNodeVersion(process.versions.node);
|
|
1434
727
|
|
|
1435
728
|
if (major !== null && major < 24) {
|
|
1436
729
|
console.warn(
|
|
1437
|
-
`Warning: @andreprado/agentkit requires Node >=24; current Node is ${process.versions.node}. Use Node 24+ before relying on local runtime
|
|
730
|
+
`Warning: @andreprado/agentkit requires Node >=24; current Node is ${process.versions.node}. Use Node 24+ before relying on local runtime commands.`,
|
|
1438
731
|
);
|
|
1439
732
|
}
|
|
1440
733
|
}
|
|
@@ -1445,291 +738,6 @@ function majorNodeVersion(version: string): number | null {
|
|
|
1445
738
|
return Number.isInteger(parsed) ? parsed : null;
|
|
1446
739
|
}
|
|
1447
740
|
|
|
1448
|
-
function printDeployProductionHandoff(input: {
|
|
1449
|
-
deployUrl: string;
|
|
1450
|
-
statePath: string;
|
|
1451
|
-
chatAccess: Awaited<ReturnType<typeof ensureDeployChatAccessToken>>;
|
|
1452
|
-
databaseSchemaPath: string | null;
|
|
1453
|
-
readinessReport: Awaited<ReturnType<typeof checkDeployReadiness>> | null;
|
|
1454
|
-
smokeMessage?: string;
|
|
1455
|
-
}): void {
|
|
1456
|
-
const context = input.readinessReport?.context;
|
|
1457
|
-
const userSecrets = context?.userManagedSecrets ?? [];
|
|
1458
|
-
const managedSecrets = context?.agentKitManagedSecrets ?? [];
|
|
1459
|
-
const composio = context?.integrations.managedComposio;
|
|
1460
|
-
|
|
1461
|
-
console.log("");
|
|
1462
|
-
console.log("Production handoff");
|
|
1463
|
-
console.log(`URL: ${input.deployUrl}`);
|
|
1464
|
-
console.log(`UI: npm run agentkit -- chat-ui --deploy`);
|
|
1465
|
-
console.log(`State: ${input.statePath}`);
|
|
1466
|
-
console.log(
|
|
1467
|
-
`Secrets: ${
|
|
1468
|
-
userSecrets.length > 0
|
|
1469
|
-
? `user-managed set (${userSecrets.join(", ")})`
|
|
1470
|
-
: "no user-managed hosted secrets required"
|
|
1471
|
-
}${managedSecrets.length > 0 ? `; AgentKit-managed: ${managedSecrets.join(", ")}` : ""}`,
|
|
1472
|
-
);
|
|
1473
|
-
console.log(
|
|
1474
|
-
`Database: ${
|
|
1475
|
-
input.databaseSchemaPath
|
|
1476
|
-
? `AgentKit-managed; schema artifact ${input.databaseSchemaPath}`
|
|
1477
|
-
: "AgentKit-managed; no application schema artifact"
|
|
1478
|
-
}`,
|
|
1479
|
-
);
|
|
1480
|
-
|
|
1481
|
-
if (composio?.enabled) {
|
|
1482
|
-
console.log(`Integrations: managed Composio configured for ${composio.toolkits.join(", ")}`);
|
|
1483
|
-
for (const toolkit of composio.toolkits) {
|
|
1484
|
-
console.log(`Connect: npm run agentkit -- integrations connect composio --toolkit ${toolkit}`);
|
|
1485
|
-
}
|
|
1486
|
-
} else {
|
|
1487
|
-
console.log("Integrations: none configured");
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
if (input.smokeMessage) {
|
|
1491
|
-
console.log(`Smoke: verified with ${JSON.stringify(input.smokeMessage)}`);
|
|
1492
|
-
} else {
|
|
1493
|
-
console.log('Smoke: not run; next check: npm run agentkit -- deploy smoke --message "hello"');
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
if (input.chatAccess.status === "ready") {
|
|
1497
|
-
console.log(`Chat token: ${relativePath(process.cwd(), input.chatAccess.path)}`);
|
|
1498
|
-
} else if (input.chatAccess.status === "skipped") {
|
|
1499
|
-
console.log("Chat token: not created for anonymous deploy");
|
|
1500
|
-
} else {
|
|
1501
|
-
console.log(`Chat token: failed; run npm run agentkit -- access token create ${defaultDeployChatAccessTokenName} --out ${defaultDeployChatAccessTokenPath}`);
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
const nextCommand = composio?.enabled && composio.toolkits.length > 0
|
|
1505
|
-
? `npm run agentkit -- integrations connect composio --toolkit ${composio.toolkits[0]}`
|
|
1506
|
-
: "npm run agentkit -- chat-ui --deploy";
|
|
1507
|
-
console.log(`Next: ${nextCommand}`);
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
function printDeployCloudSummary(report: Awaited<ReturnType<typeof checkDeployReadiness>> | null): void {
|
|
1511
|
-
if (!report) {
|
|
1512
|
-
return;
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
const authSummary = formatDeployCloudAuthSummary(report);
|
|
1516
|
-
|
|
1517
|
-
if (authSummary) {
|
|
1518
|
-
console.log(`Account: ${authSummary.account}`);
|
|
1519
|
-
console.log(`Auth: ${authSummary.source}`);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
const capacitySummary = formatDeployOnlineCapacity(report, "before deploy");
|
|
1523
|
-
|
|
1524
|
-
if (capacitySummary) {
|
|
1525
|
-
console.log(`Capacity: ${capacitySummary}`);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
|
-
async function ensureDeployChatAccessToken(options: {
|
|
1530
|
-
apiUrl: string;
|
|
1531
|
-
root: string;
|
|
1532
|
-
deployId: string;
|
|
1533
|
-
skip: boolean;
|
|
1534
|
-
}): Promise<
|
|
1535
|
-
| { status: "ready"; path: string; tokenId: string; created: boolean }
|
|
1536
|
-
| { status: "skipped" }
|
|
1537
|
-
| { status: "failed"; error: unknown }
|
|
1538
|
-
> {
|
|
1539
|
-
if (options.skip) {
|
|
1540
|
-
return { status: "skipped" };
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
try {
|
|
1544
|
-
const path = join(options.root, defaultDeployChatAccessTokenPath);
|
|
1545
|
-
const existing = await readDeployAccessTokenFile(path);
|
|
1546
|
-
|
|
1547
|
-
if (existing?.deploy_id === options.deployId && existing.id) {
|
|
1548
|
-
const listed = (await cloudApiRequest(
|
|
1549
|
-
options.apiUrl,
|
|
1550
|
-
`/v1/deploys/${encodeURIComponent(options.deployId)}/access-tokens`,
|
|
1551
|
-
{ method: "GET" },
|
|
1552
|
-
)) as DeployAccessTokenListResponse;
|
|
1553
|
-
const stillUsable = (listed.access_tokens ?? []).some(
|
|
1554
|
-
(token) => token.id === existing.id && deployAccessTokenMetadataIsUsable(token),
|
|
1555
|
-
);
|
|
1556
|
-
|
|
1557
|
-
if (stillUsable) {
|
|
1558
|
-
await chmod(path, 0o600);
|
|
1559
|
-
return { status: "ready", path, tokenId: existing.id, created: false };
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
const created = (await cloudApiRequest(
|
|
1564
|
-
options.apiUrl,
|
|
1565
|
-
`/v1/deploys/${encodeURIComponent(options.deployId)}/access-tokens`,
|
|
1566
|
-
{
|
|
1567
|
-
method: "POST",
|
|
1568
|
-
body: JSON.stringify({ name: defaultDeployChatAccessTokenName }),
|
|
1569
|
-
},
|
|
1570
|
-
)) as DeployAccessTokenCreateResponse;
|
|
1571
|
-
const token = created.access_token;
|
|
1572
|
-
|
|
1573
|
-
if (!token?.id || token.deploy_id !== options.deployId || !token.token) {
|
|
1574
|
-
throw new AgentKitError("access_token_invalid", "AgentKit Cloud returned an invalid deploy access token payload.");
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
await writeSecretJson(path, created);
|
|
1578
|
-
return { status: "ready", path, tokenId: token.id, created: true };
|
|
1579
|
-
} catch (error) {
|
|
1580
|
-
return { status: "failed", error };
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
function deployAccessTokenMetadataIsUsable(token: { expires_at?: string }): boolean {
|
|
1585
|
-
if (!token.expires_at) {
|
|
1586
|
-
return true;
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
const expiresAtMs = Date.parse(token.expires_at);
|
|
1590
|
-
return Number.isFinite(expiresAtMs) && expiresAtMs > Date.now();
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
async function readDeployAccessTokenFile(path: string): Promise<{ id?: string; deploy_id?: string } | null> {
|
|
1594
|
-
try {
|
|
1595
|
-
const parsed = JSON.parse(await readFile(path, "utf8")) as DeployAccessTokenCreateResponse;
|
|
1596
|
-
return parsed.access_token ?? null;
|
|
1597
|
-
} catch {
|
|
1598
|
-
return null;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
async function writeSecretJson(path: string, value: unknown): Promise<void> {
|
|
1603
|
-
await mkdir(dirname(path), { recursive: true });
|
|
1604
|
-
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
|
|
1605
|
-
await chmod(path, 0o600);
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
async function requireLocalDeployState(): Promise<LocalDeployState> {
|
|
1609
|
-
const state = await readLocalDeployStateIfExists(process.cwd());
|
|
1610
|
-
|
|
1611
|
-
if (!state) {
|
|
1612
|
-
throw new Error("No .agentkit/deploy.json found. Run agentkit deploy first.");
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
return state;
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
|
-
function requireDeployUrl(state: Pick<LocalDeployState, "deploy_id" | "url">): string {
|
|
1619
|
-
if (!state.url) {
|
|
1620
|
-
throw new Error(`Deploy ${state.deploy_id} does not have a URL. Run agentkit deploy again.`);
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
return state.url;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
async function readDeployAccessTokenForHostedRequest(cwd: string): Promise<string> {
|
|
1627
|
-
const root = await findAgentCapsuleRoot(cwd);
|
|
1628
|
-
return readDeployAccessTokenForUi(join(root, defaultDeployChatAccessTokenPath));
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
async function runDeploySmoke(input: { deployUrl: string; message: string; token?: string }): Promise<void> {
|
|
1632
|
-
const headers = new Headers({ "Content-Type": "application/json" });
|
|
1633
|
-
|
|
1634
|
-
if (input.token) {
|
|
1635
|
-
headers.set("Authorization", `Bearer ${input.token}`);
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
let response: Response;
|
|
1639
|
-
|
|
1640
|
-
try {
|
|
1641
|
-
response = await fetch(new URL("/v1/chat", input.deployUrl).href, {
|
|
1642
|
-
method: "POST",
|
|
1643
|
-
headers,
|
|
1644
|
-
body: JSON.stringify({ message: input.message }),
|
|
1645
|
-
});
|
|
1646
|
-
} catch (error) {
|
|
1647
|
-
throw new AgentKitError(
|
|
1648
|
-
"deploy_smoke_failed",
|
|
1649
|
-
`Deploy smoke request failed before a response: ${error instanceof Error ? error.message : String(error)}`,
|
|
1650
|
-
);
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
const payload = await response.json().catch(() => null);
|
|
1654
|
-
|
|
1655
|
-
if (!response.ok) {
|
|
1656
|
-
throw new AgentKitError("deploy_smoke_failed", readCloudError(payload, response.status));
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
const content =
|
|
1660
|
-
payload && typeof payload === "object" && "message" in payload && isRecord((payload as { message?: unknown }).message)
|
|
1661
|
-
? (payload as { message: { content?: unknown } }).message.content
|
|
1662
|
-
: undefined;
|
|
1663
|
-
|
|
1664
|
-
console.log("");
|
|
1665
|
-
console.log("Deploy smoke verified");
|
|
1666
|
-
console.log(`URL: ${input.deployUrl}`);
|
|
1667
|
-
console.log(`Message: ${input.message}`);
|
|
1668
|
-
if (typeof content === "string") {
|
|
1669
|
-
console.log(`Response: ${content}`);
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
async function fetchDeployConversationJson(cwd: string, path: string): Promise<unknown> {
|
|
1674
|
-
const state = await requireLocalDeployState();
|
|
1675
|
-
const deployUrl = requireDeployUrl(state);
|
|
1676
|
-
const token = await readDeployAccessTokenForHostedRequest(cwd);
|
|
1677
|
-
const headers = new Headers();
|
|
1678
|
-
|
|
1679
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
1680
|
-
|
|
1681
|
-
let response: Response;
|
|
1682
|
-
|
|
1683
|
-
try {
|
|
1684
|
-
response = await fetch(new URL(path, deployUrl).href, {
|
|
1685
|
-
method: "GET",
|
|
1686
|
-
headers,
|
|
1687
|
-
});
|
|
1688
|
-
} catch (error) {
|
|
1689
|
-
throw new AgentKitError(
|
|
1690
|
-
"deploy_conversation_request_failed",
|
|
1691
|
-
`Could not read hosted conversation data: ${error instanceof Error ? error.message : String(error)}`,
|
|
1692
|
-
);
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1695
|
-
const payload = await response.json().catch(() => null);
|
|
1696
|
-
|
|
1697
|
-
if (!response.ok) {
|
|
1698
|
-
throw new AgentKitError("deploy_conversation_request_failed", readCloudError(payload, response.status));
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
return payload;
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
async function fetchDeployImproveEvidence(
|
|
1705
|
-
apiUrl: string,
|
|
1706
|
-
input: { deployId: string; since?: string; conversationId?: string },
|
|
1707
|
-
): Promise<unknown | null> {
|
|
1708
|
-
try {
|
|
1709
|
-
return await cloudApiRequest(apiUrl, `/v1/deploys/${encodeURIComponent(input.deployId)}/improve/export`, {
|
|
1710
|
-
method: "POST",
|
|
1711
|
-
body: JSON.stringify({
|
|
1712
|
-
status: "all",
|
|
1713
|
-
...(input.since ? { since: input.since } : {}),
|
|
1714
|
-
...(input.conversationId ? { conversation_id: input.conversationId } : {}),
|
|
1715
|
-
}),
|
|
1716
|
-
});
|
|
1717
|
-
} catch (error) {
|
|
1718
|
-
if (
|
|
1719
|
-
isAgentKitError(error) &&
|
|
1720
|
-
(error.code === "improve_evidence_store_not_configured" || error.code === "not_found")
|
|
1721
|
-
) {
|
|
1722
|
-
return null;
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
throw error;
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
function printJson(value: unknown): void {
|
|
1730
|
-
console.log(JSON.stringify(value, null, 2));
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
741
|
function printSkillStatus(status: Awaited<ReturnType<typeof checkDefaultSkillStatus>>): void {
|
|
1734
742
|
console.log("AgentKit skills");
|
|
1735
743
|
console.log(`Status: ${status.status}`);
|
|
@@ -1754,95 +762,11 @@ function printSkillStatus(status: Awaited<ReturnType<typeof checkDefaultSkillSta
|
|
|
1754
762
|
}
|
|
1755
763
|
}
|
|
1756
764
|
|
|
1757
|
-
async function printJsonOrWrite(value: unknown, outFlag: string | boolean | undefined, usage: string): Promise<void> {
|
|
1758
|
-
const outPath = parseOptionalStringFlag(outFlag, "out", usage);
|
|
1759
|
-
|
|
1760
|
-
if (!outPath) {
|
|
1761
|
-
printJson(value);
|
|
1762
|
-
return;
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
const absolutePath = resolve(process.cwd(), outPath);
|
|
1766
|
-
await writeSecretJson(absolutePath, value);
|
|
1767
|
-
console.log(`Deploy access token written to ${absolutePath}`);
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
function parsePositiveIntegerFlag(value: string | boolean | undefined, name: string, usage: string): number {
|
|
1771
|
-
if (typeof value !== "string") {
|
|
1772
|
-
throw new Error(`Missing ${name}. Usage: ${usage}`);
|
|
1773
|
-
}
|
|
1774
|
-
|
|
1775
|
-
const parsed = Number(value);
|
|
1776
|
-
|
|
1777
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
1778
|
-
throw new Error(`Invalid ${name}. Usage: ${usage}`);
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1781
|
-
return parsed;
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
765
|
function relativePath(root: string, path: string): string {
|
|
1785
766
|
const output = relative(root, path);
|
|
1786
767
|
return output.startsWith("..") ? path : output || ".";
|
|
1787
768
|
}
|
|
1788
769
|
|
|
1789
|
-
function printBuildResult(result: Awaited<ReturnType<typeof buildAgentCapsule>>): void {
|
|
1790
|
-
console.log("AgentKit build complete");
|
|
1791
|
-
console.log("");
|
|
1792
|
-
console.log(`Target: ${result.target}`);
|
|
1793
|
-
console.log(`Build dir: ${result.buildDir}`);
|
|
1794
|
-
console.log(`Manifest: ${result.manifestPath}`);
|
|
1795
|
-
|
|
1796
|
-
if (result.target === "cloudflare") {
|
|
1797
|
-
console.log(`Worker: ${result.workerPath}`);
|
|
1798
|
-
console.log(`Wrangler: ${result.wranglerPath}`);
|
|
1799
|
-
if (result.tursoSchemaPath) {
|
|
1800
|
-
console.log(`Turso: ${result.tursoSchemaPath}`);
|
|
1801
|
-
}
|
|
1802
|
-
console.log(`Bundle: ${result.bundleSha256}`);
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
if (result.target === "container") {
|
|
1806
|
-
console.log(`Server: ${result.serverPath}`);
|
|
1807
|
-
console.log(`Docker: ${result.dockerfilePath}`);
|
|
1808
|
-
console.log(`Migrations:${result.migrationsDir}`);
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
if (result.warnings.length > 0) {
|
|
1812
|
-
console.log("");
|
|
1813
|
-
console.log("Warnings:");
|
|
1814
|
-
|
|
1815
|
-
for (const warning of result.warnings) {
|
|
1816
|
-
console.log(` - ${warning}`);
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
|
-
function printVpsDeployPlan(plan: Awaited<ReturnType<typeof prepareVpsDeploy>>): void {
|
|
1822
|
-
console.log("");
|
|
1823
|
-
console.log("VPS deploy plan ready");
|
|
1824
|
-
console.log(`Host: ${plan.host}`);
|
|
1825
|
-
console.log(`Compose: ${plan.composePath}`);
|
|
1826
|
-
console.log(`Env: ${plan.envExamplePath}`);
|
|
1827
|
-
console.log(`Secrets: ${plan.secretsPath}`);
|
|
1828
|
-
console.log(`Handoff: ${plan.handoffPath}`);
|
|
1829
|
-
console.log(`State: ${plan.statePath}`);
|
|
1830
|
-
console.log("");
|
|
1831
|
-
console.log("Commands:");
|
|
1832
|
-
|
|
1833
|
-
for (const command of plan.commands) {
|
|
1834
|
-
console.log(` ${command}`);
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
async function deployCloudflare(wranglerPath: string, buildDir: string): Promise<void> {
|
|
1839
|
-
const exitCode = await runInheritedCommand("npx", ["wrangler", "deploy", "--config", wranglerPath], buildDir);
|
|
1840
|
-
|
|
1841
|
-
if (exitCode !== 0) {
|
|
1842
|
-
throw new Error(`Cloudflare deploy failed with exit code ${exitCode}.`);
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
|
|
1846
770
|
async function installProjectDependencies(projectPath: string): Promise<void> {
|
|
1847
771
|
const exitCode = await runInheritedCommand("npm", ["install"], projectPath);
|
|
1848
772
|
|