create-agents24-app 0.1.0 → 0.1.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.
Files changed (75) hide show
  1. package/README.md +40 -2
  2. package/dist/{chunk-OCIF3LSI.js → chunk-PXJTBSPX.js} +99 -23
  3. package/dist/chunk-PXJTBSPX.js.map +1 -0
  4. package/dist/cli.js +39 -61
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.d.ts +6 -7
  7. package/dist/index.js +9 -1
  8. package/dist/scaffold/components.json +25 -0
  9. package/dist/scaffold/manifest.json +28 -0
  10. package/dist/scaffold/src/app.tsx +71 -0
  11. package/dist/scaffold/src/chat.css +54 -0
  12. package/dist/scaffold/src/components/chat/chat-composer.tsx +237 -0
  13. package/dist/scaffold/src/components/chat/chat-message.tsx +76 -0
  14. package/dist/scaffold/src/components/chat/chat-shell.tsx +257 -0
  15. package/dist/scaffold/src/components/chat/collapsible-user-message.tsx +37 -0
  16. package/dist/scaffold/src/components/chat/external-link-dialog.tsx +48 -0
  17. package/dist/scaffold/src/components/chat/identity-control.tsx +69 -0
  18. package/dist/scaffold/src/components/chat/message-parts.tsx +83 -0
  19. package/dist/scaffold/src/components/chat/theme-menu.tsx +79 -0
  20. package/dist/scaffold/src/components/chat/thread-sidebar.tsx +114 -0
  21. package/dist/scaffold/src/components/chat/timeline-loading.ts +17 -0
  22. package/dist/scaffold/src/components/chat/turn-outline.tsx +73 -0
  23. package/dist/scaffold/src/components/theme-provider.tsx +91 -0
  24. package/dist/scaffold/src/components/ui/attachment.tsx +204 -0
  25. package/dist/scaffold/src/components/ui/bubble.tsx +125 -0
  26. package/dist/scaffold/src/components/ui/button-group.tsx +83 -0
  27. package/dist/scaffold/src/components/ui/button.tsx +65 -0
  28. package/dist/scaffold/src/components/ui/dialog.tsx +171 -0
  29. package/dist/scaffold/src/components/ui/dropdown-menu.tsx +271 -0
  30. package/dist/scaffold/src/components/ui/input.tsx +19 -0
  31. package/dist/scaffold/src/components/ui/marker.tsx +69 -0
  32. package/dist/scaffold/src/components/ui/message-scroller.tsx +129 -0
  33. package/dist/scaffold/src/components/ui/message.tsx +92 -0
  34. package/dist/scaffold/src/components/ui/popover.tsx +40 -0
  35. package/dist/scaffold/src/components/ui/select.tsx +92 -0
  36. package/dist/scaffold/src/components/ui/separator.tsx +28 -0
  37. package/dist/scaffold/src/components/ui/sheet.tsx +150 -0
  38. package/dist/scaffold/src/components/ui/sidebar.tsx +677 -0
  39. package/dist/scaffold/src/components/ui/skeleton.tsx +13 -0
  40. package/dist/scaffold/src/components/ui/textarea.tsx +18 -0
  41. package/dist/scaffold/src/components/ui/tooltip.tsx +56 -0
  42. package/dist/scaffold/src/hooks/use-mobile.ts +24 -0
  43. package/dist/scaffold/src/identity.ts +17 -0
  44. package/dist/scaffold/src/index.css +221 -0
  45. package/dist/scaffold/src/index.tsx +39 -0
  46. package/dist/scaffold/src/lib/utils.ts +6 -0
  47. package/dist/scaffold/styles.css +3 -0
  48. package/dist/scaffold-manifest.json +66 -0
  49. package/package.json +7 -3
  50. package/templates/common/README.md +16 -3
  51. package/templates/common/index.html +3 -3
  52. package/templates/common/scripts/apply-preset.mjs +17 -0
  53. package/templates/common/scripts/scope-preset-theme.mjs +38 -0
  54. package/templates/common/src/styles.css +10 -6
  55. package/templates/common/src/use-thread-query-navigation.ts +41 -0
  56. package/templates/common/tsconfig.json +2 -1
  57. package/templates/integrations/bff/server/env.ts +3 -3
  58. package/templates/integrations/bff/server/index.ts +1 -2
  59. package/templates/integrations/bff/server/principal.ts +3 -3
  60. package/templates/integrations/bff/src/host-identity.ts +6 -0
  61. package/templates/integrations/bff/src/main.tsx +21 -16
  62. package/templates/integrations/bff/tsconfig.json +2 -1
  63. package/templates/integrations/bff/vite.config.ts +5 -1
  64. package/templates/integrations/client-deployment/src/main.tsx +26 -18
  65. package/templates/integrations/client-deployment/vite.config.ts +37 -4
  66. package/templates/starters/rag/agents24/agents/assistant.md +11 -0
  67. package/templates/starters/rag/agents24/agents24.yaml +19 -0
  68. package/templates/starters/rag/agents24/rag/knowledge.yaml +32 -0
  69. package/templates/starters/rag/agents24/stores/knowledge.yaml +10 -0
  70. package/templates/starters/rag/agents24/workflows/main.yaml +16 -0
  71. package/versions.json +4 -4
  72. package/dist/chunk-OCIF3LSI.js.map +0 -1
  73. package/templates/themes/essential/src/theme.css +0 -2
  74. package/templates/themes/flow/src/theme.css +0 -60
  75. package/templates/themes/workbench/src/theme.css +0 -51
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-agents24-app
2
2
 
3
- Last Updated: 2026-07-19
3
+ Last Updated: 2026-08-06
4
4
 
5
5
  Create a canonical Agents24 React/Vite application:
6
6
 
@@ -8,4 +8,42 @@ Create a canonical Agents24 React/Vite application:
8
8
  npm create agents24-app@latest
9
9
  ```
10
10
 
11
- Choose a direct client deployment or a server-backed BFF, then choose the Essential, Workbench, or Flow visual recipe. The generated app contains only the selected integration and recipe.
11
+ Create the self-contained RAG starter with:
12
+
13
+ ```bash
14
+ npm create agents24-app@latest my-agent -- --starter rag
15
+ cd my-agent
16
+ agents24 install ./agents24
17
+ pnpm dev
18
+ ```
19
+
20
+ The starter adds an editable `agents24/` source package containing an Agent, a managed Knowledge Store, and its retrieval pipeline. Installation imports and publishes the Agent through the canonical Agent publication API, which publishes its required RAG dependencies. It does not run ingestion; the Knowledge Store starts empty and can be populated later.
21
+
22
+ Choose a direct client deployment or a server-backed BFF, then paste a preset code from [shadcn/create](https://ui.shadcn.com/create). Soft preset `b2D1FHzlY` is the canonical default.
23
+
24
+ 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.
25
+
26
+ Generation does not require a deployment ID, Agent ID, or API key. `agents24 install` detects the generated app and configures its selected integration. Client deployment writes `VITE_AGENTS24_DEPLOYMENT_ID` and copies an explicit non-production `AGENTS24_BASE_URL` as public `VITE_AGENTS24_BASE_URL`; BFF writes `AGENTS24_API_KEY` and `AGENTS24_AGENT_ID`. Use `--no-write-env` to configure those values later.
27
+
28
+ Generated apps own their Shadcn component source, while `@agents24/client`, `@agents24/react`, and `@agents24/chat-react` provide the hardened runtime, state, streaming markdown, and MCP security behavior. Run `pnpm --filter create-agents24-app materialize:fixture` to create a disposable local fixture from the same canonical source used by the generator.
29
+
30
+ The generated scaffold uses canonical ordered `message.parts` and the default `AgentResponseTimeline`. Customize `components.Timeline` to reorder copied parts, compose the package part primitives, or render a fully custom timeline. Do not mutate canonical parts or fork the scaffold transport/runtime lifecycle.
31
+
32
+ For example, keep the package renderer but change its display order:
33
+
34
+ ```tsx
35
+ import { AgentResponseTimeline } from "@agents24/chat-react/ui";
36
+ import type { Agents24ChatTimelineSlotProps } from "@agents24/chat-react/scaffold";
37
+
38
+ function Timeline({ parts, ...props }: Agents24ChatTimelineSlotProps) {
39
+ return <AgentResponseTimeline {...props} parts={[...parts].reverse()} />;
40
+ }
41
+ ```
42
+
43
+ Or fully replace it by mapping copied `parts` and rendering `AgentChatPart` (or
44
+ your own controls) with the supplied HITL callbacks. The generated app README
45
+ points to the same canonical scaffold and package guidance.
46
+
47
+ ## Maintainer development
48
+
49
+ 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. Use `pnpm dev:agents24 -- --rag` to generate the RAG starter and run its `agents24/` package through the locally packed installer before starting the app. Set `AGENTS24_BASE_URL` when targeting a local backend; the installer reads `AGENTS24_API_KEY` from the environment or its masked prompt. Unchanged tarballs, scans, and packed runners are reused from the bounded development cache; add `--fresh` after `--` for a clean rebuild. The resulting app and lockfile are disposable local fixtures because their registry disappears on exit. `pnpm release:canary` publishes a clean committed train to the opt-in npm `dev` tag after bounded registry smoke validation. Neither command changes npm `rc` or `latest`.
@@ -1,5 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // src/types.ts
4
+ var INTEGRATIONS = ["client-deployment", "bff"];
5
+ var PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
6
+ var STARTERS = ["rag"];
7
+ var DEFAULT_PRESET = "b2D1FHzlY";
8
+
3
9
  // src/generator.ts
4
10
  import { spawnSync } from "child_process";
5
11
  import { randomBytes } from "crypto";
@@ -17,9 +23,13 @@ import {
17
23
  } from "fs";
18
24
  import { basename, dirname, join, resolve } from "path";
19
25
  import { fileURLToPath } from "url";
26
+ import { createRequire } from "module";
20
27
  var packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
21
28
  var templateRoot = join(packageRoot, "templates");
29
+ var scaffoldRoot = join(packageRoot, "dist/scaffold");
30
+ var scaffoldManifest = JSON.parse(readFileSync(join(packageRoot, "dist/scaffold-manifest.json"), "utf8"));
22
31
  var versions = JSON.parse(readFileSync(join(packageRoot, "versions.json"), "utf8"));
32
+ var require2 = createRequire(import.meta.url);
23
33
  function packageName(directory) {
24
34
  const value = basename(resolve(directory)).toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
25
35
  if (!value || !/^[a-z0-9]/.test(value)) throw new Error("The destination does not produce a valid npm package name.");
@@ -52,26 +62,29 @@ function generatedManifest(options, name) {
52
62
  "@agents24/client": versions.agents24["@agents24/client"],
53
63
  "@agents24/react": versions.agents24["@agents24/react"],
54
64
  "@agents24/chat-react": versions.agents24["@agents24/chat-react"],
65
+ ...scaffoldManifest.dependencies,
55
66
  react: versions.runtime.react,
56
67
  "react-dom": versions.runtime["react-dom"]
57
68
  };
58
69
  const devDependencies = {
70
+ "@types/node": versions.development["@types/node"],
59
71
  "@types/react": versions.development["@types/react"],
60
72
  "@types/react-dom": versions.development["@types/react-dom"],
61
73
  "@vitejs/plugin-react": versions.development["@vitejs/plugin-react"],
74
+ ...scaffoldManifest.devDependencies,
62
75
  typescript: versions.development.typescript,
63
76
  vite: versions.development.vite
64
77
  };
65
78
  const scripts = {
66
79
  dev: "vite",
67
80
  build: "tsc --noEmit && vite build",
68
- preview: "vite preview"
81
+ preview: "vite preview",
82
+ preset: "node scripts/apply-preset.mjs"
69
83
  };
70
84
  if (options.integration === "bff") {
71
85
  dependencies["@agents24/node"] = versions.agents24["@agents24/node"];
72
86
  dependencies.hono = versions.runtime.hono;
73
87
  dependencies["@hono/node-server"] = versions.runtime["@hono/node-server"];
74
- devDependencies["@types/node"] = versions.development["@types/node"];
75
88
  devDependencies.concurrently = versions.development.concurrently;
76
89
  devDependencies.tsx = versions.development.tsx;
77
90
  devDependencies.tsup = "^8.5.1";
@@ -79,37 +92,53 @@ function generatedManifest(options, name) {
79
92
  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";
80
93
  scripts.start = "node server-dist/index.js --production";
81
94
  }
82
- return { name, private: true, version: "0.0.0", type: "module", engines: { node: "^22.0.0 || ^24.0.0" }, scripts, dependencies, devDependencies };
95
+ return {
96
+ name,
97
+ private: true,
98
+ version: "0.0.0",
99
+ type: "module",
100
+ engines: { node: "^22.0.0 || ^24.0.0" },
101
+ agents24: {
102
+ integration: options.integration,
103
+ package_manager: options.packageManager,
104
+ preset: options.preset,
105
+ scaffold_sha256: scaffoldManifest.sha256,
106
+ ...options.starter ? { starter: options.starter } : {}
107
+ },
108
+ scripts,
109
+ dependencies,
110
+ devDependencies
111
+ };
83
112
  }
84
113
  function envFiles(options) {
85
114
  const value = (input) => JSON.stringify(String(input || ""));
115
+ const baseUrlOverride = options.baseUrl === "https://api.agents24.dev" ? [] : [
116
+ `${options.integration === "client-deployment" ? "VITE_" : ""}AGENTS24_BASE_URL=${value(options.baseUrl)}`
117
+ ];
86
118
  if (options.integration === "client-deployment") {
87
119
  return {
88
- example: "VITE_AGENTS24_BASE_URL=https://api.agents24.dev\nVITE_AGENTS24_DEPLOYMENT_ID=acd_your_public_deployment_id\n",
89
- local: `VITE_AGENTS24_BASE_URL=${value(options.baseUrl)}
90
- VITE_AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}
91
- `
120
+ example: "# VITE_AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\nVITE_AGENTS24_DEPLOYMENT_ID=acd_your_public_deployment_id\n",
121
+ local: [...baseUrlOverride, ...options.deploymentId ? [`VITE_AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : [], ""].join("\n")
92
122
  };
93
123
  }
94
124
  return {
95
125
  example: [
96
- "AGENTS24_BASE_URL=https://api.agents24.dev",
126
+ "# AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override",
97
127
  "AGENTS24_API_KEY=your_server_only_api_key",
98
- "AGENTS24_ORGANIZATION_ID=your_organization_uuid",
99
- "AGENTS24_PROJECT_ID=your_project_uuid",
100
128
  "AGENTS24_AGENT_ID=your_agent_uuid",
129
+ "AGENTS24_DEPLOYMENT_ID=your_deployment_uuid",
130
+ "AGENTS24_CUSTOMER_ISSUER=https://your-app.example",
101
131
  "AGENTS24_AGENT_VERSION_ID=",
102
132
  "SESSION_COOKIE_SECRET=generate_at_least_32_random_bytes",
103
133
  "PORT=3001",
104
134
  ""
105
135
  ].join("\n"),
106
136
  local: [
107
- `AGENTS24_BASE_URL=${value(options.baseUrl)}`,
108
- `AGENTS24_API_KEY=${value(options.apiKey)}`,
109
- `AGENTS24_ORGANIZATION_ID=${value(options.organizationId)}`,
110
- `AGENTS24_PROJECT_ID=${value(options.projectId)}`,
111
- `AGENTS24_AGENT_ID=${value(options.agentId)}`,
112
- `AGENTS24_AGENT_VERSION_ID=${value(options.agentVersionId)}`,
137
+ ...baseUrlOverride,
138
+ ...options.agentId ? [`AGENTS24_AGENT_ID=${value(options.agentId)}`] : [],
139
+ ...options.deploymentId ? [`AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : [],
140
+ "AGENTS24_CUSTOMER_ISSUER=https://your-app.example",
141
+ ...options.agentVersionId ? [`AGENTS24_AGENT_VERSION_ID=${value(options.agentVersionId)}`] : [],
113
142
  `SESSION_COOKIE_SECRET=${value(randomBytes(32).toString("base64url"))}`,
114
143
  "PORT=3001",
115
144
  ""
@@ -120,7 +149,7 @@ function installCommand(packageManager) {
120
149
  if (packageManager === "npm") return ["npm", ["install"]];
121
150
  if (packageManager === "yarn") return ["yarn", []];
122
151
  if (packageManager === "bun") return ["bun", ["install"]];
123
- return ["pnpm", ["install"]];
152
+ return ["pnpm", ["install", "--ignore-workspace"]];
124
153
  }
125
154
  function runScriptCommand(packageManager, script) {
126
155
  if (packageManager === "npm") return `npm run ${script}`;
@@ -134,6 +163,37 @@ function installDependencies(directory, packageManager) {
134
163
  if (result.error) throw new Error(`Could not start ${command}: ${result.error.message}`);
135
164
  if (result.status !== 0) throw new Error(`${command} ${args.join(" ")} failed with exit ${result.status}.`);
136
165
  }
166
+ function clearPresetInstallArtifacts(directory) {
167
+ for (const name of ["node_modules", "bun.lock", "bun.lockb", "package-lock.json", "pnpm-lock.yaml", "yarn.lock"]) {
168
+ rmSync(join(directory, name), { recursive: true, force: true });
169
+ }
170
+ }
171
+ function applyShadcnPreset(directory, preset) {
172
+ if (preset === DEFAULT_PRESET) return;
173
+ const executable = require2.resolve("shadcn");
174
+ const { AGENTS24_API_KEY: _apiKey, ...presetEnvironment } = process.env;
175
+ const result = spawnSync(
176
+ process.execPath,
177
+ [executable, "apply", preset, "--yes", "--silent", "--cwd", directory],
178
+ { cwd: directory, encoding: "utf8", env: presetEnvironment }
179
+ );
180
+ if (result.error) throw new Error(`Could not start Shadcn preset materialization: ${result.error.message}`);
181
+ if (result.status !== 0) {
182
+ const detail = String(result.stderr || result.stdout || "").trim().split("\n").at(-1);
183
+ throw new Error(detail || `Shadcn could not apply preset ${preset}.`);
184
+ }
185
+ const scopeResult = spawnSync(
186
+ process.execPath,
187
+ [join(directory, "scripts/scope-preset-theme.mjs")],
188
+ { cwd: directory, encoding: "utf8" }
189
+ );
190
+ if (scopeResult.error) throw new Error(`Could not scope the selected Shadcn preset: ${scopeResult.error.message}`);
191
+ if (scopeResult.status !== 0) {
192
+ const detail = String(scopeResult.stderr || scopeResult.stdout || "").trim().split("\n").at(-1);
193
+ throw new Error(detail || `Could not scope Shadcn preset ${preset}.`);
194
+ }
195
+ clearPresetInstallArtifacts(directory);
196
+ }
137
197
  function createApp(options) {
138
198
  const destination = resolve(options.directory);
139
199
  assertDestination(destination);
@@ -143,23 +203,35 @@ function createApp(options) {
143
203
  const staging = join(parent, `.${name}.agents24-${randomBytes(6).toString("hex")}`);
144
204
  try {
145
205
  mkdirSync(staging, { mode: 448 });
206
+ cpSync(scaffoldRoot, staging, { recursive: true, force: true });
207
+ rmSync(join(staging, "manifest.json"), { force: true });
146
208
  copyLayer("common", staging);
147
209
  copyLayer(`integrations/${options.integration}`, staging);
148
- copyLayer(`themes/${options.theme}`, staging);
149
- const apiOrigin = new URL(options.baseUrl).origin;
210
+ if (options.starter) copyLayer(`starters/${options.starter}`, staging);
150
211
  replaceTemplateValues(staging, {
151
212
  "__APP_NAME__": name,
152
- "__THEME__": options.theme,
213
+ "__PRESET__": options.preset,
153
214
  "__INTEGRATION__": options.integration,
154
- "__CONNECT_SOURCE__": options.integration === "client-deployment" ? apiOrigin : "",
215
+ "__CONNECT_SOURCE__": options.integration === "client-deployment" ? " __AGENTS24_CONNECT_SOURCE__" : "",
155
216
  "__PM_DEV__": runScriptCommand(options.packageManager, "dev"),
156
217
  "__PM_BUILD__": runScriptCommand(options.packageManager, "build"),
157
- "__PM_PRODUCTION__": runScriptCommand(options.packageManager, options.integration === "bff" ? "start" : "preview")
218
+ "__PM_PRODUCTION__": runScriptCommand(options.packageManager, options.integration === "bff" ? "start" : "preview"),
219
+ "__PM_PRESET__": `${runScriptCommand(options.packageManager, "preset")} --`,
220
+ "__STARTER_SETUP__": options.starter ? `## Publish the included Agent
221
+
222
+ This repository includes an editable Agent package in \`agents24/\`. From this directory run:
223
+
224
+ \`\`\`bash
225
+ agents24 install ./agents24
226
+ \`\`\`
227
+
228
+ The installer publishes the Agent and its RAG dependencies, then configures this app. It creates no ingestion job; the managed Knowledge Store starts empty.` : ""
158
229
  });
159
230
  const gitignore = join(staging, "_gitignore");
160
231
  if (existsSync(gitignore)) renameSync(gitignore, join(staging, ".gitignore"));
161
232
  writeFileSync(join(staging, "package.json"), `${JSON.stringify(generatedManifest(options, name), null, 2)}
162
233
  `);
234
+ applyShadcnPreset(staging, options.preset);
163
235
  const env = envFiles(options);
164
236
  writeFileSync(join(staging, ".env.example"), env.example);
165
237
  if (options.install) installDependencies(staging, options.packageManager);
@@ -175,7 +247,11 @@ function createApp(options) {
175
247
  }
176
248
 
177
249
  export {
250
+ INTEGRATIONS,
251
+ PACKAGE_MANAGERS,
252
+ STARTERS,
253
+ DEFAULT_PRESET,
178
254
  installDependencies,
179
255
  createApp
180
256
  };
181
- //# sourceMappingURL=chunk-OCIF3LSI.js.map
257
+ //# sourceMappingURL=chunk-PXJTBSPX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/generator.ts"],"sourcesContent":["export const INTEGRATIONS = [\"client-deployment\", \"bff\"] as const;\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const;\nexport const STARTERS = [\"rag\"] as const;\nexport const DEFAULT_PRESET = \"b2D1FHzlY\";\n\nexport type Integration = (typeof INTEGRATIONS)[number];\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\nexport type Starter = (typeof STARTERS)[number];\n\nexport type CreateAppOptions = {\n directory: string;\n integration: Integration;\n preset: string;\n packageManager: PackageManager;\n install: boolean;\n baseUrl: string;\n starter?: Starter;\n deploymentId?: string;\n agentId?: 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 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 ? { starter: options.starter } : {}),\n },\n scripts,\n dependencies,\n devDependencies,\n };\n}\n\nfunction envFiles(options: CreateAppOptions): { example: string; local: string } {\n const value = (input: string | undefined) => JSON.stringify(String(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 \"AGENTS24_AGENT_ID=your_agent_uuid\",\n \"AGENTS24_DEPLOYMENT_ID=your_deployment_uuid\",\n \"AGENTS24_CUSTOMER_ISSUER=https://your-app.example\",\n \"AGENTS24_AGENT_VERSION_ID=\",\n \"SESSION_COOKIE_SECRET=generate_at_least_32_random_bytes\",\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n local: [\n ...baseUrlOverride,\n ...(options.agentId ? [`AGENTS24_AGENT_ID=${value(options.agentId)}`] : []),\n ...(options.deploymentId ? [`AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : []),\n \"AGENTS24_CUSTOMER_ISSUER=https://your-app.example\",\n ...(options.agentVersionId ? [`AGENTS24_AGENT_VERSION_ID=${value(options.agentVersionId)}`] : []),\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 if (options.starter) copyLayer(`starters/${options.starter}`, staging);\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 ? `## Publish the included Agent\\n\\nThis repository includes an editable Agent package in \\`agents24/\\`. From this directory run:\\n\\n\\`\\`\\`bash\\nagents24 install ./agents24\\n\\`\\`\\`\\n\\nThe installer publishes the Agent and its RAG dependencies, then configures this app. It creates no ingestion job; the managed Knowledge Store starts empty.`\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);\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"],"mappings":"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","names":["require"]}
package/dist/cli.js CHANGED
@@ -1,9 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ DEFAULT_PRESET,
4
+ INTEGRATIONS,
5
+ PACKAGE_MANAGERS,
6
+ STARTERS,
3
7
  createApp
4
- } from "./chunk-OCIF3LSI.js";
8
+ } from "./chunk-PXJTBSPX.js";
5
9
 
6
10
  // src/cli.ts
11
+ import { writeFileSync } from "fs";
7
12
  import process3 from "process";
8
13
  import { intro, outro } from "@clack/prompts";
9
14
 
@@ -11,14 +16,13 @@ import { intro, outro } from "@clack/prompts";
11
16
  import process from "process";
12
17
  var VALUE_FLAGS = /* @__PURE__ */ new Set([
13
18
  "integration",
14
- "theme",
19
+ "preset",
15
20
  "package-manager",
16
21
  "base-url",
17
22
  "deployment-id",
18
23
  "agent-id",
19
24
  "agent-version-id",
20
- "organization-id",
21
- "project-id"
25
+ "starter"
22
26
  ]);
23
27
  var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["yes", "no-install", "help"]);
24
28
  function parseArguments(argv = process.argv.slice(2)) {
@@ -52,33 +56,25 @@ Usage:
52
56
 
53
57
  Options:
54
58
  --integration <client-deployment|bff>
55
- --theme <essential|workbench|flow>
59
+ --preset <shadcn-preset-code> Defaults to b2D1FHzlY
56
60
  --package-manager <pnpm|npm|yarn|bun>
57
61
  --base-url <url>
58
62
  --deployment-id <acd_...> Client deployment mode
59
63
  --agent-id <uuid> BFF mode
60
64
  --agent-version-id <uuid> Optional pinned BFF version
61
- --organization-id <uuid> BFF mode
62
- --project-id <uuid> BFF mode
65
+ --starter <rag> Include an editable Agent + RAG source package
63
66
  --no-install
64
67
  --yes Disable prompts; required values must be supplied
65
68
  --help
66
69
 
67
- For security, API keys are accepted only through the masked prompt or the
68
- AGENTS24_API_KEY environment variable.`;
70
+ Run agents24 install after generation to publish and configure the app.`;
69
71
 
70
72
  // src/prompts.ts
71
73
  import process2 from "process";
72
- import { confirm, isCancel, password, select, text } from "@clack/prompts";
73
-
74
- // src/types.ts
75
- var INTEGRATIONS = ["client-deployment", "bff"];
76
- var THEMES = ["essential", "workbench", "flow"];
77
- var PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
78
-
79
- // src/prompts.ts
74
+ import { confirm, isCancel, select, text } from "@clack/prompts";
80
75
  var 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;
81
76
  var DEPLOYMENT_ID = /^acd_[A-Za-z0-9_-]{10,}$/;
77
+ var PRESET = /^[A-Za-z0-9]{6,32}$/;
82
78
  function cancelled(value) {
83
79
  if (isCancel(value)) throw new Error("App creation cancelled.");
84
80
  }
@@ -122,9 +118,10 @@ async function resolveOptions(args) {
122
118
  const nonInteractive = args.flags.yes === true;
123
119
  let directory = args.directory;
124
120
  let integration = oneOf(flag(args, "integration"), INTEGRATIONS, "integration");
125
- let theme = oneOf(flag(args, "theme"), THEMES, "theme");
121
+ let preset = flag(args, "preset");
126
122
  let packageManager = oneOf(flag(args, "package-manager"), PACKAGE_MANAGERS, "package-manager");
127
123
  let baseUrl = flag(args, "base-url");
124
+ const starter = oneOf(flag(args, "starter"), STARTERS, "starter");
128
125
  let install = args.flags["no-install"] !== true;
129
126
  if (!nonInteractive) {
130
127
  directory ||= await requiredText("Where should the app be created?", "my-agents24-app");
@@ -136,22 +133,17 @@ async function resolveOptions(args) {
136
133
  cancelled(result);
137
134
  integration = result;
138
135
  }
139
- if (!theme) {
140
- const result = await select({ message: "Choose a visual recipe", initialValue: "essential", options: [
141
- { value: "essential", label: "Essential", hint: "Canonical shared-page UI" },
142
- { value: "workbench", label: "Workbench", hint: "Dense and structured" },
143
- { value: "flow", label: "Flow", hint: "Soft and conversational" }
144
- ] });
145
- cancelled(result);
146
- theme = result;
147
- }
136
+ preset ||= await requiredText(
137
+ "Shadcn preset code",
138
+ DEFAULT_PRESET,
139
+ (value) => PRESET.test(value) ? void 0 : "Enter a valid Shadcn preset code."
140
+ );
148
141
  if (!packageManager) {
149
142
  const detected = detectedPackageManager();
150
143
  const result = await select({ message: "Package manager", initialValue: detected, options: PACKAGE_MANAGERS.map((value) => ({ value, label: value })) });
151
144
  cancelled(result);
152
145
  packageManager = result;
153
146
  }
154
- baseUrl ||= await requiredText("Agents24 API URL", "https://api.agents24.dev", validateUrl);
155
147
  if (args.flags["no-install"] !== true) {
156
148
  const result = await confirm({ message: "Install dependencies?", initialValue: true });
157
149
  cancelled(result);
@@ -160,51 +152,28 @@ async function resolveOptions(args) {
160
152
  }
161
153
  directory = String(directory || "").trim();
162
154
  integration ||= "client-deployment";
163
- theme ||= "essential";
155
+ preset ||= DEFAULT_PRESET;
164
156
  packageManager ||= detectedPackageManager();
165
157
  baseUrl ||= "https://api.agents24.dev";
166
158
  const urlError = validateUrl(baseUrl);
167
159
  if (!directory) throw new Error("A destination directory is required.");
168
160
  if (urlError) throw new Error(urlError);
161
+ if (!PRESET.test(preset)) throw new Error("--preset must be a valid Shadcn preset code.");
169
162
  if (integration === "client-deployment") {
170
- let deploymentId = flag(args, "deployment-id");
171
- if (!deploymentId && !nonInteractive) deploymentId = await requiredText("Public deployment ID", void 0, (value) => DEPLOYMENT_ID.test(value) ? void 0 : "Use a public acd_\u2026 deployment ID.");
172
- if (!deploymentId || !DEPLOYMENT_ID.test(deploymentId)) throw new Error("A valid --deployment-id (acd_\u2026) is required.");
173
- return { directory, integration, theme, packageManager, install, baseUrl, deploymentId };
163
+ const deploymentId = flag(args, "deployment-id");
164
+ if (deploymentId && !DEPLOYMENT_ID.test(deploymentId)) throw new Error("--deployment-id must be a valid public acd_\u2026 deployment ID.");
165
+ return { directory, integration, preset, packageManager, install, baseUrl, starter, deploymentId };
174
166
  }
175
167
  const fields = {
176
168
  agentId: flag(args, "agent-id"),
177
- agentVersionId: flag(args, "agent-version-id"),
178
- organizationId: flag(args, "organization-id"),
179
- projectId: flag(args, "project-id")
169
+ deploymentId: flag(args, "deployment-id"),
170
+ agentVersionId: flag(args, "agent-version-id")
180
171
  };
181
- if (!nonInteractive) {
182
- fields.agentId ||= await requiredText("Agent ID", void 0, (value) => UUID.test(value) ? void 0 : "Enter an Agent UUID.");
183
- fields.organizationId ||= await requiredText("Organization ID", void 0, (value) => UUID.test(value) ? void 0 : "Enter an organization UUID.");
184
- fields.projectId ||= await requiredText("Project ID", void 0, (value) => UUID.test(value) ? void 0 : "Enter a project UUID.");
185
- if (!fields.agentVersionId) {
186
- const result = await text({
187
- message: "Agent version ID (optional)",
188
- placeholder: "Leave blank to use latest published",
189
- validate: (value) => String(value || "").trim() && !UUID.test(String(value).trim()) ? "Enter an Agent version UUID or leave blank." : void 0
190
- });
191
- cancelled(result);
192
- fields.agentVersionId = String(result || "").trim() || void 0;
193
- }
194
- }
195
172
  for (const [name, value] of Object.entries(fields)) {
196
- if (name === "agentVersionId" && !value) continue;
197
- if (!value || !UUID.test(value)) throw new Error(`A valid --${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)} UUID is required.`);
198
- }
199
- let apiKey = String(process2.env.AGENTS24_API_KEY || "").trim();
200
- if (!apiKey && !nonInteractive) {
201
- const result = await password({ message: "Agents24 API key", validate: (value) => String(value || "").trim() ? void 0 : "The API key is required." });
202
- cancelled(result);
203
- apiKey = String(result).trim();
173
+ if (!value) continue;
174
+ if (!UUID.test(value)) throw new Error(`--${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)} must be a valid UUID.`);
204
175
  }
205
- if (!apiKey) throw new Error("AGENTS24_API_KEY is required for noninteractive BFF creation.");
206
- if (/[\r\n\0]/.test(apiKey)) throw new Error("AGENTS24_API_KEY contains invalid control characters.");
207
- return { directory, integration, theme, packageManager, install, baseUrl, apiKey, ...fields };
176
+ return { directory, integration, preset, packageManager, install, baseUrl, starter, ...fields };
208
177
  }
209
178
 
210
179
  // src/cli.ts
@@ -223,6 +192,15 @@ async function main() {
223
192
  intro("Create Agents24 App");
224
193
  const options = await resolveOptions(args);
225
194
  const generated = createApp(options);
195
+ if (process3.env.AGENTS24_CREATE_RESULT_FILE) {
196
+ writeFileSync(process3.env.AGENTS24_CREATE_RESULT_FILE, `${JSON.stringify({
197
+ ...generated,
198
+ install: options.install,
199
+ integration: options.integration,
200
+ packageManager: options.packageManager
201
+ })}
202
+ `, { mode: 384 });
203
+ }
226
204
  const relative = generated.directory.startsWith(`${process3.cwd()}/`) ? generated.directory.slice(process3.cwd().length + 1) : generated.directory;
227
205
  const install = `${options.packageManager} install`;
228
206
  const productionScript = options.integration === "bff" ? "start" : "preview";
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/arguments.ts","../src/prompts.ts","../src/types.ts"],"sourcesContent":["import 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 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 \"theme\",\n \"package-manager\",\n \"base-url\",\n \"deployment-id\",\n \"agent-id\",\n \"agent-version-id\",\n \"organization-id\",\n \"project-id\",\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 --theme <essential|workbench|flow>\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-version-id <uuid> Optional pinned BFF version\n --organization-id <uuid> BFF mode\n --project-id <uuid> BFF mode\n --no-install\n --yes Disable prompts; required values must be supplied\n --help\n\nFor security, API keys are accepted only through the masked prompt or the\nAGENTS24_API_KEY environment variable.`;\n","import process from \"node:process\";\nimport { confirm, isCancel, password, select, text } from \"@clack/prompts\";\n\nimport type { ParsedArguments } from \"./arguments.js\";\nimport {\n INTEGRATIONS,\n PACKAGE_MANAGERS,\n THEMES,\n type CreateAppOptions,\n type Integration,\n type PackageManager,\n type Theme,\n} from \"./types.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,}$/;\n\nfunction cancelled(value: unknown): asserts value is Exclude<typeof value, 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 theme = oneOf(flag(args, \"theme\"), THEMES, \"theme\");\n let packageManager = oneOf(flag(args, \"package-manager\"), PACKAGE_MANAGERS, \"package-manager\");\n let baseUrl = flag(args, \"base-url\");\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 if (!theme) {\n const result = await select<Theme>({ message: \"Choose a visual recipe\", initialValue: \"essential\", options: [\n { value: \"essential\", label: \"Essential\", hint: \"Canonical shared-page UI\" },\n { value: \"workbench\", label: \"Workbench\", hint: \"Dense and structured\" },\n { value: \"flow\", label: \"Flow\", hint: \"Soft and conversational\" },\n ] });\n cancelled(result); theme = result;\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 baseUrl ||= await requiredText(\"Agents24 API URL\", \"https://api.agents24.dev\", validateUrl);\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 theme ||= \"essential\";\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\n if (integration === \"client-deployment\") {\n let deploymentId = flag(args, \"deployment-id\");\n if (!deploymentId && !nonInteractive) deploymentId = await requiredText(\"Public deployment ID\", undefined, (value) => DEPLOYMENT_ID.test(value) ? undefined : \"Use a public acd_… deployment ID.\");\n if (!deploymentId || !DEPLOYMENT_ID.test(deploymentId)) throw new Error(\"A valid --deployment-id (acd_…) is required.\");\n return { directory, integration, theme, packageManager, install, baseUrl, deploymentId };\n }\n\n const fields = {\n agentId: flag(args, \"agent-id\"),\n agentVersionId: flag(args, \"agent-version-id\"),\n organizationId: flag(args, \"organization-id\"),\n projectId: flag(args, \"project-id\"),\n };\n if (!nonInteractive) {\n fields.agentId ||= await requiredText(\"Agent ID\", undefined, (value) => UUID.test(value) ? undefined : \"Enter an Agent UUID.\");\n fields.organizationId ||= await requiredText(\"Organization ID\", undefined, (value) => UUID.test(value) ? undefined : \"Enter an organization UUID.\");\n fields.projectId ||= await requiredText(\"Project ID\", undefined, (value) => UUID.test(value) ? undefined : \"Enter a project UUID.\");\n if (!fields.agentVersionId) {\n const result = await text({\n message: \"Agent version ID (optional)\",\n placeholder: \"Leave blank to use latest published\",\n validate: (value) => String(value || \"\").trim() && !UUID.test(String(value).trim()) ? \"Enter an Agent version UUID or leave blank.\" : undefined,\n });\n cancelled(result);\n fields.agentVersionId = String(result || \"\").trim() || undefined;\n }\n }\n for (const [name, value] of Object.entries(fields)) {\n if (name === \"agentVersionId\" && !value) continue;\n if (!value || !UUID.test(value)) throw new Error(`A valid --${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)} UUID is required.`);\n }\n let apiKey = String(process.env.AGENTS24_API_KEY || \"\").trim();\n if (!apiKey && !nonInteractive) {\n const result = await password({ message: \"Agents24 API key\", validate: (value) => String(value || \"\").trim() ? undefined : \"The API key is required.\" });\n cancelled(result); apiKey = String(result).trim();\n }\n if (!apiKey) throw new Error(\"AGENTS24_API_KEY is required for noninteractive BFF creation.\");\n if (/[\\r\\n\\0]/.test(apiKey)) throw new Error(\"AGENTS24_API_KEY contains invalid control characters.\");\n return { directory, integration, theme, packageManager, install, baseUrl, apiKey, ...fields } as CreateAppOptions;\n}\n","export const INTEGRATIONS = [\"client-deployment\", \"bff\"] as const;\nexport const THEMES = [\"essential\", \"workbench\", \"flow\"] as const;\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const;\n\nexport type Integration = (typeof INTEGRATIONS)[number];\nexport type Theme = (typeof THEMES)[number];\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\n\nexport type CreateAppOptions = {\n directory: string;\n integration: Integration;\n theme: Theme;\n packageManager: PackageManager;\n install: boolean;\n baseUrl: string;\n deploymentId?: string;\n agentId?: string;\n agentVersionId?: string;\n organizationId?: string;\n projectId?: string;\n apiKey?: string;\n};\n\nexport type GeneratedApp = {\n directory: string;\n packageName: string;\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 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-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-version-id <uuid> Optional pinned BFF version\n --starter <rag> Include an editable Agent + RAG source package\n --no-install\n --yes Disable prompts; required values must be supplied\n --help\n\nRun agents24 install after generation to publish 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 STARTERS,\n DEFAULT_PRESET,\n type CreateAppOptions,\n type Integration,\n type PackageManager,\n type Starter,\n} from \"./types.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 starter = oneOf<Starter>(flag(args, \"starter\"), STARTERS, \"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 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 deploymentId: flag(args, \"deployment-id\"),\n agentVersionId: flag(args, \"agent-version-id\"),\n };\n for (const [name, value] of Object.entries(fields)) {\n if (!value) continue;\n if (!UUID.test(value)) throw new Error(`--${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)} must be a valid UUID.`);\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"]}