create-agents24-app 0.2.0 → 0.2.2
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 +21 -3
- package/dist/{chunk-ADXMZ3TT.js → chunk-F2J72UHQ.js} +35 -2
- package/dist/chunk-F2J72UHQ.js.map +1 -0
- package/dist/cli.js +44 -23
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/scaffold/src/components/chat/chat-composer.tsx +4 -2
- package/dist/scaffold-manifest.json +1 -1
- package/package.json +2 -2
- package/templates/common/README.md +6 -2
- package/templates/common/_gitignore +2 -0
- package/templates/integrations/bff/server/index.ts +11 -21
- package/templates/integrations/nextjs/app/api/agents24/[[...path]]/route.ts +14 -0
- package/templates/integrations/nextjs/app/chat.tsx +8 -0
- package/templates/integrations/nextjs/app/layout.tsx +10 -0
- package/templates/integrations/nextjs/app/page.tsx +8 -0
- package/templates/integrations/nextjs/next-env.d.ts +2 -0
- package/templates/integrations/nextjs/next.config.ts +13 -0
- package/templates/integrations/nextjs/postcss.config.mjs +1 -0
- package/templates/integrations/nextjs/proxy.ts +29 -0
- package/templates/integrations/nextjs/src/chat-app.tsx +23 -0
- package/templates/integrations/nextjs/tsconfig.json +21 -0
- package/templates/{integrations → shared}/bff/server/env.ts +24 -21
- package/templates/shared/bff/server/handler.ts +23 -0
- package/templates/{integrations → shared}/bff/server/principal.ts +2 -2
- package/templates/{integrations → shared}/bff/src/host-identity.ts +1 -1
- package/versions.json +6 -2
- package/dist/chunk-ADXMZ3TT.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# create-agents24-app
|
|
2
2
|
|
|
3
|
-
Last Updated: 2026-09-
|
|
3
|
+
Last Updated: 2026-09-07
|
|
4
4
|
|
|
5
|
-
Create a canonical Agents24 React
|
|
5
|
+
Create a canonical Agents24 React application:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm create agents24-app@latest
|
|
@@ -28,7 +28,15 @@ Use `--starter deep-research` for the Planner/Researcher/Critic template, or omi
|
|
|
28
28
|
|
|
29
29
|
The generator fetches the active compatible catalog and downloads only the selected immutable Package V2 archive. It verifies the advertised size and SHA-256 before extracting an editable `agents24/` tree with a fresh package identity. `customer-support` contains the Support Agent and empty reranked RAG foundation; `deep-research` contains the bounded Planner, Researcher, and Critic architecture with the same optional knowledge foundation. Templates never ingest content or configure credentials. `setup` combines apply, publish, and application configuration.
|
|
30
30
|
|
|
31
|
-
Choose a direct client deployment or
|
|
31
|
+
Choose a server-backed BFF (default) or direct client deployment. BFF offers Next.js (default) or Vite + Hono; direct client uses Vite. The Agent starter is an independent choice. Then paste a preset code from [shadcn/create](https://ui.shadcn.com/create). Soft preset `b2D1FHzlY` is the canonical default.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm create agents24-app@latest my-app -- --integration bff --stack nextjs
|
|
35
|
+
npm create agents24-app@latest my-app -- --integration bff --stack vite-hono
|
|
36
|
+
npm create agents24-app@latest my-app -- --integration client-deployment
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`--stack` accepts `nextjs`, `vite-hono`, or `vite`; invalid integration/stack combinations fail before generation. `--yes` now defaults to BFF + Next.js, replacing the old direct-client default. Existing Hono apps remain supported by lifecycle commands, including apps without `agents24.stack` metadata; generation does not migrate them.
|
|
32
40
|
|
|
33
41
|
The normal flow does not ask for an API base URL. Generated apps use `https://api.agents24.dev`; `--base-url` remains an advanced override for localhost, staging, private deployments, or proxies. Direct mode wires public deployment authentication through the browser session controller. BFF mode exposes a Guest host-identity adapter for customer-owned identity and login/logout navigation.
|
|
34
42
|
|
|
@@ -55,4 +63,14 @@ points to the same canonical scaffold and package guidance.
|
|
|
55
63
|
|
|
56
64
|
## Maintainer development
|
|
57
65
|
|
|
66
|
+
The stack-selection change is implemented in source and awaits canonical package publication and actual Vercel qualification. Do not assume the currently published `latest` contains it until release receipts confirm that version.
|
|
67
|
+
|
|
68
|
+
## Hosting
|
|
69
|
+
|
|
70
|
+
Next.js uses Node 22/24, builds without runtime credentials, and starts with the generated `build`/`start` scripts on Vercel, Railway, Render, or another Node host. For containers, enable `output: "standalone"` in `next.config.ts` before building; package `.next/static` and any `public` assets with the standalone server. Its nonce-based CSP requires dynamic, non-cached HTML. Browser BFF requests stay same-origin and credentials remain server-only.
|
|
71
|
+
|
|
72
|
+
Vite + Hono keeps its Node-server deployment. It does not generate a Vercel serverless adapter. Set host environment variables separately: `agents24 publish` publishes Agent resources, and `setup` configures the local app; neither deploys your website or sets up Artifact hosting.
|
|
73
|
+
|
|
74
|
+
## Local package development
|
|
75
|
+
|
|
58
76
|
From the repository root, `pnpm dev:agents24` incrementally prepares the current coordinated package train, publishes it to an ephemeral loopback registry, launches this packed interactive CLI, installs the selected app, and starts it. To refresh an existing isolated generated app after every package source or version change, use `pnpm dev:agents24 -- --serve /absolute/path/to/app`; it force-reinstalls that app. Use `pnpm dev:agents24 -- --template customer-support` or `--template deep-research` to generate and set up an official template against the platform catalog. Set `AGENTS24_BASE_URL` when targeting a local backend. Unchanged tarballs, scans, and packed runners are reused from the bounded development cache; add `--fresh` for a clean rebuild.
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// src/types.ts
|
|
4
4
|
var INTEGRATIONS = ["client-deployment", "bff"];
|
|
5
|
+
var STACKS = ["nextjs", "vite-hono", "vite"];
|
|
6
|
+
function resolveStack(integration, stack) {
|
|
7
|
+
const selected = stack ?? (integration === "bff" ? "nextjs" : "vite");
|
|
8
|
+
if (!INTEGRATIONS.includes(integration) || !STACKS.includes(selected) || (integration === "bff" ? selected === "vite" : selected !== "vite")) {
|
|
9
|
+
throw new Error(`Invalid stack/integration combination: ${selected} with ${integration}. Use bff with nextjs or vite-hono, or client-deployment with vite.`);
|
|
10
|
+
}
|
|
11
|
+
return selected;
|
|
12
|
+
}
|
|
5
13
|
var PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
|
|
6
14
|
var DEFAULT_PRESET = "b2D1FHzlY";
|
|
7
15
|
|
|
@@ -98,6 +106,21 @@ function generatedManifest(options, name) {
|
|
|
98
106
|
};
|
|
99
107
|
if (options.integration === "bff") {
|
|
100
108
|
dependencies["@agents24/node"] = versions.agents24["@agents24/node"];
|
|
109
|
+
dependencies.zod = versions.runtime.zod;
|
|
110
|
+
}
|
|
111
|
+
if (options.stack === "nextjs") {
|
|
112
|
+
dependencies.next = versions.runtime.next;
|
|
113
|
+
dependencies["server-only"] = versions.runtime["server-only"];
|
|
114
|
+
delete devDependencies.vite;
|
|
115
|
+
delete devDependencies["@vitejs/plugin-react"];
|
|
116
|
+
delete devDependencies["@tailwindcss/vite"];
|
|
117
|
+
devDependencies["@tailwindcss/postcss"] = versions.development["@tailwindcss/postcss"];
|
|
118
|
+
scripts.dev = "next dev";
|
|
119
|
+
scripts.build = "next build";
|
|
120
|
+
scripts.start = "next start";
|
|
121
|
+
delete scripts.preview;
|
|
122
|
+
}
|
|
123
|
+
if (options.stack === "vite-hono") {
|
|
101
124
|
dependencies.hono = versions.runtime.hono;
|
|
102
125
|
dependencies["@hono/node-server"] = versions.runtime["@hono/node-server"];
|
|
103
126
|
devDependencies.concurrently = versions.development.concurrently;
|
|
@@ -115,6 +138,7 @@ function generatedManifest(options, name) {
|
|
|
115
138
|
engines: { node: "^22.0.0 || ^24.0.0" },
|
|
116
139
|
agents24: {
|
|
117
140
|
integration: options.integration,
|
|
141
|
+
stack: options.stack,
|
|
118
142
|
package_manager: options.packageManager,
|
|
119
143
|
preset: options.preset,
|
|
120
144
|
scaffold_sha256: scaffoldManifest.sha256,
|
|
@@ -219,6 +243,7 @@ function applyShadcnPreset(directory, preset) {
|
|
|
219
243
|
clearPresetInstallArtifacts(directory);
|
|
220
244
|
}
|
|
221
245
|
function createApp(options) {
|
|
246
|
+
options = { ...options, stack: resolveStack(options.integration, options.stack) };
|
|
222
247
|
const destination = resolve(options.directory);
|
|
223
248
|
assertDestination(destination);
|
|
224
249
|
const name = packageName(destination);
|
|
@@ -230,12 +255,18 @@ function createApp(options) {
|
|
|
230
255
|
cpSync(scaffoldRoot, staging, { recursive: true, force: true });
|
|
231
256
|
rmSync(join(staging, "manifest.json"), { force: true });
|
|
232
257
|
copyLayer("common", staging);
|
|
233
|
-
|
|
258
|
+
if (options.integration === "bff") copyLayer("shared/bff", staging);
|
|
259
|
+
copyLayer(`integrations/${options.stack === "nextjs" ? "nextjs" : options.integration}`, staging);
|
|
260
|
+
if (options.stack === "nextjs") {
|
|
261
|
+
for (const file of ["index.html", "src/vite-env.d.ts"]) rmSync(join(staging, file), { force: true });
|
|
262
|
+
}
|
|
234
263
|
materializeTemplate(staging, options);
|
|
235
264
|
replaceTemplateValues(staging, {
|
|
236
265
|
"__APP_NAME__": name,
|
|
237
266
|
"__PRESET__": options.preset,
|
|
238
267
|
"__INTEGRATION__": options.integration,
|
|
268
|
+
"__STACK__": options.stack,
|
|
269
|
+
"__HOSTING__": options.stack === "nextjs" ? "Next.js runs on Vercel or any supported Node host, including Railway and Render. Configure server variables from `.env.example` in your host; `next build` does not need runtime credentials. For containers, enable `output: 'standalone'` in `next.config.ts` before building, then copy `.next/standalone`, `.next/static` (to `.next/static` in the standalone directory), and `public` if present, then run `node server.js` with `HOSTNAME=0.0.0.0`. The document CSP uses a fresh nonce and dynamic HTML rendering. BFF routes are never cached. Streaming duration is limited by your hosting plan; the route requests 300 seconds." : options.stack === "vite-hono" ? "The production command runs the Hono Node server and serves the built Vite frontend. Configure server variables from `.env.example` in your host. This Node template does not include a Vercel serverless routing adapter." : "Deploy `dist/` to a static host. The preview command is for local verification. Configure the exact public origin in your Client Deployment and set its public build variables before building.",
|
|
239
270
|
"__CONNECT_SOURCE__": options.integration === "client-deployment" ? " __AGENTS24_CONNECT_SOURCE__" : "",
|
|
240
271
|
"__PM_DEV__": runScriptCommand(options.packageManager, "dev"),
|
|
241
272
|
"__PM_BUILD__": runScriptCommand(options.packageManager, "build"),
|
|
@@ -411,6 +442,8 @@ async function selectTemplate(baseUrl, catalog, id) {
|
|
|
411
442
|
|
|
412
443
|
export {
|
|
413
444
|
INTEGRATIONS,
|
|
445
|
+
STACKS,
|
|
446
|
+
resolveStack,
|
|
414
447
|
PACKAGE_MANAGERS,
|
|
415
448
|
DEFAULT_PRESET,
|
|
416
449
|
installDependencies,
|
|
@@ -419,4 +452,4 @@ export {
|
|
|
419
452
|
compatibleTemplates,
|
|
420
453
|
selectTemplate
|
|
421
454
|
};
|
|
422
|
-
//# sourceMappingURL=chunk-
|
|
455
|
+
//# sourceMappingURL=chunk-F2J72UHQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/generator.ts","../src/template-catalog.ts"],"sourcesContent":["export const INTEGRATIONS = [\"client-deployment\", \"bff\"] as const;\nexport const STACKS = [\"nextjs\", \"vite-hono\", \"vite\"] as const;\nexport type Stack = (typeof STACKS)[number];\n\nexport function resolveStack(integration: Integration, stack?: Stack): Stack {\n const selected = stack ?? (integration === \"bff\" ? \"nextjs\" : \"vite\");\n if (!INTEGRATIONS.includes(integration) || !STACKS.includes(selected) ||\n (integration === \"bff\" ? selected === \"vite\" : selected !== \"vite\")) {\n throw new Error(`Invalid stack/integration combination: ${selected} with ${integration}. Use bff with nextjs or vite-hono, or client-deployment with vite.`);\n }\n return selected;\n}\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const;\nexport const DEFAULT_PRESET = \"b2D1FHzlY\";\n\nexport type Integration = (typeof INTEGRATIONS)[number];\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\nexport type Starter = string;\n\nexport type TemplateSelection = {\n id: Starter;\n version: string;\n displayName: string;\n sha256: string;\n catalogRevision: string;\n files: Map<string, string>;\n};\n\nexport type CreateAppOptions = {\n directory: string;\n integration: Integration;\n stack?: Stack;\n preset: string;\n packageManager: PackageManager;\n install: boolean;\n baseUrl: string;\n starter?: TemplateSelection;\n deploymentId?: string;\n agentId?: string;\n agentAlias?: string;\n agentVersionId?: string;\n};\n\nexport type GeneratedApp = {\n directory: string;\n packageName: string;\n};\n","import { spawnSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n chmodSync,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createRequire } from \"node:module\";\n\nimport { DEFAULT_PRESET, resolveStack, type CreateAppOptions, type GeneratedApp, type PackageManager } from \"./types.js\";\n\ntype Versions = {\n agents24: Record<string, string>;\n runtime: Record<string, string>;\n development: Record<string, string>;\n};\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), \"..\");\nconst templateRoot = join(packageRoot, \"templates\");\nconst scaffoldRoot = join(packageRoot, \"dist/scaffold\");\nconst scaffoldManifest = JSON.parse(readFileSync(join(packageRoot, \"dist/scaffold-manifest.json\"), \"utf8\")) as {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n sha256: string;\n};\nconst versions = JSON.parse(readFileSync(join(packageRoot, \"versions.json\"), \"utf8\")) as Versions;\nconst require = createRequire(import.meta.url);\n\nfunction packageName(directory: string): string {\n const value = basename(resolve(directory))\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\");\n if (!value || !/^[a-z0-9]/.test(value)) throw new Error(\"The destination does not produce a valid npm package name.\");\n return value;\n}\n\nfunction assertDestination(destination: string): void {\n if (!existsSync(destination)) return;\n if (!statSync(destination).isDirectory()) throw new Error(\"The destination already exists and is not a directory.\");\n if (readdirSync(destination).length > 0) throw new Error(\"The destination directory must be empty.\");\n}\n\nfunction walk(directory: string): string[] {\n return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {\n const path = join(directory, entry.name);\n return entry.isDirectory() ? walk(path) : [path];\n });\n}\n\nfunction replaceTemplateValues(directory: string, replacements: Record<string, string>): void {\n for (const file of walk(directory)) {\n if (file.endsWith(\".png\") || file.endsWith(\".ico\")) continue;\n let content = readFileSync(file, \"utf8\");\n for (const [token, value] of Object.entries(replacements)) content = content.split(token).join(value);\n writeFileSync(file, content);\n }\n}\n\nfunction copyLayer(name: string, destination: string): void {\n cpSync(join(templateRoot, name), destination, { recursive: true, force: true });\n}\n\nfunction materializeTemplate(destination: string, options: CreateAppOptions): void {\n if (!options.starter) return;\n const packageId = `pkg_${randomBytes(16).toString(\"hex\")}`;\n let replacedManifest = false;\n for (const [path, original] of options.starter.files) {\n let content = original;\n if (path === \"agents24.yaml\") {\n content = content.replace(/^(package_id:\\s*)[^\\s#]+/m, `$1${packageId}`);\n replacedManifest = content !== original;\n }\n const target = join(destination, \"agents24\", path);\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, content);\n }\n if (!replacedManifest) throw new Error(\"The selected Agent template has no replaceable package_id.\");\n}\n\nfunction generatedManifest(options: CreateAppOptions, name: string): Record<string, unknown> {\n const dependencies: Record<string, string> = {\n \"@agents24/client\": versions.agents24[\"@agents24/client\"]!,\n \"@agents24/react\": versions.agents24[\"@agents24/react\"]!,\n \"@agents24/chat-react\": versions.agents24[\"@agents24/chat-react\"]!,\n ...scaffoldManifest.dependencies,\n react: versions.runtime.react!,\n \"react-dom\": versions.runtime[\"react-dom\"]!,\n };\n const devDependencies: Record<string, string> = {\n \"@types/node\": versions.development[\"@types/node\"]!,\n \"@types/react\": versions.development[\"@types/react\"]!,\n \"@types/react-dom\": versions.development[\"@types/react-dom\"]!,\n \"@vitejs/plugin-react\": versions.development[\"@vitejs/plugin-react\"]!,\n ...scaffoldManifest.devDependencies,\n typescript: versions.development.typescript!,\n vite: versions.development.vite!,\n };\n const scripts: Record<string, string> = {\n dev: \"vite\",\n build: \"tsc --noEmit && vite build\",\n preview: \"vite preview\",\n preset: \"node scripts/apply-preset.mjs\",\n };\n if (options.integration === \"bff\") {\n dependencies[\"@agents24/node\"] = versions.agents24[\"@agents24/node\"]!;\n dependencies.zod = versions.runtime.zod!;\n }\n if (options.stack === \"nextjs\") {\n dependencies.next = versions.runtime.next!;\n dependencies[\"server-only\"] = versions.runtime[\"server-only\"]!;\n delete devDependencies.vite;\n delete devDependencies[\"@vitejs/plugin-react\"];\n delete devDependencies[\"@tailwindcss/vite\"];\n devDependencies[\"@tailwindcss/postcss\"] = versions.development[\"@tailwindcss/postcss\"]!;\n scripts.dev = \"next dev\";\n scripts.build = \"next build\";\n scripts.start = \"next start\";\n delete scripts.preview;\n }\n if (options.stack === \"vite-hono\") {\n dependencies.hono = versions.runtime.hono!;\n dependencies[\"@hono/node-server\"] = versions.runtime[\"@hono/node-server\"]!;\n devDependencies.concurrently = versions.development.concurrently!;\n devDependencies.tsx = versions.development.tsx!;\n devDependencies.tsup = \"^8.5.1\";\n scripts.dev = \"concurrently -k -n web,bff \\\"vite\\\" \\\"tsx watch server/index.ts\\\"\";\n scripts.build = \"tsc --noEmit && vite build && tsup server/index.ts --format esm --platform node --out-dir server-dist --external @agents24/node --external hono --external @hono/node-server\";\n scripts.start = \"node server-dist/index.js --production\";\n }\n return {\n name,\n private: true,\n version: \"0.0.0\",\n type: \"module\",\n engines: { node: \"^22.0.0 || ^24.0.0\" },\n agents24: {\n integration: options.integration,\n stack: options.stack,\n package_manager: options.packageManager,\n preset: options.preset,\n scaffold_sha256: scaffoldManifest.sha256,\n ...(options.starter ? { template: {\n id: options.starter.id,\n version: options.starter.version,\n sha256: options.starter.sha256,\n catalog_revision: options.starter.catalogRevision,\n } } : {}),\n },\n scripts,\n dependencies,\n devDependencies,\n };\n}\n\nfunction envFiles(options: CreateAppOptions, appName: string): { example: string; local: string } {\n const value = (input: string | undefined) => JSON.stringify(String(input || \"\"));\n const jsonValue = (input: unknown) => JSON.stringify(input);\n const baseUrlOverride = options.baseUrl === \"https://api.agents24.dev\" ? [] : [\n `${options.integration === \"client-deployment\" ? \"VITE_\" : \"\"}AGENTS24_BASE_URL=${value(options.baseUrl)}`,\n ];\n if (options.integration === \"client-deployment\") {\n return {\n example: \"# VITE_AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\\nVITE_AGENTS24_DEPLOYMENT_ID=acd_your_public_deployment_id\\n\",\n local: [...baseUrlOverride, ...(options.deploymentId ? [`VITE_AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : []), \"\"].join(\"\\n\"),\n };\n }\n return {\n example: [\n \"# AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\",\n \"AGENTS24_API_KEY=your_server_only_api_key\",\n \"# agentVersion accepts draft, latest, or an exact published version such as v1\",\n \"AGENTS24_AGENTS=[{\\\"agentAlias\\\":\\\"your-agent-alias\\\",\\\"agentVersion\\\":\\\"v1\\\"}]\",\n \"# agentId remains supported instead of agentAlias when UUID configuration is preferred\",\n \"AGENTS24_INTEGRATION_ID=generate_one_stable_random_value\",\n \"AGENTS24_INTEGRATION_NAME=your_app_name # optional\",\n \"# AGENTS24_RUNTIME_TARGET=draft # optional server-only override\",\n \"SESSION_COOKIE_SECRET=generate_at_least_32_random_bytes\",\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n local: [\n ...baseUrlOverride,\n ...(options.agentAlias || options.agentId ? [\n `AGENTS24_AGENTS=${jsonValue([{ ...(options.agentAlias ? { agentAlias: options.agentAlias } : { agentId: options.agentId }), ...(options.agentVersionId ? { agentVersionId: options.agentVersionId } : {}) }])}`,\n ] : []),\n `AGENTS24_INTEGRATION_ID=${value(randomBytes(24).toString(\"base64url\"))}`,\n `AGENTS24_INTEGRATION_NAME=${value(appName)}`,\n `SESSION_COOKIE_SECRET=${value(randomBytes(32).toString(\"base64url\"))}`,\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n };\n}\n\nfunction installCommand(packageManager: PackageManager): [string, string[]] {\n if (packageManager === \"npm\") return [\"npm\", [\"install\"]];\n if (packageManager === \"yarn\") return [\"yarn\", []];\n if (packageManager === \"bun\") return [\"bun\", [\"install\"]];\n return [\"pnpm\", [\"install\", \"--ignore-workspace\"]];\n}\n\nfunction runScriptCommand(packageManager: PackageManager, script: string): string {\n if (packageManager === \"npm\") return `npm run ${script}`;\n if (packageManager === \"bun\") return `bun run ${script}`;\n return `${packageManager} ${script}`;\n}\n\nexport function installDependencies(directory: string, packageManager: PackageManager): void {\n const [command, args] = installCommand(packageManager);\n const { AGENTS24_API_KEY: _apiKey, ...installerEnvironment } = process.env;\n const result = spawnSync(command, args, { cwd: directory, stdio: \"inherit\", env: installerEnvironment });\n if (result.error) throw new Error(`Could not start ${command}: ${result.error.message}`);\n if (result.status !== 0) throw new Error(`${command} ${args.join(\" \")} failed with exit ${result.status}.`);\n}\n\nfunction clearPresetInstallArtifacts(directory: string): void {\n for (const name of [\"node_modules\", \"bun.lock\", \"bun.lockb\", \"package-lock.json\", \"pnpm-lock.yaml\", \"yarn.lock\"]) {\n rmSync(join(directory, name), { recursive: true, force: true });\n }\n}\n\nfunction applyShadcnPreset(directory: string, preset: string): void {\n if (preset === DEFAULT_PRESET) return;\n const executable = require.resolve(\"shadcn\");\n const { AGENTS24_API_KEY: _apiKey, ...presetEnvironment } = process.env;\n const result = spawnSync(\n process.execPath,\n [executable, \"apply\", preset, \"--yes\", \"--silent\", \"--cwd\", directory],\n { cwd: directory, encoding: \"utf8\", env: presetEnvironment },\n );\n if (result.error) throw new Error(`Could not start Shadcn preset materialization: ${result.error.message}`);\n if (result.status !== 0) {\n const detail = String(result.stderr || result.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Shadcn could not apply preset ${preset}.`);\n }\n const scopeResult = spawnSync(\n process.execPath,\n [join(directory, \"scripts/scope-preset-theme.mjs\")],\n { cwd: directory, encoding: \"utf8\" },\n );\n if (scopeResult.error) throw new Error(`Could not scope the selected Shadcn preset: ${scopeResult.error.message}`);\n if (scopeResult.status !== 0) {\n const detail = String(scopeResult.stderr || scopeResult.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Could not scope Shadcn preset ${preset}.`);\n }\n clearPresetInstallArtifacts(directory);\n}\n\nexport function createApp(options: CreateAppOptions): GeneratedApp {\n options = { ...options, stack: resolveStack(options.integration, options.stack) };\n const destination = resolve(options.directory);\n assertDestination(destination);\n const name = packageName(destination);\n const parent = dirname(destination);\n mkdirSync(parent, { recursive: true });\n const staging = join(parent, `.${name}.agents24-${randomBytes(6).toString(\"hex\")}`);\n try {\n mkdirSync(staging, { mode: 0o700 });\n cpSync(scaffoldRoot, staging, { recursive: true, force: true });\n rmSync(join(staging, \"manifest.json\"), { force: true });\n copyLayer(\"common\", staging);\n if (options.integration === \"bff\") copyLayer(\"shared/bff\", staging);\n copyLayer(`integrations/${options.stack === \"nextjs\" ? \"nextjs\" : options.integration}`, staging);\n if (options.stack === \"nextjs\") {\n for (const file of [\"index.html\", \"src/vite-env.d.ts\"]) rmSync(join(staging, file), { force: true });\n }\n materializeTemplate(staging, options);\n replaceTemplateValues(staging, {\n \"__APP_NAME__\": name,\n \"__PRESET__\": options.preset,\n \"__INTEGRATION__\": options.integration,\n \"__STACK__\": options.stack!,\n \"__HOSTING__\": options.stack === \"nextjs\"\n ? \"Next.js runs on Vercel or any supported Node host, including Railway and Render. Configure server variables from `.env.example` in your host; `next build` does not need runtime credentials. For containers, enable `output: 'standalone'` in `next.config.ts` before building, then copy `.next/standalone`, `.next/static` (to `.next/static` in the standalone directory), and `public` if present, then run `node server.js` with `HOSTNAME=0.0.0.0`. The document CSP uses a fresh nonce and dynamic HTML rendering. BFF routes are never cached. Streaming duration is limited by your hosting plan; the route requests 300 seconds.\"\n : options.stack === \"vite-hono\"\n ? \"The production command runs the Hono Node server and serves the built Vite frontend. Configure server variables from `.env.example` in your host. This Node template does not include a Vercel serverless routing adapter.\"\n : \"Deploy `dist/` to a static host. The preview command is for local verification. Configure the exact public origin in your Client Deployment and set its public build variables before building.\",\n \"__CONNECT_SOURCE__\": options.integration === \"client-deployment\" ? \" __AGENTS24_CONNECT_SOURCE__\" : \"\",\n \"__PM_DEV__\": runScriptCommand(options.packageManager, \"dev\"),\n \"__PM_BUILD__\": runScriptCommand(options.packageManager, \"build\"),\n \"__PM_PRODUCTION__\": runScriptCommand(options.packageManager, options.integration === \"bff\" ? \"start\" : \"preview\"),\n \"__PM_PRESET__\": `${runScriptCommand(options.packageManager, \"preset\")} --`,\n \"__STARTER_SETUP__\": options.starter\n ? `## Set up the included Agent\\n\\nThis repository includes an editable Resource Package in \\`agents24/\\`. For a BFF, run \\`agents24 apply ./agents24\\` to reconcile drafts and \\`agents24 publish ./agents24\\` for production. For a direct-client app, run \\`agents24 setup ./agents24 --app .\\` so publication happens before deployment configuration. Use \\`agents24 dev ./agents24\\` when a local Artifact server is required.`\n : \"\",\n });\n const gitignore = join(staging, \"_gitignore\");\n if (existsSync(gitignore)) renameSync(gitignore, join(staging, \".gitignore\"));\n writeFileSync(join(staging, \"package.json\"), `${JSON.stringify(generatedManifest(options, name), null, 2)}\\n`);\n applyShadcnPreset(staging, options.preset);\n const env = envFiles(options, name);\n writeFileSync(join(staging, \".env.example\"), env.example);\n if (options.install) installDependencies(staging, options.packageManager);\n writeFileSync(join(staging, \".env.local\"), env.local, { mode: 0o600 });\n chmodSync(join(staging, \".env.local\"), 0o600);\n if (existsSync(destination)) rmSync(destination, { recursive: true });\n renameSync(staging, destination);\n return { directory: destination, packageName: name };\n } catch (error) {\n rmSync(staging, { recursive: true, force: true });\n throw error;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { unpackFiles } from \"@agents24/cli\";\n\nimport { type Starter, type TemplateSelection } from \"./types.js\";\n\ntype CatalogTemplate = {\n id: string;\n version: string;\n display_name: string;\n description: string;\n compatibility: { min_generator_version?: string; resource_package_schema?: string };\n archive: { sha256: string; size: number; download_url: string };\n};\n\ntype Catalog = {\n schema_version: \"agents24.template-catalog.v1\";\n revision: string;\n templates: CatalogTemplate[];\n};\n\ntype CachedCatalog = { etag?: string; catalog: Catalog };\n\nconst GENERATOR_VERSION = \"0.2.0\";\nconst SHA256 = /^[0-9a-f]{64}$/;\nconst SEMVER = /^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$/;\nconst TEMPLATE_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\n\nfunction cacheRoot(): string {\n const override = String(process.env.AGENTS24_TEMPLATE_CACHE_DIR || \"\").trim();\n if (override) return override;\n const platformRoot = process.platform === \"win32\"\n ? process.env.LOCALAPPDATA\n : process.env.XDG_CACHE_HOME || join(homedir(), \".cache\");\n return join(platformRoot || tmpdir(), \"agents24\", \"templates-v1\");\n}\n\nfunction atomicWrite(path: string, data: string | Uint8Array): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n const temporary = `${path}.${process.pid}.tmp`;\n writeFileSync(temporary, data, { mode: 0o600 });\n renameSync(temporary, path);\n}\n\nfunction parseVersion(value: string): [number, number, number] | null {\n const match = SEMVER.exec(value);\n return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;\n}\n\nfunction compatible(item: CatalogTemplate): boolean {\n const minimum = parseVersion(String(item.compatibility?.min_generator_version || \"0.0.0\"));\n const current = parseVersion(GENERATOR_VERSION)!;\n if (!minimum || item.compatibility?.resource_package_schema !== \"2.0\") return false;\n return current[0] > minimum[0]\n || (current[0] === minimum[0] && current[1] > minimum[1])\n || (current[0] === minimum[0] && current[1] === minimum[1] && current[2] >= minimum[2]);\n}\n\nfunction validateCatalog(value: unknown): Catalog {\n const catalog = value as Catalog;\n if (catalog?.schema_version !== \"agents24.template-catalog.v1\" || !SHA256.test(catalog.revision) || !Array.isArray(catalog.templates)) {\n throw new Error(\"The Agents24 template catalog is invalid.\");\n }\n const ids = new Set<string>();\n for (const item of catalog.templates) {\n if (!TEMPLATE_ID.test(item?.id) || ids.has(item.id) || !SEMVER.test(item.version)\n || !item.display_name || !SHA256.test(item.archive?.sha256) || !Number.isSafeInteger(item.archive?.size)\n || item.archive.size < 1 || item.archive.size > 5 * 1024 * 1024 || !item.archive.download_url?.startsWith(\"/templates/\")) {\n throw new Error(\"The Agents24 template catalog contains an invalid release.\");\n }\n ids.add(item.id);\n }\n return catalog;\n}\n\nfunction readCachedCatalog(path: string): CachedCatalog | null {\n try {\n const cached = JSON.parse(readFileSync(path, \"utf8\")) as CachedCatalog;\n return { ...(cached.etag ? { etag: cached.etag } : {}), catalog: validateCatalog(cached.catalog) };\n } catch {\n return null;\n }\n}\n\nexport async function loadTemplateCatalog(baseUrl: string): Promise<{ catalog: Catalog; live: boolean }> {\n const path = join(cacheRoot(), \"catalog.json\");\n const cached = existsSync(path) ? readCachedCatalog(path) : null;\n try {\n const response = await fetch(new URL(\"/templates\", `${baseUrl}/`), {\n headers: cached?.etag ? { \"If-None-Match\": cached.etag } : {},\n signal: AbortSignal.timeout(10_000),\n });\n if (response.status === 304 && cached) return { catalog: cached.catalog, live: true };\n if (!response.ok) throw new Error(`catalog request returned ${response.status}`);\n const catalog = validateCatalog(await response.json());\n const etag = response.headers.get(\"etag\") || undefined;\n atomicWrite(path, `${JSON.stringify({ ...(etag ? { etag } : {}), catalog })}\\n`);\n return { catalog, live: true };\n } catch (error) {\n if (cached) return { catalog: cached.catalog, live: false };\n const detail = error instanceof Error ? error.message : \"request failed\";\n throw new Error(`Could not load the Agents24 template catalog (${detail}), and no verified cached catalog is available.`);\n }\n}\n\nexport function compatibleTemplates(catalog: Catalog): CatalogTemplate[] {\n return catalog.templates.filter(compatible);\n}\n\nfunction verifiedArchive(path: string, item: CatalogTemplate): Uint8Array | null {\n try {\n const archive = readFileSync(path);\n if (archive.byteLength !== item.archive.size || createHash(\"sha256\").update(archive).digest(\"hex\") !== item.archive.sha256) return null;\n unpackFiles(archive);\n return archive;\n } catch {\n return null;\n }\n}\n\nasync function readArchiveResponse(response: Response, expectedSize: number): Promise<Uint8Array> {\n if (!response.body) throw new Error(\"Template download returned no archive body.\");\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > expectedSize || size > 5 * 1024 * 1024) {\n await reader.cancel();\n throw new Error(\"Template download exceeds its advertised archive size.\");\n }\n chunks.push(value);\n }\n const archive = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n archive.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return archive;\n}\n\nexport async function selectTemplate(baseUrl: string, catalog: Catalog, id: string): Promise<TemplateSelection> {\n if (id === \"rag\") throw new Error(\"The 'rag' starter was removed. Use --starter customer-support or --starter deep-research.\");\n const item = catalog.templates.find((candidate) => candidate.id === id);\n if (!item) throw new Error(`Template '${id}' is not available in the active catalog.`);\n if (!compatible(item)) throw new Error(`Template '${id}' requires a newer create-agents24-app release.`);\n const path = join(cacheRoot(), \"archives\", `${item.archive.sha256}.zip`);\n let archive = existsSync(path) ? verifiedArchive(path, item) : null;\n if (!archive) {\n let response: Response;\n try {\n response = await fetch(new URL(item.archive.download_url, `${baseUrl}/`), { signal: AbortSignal.timeout(30_000) });\n } catch (error) {\n throw new Error(`Could not download template '${id}', and no verified cached archive is available.`);\n }\n if (!response.ok) throw new Error(`Could not download template '${id}' (HTTP ${response.status}).`);\n const length = response.headers.get(\"content-length\");\n if (length && Number(length) !== item.archive.size) throw new Error(`Template '${id}' download size does not match the catalog.`);\n archive = await readArchiveResponse(response, item.archive.size);\n if (archive.byteLength !== item.archive.size || createHash(\"sha256\").update(archive).digest(\"hex\") !== item.archive.sha256) {\n throw new Error(`Template '${id}' failed integrity verification.`);\n }\n unpackFiles(archive);\n atomicWrite(path, archive);\n }\n return {\n id: item.id as Starter,\n version: item.version,\n displayName: item.display_name,\n sha256: item.archive.sha256,\n catalogRevision: catalog.revision,\n files: unpackFiles(archive),\n };\n}\n"],"mappings":"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","names":["require","existsSync","mkdirSync","readFileSync","renameSync","writeFileSync","dirname","join"]}
|
package/dist/cli.js
CHANGED
|
@@ -3,11 +3,13 @@ import {
|
|
|
3
3
|
DEFAULT_PRESET,
|
|
4
4
|
INTEGRATIONS,
|
|
5
5
|
PACKAGE_MANAGERS,
|
|
6
|
+
STACKS,
|
|
6
7
|
compatibleTemplates,
|
|
7
8
|
createApp,
|
|
8
9
|
loadTemplateCatalog,
|
|
10
|
+
resolveStack,
|
|
9
11
|
selectTemplate
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-F2J72UHQ.js";
|
|
11
13
|
|
|
12
14
|
// src/cli.ts
|
|
13
15
|
import { writeFileSync } from "fs";
|
|
@@ -18,6 +20,7 @@ import { intro, outro } from "@clack/prompts";
|
|
|
18
20
|
import process from "process";
|
|
19
21
|
var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
20
22
|
"integration",
|
|
23
|
+
"stack",
|
|
21
24
|
"preset",
|
|
22
25
|
"package-manager",
|
|
23
26
|
"base-url",
|
|
@@ -59,6 +62,7 @@ Usage:
|
|
|
59
62
|
|
|
60
63
|
Options:
|
|
61
64
|
--integration <client-deployment|bff>
|
|
65
|
+
--stack <nextjs|vite-hono|vite> BFF defaults to Next.js; direct client uses Vite
|
|
62
66
|
--preset <shadcn-preset-code> Defaults to b2D1FHzlY
|
|
63
67
|
--package-manager <pnpm|npm|yarn|bun>
|
|
64
68
|
--base-url <url>
|
|
@@ -122,6 +126,7 @@ async function resolveOptions(args) {
|
|
|
122
126
|
const nonInteractive = args.flags.yes === true;
|
|
123
127
|
let directory = args.directory;
|
|
124
128
|
let integration = oneOf(flag(args, "integration"), INTEGRATIONS, "integration");
|
|
129
|
+
let stack = oneOf(flag(args, "stack"), STACKS, "stack");
|
|
125
130
|
let preset = flag(args, "preset");
|
|
126
131
|
let packageManager = oneOf(flag(args, "package-manager"), PACKAGE_MANAGERS, "package-manager");
|
|
127
132
|
let baseUrl = flag(args, "base-url");
|
|
@@ -131,38 +136,33 @@ async function resolveOptions(args) {
|
|
|
131
136
|
directory ||= await requiredText("Where should the app be created?", "my-agents24-app");
|
|
132
137
|
if (!integration) {
|
|
133
138
|
const result = await select({ message: "How should the app connect?", options: [
|
|
134
|
-
{ value: "
|
|
135
|
-
{ value: "
|
|
139
|
+
{ value: "bff", label: "Server BFF (recommended)", hint: "API key remains on your server" },
|
|
140
|
+
{ value: "client-deployment", label: "Client deployment", hint: "Direct browser connection" }
|
|
136
141
|
] });
|
|
137
142
|
cancelled(result);
|
|
138
143
|
integration = result;
|
|
139
144
|
}
|
|
140
|
-
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (!packageManager) {
|
|
146
|
-
const detected = detectedPackageManager();
|
|
147
|
-
const result = await select({ message: "Package manager", initialValue: detected, options: PACKAGE_MANAGERS.map((value) => ({ value, label: value })) });
|
|
148
|
-
cancelled(result);
|
|
149
|
-
packageManager = result;
|
|
150
|
-
}
|
|
151
|
-
if (args.flags["no-install"] !== true) {
|
|
152
|
-
const result = await confirm({ message: "Install dependencies?", initialValue: true });
|
|
145
|
+
if (integration === "bff" && !stack) {
|
|
146
|
+
const result = await select({ message: "Application stack", initialValue: "nextjs", options: [
|
|
147
|
+
{ value: "nextjs", label: "Next.js (recommended)", hint: "Full-stack App Router application" },
|
|
148
|
+
{ value: "vite-hono", label: "Vite + Hono", hint: "Vite frontend and Node server" }
|
|
149
|
+
] });
|
|
153
150
|
cancelled(result);
|
|
154
|
-
|
|
151
|
+
stack = result;
|
|
155
152
|
}
|
|
156
153
|
}
|
|
154
|
+
integration ||= "bff";
|
|
155
|
+
stack = resolveStack(integration, stack);
|
|
156
|
+
if (integration === "bff" && flag(args, "deployment-id")) throw new Error("--deployment-id requires --integration client-deployment.");
|
|
157
|
+
if (integration === "client-deployment" && ["agent-id", "agent-alias", "agent-version-id"].some((name) => flag(args, name))) {
|
|
158
|
+
throw new Error("Agent selectors require --integration bff.");
|
|
159
|
+
}
|
|
157
160
|
directory = String(directory || "").trim();
|
|
158
|
-
integration ||= "client-deployment";
|
|
159
|
-
preset ||= DEFAULT_PRESET;
|
|
160
|
-
packageManager ||= detectedPackageManager();
|
|
161
161
|
baseUrl ||= "https://api.agents24.dev";
|
|
162
162
|
const urlError = validateUrl(baseUrl);
|
|
163
163
|
if (!directory) throw new Error("A destination directory is required.");
|
|
164
164
|
if (urlError) throw new Error(urlError);
|
|
165
|
-
if (!PRESET.test(preset)) throw new Error("--preset must be a valid Shadcn preset code.");
|
|
165
|
+
if (preset && !PRESET.test(preset)) throw new Error("--preset must be a valid Shadcn preset code.");
|
|
166
166
|
let starter;
|
|
167
167
|
if (requestedStarter || !nonInteractive) {
|
|
168
168
|
const { catalog } = await loadTemplateCatalog(baseUrl);
|
|
@@ -181,10 +181,30 @@ async function resolveOptions(args) {
|
|
|
181
181
|
}
|
|
182
182
|
if (selectedId) starter = await selectTemplate(baseUrl, catalog, selectedId);
|
|
183
183
|
}
|
|
184
|
+
if (!nonInteractive) {
|
|
185
|
+
preset ||= await requiredText(
|
|
186
|
+
"Shadcn preset code",
|
|
187
|
+
DEFAULT_PRESET,
|
|
188
|
+
(value) => PRESET.test(value) ? void 0 : "Enter a valid Shadcn preset code."
|
|
189
|
+
);
|
|
190
|
+
if (!packageManager) {
|
|
191
|
+
const detected = detectedPackageManager();
|
|
192
|
+
const result = await select({ message: "Package manager", initialValue: detected, options: PACKAGE_MANAGERS.map((value) => ({ value, label: value })) });
|
|
193
|
+
cancelled(result);
|
|
194
|
+
packageManager = result;
|
|
195
|
+
}
|
|
196
|
+
if (args.flags["no-install"] !== true) {
|
|
197
|
+
const result = await confirm({ message: "Install dependencies?", initialValue: true });
|
|
198
|
+
cancelled(result);
|
|
199
|
+
install = result;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
preset ||= DEFAULT_PRESET;
|
|
203
|
+
packageManager ||= detectedPackageManager();
|
|
184
204
|
if (integration === "client-deployment") {
|
|
185
205
|
const deploymentId = flag(args, "deployment-id");
|
|
186
206
|
if (deploymentId && !DEPLOYMENT_ID.test(deploymentId)) throw new Error("--deployment-id must be a valid public acd_\u2026 deployment ID.");
|
|
187
|
-
return { directory, integration, preset, packageManager, install, baseUrl, starter, deploymentId };
|
|
207
|
+
return { directory, integration, stack, preset, packageManager, install, baseUrl, starter, deploymentId };
|
|
188
208
|
}
|
|
189
209
|
const fields = {
|
|
190
210
|
agentId: flag(args, "agent-id"),
|
|
@@ -197,7 +217,7 @@ async function resolveOptions(args) {
|
|
|
197
217
|
if (fields.agentAlias && !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(fields.agentAlias)) {
|
|
198
218
|
throw new Error("--agent-alias must be lowercase kebab-case.");
|
|
199
219
|
}
|
|
200
|
-
return { directory, integration, preset, packageManager, install, baseUrl, starter, ...fields };
|
|
220
|
+
return { directory, integration, stack, preset, packageManager, install, baseUrl, starter, ...fields };
|
|
201
221
|
}
|
|
202
222
|
|
|
203
223
|
// src/cli.ts
|
|
@@ -221,6 +241,7 @@ async function main() {
|
|
|
221
241
|
...generated,
|
|
222
242
|
install: options.install,
|
|
223
243
|
integration: options.integration,
|
|
244
|
+
stack: options.stack,
|
|
224
245
|
packageManager: options.packageManager
|
|
225
246
|
})}
|
|
226
247
|
`, { mode: 384 });
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/arguments.ts","../src/prompts.ts"],"sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport process from \"node:process\";\nimport { intro, outro } from \"@clack/prompts\";\n\nimport { HELP, parseArguments } from \"./arguments.js\";\nimport { createApp } from \"./generator.js\";\nimport { resolveOptions } from \"./prompts.js\";\n\nfunction scriptCommand(packageManager: string, script: string): string {\n if (packageManager === \"npm\") return `npm run ${script}`;\n if (packageManager === \"bun\") return `bun run ${script}`;\n return `${packageManager} ${script}`;\n}\n\nasync function main(): Promise<void> {\n const args = parseArguments();\n if (args.flags.help) {\n process.stdout.write(`${HELP}\\n`);\n return;\n }\n intro(\"Create Agents24 App\");\n const options = await resolveOptions(args);\n const generated = createApp(options);\n if (process.env.AGENTS24_CREATE_RESULT_FILE) {\n writeFileSync(process.env.AGENTS24_CREATE_RESULT_FILE, `${JSON.stringify({\n ...generated,\n install: options.install,\n integration: options.integration,\n packageManager: options.packageManager,\n })}\\n`, { mode: 0o600 });\n }\n const relative = generated.directory.startsWith(`${process.cwd()}/`)\n ? generated.directory.slice(process.cwd().length + 1)\n : generated.directory;\n const install = `${options.packageManager} install`;\n const productionScript = options.integration === \"bff\" ? \"start\" : \"preview\";\n outro([\n `Created ${generated.packageName}`,\n \"\",\n ` cd ${relative}`,\n ` ${install}${options.install ? \" # already completed\" : \"\"}`,\n ` ${scriptCommand(options.packageManager, \"dev\")}`,\n ` ${scriptCommand(options.packageManager, \"build\")}`,\n ` ${scriptCommand(options.packageManager, productionScript)}`,\n ].join(\"\\n\"));\n}\n\nmain().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"App creation failed.\";\n process.stderr.write(`create-agents24-app: ${message}\\n`);\n process.exitCode = 1;\n});\n","import process from \"node:process\";\n\nexport type ParsedArguments = {\n directory?: string;\n flags: Record<string, string | boolean>;\n};\n\nconst VALUE_FLAGS = new Set([\n \"integration\",\n \"preset\",\n \"package-manager\",\n \"base-url\",\n \"deployment-id\",\n \"agent-id\",\n \"agent-alias\",\n \"agent-version-id\",\n \"starter\",\n]);\nconst BOOLEAN_FLAGS = new Set([\"yes\", \"no-install\", \"help\"]);\n\nexport function parseArguments(argv = process.argv.slice(2)): ParsedArguments {\n const flags: Record<string, string | boolean> = {};\n let directory: string | undefined;\n for (let index = 0; index < argv.length; index += 1) {\n const argument = argv[index] || \"\";\n if (!argument.startsWith(\"--\")) {\n if (directory) throw new Error(\"Only one destination directory may be provided.\");\n directory = argument;\n continue;\n }\n const [rawName, inlineValue] = argument.slice(2).split(\"=\", 2);\n if (BOOLEAN_FLAGS.has(rawName)) {\n if (inlineValue !== undefined) throw new Error(`--${rawName} does not accept a value.`);\n flags[rawName] = true;\n continue;\n }\n if (!VALUE_FLAGS.has(rawName)) throw new Error(`Unknown option: --${rawName}`);\n const value = inlineValue ?? argv[index + 1];\n if (!value || value.startsWith(\"--\")) throw new Error(`--${rawName} requires a value.`);\n flags[rawName] = value;\n if (inlineValue === undefined) index += 1;\n }\n return { ...(directory ? { directory } : {}), flags };\n}\n\nexport const HELP = `Create an Agents24 React application.\n\nUsage:\n npm create agents24-app@latest [directory] [options]\n\nOptions:\n --integration <client-deployment|bff>\n --preset <shadcn-preset-code> Defaults to b2D1FHzlY\n --package-manager <pnpm|npm|yarn|bun>\n --base-url <url>\n --deployment-id <acd_...> Client deployment mode\n --agent-id <uuid> BFF mode\n --agent-alias <alias> BFF mode; preferred human-readable selector\n --agent-version-id <uuid> Optional pinned BFF version\n --starter <template-id> customer-support or deep-research\n --no-install\n --yes Disable prompts; required values must be supplied\n --help\n\nRun agents24 apply for drafts, agents24 publish for production, or agents24 setup to perform both and configure the app.`;\n","import process from \"node:process\";\nimport { confirm, isCancel, select, text } from \"@clack/prompts\";\n\nimport type { ParsedArguments } from \"./arguments.js\";\nimport {\n INTEGRATIONS,\n PACKAGE_MANAGERS,\n DEFAULT_PRESET,\n type CreateAppOptions,\n type Integration,\n type PackageManager,\n} from \"./types.js\";\nimport { compatibleTemplates, loadTemplateCatalog, selectTemplate } from \"./template-catalog.js\";\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst DEPLOYMENT_ID = /^acd_[A-Za-z0-9_-]{10,}$/;\nconst PRESET = /^[A-Za-z0-9]{6,32}$/;\n\nfunction cancelled<T>(value: T): asserts value is Exclude<T, symbol> {\n if (isCancel(value)) throw new Error(\"App creation cancelled.\");\n}\n\nfunction flag(args: ParsedArguments, name: string): string | undefined {\n const value = args.flags[name];\n return typeof value === \"string\" ? value.trim() : undefined;\n}\n\nfunction oneOf<T extends string>(value: string | undefined, choices: readonly T[], field: string): T | undefined {\n if (value === undefined) return undefined;\n if (!choices.includes(value as T)) throw new Error(`${field} must be one of: ${choices.join(\", \")}.`);\n return value as T;\n}\n\nfunction detectedPackageManager(): PackageManager {\n const name = String(process.env.npm_config_user_agent || \"\").split(\"/\")[0];\n return PACKAGE_MANAGERS.includes(name as PackageManager) ? name as PackageManager : \"pnpm\";\n}\n\nfunction validateUrl(value: string): string | undefined {\n try {\n const parsed = new URL(value);\n if (/[\\r\\n\\0]/.test(value) || parsed.username || parsed.password || parsed.search || parsed.hash) {\n return \"Use a base URL without credentials, query parameters, or fragments.\";\n }\n return parsed.protocol === \"https:\" || (parsed.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"::1\"].includes(parsed.hostname))\n ? undefined\n : \"Use HTTPS, or HTTP for a local development server.\";\n } catch { return \"Enter a valid URL.\"; }\n}\n\nasync function requiredText(message: string, initialValue: string | undefined, validate?: (value: string) => string | undefined): Promise<string> {\n const result = await text({\n message,\n ...(initialValue ? { initialValue } : {}),\n validate(value) {\n const normalized = String(value || \"\").trim();\n return normalized ? validate?.(normalized) : \"This value is required.\";\n },\n });\n cancelled(result);\n return String(result).trim();\n}\n\nexport async function resolveOptions(args: ParsedArguments): Promise<CreateAppOptions> {\n const nonInteractive = args.flags.yes === true;\n let directory = args.directory;\n let integration = oneOf(flag(args, \"integration\"), INTEGRATIONS, \"integration\");\n let preset = flag(args, \"preset\");\n let packageManager = oneOf(flag(args, \"package-manager\"), PACKAGE_MANAGERS, \"package-manager\");\n let baseUrl = flag(args, \"base-url\");\n const requestedStarter = flag(args, \"starter\");\n let install = args.flags[\"no-install\"] !== true;\n\n if (!nonInteractive) {\n directory ||= await requiredText(\"Where should the app be created?\", \"my-agents24-app\");\n if (!integration) {\n const result = await select<Integration>({ message: \"How should the app connect?\", options: [\n { value: \"client-deployment\", label: \"Client deployment\", hint: \"Direct anonymous browser connection\" },\n { value: \"bff\", label: \"Server BFF\", hint: \"API key remains on your Node server\" },\n ] });\n cancelled(result); integration = result;\n }\n preset ||= await requiredText(\n \"Shadcn preset code\",\n DEFAULT_PRESET,\n (value) => PRESET.test(value) ? undefined : \"Enter a valid Shadcn preset code.\",\n );\n if (!packageManager) {\n const detected = detectedPackageManager();\n const result = await select<PackageManager>({ message: \"Package manager\", initialValue: detected, options: PACKAGE_MANAGERS.map((value) => ({ value, label: value })) });\n cancelled(result); packageManager = result;\n }\n if (args.flags[\"no-install\"] !== true) {\n const result = await confirm({ message: \"Install dependencies?\", initialValue: true });\n cancelled(result); install = result;\n }\n }\n\n directory = String(directory || \"\").trim();\n integration ||= \"client-deployment\";\n preset ||= DEFAULT_PRESET;\n packageManager ||= detectedPackageManager();\n baseUrl ||= \"https://api.agents24.dev\";\n const urlError = validateUrl(baseUrl);\n if (!directory) throw new Error(\"A destination directory is required.\");\n if (urlError) throw new Error(urlError);\n if (!PRESET.test(preset)) throw new Error(\"--preset must be a valid Shadcn preset code.\");\n\n let starter;\n if (requestedStarter || !nonInteractive) {\n const { catalog } = await loadTemplateCatalog(baseUrl);\n let selectedId = requestedStarter;\n if (!selectedId) {\n const templates = compatibleTemplates(catalog);\n const result = await select<string>({\n message: \"Start with an Agent template?\",\n options: [\n { value: \"none\", label: \"No Agent template\" },\n ...templates.map((item) => ({ value: item.id, label: item.display_name, hint: item.description })),\n ],\n });\n cancelled(result);\n selectedId = result === \"none\" ? undefined : result;\n }\n if (selectedId) starter = await selectTemplate(baseUrl, catalog, selectedId);\n }\n\n if (integration === \"client-deployment\") {\n const deploymentId = flag(args, \"deployment-id\");\n if (deploymentId && !DEPLOYMENT_ID.test(deploymentId)) throw new Error(\"--deployment-id must be a valid public acd_… deployment ID.\");\n return { directory, integration, preset, packageManager, install, baseUrl, starter, deploymentId };\n }\n\n const fields = {\n agentId: flag(args, \"agent-id\"),\n agentAlias: flag(args, \"agent-alias\"),\n agentVersionId: flag(args, \"agent-version-id\"),\n };\n if (fields.agentId && fields.agentAlias) throw new Error(\"Use either --agent-id or --agent-alias, not both.\");\n if (fields.agentId && !UUID.test(fields.agentId)) throw new Error(\"--agent-id must be a valid UUID.\");\n if (fields.agentVersionId && !UUID.test(fields.agentVersionId)) throw new Error(\"--agent-version-id must be a valid UUID.\");\n if (fields.agentAlias && !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(fields.agentAlias)) {\n throw new Error(\"--agent-alias must be lowercase kebab-case.\");\n }\n return { directory, integration, preset, packageManager, install, baseUrl, starter, ...fields } as CreateAppOptions;\n}\n"],"mappings":"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","names":["process","process","process","process"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/arguments.ts","../src/prompts.ts"],"sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport process from \"node:process\";\nimport { intro, outro } from \"@clack/prompts\";\n\nimport { HELP, parseArguments } from \"./arguments.js\";\nimport { createApp } from \"./generator.js\";\nimport { resolveOptions } from \"./prompts.js\";\n\nfunction scriptCommand(packageManager: string, script: string): string {\n if (packageManager === \"npm\") return `npm run ${script}`;\n if (packageManager === \"bun\") return `bun run ${script}`;\n return `${packageManager} ${script}`;\n}\n\nasync function main(): Promise<void> {\n const args = parseArguments();\n if (args.flags.help) {\n process.stdout.write(`${HELP}\\n`);\n return;\n }\n intro(\"Create Agents24 App\");\n const options = await resolveOptions(args);\n const generated = createApp(options);\n if (process.env.AGENTS24_CREATE_RESULT_FILE) {\n writeFileSync(process.env.AGENTS24_CREATE_RESULT_FILE, `${JSON.stringify({\n ...generated,\n install: options.install,\n integration: options.integration,\n stack: options.stack,\n packageManager: options.packageManager,\n })}\\n`, { mode: 0o600 });\n }\n const relative = generated.directory.startsWith(`${process.cwd()}/`)\n ? generated.directory.slice(process.cwd().length + 1)\n : generated.directory;\n const install = `${options.packageManager} install`;\n const productionScript = options.integration === \"bff\" ? \"start\" : \"preview\";\n outro([\n `Created ${generated.packageName}`,\n \"\",\n ` cd ${relative}`,\n ` ${install}${options.install ? \" # already completed\" : \"\"}`,\n ` ${scriptCommand(options.packageManager, \"dev\")}`,\n ` ${scriptCommand(options.packageManager, \"build\")}`,\n ` ${scriptCommand(options.packageManager, productionScript)}`,\n ].join(\"\\n\"));\n}\n\nmain().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"App creation failed.\";\n process.stderr.write(`create-agents24-app: ${message}\\n`);\n process.exitCode = 1;\n});\n","import process from \"node:process\";\n\nexport type ParsedArguments = {\n directory?: string;\n flags: Record<string, string | boolean>;\n};\n\nconst VALUE_FLAGS = new Set([\n \"integration\",\n \"stack\",\n \"preset\",\n \"package-manager\",\n \"base-url\",\n \"deployment-id\",\n \"agent-id\",\n \"agent-alias\",\n \"agent-version-id\",\n \"starter\",\n]);\nconst BOOLEAN_FLAGS = new Set([\"yes\", \"no-install\", \"help\"]);\n\nexport function parseArguments(argv = process.argv.slice(2)): ParsedArguments {\n const flags: Record<string, string | boolean> = {};\n let directory: string | undefined;\n for (let index = 0; index < argv.length; index += 1) {\n const argument = argv[index] || \"\";\n if (!argument.startsWith(\"--\")) {\n if (directory) throw new Error(\"Only one destination directory may be provided.\");\n directory = argument;\n continue;\n }\n const [rawName, inlineValue] = argument.slice(2).split(\"=\", 2);\n if (BOOLEAN_FLAGS.has(rawName)) {\n if (inlineValue !== undefined) throw new Error(`--${rawName} does not accept a value.`);\n flags[rawName] = true;\n continue;\n }\n if (!VALUE_FLAGS.has(rawName)) throw new Error(`Unknown option: --${rawName}`);\n const value = inlineValue ?? argv[index + 1];\n if (!value || value.startsWith(\"--\")) throw new Error(`--${rawName} requires a value.`);\n flags[rawName] = value;\n if (inlineValue === undefined) index += 1;\n }\n return { ...(directory ? { directory } : {}), flags };\n}\n\nexport const HELP = `Create an Agents24 React application.\n\nUsage:\n npm create agents24-app@latest [directory] [options]\n\nOptions:\n --integration <client-deployment|bff>\n --stack <nextjs|vite-hono|vite> BFF defaults to Next.js; direct client uses Vite\n --preset <shadcn-preset-code> Defaults to b2D1FHzlY\n --package-manager <pnpm|npm|yarn|bun>\n --base-url <url>\n --deployment-id <acd_...> Client deployment mode\n --agent-id <uuid> BFF mode\n --agent-alias <alias> BFF mode; preferred human-readable selector\n --agent-version-id <uuid> Optional pinned BFF version\n --starter <template-id> customer-support or deep-research\n --no-install\n --yes Disable prompts; required values must be supplied\n --help\n\nRun agents24 apply for drafts, agents24 publish for production, or agents24 setup to perform both and configure the app.`;\n","import process from \"node:process\";\nimport { confirm, isCancel, select, text } from \"@clack/prompts\";\n\nimport type { ParsedArguments } from \"./arguments.js\";\nimport {\n INTEGRATIONS,\n STACKS,\n resolveStack,\n type Stack,\n PACKAGE_MANAGERS,\n DEFAULT_PRESET,\n type CreateAppOptions,\n type Integration,\n type PackageManager,\n} from \"./types.js\";\nimport { compatibleTemplates, loadTemplateCatalog, selectTemplate } from \"./template-catalog.js\";\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst DEPLOYMENT_ID = /^acd_[A-Za-z0-9_-]{10,}$/;\nconst PRESET = /^[A-Za-z0-9]{6,32}$/;\n\nfunction cancelled<T>(value: T): asserts value is Exclude<T, symbol> {\n if (isCancel(value)) throw new Error(\"App creation cancelled.\");\n}\n\nfunction flag(args: ParsedArguments, name: string): string | undefined {\n const value = args.flags[name];\n return typeof value === \"string\" ? value.trim() : undefined;\n}\n\nfunction oneOf<T extends string>(value: string | undefined, choices: readonly T[], field: string): T | undefined {\n if (value === undefined) return undefined;\n if (!choices.includes(value as T)) throw new Error(`${field} must be one of: ${choices.join(\", \")}.`);\n return value as T;\n}\n\nfunction detectedPackageManager(): PackageManager {\n const name = String(process.env.npm_config_user_agent || \"\").split(\"/\")[0];\n return PACKAGE_MANAGERS.includes(name as PackageManager) ? name as PackageManager : \"pnpm\";\n}\n\nfunction validateUrl(value: string): string | undefined {\n try {\n const parsed = new URL(value);\n if (/[\\r\\n\\0]/.test(value) || parsed.username || parsed.password || parsed.search || parsed.hash) {\n return \"Use a base URL without credentials, query parameters, or fragments.\";\n }\n return parsed.protocol === \"https:\" || (parsed.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"::1\"].includes(parsed.hostname))\n ? undefined\n : \"Use HTTPS, or HTTP for a local development server.\";\n } catch { return \"Enter a valid URL.\"; }\n}\n\nasync function requiredText(message: string, initialValue: string | undefined, validate?: (value: string) => string | undefined): Promise<string> {\n const result = await text({\n message,\n ...(initialValue ? { initialValue } : {}),\n validate(value) {\n const normalized = String(value || \"\").trim();\n return normalized ? validate?.(normalized) : \"This value is required.\";\n },\n });\n cancelled(result);\n return String(result).trim();\n}\n\nexport async function resolveOptions(args: ParsedArguments): Promise<CreateAppOptions> {\n const nonInteractive = args.flags.yes === true;\n let directory = args.directory;\n let integration = oneOf(flag(args, \"integration\"), INTEGRATIONS, \"integration\");\n let stack = oneOf(flag(args, \"stack\"), STACKS, \"stack\");\n let preset = flag(args, \"preset\");\n let packageManager = oneOf(flag(args, \"package-manager\"), PACKAGE_MANAGERS, \"package-manager\");\n let baseUrl = flag(args, \"base-url\");\n const requestedStarter = flag(args, \"starter\");\n let install = args.flags[\"no-install\"] !== true;\n\n if (!nonInteractive) {\n directory ||= await requiredText(\"Where should the app be created?\", \"my-agents24-app\");\n if (!integration) {\n const result = await select<Integration>({ message: \"How should the app connect?\", options: [\n { value: \"bff\", label: \"Server BFF (recommended)\", hint: \"API key remains on your server\" },\n { value: \"client-deployment\", label: \"Client deployment\", hint: \"Direct browser connection\" },\n ] });\n cancelled(result); integration = result;\n }\n if (integration === \"bff\" && !stack) {\n const result = await select<Stack>({ message: \"Application stack\", initialValue: \"nextjs\", options: [\n { value: \"nextjs\", label: \"Next.js (recommended)\", hint: \"Full-stack App Router application\" },\n { value: \"vite-hono\", label: \"Vite + Hono\", hint: \"Vite frontend and Node server\" },\n ] });\n cancelled(result); stack = result;\n }\n }\n\n integration ||= \"bff\";\n stack = resolveStack(integration, stack);\n if (integration === \"bff\" && flag(args, \"deployment-id\")) throw new Error(\"--deployment-id requires --integration client-deployment.\");\n if (integration === \"client-deployment\" && [\"agent-id\", \"agent-alias\", \"agent-version-id\"].some((name) => flag(args, name))) {\n throw new Error(\"Agent selectors require --integration bff.\");\n }\n\n directory = String(directory || \"\").trim();\n baseUrl ||= \"https://api.agents24.dev\";\n const urlError = validateUrl(baseUrl);\n if (!directory) throw new Error(\"A destination directory is required.\");\n if (urlError) throw new Error(urlError);\n if (preset && !PRESET.test(preset)) throw new Error(\"--preset must be a valid Shadcn preset code.\");\n\n let starter;\n if (requestedStarter || !nonInteractive) {\n const { catalog } = await loadTemplateCatalog(baseUrl);\n let selectedId = requestedStarter;\n if (!selectedId) {\n const templates = compatibleTemplates(catalog);\n const result = await select<string>({\n message: \"Start with an Agent template?\",\n options: [\n { value: \"none\", label: \"No Agent template\" },\n ...templates.map((item) => ({ value: item.id, label: item.display_name, hint: item.description })),\n ],\n });\n cancelled(result);\n selectedId = result === \"none\" ? undefined : result;\n }\n if (selectedId) starter = await selectTemplate(baseUrl, catalog, selectedId);\n }\n\n if (!nonInteractive) {\n preset ||= await requiredText(\n \"Shadcn preset code\",\n DEFAULT_PRESET,\n (value) => PRESET.test(value) ? undefined : \"Enter a valid Shadcn preset code.\",\n );\n if (!packageManager) {\n const detected = detectedPackageManager();\n const result = await select<PackageManager>({ message: \"Package manager\", initialValue: detected, options: PACKAGE_MANAGERS.map((value) => ({ value, label: value })) });\n cancelled(result); packageManager = result;\n }\n if (args.flags[\"no-install\"] !== true) {\n const result = await confirm({ message: \"Install dependencies?\", initialValue: true });\n cancelled(result); install = result;\n }\n }\n preset ||= DEFAULT_PRESET;\n packageManager ||= detectedPackageManager();\n\n if (integration === \"client-deployment\") {\n const deploymentId = flag(args, \"deployment-id\");\n if (deploymentId && !DEPLOYMENT_ID.test(deploymentId)) throw new Error(\"--deployment-id must be a valid public acd_… deployment ID.\");\n return { directory, integration, stack, preset, packageManager, install, baseUrl, starter, deploymentId };\n }\n\n const fields = {\n agentId: flag(args, \"agent-id\"),\n agentAlias: flag(args, \"agent-alias\"),\n agentVersionId: flag(args, \"agent-version-id\"),\n };\n if (fields.agentId && fields.agentAlias) throw new Error(\"Use either --agent-id or --agent-alias, not both.\");\n if (fields.agentId && !UUID.test(fields.agentId)) throw new Error(\"--agent-id must be a valid UUID.\");\n if (fields.agentVersionId && !UUID.test(fields.agentVersionId)) throw new Error(\"--agent-version-id must be a valid UUID.\");\n if (fields.agentAlias && !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(fields.agentAlias)) {\n throw new Error(\"--agent-alias must be lowercase kebab-case.\");\n }\n return { directory, integration, stack, preset, packageManager, install, baseUrl, starter, ...fields } as CreateAppOptions;\n}\n"],"mappings":"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","names":["process","process","process","process"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
declare const INTEGRATIONS: readonly ["client-deployment", "bff"];
|
|
2
|
+
declare const STACKS: readonly ["nextjs", "vite-hono", "vite"];
|
|
3
|
+
type Stack = (typeof STACKS)[number];
|
|
4
|
+
declare function resolveStack(integration: Integration, stack?: Stack): Stack;
|
|
2
5
|
declare const PACKAGE_MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
|
|
3
6
|
declare const DEFAULT_PRESET = "b2D1FHzlY";
|
|
4
7
|
type Integration = (typeof INTEGRATIONS)[number];
|
|
@@ -15,6 +18,7 @@ type TemplateSelection = {
|
|
|
15
18
|
type CreateAppOptions = {
|
|
16
19
|
directory: string;
|
|
17
20
|
integration: Integration;
|
|
21
|
+
stack?: Stack;
|
|
18
22
|
preset: string;
|
|
19
23
|
packageManager: PackageManager;
|
|
20
24
|
install: boolean;
|
|
@@ -60,4 +64,4 @@ declare function loadTemplateCatalog(baseUrl: string): Promise<{
|
|
|
60
64
|
declare function compatibleTemplates(catalog: Catalog): CatalogTemplate[];
|
|
61
65
|
declare function selectTemplate(baseUrl: string, catalog: Catalog, id: string): Promise<TemplateSelection>;
|
|
62
66
|
|
|
63
|
-
export { type CreateAppOptions, DEFAULT_PRESET, type GeneratedApp, INTEGRATIONS, type Integration, PACKAGE_MANAGERS, type PackageManager, type Starter, type TemplateSelection, compatibleTemplates, createApp, installDependencies, loadTemplateCatalog, selectTemplate };
|
|
67
|
+
export { type CreateAppOptions, DEFAULT_PRESET, type GeneratedApp, INTEGRATIONS, type Integration, PACKAGE_MANAGERS, type PackageManager, STACKS, type Stack, type Starter, type TemplateSelection, compatibleTemplates, createApp, installDependencies, loadTemplateCatalog, resolveStack, selectTemplate };
|
package/dist/index.js
CHANGED
|
@@ -3,20 +3,24 @@ import {
|
|
|
3
3
|
DEFAULT_PRESET,
|
|
4
4
|
INTEGRATIONS,
|
|
5
5
|
PACKAGE_MANAGERS,
|
|
6
|
+
STACKS,
|
|
6
7
|
compatibleTemplates,
|
|
7
8
|
createApp,
|
|
8
9
|
installDependencies,
|
|
9
10
|
loadTemplateCatalog,
|
|
11
|
+
resolveStack,
|
|
10
12
|
selectTemplate
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-F2J72UHQ.js";
|
|
12
14
|
export {
|
|
13
15
|
DEFAULT_PRESET,
|
|
14
16
|
INTEGRATIONS,
|
|
15
17
|
PACKAGE_MANAGERS,
|
|
18
|
+
STACKS,
|
|
16
19
|
compatibleTemplates,
|
|
17
20
|
createApp,
|
|
18
21
|
installDependencies,
|
|
19
22
|
loadTemplateCatalog,
|
|
23
|
+
resolveStack,
|
|
20
24
|
selectTemplate
|
|
21
25
|
};
|
|
22
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -290,9 +290,11 @@ export function ChatComposer({
|
|
|
290
290
|
</Button>
|
|
291
291
|
) : (
|
|
292
292
|
validationError ? (
|
|
293
|
-
<Tooltip
|
|
293
|
+
<Tooltip>
|
|
294
294
|
<TooltipTrigger asChild>
|
|
295
|
-
<
|
|
295
|
+
<span tabIndex={0} aria-label={validationError}>
|
|
296
|
+
<Button size="icon" aria-label="Send message" disabled onClick={() => void submit()}><ArrowUp /></Button>
|
|
297
|
+
</span>
|
|
296
298
|
</TooltipTrigger>
|
|
297
299
|
<TooltipContent>{validationError}</TooltipContent>
|
|
298
300
|
</Tooltip>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"tailwindcss": "^4.1.16"
|
|
21
21
|
},
|
|
22
22
|
"source": "packages/agents24-chat-react/scaffold",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "219ce9cefa31343090e56a1f27418985a9f75fa1e1aaa59468e1cdaaf1b07841",
|
|
24
24
|
"files": [
|
|
25
25
|
"components.json",
|
|
26
26
|
"manifest.json",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-agents24-app",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Create a production-ready Agents24 React application.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"provenance": false
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@agents24/cli": "0.3.
|
|
36
|
+
"@agents24/cli": "0.3.4",
|
|
37
37
|
"@clack/prompts": "1.7.0",
|
|
38
38
|
"shadcn": "4.13.1"
|
|
39
39
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# __APP_NAME__
|
|
2
2
|
|
|
3
|
-
Last Updated: 2026-07
|
|
3
|
+
Last Updated: 2026-09-07
|
|
4
4
|
|
|
5
|
-
This app was generated by `create-agents24-app` with the `__INTEGRATION__` integration and Shadcn preset `__PRESET__`.
|
|
5
|
+
This app was generated by `create-agents24-app` with the `__INTEGRATION__` integration, `__STACK__` stack, and Shadcn preset `__PRESET__`.
|
|
6
6
|
|
|
7
7
|
The app includes a strict document CSP. If you deploy the static client-deployment build without the generated BFF, configure your host to send `Content-Security-Policy: frame-ancestors 'none'`; browsers do not honor that directive in an HTML meta tag.
|
|
8
8
|
|
|
@@ -18,6 +18,10 @@ __STARTER_SETUP__
|
|
|
18
18
|
|
|
19
19
|
## Production
|
|
20
20
|
|
|
21
|
+
__HOSTING__
|
|
22
|
+
|
|
23
|
+
`agents24 publish` publishes Agent resources; it does not deploy this website or upload its environment variables.
|
|
24
|
+
|
|
21
25
|
```bash
|
|
22
26
|
__PM_BUILD__
|
|
23
27
|
__PM_PRODUCTION__
|
|
@@ -2,26 +2,16 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { serve } from "@hono/node-server";
|
|
4
4
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
5
|
-
import { Agents24 } from "@agents24/node";
|
|
6
|
-
import { createAgents24BffHandler } from "@agents24/node/bff";
|
|
7
5
|
import { Hono } from "hono";
|
|
8
6
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { getServerEnvironment } from "./env";
|
|
8
|
+
import { handleAgents24 } from "./handler";
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
client,
|
|
18
|
-
agents: env.AGENTS24_AGENTS,
|
|
19
|
-
integrationId: env.AGENTS24_INTEGRATION_ID,
|
|
20
|
-
integrationName: env.AGENTS24_INTEGRATION_NAME,
|
|
21
|
-
runtimeTarget: (env.AGENTS24_RUNTIME_TARGET || (process.env.NODE_ENV === "production" ? "published" : "draft")) as "draft" | "published",
|
|
22
|
-
resolvePrincipal: resolveAgents24Principal,
|
|
23
|
-
revokePrincipal: (request) => revokeAgents24Principal(request),
|
|
24
|
-
});
|
|
10
|
+
try { process.loadEnvFile(".env.local"); }
|
|
11
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; }
|
|
12
|
+
if (process.argv.includes("--production")) process.env.NODE_ENV = "production";
|
|
13
|
+
const env = getServerEnvironment();
|
|
14
|
+
const production = process.env.NODE_ENV === "production";
|
|
25
15
|
const app = new Hono();
|
|
26
16
|
|
|
27
17
|
app.use("*", async (context, next) => {
|
|
@@ -31,14 +21,14 @@ app.use("*", async (context, next) => {
|
|
|
31
21
|
context.header("X-Content-Type-Options", "nosniff");
|
|
32
22
|
context.header("X-Frame-Options", "DENY");
|
|
33
23
|
});
|
|
34
|
-
app.all("/api/agents24", (context) =>
|
|
35
|
-
app.all("/api/agents24/*", (context) =>
|
|
24
|
+
app.all("/api/agents24", (context) => handleAgents24(context.req.raw));
|
|
25
|
+
app.all("/api/agents24/*", (context) => handleAgents24(context.req.raw));
|
|
36
26
|
|
|
37
|
-
if (
|
|
27
|
+
if (production) {
|
|
38
28
|
app.use("*", serveStatic({ root: "./dist" }));
|
|
39
29
|
app.get("*", async (context) => context.html(await readFile(resolve("dist/index.html"), "utf8")));
|
|
40
30
|
}
|
|
41
31
|
|
|
42
|
-
serve({ fetch: app.fetch, hostname: "127.0.0.1", port: env.PORT }, (info) => {
|
|
32
|
+
serve({ fetch: app.fetch, hostname: production ? "0.0.0.0" : "127.0.0.1", port: env.PORT }, (info) => {
|
|
43
33
|
process.stdout.write(`Agents24 app listening on http://127.0.0.1:${info.port}\n`);
|
|
44
34
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import { handleAgents24 } from "../../../../server/handler";
|
|
3
|
+
|
|
4
|
+
export const runtime = "nodejs";
|
|
5
|
+
export const dynamic = "force-dynamic";
|
|
6
|
+
export const maxDuration = 300;
|
|
7
|
+
|
|
8
|
+
export const GET = handleAgents24;
|
|
9
|
+
export const POST = handleAgents24;
|
|
10
|
+
export const PUT = handleAgents24;
|
|
11
|
+
export const PATCH = handleAgents24;
|
|
12
|
+
export const DELETE = handleAgents24;
|
|
13
|
+
export const HEAD = handleAgents24;
|
|
14
|
+
export const OPTIONS = handleAgents24;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import dynamic from "next/dynamic";
|
|
4
|
+
|
|
5
|
+
// The chat controller and query navigation own browser state. Do not initialize
|
|
6
|
+
// them during server rendering or share a controller between server requests.
|
|
7
|
+
const Chat = dynamic(() => import("@/chat-app"), { ssr: false });
|
|
8
|
+
export default Chat;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Metadata, Viewport } from "next";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import "../src/styles.css";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = { title: "__APP_NAME__" };
|
|
6
|
+
export const viewport: Viewport = { width: "device-width", initialScale: 1, viewportFit: "cover" };
|
|
7
|
+
|
|
8
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
9
|
+
return <html lang="en"><body><div id="root">{children}</div></body></html>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
const config: NextConfig = {
|
|
4
|
+
poweredByHeader: false,
|
|
5
|
+
async headers() {
|
|
6
|
+
return [{ source: "/:path*", headers: [
|
|
7
|
+
{ key: "Referrer-Policy", value: "no-referrer" },
|
|
8
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
9
|
+
{ key: "X-Frame-Options", value: "DENY" },
|
|
10
|
+
] }];
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
export default config;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default { plugins: { "@tailwindcss/postcss": {} } };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { NextResponse, type NextRequest } from "next/server";
|
|
3
|
+
|
|
4
|
+
export function proxy(request: NextRequest) {
|
|
5
|
+
const nonce = randomBytes(16).toString("base64");
|
|
6
|
+
const development = process.env.NODE_ENV === "development";
|
|
7
|
+
const csp = [
|
|
8
|
+
"default-src 'self'",
|
|
9
|
+
"base-uri 'none'",
|
|
10
|
+
"object-src 'none'",
|
|
11
|
+
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic'${development ? " 'unsafe-eval'" : ""}`,
|
|
12
|
+
`style-src 'self' 'nonce-${nonce}'`,
|
|
13
|
+
// Radix positioning and chat layout use React style attributes, not executable scripts.
|
|
14
|
+
"style-src-attr 'unsafe-inline'",
|
|
15
|
+
"font-src 'self' data:",
|
|
16
|
+
"img-src 'self' data: blob:",
|
|
17
|
+
`connect-src 'self'${development ? " ws: wss:" : ""}`,
|
|
18
|
+
"form-action 'self'",
|
|
19
|
+
"frame-ancestors 'none'",
|
|
20
|
+
].join("; ");
|
|
21
|
+
const headers = new Headers(request.headers);
|
|
22
|
+
headers.set("Content-Security-Policy", csp);
|
|
23
|
+
const response = NextResponse.next({ request: { headers } });
|
|
24
|
+
response.headers.set("Content-Security-Policy", csp);
|
|
25
|
+
response.headers.set("Cache-Control", "private, no-store");
|
|
26
|
+
return response;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const config = { matcher: ["/((?!api(?:/|$)|_next/|favicon.ico).*)"] };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createBffAgentClient } from "@agents24/client/bff";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Agents24ChatScaffold } from "@/index";
|
|
6
|
+
import { useThreadQueryNavigation } from "@/use-thread-query-navigation";
|
|
7
|
+
import { getHostIdentity } from "@/host-identity";
|
|
8
|
+
|
|
9
|
+
export default function ChatApp() {
|
|
10
|
+
const [client] = useState(() => createBffAgentClient({ basePath: "/api/agents24" }));
|
|
11
|
+
const navigation = useThreadQueryNavigation();
|
|
12
|
+
return <Agents24ChatScaffold
|
|
13
|
+
client={client}
|
|
14
|
+
identity={getHostIdentity()}
|
|
15
|
+
activeThreadId={navigation.activeThreadId}
|
|
16
|
+
onActiveThreadIdChange={navigation.onActiveThreadIdChange}
|
|
17
|
+
completeMcpAuthorization={async ({ completion, serverId }) => {
|
|
18
|
+
if (completion.serverId !== serverId || !completion.connectionId) {
|
|
19
|
+
throw new Error("MCP authorization did not return the expected connection.");
|
|
20
|
+
}
|
|
21
|
+
}}
|
|
22
|
+
/>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "ESNext",
|
|
11
|
+
"moduleResolution": "Bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": { "@/*": ["./src/*"] }
|
|
18
|
+
},
|
|
19
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
|
|
20
|
+
"exclude": ["node_modules"]
|
|
21
|
+
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import process from "node:process";
|
|
2
2
|
|
|
3
|
-
try { process.loadEnvFile?.(".env.local"); }
|
|
4
|
-
catch (error) {
|
|
5
|
-
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
3
|
const REQUIRED = [
|
|
9
4
|
"AGENTS24_API_KEY",
|
|
10
5
|
"AGENTS24_AGENTS",
|
|
@@ -62,21 +57,29 @@ function agentsConfig(): {
|
|
|
62
57
|
return { agents, impliedRuntimeTarget: impliedTargets.values().next().value };
|
|
63
58
|
}
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
if (explicitRuntimeTarget &&
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
export function readServerEnvironment() {
|
|
61
|
+
const parsedAgents = agentsConfig();
|
|
62
|
+
const explicitRuntimeTarget = String(process.env.AGENTS24_RUNTIME_TARGET || "").trim() || undefined;
|
|
63
|
+
if (explicitRuntimeTarget && !["draft", "published"].includes(explicitRuntimeTarget)) throw new Error("AGENTS24_RUNTIME_TARGET must be draft or published.");
|
|
64
|
+
if (explicitRuntimeTarget && parsedAgents.impliedRuntimeTarget && explicitRuntimeTarget !== parsedAgents.impliedRuntimeTarget) {
|
|
65
|
+
throw new Error("AGENTS24_RUNTIME_TARGET conflicts with the configured agentVersion selectors.");
|
|
66
|
+
}
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
};
|
|
68
|
+
const env = {
|
|
69
|
+
...Object.fromEntries(REQUIRED.map((name) => [name, required(name)])) as Record<(typeof REQUIRED)[number], string>,
|
|
70
|
+
AGENTS24_BASE_URL: String(process.env.AGENTS24_BASE_URL || "https://api.agents24.dev").trim(),
|
|
71
|
+
AGENTS24_AGENTS: parsedAgents.agents,
|
|
72
|
+
AGENTS24_RUNTIME_TARGET: explicitRuntimeTarget || parsedAgents.impliedRuntimeTarget,
|
|
73
|
+
AGENTS24_INTEGRATION_NAME: String(process.env.AGENTS24_INTEGRATION_NAME || "").trim() || undefined,
|
|
74
|
+
PORT: Number(process.env.PORT || 3001),
|
|
75
|
+
};
|
|
80
76
|
|
|
81
|
-
if (!Number.isInteger(env.PORT) || env.PORT < 1 || env.PORT > 65535) throw new Error("PORT must be a valid port.");
|
|
82
|
-
if (env.SESSION_COOKIE_SECRET.length < 32) throw new Error("SESSION_COOKIE_SECRET must contain at least 32 characters.");
|
|
77
|
+
if (!Number.isInteger(env.PORT) || env.PORT < 1 || env.PORT > 65535) throw new Error("PORT must be a valid port.");
|
|
78
|
+
if (env.SESSION_COOKIE_SECRET.length < 32) throw new Error("SESSION_COOKIE_SECRET must contain at least 32 characters.");
|
|
79
|
+
return env;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let environment: ReturnType<typeof readServerEnvironment> | undefined;
|
|
83
|
+
export function getServerEnvironment() {
|
|
84
|
+
return environment ??= readServerEnvironment();
|
|
85
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Agents24 } from "@agents24/node";
|
|
2
|
+
import { createAgents24BffHandler, type Agents24BffHandler } from "@agents24/node/bff";
|
|
3
|
+
import { getServerEnvironment } from "./env";
|
|
4
|
+
import { resolveAgents24Principal, revokeAgents24Principal } from "./principal";
|
|
5
|
+
|
|
6
|
+
let handler: Agents24BffHandler | undefined;
|
|
7
|
+
|
|
8
|
+
// Initialize on the first runtime request, never while the host collects routes during a build.
|
|
9
|
+
export function handleAgents24(request: Request): Promise<Response> {
|
|
10
|
+
if (!handler) {
|
|
11
|
+
const env = getServerEnvironment();
|
|
12
|
+
handler = createAgents24BffHandler({
|
|
13
|
+
client: new Agents24({ baseUrl: env.AGENTS24_BASE_URL, apiKey: env.AGENTS24_API_KEY }),
|
|
14
|
+
agents: env.AGENTS24_AGENTS,
|
|
15
|
+
integrationId: env.AGENTS24_INTEGRATION_ID,
|
|
16
|
+
integrationName: env.AGENTS24_INTEGRATION_NAME,
|
|
17
|
+
runtimeTarget: (env.AGENTS24_RUNTIME_TARGET || (process.env.NODE_ENV === "production" ? "published" : "draft")) as "draft" | "published",
|
|
18
|
+
resolvePrincipal: resolveAgents24Principal,
|
|
19
|
+
revokePrincipal: revokeAgents24Principal,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return handler(request);
|
|
23
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import type { AgentBffPrincipalResolution } from "@agents24/node/bff";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { getServerEnvironment } from "./env";
|
|
5
5
|
|
|
6
6
|
const COOKIE = "agents24_app_session";
|
|
7
7
|
const MAX_AGE = 60 * 60 * 24 * 30;
|
|
8
8
|
|
|
9
9
|
function signature(value: string): string {
|
|
10
|
-
return createHmac("sha256",
|
|
10
|
+
return createHmac("sha256", getServerEnvironment().SESSION_COOKIE_SECRET).update(value).digest("base64url");
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function parseCookies(request: Request): Record<string, string> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Agents24ChatIdentity } from "@/identity";
|
|
2
2
|
|
|
3
|
-
/** Replace this adapter with your host application's authenticated identity. */
|
|
3
|
+
/** Replace this adapter with your host application's authenticated display identity. */
|
|
4
4
|
export function getHostIdentity(): Agents24ChatIdentity {
|
|
5
5
|
return { state: "guest", displayName: "Guest" };
|
|
6
6
|
}
|
package/versions.json
CHANGED
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
"agents24": {
|
|
3
3
|
"@agents24/client": "^0.2.4",
|
|
4
4
|
"@agents24/react": "^0.2.4",
|
|
5
|
-
"@agents24/chat-react": "^0.5.
|
|
6
|
-
"@agents24/node": "^0.5.
|
|
5
|
+
"@agents24/chat-react": "^0.5.8",
|
|
6
|
+
"@agents24/node": "^0.5.3"
|
|
7
7
|
},
|
|
8
8
|
"runtime": {
|
|
9
|
+
"next": "^16.3.4",
|
|
10
|
+
"server-only": "^0.0.1",
|
|
11
|
+
"zod": "^4.5.4",
|
|
9
12
|
"react": "^19.2.3",
|
|
10
13
|
"react-dom": "^19.2.3",
|
|
11
14
|
"hono": "^4.12.31",
|
|
12
15
|
"@hono/node-server": "^2.0.10"
|
|
13
16
|
},
|
|
14
17
|
"development": {
|
|
18
|
+
"@tailwindcss/postcss": "^4.1.16",
|
|
15
19
|
"@types/node": "^24.7.2",
|
|
16
20
|
"@types/react": "^19.2.3",
|
|
17
21
|
"@types/react-dom": "^19.2.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/generator.ts","../src/template-catalog.ts"],"sourcesContent":["export const INTEGRATIONS = [\"client-deployment\", \"bff\"] as const;\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const;\nexport const DEFAULT_PRESET = \"b2D1FHzlY\";\n\nexport type Integration = (typeof INTEGRATIONS)[number];\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\nexport type Starter = string;\n\nexport type TemplateSelection = {\n id: Starter;\n version: string;\n displayName: string;\n sha256: string;\n catalogRevision: string;\n files: Map<string, string>;\n};\n\nexport type CreateAppOptions = {\n directory: string;\n integration: Integration;\n preset: string;\n packageManager: PackageManager;\n install: boolean;\n baseUrl: string;\n starter?: TemplateSelection;\n deploymentId?: string;\n agentId?: string;\n agentAlias?: string;\n agentVersionId?: string;\n};\n\nexport type GeneratedApp = {\n directory: string;\n packageName: string;\n};\n","import { spawnSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n chmodSync,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createRequire } from \"node:module\";\n\nimport { DEFAULT_PRESET, type CreateAppOptions, type GeneratedApp, type PackageManager } from \"./types.js\";\n\ntype Versions = {\n agents24: Record<string, string>;\n runtime: Record<string, string>;\n development: Record<string, string>;\n};\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), \"..\");\nconst templateRoot = join(packageRoot, \"templates\");\nconst scaffoldRoot = join(packageRoot, \"dist/scaffold\");\nconst scaffoldManifest = JSON.parse(readFileSync(join(packageRoot, \"dist/scaffold-manifest.json\"), \"utf8\")) as {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n sha256: string;\n};\nconst versions = JSON.parse(readFileSync(join(packageRoot, \"versions.json\"), \"utf8\")) as Versions;\nconst require = createRequire(import.meta.url);\n\nfunction packageName(directory: string): string {\n const value = basename(resolve(directory))\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\");\n if (!value || !/^[a-z0-9]/.test(value)) throw new Error(\"The destination does not produce a valid npm package name.\");\n return value;\n}\n\nfunction assertDestination(destination: string): void {\n if (!existsSync(destination)) return;\n if (!statSync(destination).isDirectory()) throw new Error(\"The destination already exists and is not a directory.\");\n if (readdirSync(destination).length > 0) throw new Error(\"The destination directory must be empty.\");\n}\n\nfunction walk(directory: string): string[] {\n return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {\n const path = join(directory, entry.name);\n return entry.isDirectory() ? walk(path) : [path];\n });\n}\n\nfunction replaceTemplateValues(directory: string, replacements: Record<string, string>): void {\n for (const file of walk(directory)) {\n if (file.endsWith(\".png\") || file.endsWith(\".ico\")) continue;\n let content = readFileSync(file, \"utf8\");\n for (const [token, value] of Object.entries(replacements)) content = content.split(token).join(value);\n writeFileSync(file, content);\n }\n}\n\nfunction copyLayer(name: string, destination: string): void {\n cpSync(join(templateRoot, name), destination, { recursive: true, force: true });\n}\n\nfunction materializeTemplate(destination: string, options: CreateAppOptions): void {\n if (!options.starter) return;\n const packageId = `pkg_${randomBytes(16).toString(\"hex\")}`;\n let replacedManifest = false;\n for (const [path, original] of options.starter.files) {\n let content = original;\n if (path === \"agents24.yaml\") {\n content = content.replace(/^(package_id:\\s*)[^\\s#]+/m, `$1${packageId}`);\n replacedManifest = content !== original;\n }\n const target = join(destination, \"agents24\", path);\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, content);\n }\n if (!replacedManifest) throw new Error(\"The selected Agent template has no replaceable package_id.\");\n}\n\nfunction generatedManifest(options: CreateAppOptions, name: string): Record<string, unknown> {\n const dependencies: Record<string, string> = {\n \"@agents24/client\": versions.agents24[\"@agents24/client\"]!,\n \"@agents24/react\": versions.agents24[\"@agents24/react\"]!,\n \"@agents24/chat-react\": versions.agents24[\"@agents24/chat-react\"]!,\n ...scaffoldManifest.dependencies,\n react: versions.runtime.react!,\n \"react-dom\": versions.runtime[\"react-dom\"]!,\n };\n const devDependencies: Record<string, string> = {\n \"@types/node\": versions.development[\"@types/node\"]!,\n \"@types/react\": versions.development[\"@types/react\"]!,\n \"@types/react-dom\": versions.development[\"@types/react-dom\"]!,\n \"@vitejs/plugin-react\": versions.development[\"@vitejs/plugin-react\"]!,\n ...scaffoldManifest.devDependencies,\n typescript: versions.development.typescript!,\n vite: versions.development.vite!,\n };\n const scripts: Record<string, string> = {\n dev: \"vite\",\n build: \"tsc --noEmit && vite build\",\n preview: \"vite preview\",\n preset: \"node scripts/apply-preset.mjs\",\n };\n if (options.integration === \"bff\") {\n dependencies[\"@agents24/node\"] = versions.agents24[\"@agents24/node\"]!;\n dependencies.hono = versions.runtime.hono!;\n dependencies[\"@hono/node-server\"] = versions.runtime[\"@hono/node-server\"]!;\n devDependencies.concurrently = versions.development.concurrently!;\n devDependencies.tsx = versions.development.tsx!;\n devDependencies.tsup = \"^8.5.1\";\n scripts.dev = \"concurrently -k -n web,bff \\\"vite\\\" \\\"tsx watch server/index.ts\\\"\";\n scripts.build = \"tsc --noEmit && vite build && tsup server/index.ts --format esm --platform node --out-dir server-dist --external @agents24/node --external hono --external @hono/node-server\";\n scripts.start = \"node server-dist/index.js --production\";\n }\n return {\n name,\n private: true,\n version: \"0.0.0\",\n type: \"module\",\n engines: { node: \"^22.0.0 || ^24.0.0\" },\n agents24: {\n integration: options.integration,\n package_manager: options.packageManager,\n preset: options.preset,\n scaffold_sha256: scaffoldManifest.sha256,\n ...(options.starter ? { template: {\n id: options.starter.id,\n version: options.starter.version,\n sha256: options.starter.sha256,\n catalog_revision: options.starter.catalogRevision,\n } } : {}),\n },\n scripts,\n dependencies,\n devDependencies,\n };\n}\n\nfunction envFiles(options: CreateAppOptions, appName: string): { example: string; local: string } {\n const value = (input: string | undefined) => JSON.stringify(String(input || \"\"));\n const jsonValue = (input: unknown) => JSON.stringify(input);\n const baseUrlOverride = options.baseUrl === \"https://api.agents24.dev\" ? [] : [\n `${options.integration === \"client-deployment\" ? \"VITE_\" : \"\"}AGENTS24_BASE_URL=${value(options.baseUrl)}`,\n ];\n if (options.integration === \"client-deployment\") {\n return {\n example: \"# VITE_AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\\nVITE_AGENTS24_DEPLOYMENT_ID=acd_your_public_deployment_id\\n\",\n local: [...baseUrlOverride, ...(options.deploymentId ? [`VITE_AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : []), \"\"].join(\"\\n\"),\n };\n }\n return {\n example: [\n \"# AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\",\n \"AGENTS24_API_KEY=your_server_only_api_key\",\n \"# agentVersion accepts draft, latest, or an exact published version such as v1\",\n \"AGENTS24_AGENTS=[{\\\"agentAlias\\\":\\\"your-agent-alias\\\",\\\"agentVersion\\\":\\\"v1\\\"}]\",\n \"# agentId remains supported instead of agentAlias when UUID configuration is preferred\",\n \"AGENTS24_INTEGRATION_ID=generate_one_stable_random_value\",\n \"AGENTS24_INTEGRATION_NAME=your_app_name # optional\",\n \"# AGENTS24_RUNTIME_TARGET=draft # optional server-only override\",\n \"SESSION_COOKIE_SECRET=generate_at_least_32_random_bytes\",\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n local: [\n ...baseUrlOverride,\n ...(options.agentAlias || options.agentId ? [\n `AGENTS24_AGENTS=${jsonValue([{ ...(options.agentAlias ? { agentAlias: options.agentAlias } : { agentId: options.agentId }), ...(options.agentVersionId ? { agentVersionId: options.agentVersionId } : {}) }])}`,\n ] : []),\n `AGENTS24_INTEGRATION_ID=${value(randomBytes(24).toString(\"base64url\"))}`,\n `AGENTS24_INTEGRATION_NAME=${value(appName)}`,\n `SESSION_COOKIE_SECRET=${value(randomBytes(32).toString(\"base64url\"))}`,\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n };\n}\n\nfunction installCommand(packageManager: PackageManager): [string, string[]] {\n if (packageManager === \"npm\") return [\"npm\", [\"install\"]];\n if (packageManager === \"yarn\") return [\"yarn\", []];\n if (packageManager === \"bun\") return [\"bun\", [\"install\"]];\n return [\"pnpm\", [\"install\", \"--ignore-workspace\"]];\n}\n\nfunction runScriptCommand(packageManager: PackageManager, script: string): string {\n if (packageManager === \"npm\") return `npm run ${script}`;\n if (packageManager === \"bun\") return `bun run ${script}`;\n return `${packageManager} ${script}`;\n}\n\nexport function installDependencies(directory: string, packageManager: PackageManager): void {\n const [command, args] = installCommand(packageManager);\n const { AGENTS24_API_KEY: _apiKey, ...installerEnvironment } = process.env;\n const result = spawnSync(command, args, { cwd: directory, stdio: \"inherit\", env: installerEnvironment });\n if (result.error) throw new Error(`Could not start ${command}: ${result.error.message}`);\n if (result.status !== 0) throw new Error(`${command} ${args.join(\" \")} failed with exit ${result.status}.`);\n}\n\nfunction clearPresetInstallArtifacts(directory: string): void {\n for (const name of [\"node_modules\", \"bun.lock\", \"bun.lockb\", \"package-lock.json\", \"pnpm-lock.yaml\", \"yarn.lock\"]) {\n rmSync(join(directory, name), { recursive: true, force: true });\n }\n}\n\nfunction applyShadcnPreset(directory: string, preset: string): void {\n if (preset === DEFAULT_PRESET) return;\n const executable = require.resolve(\"shadcn\");\n const { AGENTS24_API_KEY: _apiKey, ...presetEnvironment } = process.env;\n const result = spawnSync(\n process.execPath,\n [executable, \"apply\", preset, \"--yes\", \"--silent\", \"--cwd\", directory],\n { cwd: directory, encoding: \"utf8\", env: presetEnvironment },\n );\n if (result.error) throw new Error(`Could not start Shadcn preset materialization: ${result.error.message}`);\n if (result.status !== 0) {\n const detail = String(result.stderr || result.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Shadcn could not apply preset ${preset}.`);\n }\n const scopeResult = spawnSync(\n process.execPath,\n [join(directory, \"scripts/scope-preset-theme.mjs\")],\n { cwd: directory, encoding: \"utf8\" },\n );\n if (scopeResult.error) throw new Error(`Could not scope the selected Shadcn preset: ${scopeResult.error.message}`);\n if (scopeResult.status !== 0) {\n const detail = String(scopeResult.stderr || scopeResult.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Could not scope Shadcn preset ${preset}.`);\n }\n clearPresetInstallArtifacts(directory);\n}\n\nexport function createApp(options: CreateAppOptions): GeneratedApp {\n const destination = resolve(options.directory);\n assertDestination(destination);\n const name = packageName(destination);\n const parent = dirname(destination);\n mkdirSync(parent, { recursive: true });\n const staging = join(parent, `.${name}.agents24-${randomBytes(6).toString(\"hex\")}`);\n try {\n mkdirSync(staging, { mode: 0o700 });\n cpSync(scaffoldRoot, staging, { recursive: true, force: true });\n rmSync(join(staging, \"manifest.json\"), { force: true });\n copyLayer(\"common\", staging);\n copyLayer(`integrations/${options.integration}`, staging);\n materializeTemplate(staging, options);\n replaceTemplateValues(staging, {\n \"__APP_NAME__\": name,\n \"__PRESET__\": options.preset,\n \"__INTEGRATION__\": options.integration,\n \"__CONNECT_SOURCE__\": options.integration === \"client-deployment\" ? \" __AGENTS24_CONNECT_SOURCE__\" : \"\",\n \"__PM_DEV__\": runScriptCommand(options.packageManager, \"dev\"),\n \"__PM_BUILD__\": runScriptCommand(options.packageManager, \"build\"),\n \"__PM_PRODUCTION__\": runScriptCommand(options.packageManager, options.integration === \"bff\" ? \"start\" : \"preview\"),\n \"__PM_PRESET__\": `${runScriptCommand(options.packageManager, \"preset\")} --`,\n \"__STARTER_SETUP__\": options.starter\n ? `## Set up the included Agent\\n\\nThis repository includes an editable Resource Package in \\`agents24/\\`. For a BFF, run \\`agents24 apply ./agents24\\` to reconcile drafts and \\`agents24 publish ./agents24\\` for production. For a direct-client app, run \\`agents24 setup ./agents24 --app .\\` so publication happens before deployment configuration. Use \\`agents24 dev ./agents24\\` when a local Artifact server is required.`\n : \"\",\n });\n const gitignore = join(staging, \"_gitignore\");\n if (existsSync(gitignore)) renameSync(gitignore, join(staging, \".gitignore\"));\n writeFileSync(join(staging, \"package.json\"), `${JSON.stringify(generatedManifest(options, name), null, 2)}\\n`);\n applyShadcnPreset(staging, options.preset);\n const env = envFiles(options, name);\n writeFileSync(join(staging, \".env.example\"), env.example);\n if (options.install) installDependencies(staging, options.packageManager);\n writeFileSync(join(staging, \".env.local\"), env.local, { mode: 0o600 });\n chmodSync(join(staging, \".env.local\"), 0o600);\n if (existsSync(destination)) rmSync(destination, { recursive: true });\n renameSync(staging, destination);\n return { directory: destination, packageName: name };\n } catch (error) {\n rmSync(staging, { recursive: true, force: true });\n throw error;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { unpackFiles } from \"@agents24/cli\";\n\nimport { type Starter, type TemplateSelection } from \"./types.js\";\n\ntype CatalogTemplate = {\n id: string;\n version: string;\n display_name: string;\n description: string;\n compatibility: { min_generator_version?: string; resource_package_schema?: string };\n archive: { sha256: string; size: number; download_url: string };\n};\n\ntype Catalog = {\n schema_version: \"agents24.template-catalog.v1\";\n revision: string;\n templates: CatalogTemplate[];\n};\n\ntype CachedCatalog = { etag?: string; catalog: Catalog };\n\nconst GENERATOR_VERSION = \"0.2.0\";\nconst SHA256 = /^[0-9a-f]{64}$/;\nconst SEMVER = /^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$/;\nconst TEMPLATE_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\n\nfunction cacheRoot(): string {\n const override = String(process.env.AGENTS24_TEMPLATE_CACHE_DIR || \"\").trim();\n if (override) return override;\n const platformRoot = process.platform === \"win32\"\n ? process.env.LOCALAPPDATA\n : process.env.XDG_CACHE_HOME || join(homedir(), \".cache\");\n return join(platformRoot || tmpdir(), \"agents24\", \"templates-v1\");\n}\n\nfunction atomicWrite(path: string, data: string | Uint8Array): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n const temporary = `${path}.${process.pid}.tmp`;\n writeFileSync(temporary, data, { mode: 0o600 });\n renameSync(temporary, path);\n}\n\nfunction parseVersion(value: string): [number, number, number] | null {\n const match = SEMVER.exec(value);\n return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;\n}\n\nfunction compatible(item: CatalogTemplate): boolean {\n const minimum = parseVersion(String(item.compatibility?.min_generator_version || \"0.0.0\"));\n const current = parseVersion(GENERATOR_VERSION)!;\n if (!minimum || item.compatibility?.resource_package_schema !== \"2.0\") return false;\n return current[0] > minimum[0]\n || (current[0] === minimum[0] && current[1] > minimum[1])\n || (current[0] === minimum[0] && current[1] === minimum[1] && current[2] >= minimum[2]);\n}\n\nfunction validateCatalog(value: unknown): Catalog {\n const catalog = value as Catalog;\n if (catalog?.schema_version !== \"agents24.template-catalog.v1\" || !SHA256.test(catalog.revision) || !Array.isArray(catalog.templates)) {\n throw new Error(\"The Agents24 template catalog is invalid.\");\n }\n const ids = new Set<string>();\n for (const item of catalog.templates) {\n if (!TEMPLATE_ID.test(item?.id) || ids.has(item.id) || !SEMVER.test(item.version)\n || !item.display_name || !SHA256.test(item.archive?.sha256) || !Number.isSafeInteger(item.archive?.size)\n || item.archive.size < 1 || item.archive.size > 5 * 1024 * 1024 || !item.archive.download_url?.startsWith(\"/templates/\")) {\n throw new Error(\"The Agents24 template catalog contains an invalid release.\");\n }\n ids.add(item.id);\n }\n return catalog;\n}\n\nfunction readCachedCatalog(path: string): CachedCatalog | null {\n try {\n const cached = JSON.parse(readFileSync(path, \"utf8\")) as CachedCatalog;\n return { ...(cached.etag ? { etag: cached.etag } : {}), catalog: validateCatalog(cached.catalog) };\n } catch {\n return null;\n }\n}\n\nexport async function loadTemplateCatalog(baseUrl: string): Promise<{ catalog: Catalog; live: boolean }> {\n const path = join(cacheRoot(), \"catalog.json\");\n const cached = existsSync(path) ? readCachedCatalog(path) : null;\n try {\n const response = await fetch(new URL(\"/templates\", `${baseUrl}/`), {\n headers: cached?.etag ? { \"If-None-Match\": cached.etag } : {},\n signal: AbortSignal.timeout(10_000),\n });\n if (response.status === 304 && cached) return { catalog: cached.catalog, live: true };\n if (!response.ok) throw new Error(`catalog request returned ${response.status}`);\n const catalog = validateCatalog(await response.json());\n const etag = response.headers.get(\"etag\") || undefined;\n atomicWrite(path, `${JSON.stringify({ ...(etag ? { etag } : {}), catalog })}\\n`);\n return { catalog, live: true };\n } catch (error) {\n if (cached) return { catalog: cached.catalog, live: false };\n const detail = error instanceof Error ? error.message : \"request failed\";\n throw new Error(`Could not load the Agents24 template catalog (${detail}), and no verified cached catalog is available.`);\n }\n}\n\nexport function compatibleTemplates(catalog: Catalog): CatalogTemplate[] {\n return catalog.templates.filter(compatible);\n}\n\nfunction verifiedArchive(path: string, item: CatalogTemplate): Uint8Array | null {\n try {\n const archive = readFileSync(path);\n if (archive.byteLength !== item.archive.size || createHash(\"sha256\").update(archive).digest(\"hex\") !== item.archive.sha256) return null;\n unpackFiles(archive);\n return archive;\n } catch {\n return null;\n }\n}\n\nasync function readArchiveResponse(response: Response, expectedSize: number): Promise<Uint8Array> {\n if (!response.body) throw new Error(\"Template download returned no archive body.\");\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > expectedSize || size > 5 * 1024 * 1024) {\n await reader.cancel();\n throw new Error(\"Template download exceeds its advertised archive size.\");\n }\n chunks.push(value);\n }\n const archive = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n archive.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return archive;\n}\n\nexport async function selectTemplate(baseUrl: string, catalog: Catalog, id: string): Promise<TemplateSelection> {\n if (id === \"rag\") throw new Error(\"The 'rag' starter was removed. Use --starter customer-support or --starter deep-research.\");\n const item = catalog.templates.find((candidate) => candidate.id === id);\n if (!item) throw new Error(`Template '${id}' is not available in the active catalog.`);\n if (!compatible(item)) throw new Error(`Template '${id}' requires a newer create-agents24-app release.`);\n const path = join(cacheRoot(), \"archives\", `${item.archive.sha256}.zip`);\n let archive = existsSync(path) ? verifiedArchive(path, item) : null;\n if (!archive) {\n let response: Response;\n try {\n response = await fetch(new URL(item.archive.download_url, `${baseUrl}/`), { signal: AbortSignal.timeout(30_000) });\n } catch (error) {\n throw new Error(`Could not download template '${id}', and no verified cached archive is available.`);\n }\n if (!response.ok) throw new Error(`Could not download template '${id}' (HTTP ${response.status}).`);\n const length = response.headers.get(\"content-length\");\n if (length && Number(length) !== item.archive.size) throw new Error(`Template '${id}' download size does not match the catalog.`);\n archive = await readArchiveResponse(response, item.archive.size);\n if (archive.byteLength !== item.archive.size || createHash(\"sha256\").update(archive).digest(\"hex\") !== item.archive.sha256) {\n throw new Error(`Template '${id}' failed integrity verification.`);\n }\n unpackFiles(archive);\n atomicWrite(path, archive);\n }\n return {\n id: item.id as Starter,\n version: item.version,\n displayName: item.display_name,\n sha256: item.archive.sha256,\n catalogRevision: catalog.revision,\n files: unpackFiles(archive),\n };\n}\n"],"mappings":"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","names":["require","existsSync","mkdirSync","readFileSync","renameSync","writeFileSync","dirname","join"]}
|