@andreprado/agentkit 0.1.0-alpha.10

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.
Files changed (122) hide show
  1. package/README.md +69 -0
  2. package/bin/agentkit.mjs +23 -0
  3. package/docs/guides/add-channel.md +114 -0
  4. package/docs/guides/add-knowledge.md +134 -0
  5. package/docs/guides/add-tool.md +342 -0
  6. package/docs/guides/agentkit-skills-architecture.md +471 -0
  7. package/docs/guides/channel-security.md +81 -0
  8. package/docs/guides/channels-implementation-map.md +243 -0
  9. package/docs/guides/channels-production-handoff.md +102 -0
  10. package/docs/guides/connect-telegram.md +110 -0
  11. package/docs/guides/connect-whatsapp-zapster.md +119 -0
  12. package/docs/guides/create-agent.md +220 -0
  13. package/docs/guides/prepare-deploy.md +209 -0
  14. package/docs/guides/run-evals.md +179 -0
  15. package/docs/guides/security-rules.md +156 -0
  16. package/docs/guides/use-provider.md +140 -0
  17. package/docs/llms-full.txt +876 -0
  18. package/docs/llms.txt +83 -0
  19. package/docs/portable-deploy-release-checklist.md +41 -0
  20. package/package.json +47 -0
  21. package/src/cli/args.ts +36 -0
  22. package/src/cli/cloud-client.ts +265 -0
  23. package/src/cli/commands/channels.ts +810 -0
  24. package/src/cli/commands/knowledge.ts +136 -0
  25. package/src/cli/constants.ts +4 -0
  26. package/src/cli/deploy-chat-ui.ts +392 -0
  27. package/src/cli/deploy-readiness.ts +348 -0
  28. package/src/cli/flags.ts +162 -0
  29. package/src/cli/help.ts +184 -0
  30. package/src/cli/index.ts +1276 -0
  31. package/src/cli/process.ts +31 -0
  32. package/src/cloud/artifact.ts +139 -0
  33. package/src/cloud/client.ts +79 -0
  34. package/src/cloud/contracts.ts +63 -0
  35. package/src/cloud/index.ts +3 -0
  36. package/src/create-project.ts +177 -0
  37. package/src/index.ts +408 -0
  38. package/src/providers/index.ts +25 -0
  39. package/src/providers/pi.ts +286 -0
  40. package/src/providers/test.ts +133 -0
  41. package/src/providers/types.ts +34 -0
  42. package/src/runtime/build.ts +43 -0
  43. package/src/runtime/channel-buffer.ts +30 -0
  44. package/src/runtime/channel-test-harness.ts +112 -0
  45. package/src/runtime/channels/telegram.ts +360 -0
  46. package/src/runtime/channels/website.ts +132 -0
  47. package/src/runtime/channels/whatsapp-meta.ts +71 -0
  48. package/src/runtime/channels/whatsapp-zapster.ts +278 -0
  49. package/src/runtime/channels.ts +138 -0
  50. package/src/runtime/chat.ts +218 -0
  51. package/src/runtime/config.ts +684 -0
  52. package/src/runtime/conversations.ts +38 -0
  53. package/src/runtime/core/deploy-state.ts +54 -0
  54. package/src/runtime/core/manifest.ts +213 -0
  55. package/src/runtime/core/targets.ts +133 -0
  56. package/src/runtime/database.ts +256 -0
  57. package/src/runtime/db-commands.ts +167 -0
  58. package/src/runtime/deploy-readiness.ts +105 -0
  59. package/src/runtime/deploy.ts +1 -0
  60. package/src/runtime/dev-server.ts +1247 -0
  61. package/src/runtime/docs.ts +36 -0
  62. package/src/runtime/env.ts +152 -0
  63. package/src/runtime/errors.ts +13 -0
  64. package/src/runtime/evals.ts +509 -0
  65. package/src/runtime/inspect.ts +203 -0
  66. package/src/runtime/knowledge/chunk.ts +333 -0
  67. package/src/runtime/knowledge/config.ts +135 -0
  68. package/src/runtime/knowledge/embeddings.ts +133 -0
  69. package/src/runtime/knowledge/ingest.ts +521 -0
  70. package/src/runtime/knowledge/prompt-policy.ts +30 -0
  71. package/src/runtime/knowledge/retrieve.ts +283 -0
  72. package/src/runtime/knowledge/schema.ts +56 -0
  73. package/src/runtime/knowledge/tool.ts +64 -0
  74. package/src/runtime/knowledge/vector.ts +258 -0
  75. package/src/runtime/runtime-contract.ts +93 -0
  76. package/src/runtime/spec.ts +152 -0
  77. package/src/runtime/sync.ts +144 -0
  78. package/src/runtime/targets/cloudflare/build.ts +2517 -0
  79. package/src/runtime/targets/container/build.ts +146 -0
  80. package/src/runtime/targets/container/server.ts +33 -0
  81. package/src/runtime/targets/vps/deploy.ts +206 -0
  82. package/src/runtime/tool-runner.ts +65 -0
  83. package/src/runtime/tools.ts +470 -0
  84. package/src/runtime/traces.ts +41 -0
  85. package/src/storage/sqlite.ts +1118 -0
  86. package/src/templates/blank.ts +394 -0
  87. package/src/templates/dentista.ts +1003 -0
  88. package/src/templates/index.ts +33 -0
  89. package/src/templates/skills/agentkit-build-agent/SKILL.md +51 -0
  90. package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +20 -0
  91. package/src/templates/skills/agentkit-build-agent/templates/sales-qualifier.instructions.md +17 -0
  92. package/src/templates/skills/agentkit-build-agent/templates/support-agent.instructions.md +16 -0
  93. package/src/templates/skills/agentkit-capsule/SKILL.md +62 -0
  94. package/src/templates/skills/agentkit-capsule/references/docs-router.md +15 -0
  95. package/src/templates/skills/agentkit-channels/SKILL.md +62 -0
  96. package/src/templates/skills/agentkit-channels/references/channel-buffering.md +58 -0
  97. package/src/templates/skills/agentkit-channels/references/channel-debugging.md +41 -0
  98. package/src/templates/skills/agentkit-channels/references/telegram.md +38 -0
  99. package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +44 -0
  100. package/src/templates/skills/agentkit-database/SKILL.md +45 -0
  101. package/src/templates/skills/agentkit-database/templates/appointments.schema.sql +15 -0
  102. package/src/templates/skills/agentkit-database/templates/leads.schema.sql +17 -0
  103. package/src/templates/skills/agentkit-deploy/SKILL.md +44 -0
  104. package/src/templates/skills/agentkit-evals/SKILL.md +60 -0
  105. package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +22 -0
  106. package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +14 -0
  107. package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +14 -0
  108. package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +18 -0
  109. package/src/templates/skills/agentkit-knowledge/SKILL.md +40 -0
  110. package/src/templates/skills/agentkit-knowledge/templates/faq.md +14 -0
  111. package/src/templates/skills/agentkit-knowledge/templates/policies.md +14 -0
  112. package/src/templates/skills/agentkit-knowledge/templates/prices.csv +3 -0
  113. package/src/templates/skills/agentkit-prompts/SKILL.md +45 -0
  114. package/src/templates/skills/agentkit-prompts/templates/knowledge-grounded-faq.instructions.md +11 -0
  115. package/src/templates/skills/agentkit-provider/SKILL.md +57 -0
  116. package/src/templates/skills/agentkit-security/SKILL.md +55 -0
  117. package/src/templates/skills/agentkit-tools/SKILL.md +36 -0
  118. package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +35 -0
  119. package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +37 -0
  120. package/src/templates/skills/agentkit-tools/examples/lookup-order.tool.md +46 -0
  121. package/src/templates/skills/agentkit-troubleshooting/SKILL.md +52 -0
  122. package/src/templates/support.ts +401 -0
@@ -0,0 +1,348 @@
1
+ import { findAgentCapsuleRoot, loadAgentCapsule } from "../runtime/config";
2
+ import { readLocalDeployStateIfExists } from "../runtime/core/deploy-state";
3
+ import { loadDeployReadinessContext, stableCloudProjectId, type DeployReadinessContext } from "../runtime/deploy-readiness";
4
+ import { loadCapsuleEnv } from "../runtime/env";
5
+ import { isAgentKitError } from "../runtime/errors";
6
+ import {
7
+ cloudApiRequest,
8
+ formatCloudAuthSource,
9
+ readCloudAuth,
10
+ type CloudCapabilitiesResponse,
11
+ type CloudLimitsResponse,
12
+ type CloudMeResponse,
13
+ type CloudSecretsResponse,
14
+ } from "./cloud-client";
15
+
16
+ type DeployReadinessStatus = "pass" | "fail" | "warn" | "info";
17
+
18
+ type DeployReadinessCheck = {
19
+ status: DeployReadinessStatus;
20
+ title: string;
21
+ message: string;
22
+ action?: string;
23
+ };
24
+
25
+ type DeployReadinessReport = {
26
+ ok: boolean;
27
+ apiUrl: string;
28
+ context: DeployReadinessContext;
29
+ checks: DeployReadinessCheck[];
30
+ };
31
+
32
+ export async function checkDeployReadiness(options: {
33
+ apiUrl: string;
34
+ requireLogin: boolean;
35
+ }): Promise<DeployReadinessReport> {
36
+ const context = await loadDeployReadinessContext(process.cwd(), process.env);
37
+ const auth = await readCloudAuth();
38
+ const checks: DeployReadinessCheck[] = [];
39
+ let cloudAuthUsable = false;
40
+
41
+ if (context.runtime !== "edge") {
42
+ checks.push({
43
+ status: "fail",
44
+ title: "Target runtime",
45
+ message: 'Cloudflare deploy requires runtime: "edge" in agentkit.config.ts.',
46
+ action: "set runtime: \"edge\" before deploying to AgentKit Cloud",
47
+ });
48
+ } else {
49
+ checks.push({
50
+ status: "pass",
51
+ title: "Target runtime",
52
+ message: "Capsule is configured for edge deploy.",
53
+ });
54
+ }
55
+
56
+ if (!auth?.token) {
57
+ checks.push({
58
+ status: options.requireLogin ? "fail" : "warn",
59
+ title: "Login",
60
+ message: options.requireLogin
61
+ ? "No AgentKit Cloud token was found for hosted production deploy."
62
+ : "No AgentKit Cloud token was found; deploy will request anonymous mode.",
63
+ action: "agentkit login --token <token>",
64
+ });
65
+ } else {
66
+ try {
67
+ const me = (await cloudApiRequest(options.apiUrl, "/v1/me", { method: "GET" })) as CloudMeResponse;
68
+ const email = me.account?.email;
69
+ checks.push({
70
+ status: "pass",
71
+ title: "Login",
72
+ message: email ? `Authenticated as ${email}.` : "AgentKit Cloud token is accepted.",
73
+ });
74
+ cloudAuthUsable = true;
75
+ } catch (error) {
76
+ checks.push({
77
+ status: "fail",
78
+ title: "Login",
79
+ message: `AgentKit Cloud rejected the token from ${formatCloudAuthSource(auth)}. ${formatReadinessError(error)}`,
80
+ action: "agentkit login --token <token>",
81
+ });
82
+ }
83
+ }
84
+
85
+ if (cloudAuthUsable) {
86
+ try {
87
+ const payload = (await cloudApiRequest(options.apiUrl, "/v1/me/capabilities", {
88
+ method: "GET",
89
+ })) as CloudCapabilitiesResponse;
90
+ const capabilities = payload.capabilities ?? [];
91
+ const hasCloudflareAlpha = capabilities.some(
92
+ (capability) => capability.name === "cloudflare_deploy_alpha" && capability.status === "active",
93
+ );
94
+
95
+ checks.push({
96
+ status: hasCloudflareAlpha ? "pass" : "fail",
97
+ title: "Deploy entitlement",
98
+ message: hasCloudflareAlpha
99
+ ? "cloudflare_deploy_alpha is active."
100
+ : "This account is missing the cloudflare_deploy_alpha entitlement.",
101
+ ...(hasCloudflareAlpha ? {} : { action: "log in with an invited AgentKit Cloud alpha token" }),
102
+ });
103
+ } catch (error) {
104
+ checks.push({
105
+ status: "fail",
106
+ title: "Deploy entitlement",
107
+ message: `Could not verify AgentKit Cloud capabilities. ${formatReadinessError(error)}`,
108
+ });
109
+ }
110
+
111
+ try {
112
+ const payload = (await cloudApiRequest(options.apiUrl, "/v1/me/limits", {
113
+ method: "GET",
114
+ })) as CloudLimitsResponse;
115
+ const account = payload.online_agents?.account;
116
+ const global = payload.online_agents?.global;
117
+ const accountLimit = normalizeOptionalNumber(account?.limit);
118
+ const accountUsed = normalizeOptionalNumber(account?.used);
119
+ const globalLimit = normalizeOptionalNumber(global?.limit);
120
+ const globalUsed = normalizeOptionalNumber(global?.used);
121
+
122
+ if (accountLimit !== undefined && accountUsed !== undefined && accountUsed >= accountLimit) {
123
+ checks.push({
124
+ status: "fail",
125
+ title: "Online agent capacity",
126
+ message: `This account is already using ${accountUsed}/${accountLimit} online AgentKit deploys.`,
127
+ action: "agentkit deploy pause",
128
+ });
129
+ } else if (globalLimit !== undefined && globalUsed !== undefined && globalUsed >= globalLimit) {
130
+ checks.push({
131
+ status: "fail",
132
+ title: "Online agent capacity",
133
+ message: `AgentKit Cloud is already using ${globalUsed}/${globalLimit} global online deploy slots.`,
134
+ action: "agentkit deploy status",
135
+ });
136
+ } else if (accountLimit !== undefined && accountUsed !== undefined) {
137
+ checks.push({
138
+ status: "pass",
139
+ title: "Online agent capacity",
140
+ message: `Account has capacity: ${accountUsed}/${accountLimit} online deploys are in use.`,
141
+ });
142
+ } else if (globalLimit !== undefined && globalUsed !== undefined) {
143
+ checks.push({
144
+ status: "pass",
145
+ title: "Online agent capacity",
146
+ message: `Global capacity is available: ${globalUsed}/${globalLimit} online deploys are in use.`,
147
+ });
148
+ } else {
149
+ checks.push({
150
+ status: "info",
151
+ title: "Online agent capacity",
152
+ message: "No online deploy limit is configured for this account.",
153
+ });
154
+ }
155
+ } catch (error) {
156
+ checks.push({
157
+ status: "warn",
158
+ title: "Online agent capacity",
159
+ message: `Could not verify online deploy capacity. ${formatReadinessError(error)}`,
160
+ });
161
+ }
162
+ }
163
+
164
+ if (context.agentKitManagedSecrets.length > 0) {
165
+ checks.push({
166
+ status: "info",
167
+ title: "AgentKit-managed secrets",
168
+ message: `${context.agentKitManagedSecrets.join(", ")} ${
169
+ context.agentKitManagedSecrets.length === 1 ? "is" : "are"
170
+ } provisioned by AgentKit Cloud during deploy.`,
171
+ });
172
+ }
173
+
174
+ if (context.accessMode === "private") {
175
+ checks.push({
176
+ status: "info",
177
+ title: "Private access",
178
+ message: "AGENTKIT_PRIVATE_TOKEN is required at runtime; AgentKit Cloud generates it and saves it in .agentkit/deploy.json.",
179
+ });
180
+ }
181
+
182
+ if (context.knowledge.enabled) {
183
+ if (context.knowledge.databaseDriver !== "turso") {
184
+ checks.push({
185
+ status: "fail",
186
+ title: "Knowledge storage",
187
+ message: "Hosted Knowledge requires a Turso database so indexed chunks are available to the Cloudflare runtime.",
188
+ action: 'set storage.database.driver: "turso" in agentkit.config.ts before deploying Knowledge',
189
+ });
190
+ } else {
191
+ checks.push({
192
+ status: "pass",
193
+ title: "Knowledge storage",
194
+ message: `Knowledge is configured with ${context.knowledge.sourceCount} source${
195
+ context.knowledge.sourceCount === 1 ? "" : "s"
196
+ } and Turso storage.`,
197
+ });
198
+ }
199
+ }
200
+
201
+ if (context.userManagedSecrets.length === 0) {
202
+ checks.push({
203
+ status: "pass",
204
+ title: "Hosted secrets",
205
+ message: "No user-managed hosted secrets are required by this capsule.",
206
+ });
207
+ } else if (!cloudAuthUsable) {
208
+ checks.push({
209
+ status: options.requireLogin ? "fail" : "warn",
210
+ title: "Hosted secrets",
211
+ message: `Could not check hosted secrets without a valid AgentKit Cloud login. Required: ${context.userManagedSecrets.join(", ")}.`,
212
+ action: "agentkit secret list",
213
+ });
214
+ } else {
215
+ try {
216
+ const payload = (await cloudApiRequest(
217
+ options.apiUrl,
218
+ `/v1/projects/${encodeURIComponent(context.projectId)}/secrets`,
219
+ { method: "GET" },
220
+ )) as CloudSecretsResponse;
221
+ const hostedSecretNames = new Set((payload.secrets ?? []).map((secret) => secret.name).filter(isString));
222
+ const missing = context.userManagedSecrets.filter((name) => !hostedSecretNames.has(name));
223
+
224
+ if (missing.length === 0) {
225
+ checks.push({
226
+ status: "pass",
227
+ title: "Hosted secrets",
228
+ message: "All user-managed hosted secrets are set.",
229
+ });
230
+ } else {
231
+ for (const secret of missing) {
232
+ const localSource = context.localSecrets[secret];
233
+ checks.push({
234
+ status: "fail",
235
+ title: `Hosted secret ${secret}`,
236
+ message: localSource
237
+ ? `${secret} is present locally but has not been set in AgentKit Cloud.`
238
+ : `${secret} is required but missing from AgentKit Cloud.`,
239
+ action: secretSetCommand(secret, localSource),
240
+ });
241
+ }
242
+ }
243
+ } catch (error) {
244
+ checks.push({
245
+ status: "fail",
246
+ title: "Hosted secrets",
247
+ message: `Could not list hosted secrets for project ${context.projectId}. ${formatReadinessError(error)}`,
248
+ action: "agentkit secret list",
249
+ });
250
+ }
251
+ }
252
+
253
+ return {
254
+ ok: checks.every((check) => check.status !== "fail"),
255
+ apiUrl: options.apiUrl,
256
+ context,
257
+ checks,
258
+ };
259
+ }
260
+
261
+ export function printDeployReadinessReport(report: DeployReadinessReport): void {
262
+ console.log("AgentKit deploy readiness");
263
+ console.log(`Project: ${report.context.projectName}`);
264
+ console.log(`Project ID: ${report.context.projectId}`);
265
+ console.log(`Target: ${report.context.target}`);
266
+ console.log(`API: ${report.apiUrl}`);
267
+ console.log("");
268
+
269
+ for (const check of report.checks) {
270
+ console.log(`[${check.status}] ${check.title}: ${check.message}`);
271
+
272
+ if (check.action) {
273
+ console.log(` Run: ${check.action}`);
274
+ }
275
+ }
276
+ }
277
+
278
+ export async function syncHostedSecretsFromLocal(options: { apiUrl: string; projectId: string }): Promise<void> {
279
+ const context = await loadDeployReadinessContext(process.cwd(), process.env);
280
+ const localEnv = await loadCapsuleEnv(context.root, {});
281
+ let synced = 0;
282
+ let skipped = 0;
283
+
284
+ for (const secret of context.userManagedSecrets) {
285
+ const value = localEnv[secret];
286
+
287
+ if (value === undefined) {
288
+ skipped += 1;
289
+ console.log(`${secret}\tskipped_missing_local`);
290
+ continue;
291
+ }
292
+
293
+ await cloudApiRequest(options.apiUrl, `/v1/projects/${encodeURIComponent(options.projectId)}/secrets/${encodeURIComponent(secret)}`, {
294
+ method: "PUT",
295
+ body: JSON.stringify({ value }),
296
+ });
297
+ synced += 1;
298
+ console.log(`${secret}\tsynced`);
299
+ }
300
+
301
+ if (context.userManagedSecrets.length === 0) {
302
+ console.log("No user-managed hosted secrets are declared by this capsule.");
303
+ return;
304
+ }
305
+
306
+ console.log("");
307
+ console.log(`${synced} synced, ${skipped} skipped`);
308
+ }
309
+
310
+ export function formatReadinessError(error: unknown): string {
311
+ if (isAgentKitError(error)) {
312
+ return `${error.code}: ${error.message}`;
313
+ }
314
+
315
+ return error instanceof Error ? error.message : String(error);
316
+ }
317
+
318
+ export async function resolveProjectIdForSecretCommand(cwd: string): Promise<string> {
319
+ const state = await readLocalDeployStateIfExists(cwd);
320
+
321
+ if (state?.project_id) {
322
+ return state.project_id;
323
+ }
324
+
325
+ const root = await findAgentCapsuleRoot(cwd);
326
+ const capsule = await loadAgentCapsule(root);
327
+ return stableCloudProjectId(capsule.config.name);
328
+ }
329
+
330
+ function secretSetCommand(secret: string, source: DeployReadinessContext["localSecrets"][string] | undefined): string {
331
+ if (source?.dotenv) {
332
+ return `agentkit secret set ${secret} --from-local-env`;
333
+ }
334
+
335
+ if (source?.environment) {
336
+ return `agentkit secret set ${secret} --from-env`;
337
+ }
338
+
339
+ return `agentkit secret set ${secret} --stdin`;
340
+ }
341
+
342
+ function normalizeOptionalNumber(value: number | null | undefined): number | undefined {
343
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
344
+ }
345
+
346
+ function isString(value: unknown): value is string {
347
+ return typeof value === "string";
348
+ }
@@ -0,0 +1,162 @@
1
+ import { listTargetsWithCapability } from "../runtime/core/targets";
2
+ import { loadCapsuleEnv } from "../runtime/env";
3
+ import { AgentKitError } from "../runtime/errors";
4
+ import { defaultAgentKitCloudApiUrl } from "./constants";
5
+
6
+ export function parsePort(value: string | boolean | undefined, usage = "agentkit dev --port <number>"): number | undefined {
7
+ if (value === undefined) {
8
+ return undefined;
9
+ }
10
+
11
+ if (typeof value !== "string") {
12
+ throw new Error(`Missing port. Usage: ${usage}`);
13
+ }
14
+
15
+ const port = Number(value);
16
+
17
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
18
+ throw new Error(`Invalid port. Usage: ${usage}`);
19
+ }
20
+
21
+ return port;
22
+ }
23
+
24
+ export function parseTargetFlag(value: string | boolean | undefined, capability: "build" | "deploy"): string {
25
+ if (value === undefined) {
26
+ return "cloudflare";
27
+ }
28
+
29
+ if (typeof value !== "string") {
30
+ throw new Error(
31
+ `Missing target. Usage: agentkit ${capability} --target ${listTargetsWithCapability(capability).join("|")}`,
32
+ );
33
+ }
34
+
35
+ return value;
36
+ }
37
+
38
+ export function parseCloudApiUrl(value: string | boolean | undefined): string {
39
+ if (value === undefined) {
40
+ return process.env.AGENTKIT_CLOUD_API_URL ?? defaultAgentKitCloudApiUrl;
41
+ }
42
+
43
+ if (typeof value !== "string") {
44
+ throw new Error("Missing API URL. Usage: agentkit deploy --api <url>");
45
+ }
46
+
47
+ return value;
48
+ }
49
+
50
+ export function parseRequiredStringFlag(value: string | boolean | undefined, name: string, usage: string): string {
51
+ if (typeof value !== "string" || value.trim().length === 0) {
52
+ throw new Error(`Missing ${name}. Usage: ${usage}`);
53
+ }
54
+
55
+ return value.trim();
56
+ }
57
+
58
+ export function parseOptionalStringFlag(value: string | boolean | undefined, name: string, usage: string): string | undefined {
59
+ if (value === undefined) {
60
+ return undefined;
61
+ }
62
+
63
+ if (typeof value !== "string" || value.trim().length === 0) {
64
+ throw new Error(`Missing ${name}. Usage: ${usage}`);
65
+ }
66
+
67
+ return value.trim();
68
+ }
69
+
70
+ export async function resolveSecretInputValue(options: {
71
+ name: string | undefined;
72
+ valueParts: string[];
73
+ stdinFlag: string | boolean | undefined;
74
+ fromEnvFlag: string | boolean | undefined;
75
+ fromLocalEnvFlag: string | boolean | undefined;
76
+ localEnvRoot?: string;
77
+ usage: string;
78
+ inlineSensitiveHelp?: string;
79
+ }): Promise<string> {
80
+ const { name, valueParts, stdinFlag, fromEnvFlag, fromLocalEnvFlag, localEnvRoot, usage, inlineSensitiveHelp } = options;
81
+
82
+ if (!name) {
83
+ throw new Error(`Missing name. Usage: ${usage}`);
84
+ }
85
+
86
+ const hasInlineValue = valueParts.length > 0;
87
+ const hasStdin = stdinFlag !== undefined;
88
+ const hasFromEnv = fromEnvFlag !== undefined;
89
+ const hasFromLocalEnv = fromLocalEnvFlag !== undefined;
90
+ const inputModes = [hasInlineValue, hasStdin, hasFromEnv, hasFromLocalEnv].filter(Boolean).length;
91
+
92
+ if (inputModes !== 1) {
93
+ throw new Error(`Provide exactly one value source. Usage: ${usage}`);
94
+ }
95
+
96
+ let value: string;
97
+
98
+ if (hasInlineValue) {
99
+ value = valueParts.join(" ");
100
+ if (looksLikeSecretName(name)) {
101
+ console.error(
102
+ `Warning: ${name} looks sensitive. ${inlineSensitiveHelp ?? "Prefer --stdin or --from-env so the value does not enter shell history."}`,
103
+ );
104
+ }
105
+ } else if (hasStdin) {
106
+ if (stdinFlag !== true) {
107
+ throw new Error(`--stdin does not take a value. Usage: ${usage}`);
108
+ }
109
+
110
+ value = stripOneTrailingNewline(await readStdinText());
111
+ } else if (hasFromEnv) {
112
+ const envName = fromEnvFlag === true ? name : parseRequiredStringFlag(fromEnvFlag, "env name", usage);
113
+ const envValue = process.env[envName];
114
+
115
+ if (envValue === undefined) {
116
+ throw new AgentKitError("secret_not_found", `Environment variable ${envName} is not set.`);
117
+ }
118
+
119
+ value = envValue;
120
+ } else {
121
+ if (fromLocalEnvFlag !== true) {
122
+ throw new Error(`--from-local-env does not take a value. Usage: ${usage}`);
123
+ }
124
+
125
+ if (!localEnvRoot) {
126
+ throw new Error(`--from-local-env is not available for this command. Usage: ${usage}`);
127
+ }
128
+
129
+ const localEnv = await loadCapsuleEnv(localEnvRoot, {});
130
+ const localValue = localEnv[name];
131
+
132
+ if (localValue === undefined) {
133
+ throw new AgentKitError("secret_not_found", `Local .env does not contain ${name}.`);
134
+ }
135
+
136
+ value = localValue;
137
+ }
138
+
139
+ if (value.length === 0) {
140
+ throw new Error(`Secret value cannot be empty. Usage: ${usage}`);
141
+ }
142
+
143
+ return value;
144
+ }
145
+
146
+ function looksLikeSecretName(name: string): boolean {
147
+ return /(?:SECRET|TOKEN|KEY|PASSWORD|CREDENTIAL|PRIVATE)/i.test(name);
148
+ }
149
+
150
+ async function readStdinText(): Promise<string> {
151
+ const chunks: Buffer[] = [];
152
+
153
+ for await (const chunk of process.stdin) {
154
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
155
+ }
156
+
157
+ return Buffer.concat(chunks).toString("utf8");
158
+ }
159
+
160
+ function stripOneTrailingNewline(value: string): string {
161
+ return value.replace(/\r?\n$/, "");
162
+ }
@@ -0,0 +1,184 @@
1
+ export function renderHelp(): string {
2
+ return `AgentKit
3
+
4
+ Create, run, inspect, and deploy Agent Capsules.
5
+
6
+ Quick start:
7
+ agentkit new support-agent --template support
8
+ cd support-agent
9
+ npm run dev
10
+ npm run chat -- --message "hello"
11
+
12
+ Usage:
13
+ agentkit <command> [options]
14
+
15
+ Start:
16
+ agentkit new <name> [--template blank|support|dentista] [--no-install]
17
+ agentkit dev
18
+ agentkit open
19
+ agentkit chat-ui --deploy
20
+ agentkit chat --message <text> [--conversation-id <id>]
21
+ agentkit inspect
22
+
23
+ Build:
24
+ agentkit knowledge add <path>
25
+ agentkit knowledge search <query>
26
+ agentkit spec init --brief <text>
27
+ agentkit sync run
28
+ agentkit tool <name> [--input <path-or-json>]
29
+ agentkit db migrate
30
+ agentkit eval run
31
+ agentkit eval from-conversation <id>
32
+ agentkit conversations list
33
+
34
+ Deploy:
35
+ agentkit login --token <token>
36
+ agentkit deploy doctor
37
+ agentkit secret set <NAME> --stdin
38
+ agentkit secret sync --from-local
39
+ agentkit deploy --smoke "hello"
40
+ agentkit deploy status
41
+
42
+ More:
43
+ agentkit channels ...
44
+ agentkit access token ...
45
+ agentkit env ...
46
+ agentkit docs full
47
+ agentkit help commands
48
+ `;
49
+ }
50
+
51
+ export function renderCommandReference(): string {
52
+ return `AgentKit Command Reference
53
+
54
+ Usage:
55
+ agentkit new <name> [--template blank|support|dentista] [--no-install]
56
+ agentkit dev [--port <number>]
57
+ agentkit open
58
+ agentkit chat-ui --deploy [--port <number>] [--token-file <path>]
59
+ agentkit chat --message <text> [--conversation-id <id>]
60
+ agentkit tool <name> [--input <path-or-json>]
61
+ agentkit knowledge add <path-or-url>
62
+ agentkit knowledge sync
63
+ agentkit knowledge inspect
64
+ agentkit knowledge search <query> [--top-k <number>]
65
+ agentkit spec init --brief <text> [--out <path>] [--force]
66
+ agentkit spec check [--file <path>]
67
+ agentkit sync init [--force]
68
+ agentkit sync run [--file <path>]
69
+ agentkit db migrate
70
+ agentkit db reset --yes
71
+ agentkit db shell
72
+ agentkit db seed [--file <path>]
73
+ agentkit eval run
74
+ agentkit eval from-conversation <conversation-id> [--out <path>] [--force]
75
+ agentkit conversations list
76
+ agentkit conversations show <conversation-id>
77
+ agentkit conversations trace <conversation-id>
78
+ agentkit channels list
79
+ agentkit channels add <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
80
+ agentkit channels connect <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
81
+ agentkit channels setup <name> [--apply] [--api <url>]
82
+ agentkit channels status <name> [--api <url>]
83
+ agentkit channels doctor <name> [--api <url>]
84
+ agentkit channels test <name> [--message <text>] [--fixture <path>] [--api <url>]
85
+ agentkit channels deliveries list <name> [--api <url>]
86
+ agentkit channels deliveries show <delivery-id> [--api <url>]
87
+ agentkit inspect
88
+ agentkit build [--target cloudflare|container]
89
+ agentkit login --token <token> [--api <url>]
90
+ agentkit logout
91
+ agentkit deploy [--target cloudflare|vps] [--host <host>] [--api <url>] [--dry-run] [--anonymous] [--local-wrangler] [--smoke <message>]
92
+ agentkit deploy doctor [--api <url>] [--anonymous]
93
+ agentkit deploy smoke [--message <text>] [--api <url>]
94
+ agentkit deploy status [--api <url>]
95
+ agentkit deploy pause [--api <url>]
96
+ agentkit deploy resume [--api <url>]
97
+ agentkit secret set <NAME> <VALUE> [--api <url>]
98
+ agentkit secret set <NAME> --stdin [--api <url>]
99
+ agentkit secret set <NAME> --from-env [ENV_NAME] [--api <url>]
100
+ agentkit secret set <NAME> --from-local-env [--api <url>]
101
+ agentkit secret sync --from-local [--api <url>]
102
+ agentkit secret list [--api <url>]
103
+ agentkit secret unset <NAME> [--api <url>]
104
+ agentkit access token create <name> [--api <url>] [--out <path>]
105
+ agentkit access token list [--api <url>]
106
+ agentkit access token revoke <token-id> [--api <url>]
107
+ agentkit env set <NAME> <VALUE>
108
+ agentkit env set <NAME> --stdin
109
+ agentkit env set <NAME> --from-env [ENV_NAME]
110
+ agentkit env list
111
+ agentkit env unset <NAME>
112
+ agentkit docs path
113
+ agentkit docs llms
114
+ agentkit docs full
115
+ agentkit handoff codex [goal]
116
+ agentkit help commands
117
+ agentkit --help
118
+
119
+ Commands:
120
+ new Create a new Agent Capsule
121
+ dev Run the Agent Capsule locally
122
+ open Open the local Agent Capsule UI if it is already running
123
+ chat-ui Run a local chat UI, optionally pointed at a hosted deploy
124
+ chat Send one message to the local Agent Capsule
125
+ tool Run one registered tool directly
126
+ knowledge Add, sync, inspect, and search local Knowledge sources
127
+ spec Create or check the agent implementation contract from the owner brief
128
+ sync Run or scaffold catalog/data synchronization
129
+ db Manage the local SQLite database
130
+ eval Run local eval files or create one from a conversation
131
+ conversations List, inspect, and trace stored local conversations
132
+ channels Manage hosted channel resources
133
+ inspect Print machine-readable Agent Capsule state
134
+ build Build a hosted deploy artifact
135
+ login Store an AgentKit Cloud alpha token outside the capsule
136
+ logout Remove the stored AgentKit Cloud alpha token
137
+ deploy Build and send a hosted artifact to AgentKit Cloud
138
+ secret Manage hosted AgentKit Cloud secrets without readback
139
+ access Manage hosted deploy access tokens
140
+ env Manage local .env values without opening code
141
+ docs Print AgentKit docs locations
142
+ handoff Print a ready-to-paste prompt for another coding agent
143
+ help Print focused help or the full command reference
144
+
145
+ Examples:
146
+ agentkit new support-agent --template support
147
+ cd support-agent
148
+ agentkit dev
149
+ agentkit open
150
+ agentkit tool lookup_order --input '{"orderId":"A100"}'
151
+ agentkit eval run
152
+
153
+ agentkit new clara-dentista --template dentista
154
+ `;
155
+ }
156
+
157
+ export function renderCommandHelp(command: string): string {
158
+ const usage: Record<string, string> = {
159
+ new: "agentkit new <name> [--template blank|support|dentista] [--no-install]",
160
+ dev: "agentkit dev [--port <number>]",
161
+ open: "agentkit open",
162
+ "chat-ui": "agentkit chat-ui --deploy [--port <number>] [--token-file <path>]",
163
+ chat: 'agentkit chat --message "hello" [--conversation-id <id>]',
164
+ tool: "agentkit tool <name> [--input <path-or-json>]",
165
+ knowledge: "agentkit knowledge add <path-or-url> | sync | inspect | search <query> [--top-k <number>]",
166
+ spec: 'agentkit spec init --brief "owner request" | agentkit spec check',
167
+ sync: "agentkit sync init [--force] | agentkit sync run [--file <path>]",
168
+ eval: "agentkit eval run | agentkit eval from-conversation <conversation-id> [--out <path>] [--force]",
169
+ conversations:
170
+ "agentkit conversations list | agentkit conversations show <conversation-id> | agentkit conversations trace <conversation-id>",
171
+ deploy:
172
+ 'agentkit deploy [--smoke "hello"] | agentkit deploy smoke [--message "hello"] | agentkit deploy doctor | status | pause | resume',
173
+ secret:
174
+ "agentkit secret set <NAME> --stdin | --from-env [ENV_NAME] | --from-local-env | agentkit secret sync --from-local | list | unset <NAME>",
175
+ access: "agentkit access token create <name> [--out <path>] | list | revoke <token-id>",
176
+ env: "agentkit env set <NAME> --stdin | --from-env [ENV_NAME] | list | unset <NAME>",
177
+ docs: "agentkit docs path | llms | full",
178
+ handoff: "agentkit handoff codex [goal] | agentkit handoff claude [goal]",
179
+ };
180
+
181
+ return `Usage: ${usage[command] ?? "agentkit <command> [options]"}
182
+
183
+ Run \`agentkit help commands\` for the full command reference.`;
184
+ }