create-agents24-app 0.1.8 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-agents24-app
2
2
 
3
- Last Updated: 2026-08-20
3
+ Last Updated: 2026-09-02
4
4
 
5
5
  Create a canonical Agents24 React/Vite application:
6
6
 
@@ -8,10 +8,10 @@ Create a canonical Agents24 React/Vite application:
8
8
  npm create agents24-app@latest
9
9
  ```
10
10
 
11
- Create the self-contained RAG starter with:
11
+ Create an app with an official Agent template:
12
12
 
13
13
  ```bash
14
- npm create agents24-app@latest my-agent -- --starter rag
14
+ npm create agents24-app@latest my-agent -- --starter customer-support
15
15
  cd my-agent
16
16
  agents24 prepare ./agents24
17
17
  agents24 plan ./agents24
@@ -22,13 +22,17 @@ agents24 status ./agents24
22
22
  pnpm dev
23
23
  ```
24
24
 
25
- The starter adds an editable Package V2 source tree containing an Agent, managed Knowledge Store, retrieval pipeline, and managed content. Its stable manifest keys intentionally remain independent from filenames. `apply` creates or updates drafts, mirrors the draft Store snapshot, and never requires a self-hosted Artifact relay or production endpoint. Verify the generated RAG Tool through `agents24 status`, then `publish` atomically promotes the unchanged current synchronized draft snapshot. `pull` is lossless and platform-authoritative for package-owned files: before any write, it round-trips the platform draft through Bundle projection, canonical package files, recompilation, and semantic equality. `setup` combines apply, publish, and application configuration.
25
+ Use `--starter deep-research` for the Planner/Researcher/Critic template, or omit
26
+ `--starter` to generate the scaffold without an Agent package. The old
27
+ `--starter rag` value is intentionally rejected.
28
+
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.
26
30
 
27
31
  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.
28
32
 
29
33
  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.
30
34
 
31
- Generation does not require a deployment ID, Agent ID, or API key. `agents24 setup` detects the generated app and configures its selected integration. Direct-client mode retains `VITE_AGENTS24_DEPLOYMENT_ID`; BFF writes only `AGENTS24_API_KEY` and `AGENTS24_AGENT_ID` and uses no deployment. The generator creates `SESSION_COOKIE_SECRET` for the default signed guest session, and setup preserves it. Generated BFFs use draft runtime locally and published runtime in production; direct clients are published-only. Use `--no-write-env` to configure platform values later.
35
+ Generation does not require a deployment ID, Agent ID, or API key. `agents24 setup` detects the generated app and configures its selected integration. Direct-client mode retains `VITE_AGENTS24_DEPLOYMENT_ID`; BFF writes only the server-only `AGENTS24_API_KEY` and `AGENTS24_AGENTS` selectors and uses no deployment. The generator creates `SESSION_COOKIE_SECRET` for the default signed guest session, and setup preserves it. Generated BFFs use draft runtime locally and published runtime in production; direct clients are published-only. Use `--no-write-env` to configure platform values later.
32
36
 
33
37
  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.
34
38
 
@@ -51,4 +55,4 @@ points to the same canonical scaffold and package guidance.
51
55
 
52
56
  ## Maintainer development
53
57
 
54
- 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 the app from the current packed train before holding the registry open. Use `pnpm dev:agents24 -- --rag` to generate the RAG starter and run its `agents24/` package through the locally packed `prepare`, `plan`, `apply`, `status`, and `publish` lifecycle before starting the app. Set `AGENTS24_BASE_URL` when targeting a local backend; the CLI 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`.
58
+ 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.
@@ -3,7 +3,6 @@
3
3
  // src/types.ts
4
4
  var INTEGRATIONS = ["client-deployment", "bff"];
5
5
  var PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
6
- var STARTERS = ["rag"];
7
6
  var DEFAULT_PRESET = "b2D1FHzlY";
8
7
 
9
8
  // src/generator.ts
@@ -57,6 +56,22 @@ function replaceTemplateValues(directory, replacements) {
57
56
  function copyLayer(name, destination) {
58
57
  cpSync(join(templateRoot, name), destination, { recursive: true, force: true });
59
58
  }
59
+ function materializeTemplate(destination, options) {
60
+ if (!options.starter) return;
61
+ const packageId = `pkg_${randomBytes(16).toString("hex")}`;
62
+ let replacedManifest = false;
63
+ for (const [path, original] of options.starter.files) {
64
+ let content = original;
65
+ if (path === "agents24.yaml") {
66
+ content = content.replace(/^(package_id:\s*)[^\s#]+/m, `$1${packageId}`);
67
+ replacedManifest = content !== original;
68
+ }
69
+ const target = join(destination, "agents24", path);
70
+ mkdirSync(dirname(target), { recursive: true });
71
+ writeFileSync(target, content);
72
+ }
73
+ if (!replacedManifest) throw new Error("The selected Agent template has no replaceable package_id.");
74
+ }
60
75
  function generatedManifest(options, name) {
61
76
  const dependencies = {
62
77
  "@agents24/client": versions.agents24["@agents24/client"],
@@ -103,7 +118,12 @@ function generatedManifest(options, name) {
103
118
  package_manager: options.packageManager,
104
119
  preset: options.preset,
105
120
  scaffold_sha256: scaffoldManifest.sha256,
106
- ...options.starter ? { starter: options.starter } : {}
121
+ ...options.starter ? { template: {
122
+ id: options.starter.id,
123
+ version: options.starter.version,
124
+ sha256: options.starter.sha256,
125
+ catalog_revision: options.starter.catalogRevision
126
+ } } : {}
107
127
  },
108
128
  scripts,
109
129
  dependencies,
@@ -211,10 +231,9 @@ function createApp(options) {
211
231
  rmSync(join(staging, "manifest.json"), { force: true });
212
232
  copyLayer("common", staging);
213
233
  copyLayer(`integrations/${options.integration}`, staging);
214
- if (options.starter) copyLayer(`starters/${options.starter}`, staging);
234
+ materializeTemplate(staging, options);
215
235
  replaceTemplateValues(staging, {
216
236
  "__APP_NAME__": name,
217
- "__PACKAGE_ID__": `pkg_${randomBytes(16).toString("hex")}`,
218
237
  "__PRESET__": options.preset,
219
238
  "__INTEGRATION__": options.integration,
220
239
  "__CONNECT_SOURCE__": options.integration === "client-deployment" ? " __AGENTS24_CONNECT_SOURCE__" : "",
@@ -245,12 +264,159 @@ This repository includes an editable Resource Package in \`agents24/\`. For a BF
245
264
  }
246
265
  }
247
266
 
267
+ // src/template-catalog.ts
268
+ import { createHash } from "crypto";
269
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "fs";
270
+ import { homedir, tmpdir } from "os";
271
+ import { dirname as dirname2, join as join2 } from "path";
272
+ import { unpackFiles } from "@agents24/cli";
273
+ var GENERATOR_VERSION = "0.2.0";
274
+ var SHA256 = /^[0-9a-f]{64}$/;
275
+ var SEMVER = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/;
276
+ var TEMPLATE_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
277
+ function cacheRoot() {
278
+ const override = String(process.env.AGENTS24_TEMPLATE_CACHE_DIR || "").trim();
279
+ if (override) return override;
280
+ const platformRoot = process.platform === "win32" ? process.env.LOCALAPPDATA : process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");
281
+ return join2(platformRoot || tmpdir(), "agents24", "templates-v1");
282
+ }
283
+ function atomicWrite(path, data) {
284
+ mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
285
+ const temporary = `${path}.${process.pid}.tmp`;
286
+ writeFileSync2(temporary, data, { mode: 384 });
287
+ renameSync2(temporary, path);
288
+ }
289
+ function parseVersion(value) {
290
+ const match = SEMVER.exec(value);
291
+ return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
292
+ }
293
+ function compatible(item) {
294
+ const minimum = parseVersion(String(item.compatibility?.min_generator_version || "0.0.0"));
295
+ const current = parseVersion(GENERATOR_VERSION);
296
+ if (!minimum || item.compatibility?.resource_package_schema !== "2.0") return false;
297
+ return current[0] > minimum[0] || current[0] === minimum[0] && current[1] > minimum[1] || current[0] === minimum[0] && current[1] === minimum[1] && current[2] >= minimum[2];
298
+ }
299
+ function validateCatalog(value) {
300
+ const catalog = value;
301
+ if (catalog?.schema_version !== "agents24.template-catalog.v1" || !SHA256.test(catalog.revision) || !Array.isArray(catalog.templates)) {
302
+ throw new Error("The Agents24 template catalog is invalid.");
303
+ }
304
+ const ids = /* @__PURE__ */ new Set();
305
+ for (const item of catalog.templates) {
306
+ if (!TEMPLATE_ID.test(item?.id) || ids.has(item.id) || !SEMVER.test(item.version) || !item.display_name || !SHA256.test(item.archive?.sha256) || !Number.isSafeInteger(item.archive?.size) || item.archive.size < 1 || item.archive.size > 5 * 1024 * 1024 || !item.archive.download_url?.startsWith("/templates/")) {
307
+ throw new Error("The Agents24 template catalog contains an invalid release.");
308
+ }
309
+ ids.add(item.id);
310
+ }
311
+ return catalog;
312
+ }
313
+ function readCachedCatalog(path) {
314
+ try {
315
+ const cached = JSON.parse(readFileSync2(path, "utf8"));
316
+ return { ...cached.etag ? { etag: cached.etag } : {}, catalog: validateCatalog(cached.catalog) };
317
+ } catch {
318
+ return null;
319
+ }
320
+ }
321
+ async function loadTemplateCatalog(baseUrl) {
322
+ const path = join2(cacheRoot(), "catalog.json");
323
+ const cached = existsSync2(path) ? readCachedCatalog(path) : null;
324
+ try {
325
+ const response = await fetch(new URL("/templates", `${baseUrl}/`), {
326
+ headers: cached?.etag ? { "If-None-Match": cached.etag } : {},
327
+ signal: AbortSignal.timeout(1e4)
328
+ });
329
+ if (response.status === 304 && cached) return { catalog: cached.catalog, live: true };
330
+ if (!response.ok) throw new Error(`catalog request returned ${response.status}`);
331
+ const catalog = validateCatalog(await response.json());
332
+ const etag = response.headers.get("etag") || void 0;
333
+ atomicWrite(path, `${JSON.stringify({ ...etag ? { etag } : {}, catalog })}
334
+ `);
335
+ return { catalog, live: true };
336
+ } catch (error) {
337
+ if (cached) return { catalog: cached.catalog, live: false };
338
+ const detail = error instanceof Error ? error.message : "request failed";
339
+ throw new Error(`Could not load the Agents24 template catalog (${detail}), and no verified cached catalog is available.`);
340
+ }
341
+ }
342
+ function compatibleTemplates(catalog) {
343
+ return catalog.templates.filter(compatible);
344
+ }
345
+ function verifiedArchive(path, item) {
346
+ try {
347
+ const archive = readFileSync2(path);
348
+ if (archive.byteLength !== item.archive.size || createHash("sha256").update(archive).digest("hex") !== item.archive.sha256) return null;
349
+ unpackFiles(archive);
350
+ return archive;
351
+ } catch {
352
+ return null;
353
+ }
354
+ }
355
+ async function readArchiveResponse(response, expectedSize) {
356
+ if (!response.body) throw new Error("Template download returned no archive body.");
357
+ const reader = response.body.getReader();
358
+ const chunks = [];
359
+ let size = 0;
360
+ while (true) {
361
+ const { done, value } = await reader.read();
362
+ if (done) break;
363
+ size += value.byteLength;
364
+ if (size > expectedSize || size > 5 * 1024 * 1024) {
365
+ await reader.cancel();
366
+ throw new Error("Template download exceeds its advertised archive size.");
367
+ }
368
+ chunks.push(value);
369
+ }
370
+ const archive = new Uint8Array(size);
371
+ let offset = 0;
372
+ for (const chunk of chunks) {
373
+ archive.set(chunk, offset);
374
+ offset += chunk.byteLength;
375
+ }
376
+ return archive;
377
+ }
378
+ async function selectTemplate(baseUrl, catalog, id) {
379
+ if (id === "rag") throw new Error("The 'rag' starter was removed. Use --starter customer-support or --starter deep-research.");
380
+ const item = catalog.templates.find((candidate) => candidate.id === id);
381
+ if (!item) throw new Error(`Template '${id}' is not available in the active catalog.`);
382
+ if (!compatible(item)) throw new Error(`Template '${id}' requires a newer create-agents24-app release.`);
383
+ const path = join2(cacheRoot(), "archives", `${item.archive.sha256}.zip`);
384
+ let archive = existsSync2(path) ? verifiedArchive(path, item) : null;
385
+ if (!archive) {
386
+ let response;
387
+ try {
388
+ response = await fetch(new URL(item.archive.download_url, `${baseUrl}/`), { signal: AbortSignal.timeout(3e4) });
389
+ } catch (error) {
390
+ throw new Error(`Could not download template '${id}', and no verified cached archive is available.`);
391
+ }
392
+ if (!response.ok) throw new Error(`Could not download template '${id}' (HTTP ${response.status}).`);
393
+ const length = response.headers.get("content-length");
394
+ if (length && Number(length) !== item.archive.size) throw new Error(`Template '${id}' download size does not match the catalog.`);
395
+ archive = await readArchiveResponse(response, item.archive.size);
396
+ if (archive.byteLength !== item.archive.size || createHash("sha256").update(archive).digest("hex") !== item.archive.sha256) {
397
+ throw new Error(`Template '${id}' failed integrity verification.`);
398
+ }
399
+ unpackFiles(archive);
400
+ atomicWrite(path, archive);
401
+ }
402
+ return {
403
+ id: item.id,
404
+ version: item.version,
405
+ displayName: item.display_name,
406
+ sha256: item.archive.sha256,
407
+ catalogRevision: catalog.revision,
408
+ files: unpackFiles(archive)
409
+ };
410
+ }
411
+
248
412
  export {
249
413
  INTEGRATIONS,
250
414
  PACKAGE_MANAGERS,
251
- STARTERS,
252
415
  DEFAULT_PRESET,
253
416
  installDependencies,
254
- createApp
417
+ createApp,
418
+ loadTemplateCatalog,
419
+ compatibleTemplates,
420
+ selectTemplate
255
421
  };
256
- //# sourceMappingURL=chunk-UBR5T75X.js.map
422
+ //# sourceMappingURL=chunk-ADXMZ3TT.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 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":";;;AAAO,IAAM,eAAe,CAAC,qBAAqB,KAAK;AAChD,IAAM,mBAAmB,CAAC,QAAQ,OAAO,QAAQ,KAAK;AACtD,IAAM,iBAAiB;;;ACF9B,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU,SAAS,MAAM,eAAe;AACjD,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAU9B,IAAM,cAAc,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,IAAI;AACzE,IAAM,eAAe,KAAK,aAAa,WAAW;AAClD,IAAM,eAAe,KAAK,aAAa,eAAe;AACtD,IAAM,mBAAmB,KAAK,MAAM,aAAa,KAAK,aAAa,6BAA6B,GAAG,MAAM,CAAC;AAK1G,IAAM,WAAW,KAAK,MAAM,aAAa,KAAK,aAAa,eAAe,GAAG,MAAM,CAAC;AACpF,IAAMA,WAAU,cAAc,YAAY,GAAG;AAE7C,SAAS,YAAY,WAA2B;AAC9C,QAAM,QAAQ,SAAS,QAAQ,SAAS,CAAC,EACtC,YAAY,EACZ,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,oBAAoB,EAAE;AACjC,MAAI,CAAC,SAAS,CAAC,YAAY,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,4DAA4D;AACpH,SAAO;AACT;AAEA,SAAS,kBAAkB,aAA2B;AACpD,MAAI,CAAC,WAAW,WAAW,EAAG;AAC9B,MAAI,CAAC,SAAS,WAAW,EAAE,YAAY,EAAG,OAAM,IAAI,MAAM,wDAAwD;AAClH,MAAI,YAAY,WAAW,EAAE,SAAS,EAAG,OAAM,IAAI,MAAM,0CAA0C;AACrG;AAEA,SAAS,KAAK,WAA6B;AACzC,SAAO,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,EAAE,QAAQ,CAAC,UAAU;AACxE,UAAM,OAAO,KAAK,WAAW,MAAM,IAAI;AACvC,WAAO,MAAM,YAAY,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;AAAA,EACjD,CAAC;AACH;AAEA,SAAS,sBAAsB,WAAmB,cAA4C;AAC5F,aAAW,QAAQ,KAAK,SAAS,GAAG;AAClC,QAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,MAAM,EAAG;AACpD,QAAI,UAAU,aAAa,MAAM,MAAM;AACvC,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,YAAY,EAAG,WAAU,QAAQ,MAAM,KAAK,EAAE,KAAK,KAAK;AACpG,kBAAc,MAAM,OAAO;AAAA,EAC7B;AACF;AAEA,SAAS,UAAU,MAAc,aAA2B;AAC1D,SAAO,KAAK,cAAc,IAAI,GAAG,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAChF;AAEA,SAAS,oBAAoB,aAAqB,SAAiC;AACjF,MAAI,CAAC,QAAQ,QAAS;AACtB,QAAM,YAAY,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK,CAAC;AACxD,MAAI,mBAAmB;AACvB,aAAW,CAAC,MAAM,QAAQ,KAAK,QAAQ,QAAQ,OAAO;AACpD,QAAI,UAAU;AACd,QAAI,SAAS,iBAAiB;AAC5B,gBAAU,QAAQ,QAAQ,6BAA6B,KAAK,SAAS,EAAE;AACvE,yBAAmB,YAAY;AAAA,IACjC;AACA,UAAM,SAAS,KAAK,aAAa,YAAY,IAAI;AACjD,cAAU,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,kBAAc,QAAQ,OAAO;AAAA,EAC/B;AACA,MAAI,CAAC,iBAAkB,OAAM,IAAI,MAAM,4DAA4D;AACrG;AAEA,SAAS,kBAAkB,SAA2B,MAAuC;AAC3F,QAAM,eAAuC;AAAA,IAC3C,oBAAoB,SAAS,SAAS,kBAAkB;AAAA,IACxD,mBAAmB,SAAS,SAAS,iBAAiB;AAAA,IACtD,wBAAwB,SAAS,SAAS,sBAAsB;AAAA,IAChE,GAAG,iBAAiB;AAAA,IACpB,OAAO,SAAS,QAAQ;AAAA,IACxB,aAAa,SAAS,QAAQ,WAAW;AAAA,EAC3C;AACA,QAAM,kBAA0C;AAAA,IAC9C,eAAe,SAAS,YAAY,aAAa;AAAA,IACjD,gBAAgB,SAAS,YAAY,cAAc;AAAA,IACnD,oBAAoB,SAAS,YAAY,kBAAkB;AAAA,IAC3D,wBAAwB,SAAS,YAAY,sBAAsB;AAAA,IACnE,GAAG,iBAAiB;AAAA,IACpB,YAAY,SAAS,YAAY;AAAA,IACjC,MAAM,SAAS,YAAY;AAAA,EAC7B;AACA,QAAM,UAAkC;AAAA,IACtC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AACA,MAAI,QAAQ,gBAAgB,OAAO;AACjC,iBAAa,gBAAgB,IAAI,SAAS,SAAS,gBAAgB;AACnE,iBAAa,OAAO,SAAS,QAAQ;AACrC,iBAAa,mBAAmB,IAAI,SAAS,QAAQ,mBAAmB;AACxE,oBAAgB,eAAe,SAAS,YAAY;AACpD,oBAAgB,MAAM,SAAS,YAAY;AAC3C,oBAAgB,OAAO;AACvB,YAAQ,MAAM;AACd,YAAQ,QAAQ;AAChB,YAAQ,QAAQ;AAAA,EAClB;AACA,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,EAAE,MAAM,qBAAqB;AAAA,IACtC,UAAU;AAAA,MACR,aAAa,QAAQ;AAAA,MACrB,iBAAiB,QAAQ;AAAA,MACzB,QAAQ,QAAQ;AAAA,MAChB,iBAAiB,iBAAiB;AAAA,MAClC,GAAI,QAAQ,UAAU,EAAE,UAAU;AAAA,QAChC,IAAI,QAAQ,QAAQ;AAAA,QACpB,SAAS,QAAQ,QAAQ;AAAA,QACzB,QAAQ,QAAQ,QAAQ;AAAA,QACxB,kBAAkB,QAAQ,QAAQ;AAAA,MACpC,EAAE,IAAI,CAAC;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,SAAS,SAA2B,SAAqD;AAChG,QAAM,QAAQ,CAAC,UAA8B,KAAK,UAAU,OAAO,SAAS,EAAE,CAAC;AAC/E,QAAM,YAAY,CAAC,UAAmB,KAAK,UAAU,KAAK;AAC1D,QAAM,kBAAkB,QAAQ,YAAY,6BAA6B,CAAC,IAAI;AAAA,IAC5E,GAAG,QAAQ,gBAAgB,sBAAsB,UAAU,EAAE,qBAAqB,MAAM,QAAQ,OAAO,CAAC;AAAA,EAC1G;AACA,MAAI,QAAQ,gBAAgB,qBAAqB;AAC/C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,CAAC,GAAG,iBAAiB,GAAI,QAAQ,eAAe,CAAC,+BAA+B,MAAM,QAAQ,YAAY,CAAC,EAAE,IAAI,CAAC,GAAI,EAAE,EAAE,KAAK,IAAI;AAAA,IAC5I;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,IACX,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI,QAAQ,cAAc,QAAQ,UAAU;AAAA,QAC1C,mBAAmB,UAAU,CAAC,EAAE,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,EAAE,SAAS,QAAQ,QAAQ,GAAI,GAAI,QAAQ,iBAAiB,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC,EAAG,CAAC,CAAC,CAAC;AAAA,MAChN,IAAI,CAAC;AAAA,MACL,2BAA2B,MAAM,YAAY,EAAE,EAAE,SAAS,WAAW,CAAC,CAAC;AAAA,MACvE,6BAA6B,MAAM,OAAO,CAAC;AAAA,MAC3C,yBAAyB,MAAM,YAAY,EAAE,EAAE,SAAS,WAAW,CAAC,CAAC;AAAA,MACrE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,SAAS,eAAe,gBAAoD;AAC1E,MAAI,mBAAmB,MAAO,QAAO,CAAC,OAAO,CAAC,SAAS,CAAC;AACxD,MAAI,mBAAmB,OAAQ,QAAO,CAAC,QAAQ,CAAC,CAAC;AACjD,MAAI,mBAAmB,MAAO,QAAO,CAAC,OAAO,CAAC,SAAS,CAAC;AACxD,SAAO,CAAC,QAAQ,CAAC,WAAW,oBAAoB,CAAC;AACnD;AAEA,SAAS,iBAAiB,gBAAgC,QAAwB;AAChF,MAAI,mBAAmB,MAAO,QAAO,WAAW,MAAM;AACtD,MAAI,mBAAmB,MAAO,QAAO,WAAW,MAAM;AACtD,SAAO,GAAG,cAAc,IAAI,MAAM;AACpC;AAEO,SAAS,oBAAoB,WAAmB,gBAAsC;AAC3F,QAAM,CAAC,SAAS,IAAI,IAAI,eAAe,cAAc;AACrD,QAAM,EAAE,kBAAkB,SAAS,GAAG,qBAAqB,IAAI,QAAQ;AACvE,QAAM,SAAS,UAAU,SAAS,MAAM,EAAE,KAAK,WAAW,OAAO,WAAW,KAAK,qBAAqB,CAAC;AACvG,MAAI,OAAO,MAAO,OAAM,IAAI,MAAM,mBAAmB,OAAO,KAAK,OAAO,MAAM,OAAO,EAAE;AACvF,MAAI,OAAO,WAAW,EAAG,OAAM,IAAI,MAAM,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,qBAAqB,OAAO,MAAM,GAAG;AAC5G;AAEA,SAAS,4BAA4B,WAAyB;AAC5D,aAAW,QAAQ,CAAC,gBAAgB,YAAY,aAAa,qBAAqB,kBAAkB,WAAW,GAAG;AAChH,WAAO,KAAK,WAAW,IAAI,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,kBAAkB,WAAmB,QAAsB;AAClE,MAAI,WAAW,eAAgB;AAC/B,QAAM,aAAaA,SAAQ,QAAQ,QAAQ;AAC3C,QAAM,EAAE,kBAAkB,SAAS,GAAG,kBAAkB,IAAI,QAAQ;AACpE,QAAM,SAAS;AAAA,IACb,QAAQ;AAAA,IACR,CAAC,YAAY,SAAS,QAAQ,SAAS,YAAY,SAAS,SAAS;AAAA,IACrE,EAAE,KAAK,WAAW,UAAU,QAAQ,KAAK,kBAAkB;AAAA,EAC7D;AACA,MAAI,OAAO,MAAO,OAAM,IAAI,MAAM,kDAAkD,OAAO,MAAM,OAAO,EAAE;AAC1G,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,SAAS,OAAO,OAAO,UAAU,OAAO,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,GAAG,EAAE;AACpF,UAAM,IAAI,MAAM,UAAU,iCAAiC,MAAM,GAAG;AAAA,EACtE;AACA,QAAM,cAAc;AAAA,IAClB,QAAQ;AAAA,IACR,CAAC,KAAK,WAAW,gCAAgC,CAAC;AAAA,IAClD,EAAE,KAAK,WAAW,UAAU,OAAO;AAAA,EACrC;AACA,MAAI,YAAY,MAAO,OAAM,IAAI,MAAM,+CAA+C,YAAY,MAAM,OAAO,EAAE;AACjH,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,SAAS,OAAO,YAAY,UAAU,YAAY,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,GAAG,EAAE;AAC9F,UAAM,IAAI,MAAM,UAAU,iCAAiC,MAAM,GAAG;AAAA,EACtE;AACA,8BAA4B,SAAS;AACvC;AAEO,SAAS,UAAU,SAAyC;AACjE,QAAM,cAAc,QAAQ,QAAQ,SAAS;AAC7C,oBAAkB,WAAW;AAC7B,QAAM,OAAO,YAAY,WAAW;AACpC,QAAM,SAAS,QAAQ,WAAW;AAClC,YAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC,QAAM,UAAU,KAAK,QAAQ,IAAI,IAAI,aAAa,YAAY,CAAC,EAAE,SAAS,KAAK,CAAC,EAAE;AAClF,MAAI;AACF,cAAU,SAAS,EAAE,MAAM,IAAM,CAAC;AAClC,WAAO,cAAc,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC9D,WAAO,KAAK,SAAS,eAAe,GAAG,EAAE,OAAO,KAAK,CAAC;AACtD,cAAU,UAAU,OAAO;AAC3B,cAAU,gBAAgB,QAAQ,WAAW,IAAI,OAAO;AACxD,wBAAoB,SAAS,OAAO;AACpC,0BAAsB,SAAS;AAAA,MAC7B,gBAAgB;AAAA,MAChB,cAAc,QAAQ;AAAA,MACtB,mBAAmB,QAAQ;AAAA,MAC3B,sBAAsB,QAAQ,gBAAgB,sBAAsB,iCAAiC;AAAA,MACrG,cAAc,iBAAiB,QAAQ,gBAAgB,KAAK;AAAA,MAC5D,gBAAgB,iBAAiB,QAAQ,gBAAgB,OAAO;AAAA,MAChE,qBAAqB,iBAAiB,QAAQ,gBAAgB,QAAQ,gBAAgB,QAAQ,UAAU,SAAS;AAAA,MACjH,iBAAiB,GAAG,iBAAiB,QAAQ,gBAAgB,QAAQ,CAAC;AAAA,MACtE,qBAAqB,QAAQ,UACzB;AAAA;AAAA,qYACA;AAAA,IACN,CAAC;AACD,UAAM,YAAY,KAAK,SAAS,YAAY;AAC5C,QAAI,WAAW,SAAS,EAAG,YAAW,WAAW,KAAK,SAAS,YAAY,CAAC;AAC5E,kBAAc,KAAK,SAAS,cAAc,GAAG,GAAG,KAAK,UAAU,kBAAkB,SAAS,IAAI,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAC7G,sBAAkB,SAAS,QAAQ,MAAM;AACzC,UAAM,MAAM,SAAS,SAAS,IAAI;AAClC,kBAAc,KAAK,SAAS,cAAc,GAAG,IAAI,OAAO;AACxD,QAAI,QAAQ,QAAS,qBAAoB,SAAS,QAAQ,cAAc;AACxE,kBAAc,KAAK,SAAS,YAAY,GAAG,IAAI,OAAO,EAAE,MAAM,IAAM,CAAC;AACrE,cAAU,KAAK,SAAS,YAAY,GAAG,GAAK;AAC5C,QAAI,WAAW,WAAW,EAAG,QAAO,aAAa,EAAE,WAAW,KAAK,CAAC;AACpE,eAAW,SAAS,WAAW;AAC/B,WAAO,EAAE,WAAW,aAAa,aAAa,KAAK;AAAA,EACrD,SAAS,OAAO;AACd,WAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAChD,UAAM;AAAA,EACR;AACF;;;AC7RA,SAAS,kBAAkB;AAC3B,SAAS,cAAAC,aAAY,aAAAC,YAAW,gBAAAC,eAAc,cAAAC,aAAY,iBAAAC,sBAAqB;AAC/E,SAAS,SAAS,cAAc;AAChC,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAE9B,SAAS,mBAAmB;AAqB5B,IAAM,oBAAoB;AAC1B,IAAM,SAAS;AACf,IAAM,SAAS;AACf,IAAM,cAAc;AAEpB,SAAS,YAAoB;AAC3B,QAAM,WAAW,OAAO,QAAQ,IAAI,+BAA+B,EAAE,EAAE,KAAK;AAC5E,MAAI,SAAU,QAAO;AACrB,QAAM,eAAe,QAAQ,aAAa,UACtC,QAAQ,IAAI,eACZ,QAAQ,IAAI,kBAAkBA,MAAK,QAAQ,GAAG,QAAQ;AAC1D,SAAOA,MAAK,gBAAgB,OAAO,GAAG,YAAY,cAAc;AAClE;AAEA,SAAS,YAAY,MAAc,MAAiC;AAClE,EAAAL,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,QAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,EAAAD,eAAc,WAAW,MAAM,EAAE,MAAM,IAAM,CAAC;AAC9C,EAAAD,YAAW,WAAW,IAAI;AAC5B;AAEA,SAAS,aAAa,OAAgD;AACpE,QAAM,QAAQ,OAAO,KAAK,KAAK;AAC/B,SAAO,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI;AAC1E;AAEA,SAAS,WAAW,MAAgC;AAClD,QAAM,UAAU,aAAa,OAAO,KAAK,eAAe,yBAAyB,OAAO,CAAC;AACzF,QAAM,UAAU,aAAa,iBAAiB;AAC9C,MAAI,CAAC,WAAW,KAAK,eAAe,4BAA4B,MAAO,QAAO;AAC9E,SAAO,QAAQ,CAAC,IAAI,QAAQ,CAAC,KACvB,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,QAAQ,CAAC,IAAI,QAAQ,CAAC,KACnD,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,QAAQ,CAAC;AACzF;AAEA,SAAS,gBAAgB,OAAyB;AAChD,QAAM,UAAU;AAChB,MAAI,SAAS,mBAAmB,kCAAkC,CAAC,OAAO,KAAK,QAAQ,QAAQ,KAAK,CAAC,MAAM,QAAQ,QAAQ,SAAS,GAAG;AACrI,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AACA,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,QAAQ,QAAQ,WAAW;AACpC,QAAI,CAAC,YAAY,KAAK,MAAM,EAAE,KAAK,IAAI,IAAI,KAAK,EAAE,KAAK,CAAC,OAAO,KAAK,KAAK,OAAO,KAC3E,CAAC,KAAK,gBAAgB,CAAC,OAAO,KAAK,KAAK,SAAS,MAAM,KAAK,CAAC,OAAO,cAAc,KAAK,SAAS,IAAI,KACpG,KAAK,QAAQ,OAAO,KAAK,KAAK,QAAQ,OAAO,IAAI,OAAO,QAAQ,CAAC,KAAK,QAAQ,cAAc,WAAW,aAAa,GAAG;AAC1H,YAAM,IAAI,MAAM,4DAA4D;AAAA,IAC9E;AACA,QAAI,IAAI,KAAK,EAAE;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAoC;AAC7D,MAAI;AACF,UAAM,SAAS,KAAK,MAAMD,cAAa,MAAM,MAAM,CAAC;AACpD,WAAO,EAAE,GAAI,OAAO,OAAO,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC,GAAI,SAAS,gBAAgB,OAAO,OAAO,EAAE;AAAA,EACnG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,oBAAoB,SAA+D;AACvG,QAAM,OAAOI,MAAK,UAAU,GAAG,cAAc;AAC7C,QAAM,SAASN,YAAW,IAAI,IAAI,kBAAkB,IAAI,IAAI;AAC5D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,cAAc,GAAG,OAAO,GAAG,GAAG;AAAA,MACjE,SAAS,QAAQ,OAAO,EAAE,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,MAC5D,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AACD,QAAI,SAAS,WAAW,OAAO,OAAQ,QAAO,EAAE,SAAS,OAAO,SAAS,MAAM,KAAK;AACpF,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,EAAE;AAC/E,UAAM,UAAU,gBAAgB,MAAM,SAAS,KAAK,CAAC;AACrD,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM,KAAK;AAC7C,gBAAY,MAAM,GAAG,KAAK,UAAU,EAAE,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,GAAI,QAAQ,CAAC,CAAC;AAAA,CAAI;AAC/E,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B,SAAS,OAAO;AACd,QAAI,OAAQ,QAAO,EAAE,SAAS,OAAO,SAAS,MAAM,MAAM;AAC1D,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AACxD,UAAM,IAAI,MAAM,iDAAiD,MAAM,iDAAiD;AAAA,EAC1H;AACF;AAEO,SAAS,oBAAoB,SAAqC;AACvE,SAAO,QAAQ,UAAU,OAAO,UAAU;AAC5C;AAEA,SAAS,gBAAgB,MAAc,MAA0C;AAC/E,MAAI;AACF,UAAM,UAAUE,cAAa,IAAI;AACjC,QAAI,QAAQ,eAAe,KAAK,QAAQ,QAAQ,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,MAAM,KAAK,QAAQ,OAAQ,QAAO;AACnI,gBAAY,OAAO;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,oBAAoB,UAAoB,cAA2C;AAChG,MAAI,CAAC,SAAS,KAAM,OAAM,IAAI,MAAM,6CAA6C;AACjF,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,SAAuB,CAAC;AAC9B,MAAI,OAAO;AACX,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,YAAQ,MAAM;AACd,QAAI,OAAO,gBAAgB,OAAO,IAAI,OAAO,MAAM;AACjD,YAAM,OAAO,OAAO;AACpB,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,QAAM,UAAU,IAAI,WAAW,IAAI;AACnC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,YAAQ,IAAI,OAAO,MAAM;AACzB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAEA,eAAsB,eAAe,SAAiB,SAAkB,IAAwC;AAC9G,MAAI,OAAO,MAAO,OAAM,IAAI,MAAM,2FAA2F;AAC7H,QAAM,OAAO,QAAQ,UAAU,KAAK,CAAC,cAAc,UAAU,OAAO,EAAE;AACtE,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,aAAa,EAAE,2CAA2C;AACrF,MAAI,CAAC,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,aAAa,EAAE,iDAAiD;AACvG,QAAM,OAAOI,MAAK,UAAU,GAAG,YAAY,GAAG,KAAK,QAAQ,MAAM,MAAM;AACvE,MAAI,UAAUN,YAAW,IAAI,IAAI,gBAAgB,MAAM,IAAI,IAAI;AAC/D,MAAI,CAAC,SAAS;AACZ,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,IAAI,IAAI,KAAK,QAAQ,cAAc,GAAG,OAAO,GAAG,GAAG,EAAE,QAAQ,YAAY,QAAQ,GAAM,EAAE,CAAC;AAAA,IACnH,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,gCAAgC,EAAE,iDAAiD;AAAA,IACrG;AACA,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,gCAAgC,EAAE,WAAW,SAAS,MAAM,IAAI;AAClG,UAAM,SAAS,SAAS,QAAQ,IAAI,gBAAgB;AACpD,QAAI,UAAU,OAAO,MAAM,MAAM,KAAK,QAAQ,KAAM,OAAM,IAAI,MAAM,aAAa,EAAE,6CAA6C;AAChI,cAAU,MAAM,oBAAoB,UAAU,KAAK,QAAQ,IAAI;AAC/D,QAAI,QAAQ,eAAe,KAAK,QAAQ,QAAQ,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,MAAM,KAAK,QAAQ,QAAQ;AAC1H,YAAM,IAAI,MAAM,aAAa,EAAE,kCAAkC;AAAA,IACnE;AACA,gBAAY,OAAO;AACnB,gBAAY,MAAM,OAAO;AAAA,EAC3B;AACA,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,SAAS,KAAK;AAAA,IACd,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK,QAAQ;AAAA,IACrB,iBAAiB,QAAQ;AAAA,IACzB,OAAO,YAAY,OAAO;AAAA,EAC5B;AACF;","names":["require","existsSync","mkdirSync","readFileSync","renameSync","writeFileSync","dirname","join"]}
package/dist/cli.js CHANGED
@@ -3,9 +3,11 @@ import {
3
3
  DEFAULT_PRESET,
4
4
  INTEGRATIONS,
5
5
  PACKAGE_MANAGERS,
6
- STARTERS,
7
- createApp
8
- } from "./chunk-UBR5T75X.js";
6
+ compatibleTemplates,
7
+ createApp,
8
+ loadTemplateCatalog,
9
+ selectTemplate
10
+ } from "./chunk-ADXMZ3TT.js";
9
11
 
10
12
  // src/cli.ts
11
13
  import { writeFileSync } from "fs";
@@ -64,7 +66,7 @@ Options:
64
66
  --agent-id <uuid> BFF mode
65
67
  --agent-alias <alias> BFF mode; preferred human-readable selector
66
68
  --agent-version-id <uuid> Optional pinned BFF version
67
- --starter <rag> Include an editable Agent + RAG source package
69
+ --starter <template-id> customer-support or deep-research
68
70
  --no-install
69
71
  --yes Disable prompts; required values must be supplied
70
72
  --help
@@ -123,7 +125,7 @@ async function resolveOptions(args) {
123
125
  let preset = flag(args, "preset");
124
126
  let packageManager = oneOf(flag(args, "package-manager"), PACKAGE_MANAGERS, "package-manager");
125
127
  let baseUrl = flag(args, "base-url");
126
- const starter = oneOf(flag(args, "starter"), STARTERS, "starter");
128
+ const requestedStarter = flag(args, "starter");
127
129
  let install = args.flags["no-install"] !== true;
128
130
  if (!nonInteractive) {
129
131
  directory ||= await requiredText("Where should the app be created?", "my-agents24-app");
@@ -161,6 +163,24 @@ async function resolveOptions(args) {
161
163
  if (!directory) throw new Error("A destination directory is required.");
162
164
  if (urlError) throw new Error(urlError);
163
165
  if (!PRESET.test(preset)) throw new Error("--preset must be a valid Shadcn preset code.");
166
+ let starter;
167
+ if (requestedStarter || !nonInteractive) {
168
+ const { catalog } = await loadTemplateCatalog(baseUrl);
169
+ let selectedId = requestedStarter;
170
+ if (!selectedId) {
171
+ const templates = compatibleTemplates(catalog);
172
+ const result = await select({
173
+ message: "Start with an Agent template?",
174
+ options: [
175
+ { value: "none", label: "No Agent template" },
176
+ ...templates.map((item) => ({ value: item.id, label: item.display_name, hint: item.description }))
177
+ ]
178
+ });
179
+ cancelled(result);
180
+ selectedId = result === "none" ? void 0 : result;
181
+ }
182
+ if (selectedId) starter = await selectTemplate(baseUrl, catalog, selectedId);
183
+ }
164
184
  if (integration === "client-deployment") {
165
185
  const deploymentId = flag(args, "deployment-id");
166
186
  if (deploymentId && !DEPLOYMENT_ID.test(deploymentId)) throw new Error("--deployment-id must be a valid public acd_\u2026 deployment ID.");
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 <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 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 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 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 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":";;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,OAAOA,cAAa;AACpB,SAAS,OAAO,aAAa;;;ACF7B,OAAO,aAAa;AAOpB,IAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,OAAO,cAAc,MAAM,CAAC;AAEpD,SAAS,eAAe,OAAO,QAAQ,KAAK,MAAM,CAAC,GAAoB;AAC5E,QAAM,QAA0C,CAAC;AACjD,MAAI;AACJ,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,WAAW,KAAK,KAAK,KAAK;AAChC,QAAI,CAAC,SAAS,WAAW,IAAI,GAAG;AAC9B,UAAI,UAAW,OAAM,IAAI,MAAM,iDAAiD;AAChF,kBAAY;AACZ;AAAA,IACF;AACA,UAAM,CAAC,SAAS,WAAW,IAAI,SAAS,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7D,QAAI,cAAc,IAAI,OAAO,GAAG;AAC9B,UAAI,gBAAgB,OAAW,OAAM,IAAI,MAAM,KAAK,OAAO,2BAA2B;AACtF,YAAM,OAAO,IAAI;AACjB;AAAA,IACF;AACA,QAAI,CAAC,YAAY,IAAI,OAAO,EAAG,OAAM,IAAI,MAAM,qBAAqB,OAAO,EAAE;AAC7E,UAAM,QAAQ,eAAe,KAAK,QAAQ,CAAC;AAC3C,QAAI,CAAC,SAAS,MAAM,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,KAAK,OAAO,oBAAoB;AACtF,UAAM,OAAO,IAAI;AACjB,QAAI,gBAAgB,OAAW,UAAS;AAAA,EAC1C;AACA,SAAO,EAAE,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,GAAI,MAAM;AACtD;AAEO,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC7CpB,OAAOC,cAAa;AACpB,SAAS,SAAS,UAAU,QAAQ,YAAY;AAahD,IAAM,OAAO;AACb,IAAM,gBAAgB;AACtB,IAAM,SAAS;AAEf,SAAS,UAAa,OAA+C;AACnE,MAAI,SAAS,KAAK,EAAG,OAAM,IAAI,MAAM,yBAAyB;AAChE;AAEA,SAAS,KAAK,MAAuB,MAAkC;AACrE,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,SAAO,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACpD;AAEA,SAAS,MAAwB,OAA2B,SAAuB,OAA8B;AAC/G,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,QAAQ,SAAS,KAAU,EAAG,OAAM,IAAI,MAAM,GAAG,KAAK,oBAAoB,QAAQ,KAAK,IAAI,CAAC,GAAG;AACpG,SAAO;AACT;AAEA,SAAS,yBAAyC;AAChD,QAAM,OAAO,OAAOC,SAAQ,IAAI,yBAAyB,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACzE,SAAO,iBAAiB,SAAS,IAAsB,IAAI,OAAyB;AACtF;AAEA,SAAS,YAAY,OAAmC;AACtD,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,QAAI,WAAW,KAAK,KAAK,KAAK,OAAO,YAAY,OAAO,YAAY,OAAO,UAAU,OAAO,MAAM;AAChG,aAAO;AAAA,IACT;AACA,WAAO,OAAO,aAAa,YAAa,OAAO,aAAa,WAAW,CAAC,aAAa,aAAa,KAAK,EAAE,SAAS,OAAO,QAAQ,IAC7H,SACA;AAAA,EACN,QAAQ;AAAE,WAAO;AAAA,EAAsB;AACzC;AAEA,eAAe,aAAa,SAAiB,cAAkC,UAAmE;AAChJ,QAAM,SAAS,MAAM,KAAK;AAAA,IACxB;AAAA,IACA,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,SAAS,EAAE,EAAE,KAAK;AAC5C,aAAO,aAAa,WAAW,UAAU,IAAI;AAAA,IAC/C;AAAA,EACF,CAAC;AACD,YAAU,MAAM;AAChB,SAAO,OAAO,MAAM,EAAE,KAAK;AAC7B;AAEA,eAAsB,eAAe,MAAkD;AACrF,QAAM,iBAAiB,KAAK,MAAM,QAAQ;AAC1C,MAAI,YAAY,KAAK;AACrB,MAAI,cAAc,MAAM,KAAK,MAAM,aAAa,GAAG,cAAc,aAAa;AAC9E,MAAI,SAAS,KAAK,MAAM,QAAQ;AAChC,MAAI,iBAAiB,MAAM,KAAK,MAAM,iBAAiB,GAAG,kBAAkB,iBAAiB;AAC7F,MAAI,UAAU,KAAK,MAAM,UAAU;AACnC,QAAM,mBAAmB,KAAK,MAAM,SAAS;AAC7C,MAAI,UAAU,KAAK,MAAM,YAAY,MAAM;AAE3C,MAAI,CAAC,gBAAgB;AACnB,kBAAc,MAAM,aAAa,oCAAoC,iBAAiB;AACtF,QAAI,CAAC,aAAa;AAChB,YAAM,SAAS,MAAM,OAAoB,EAAE,SAAS,+BAA+B,SAAS;AAAA,QAC1F,EAAE,OAAO,qBAAqB,OAAO,qBAAqB,MAAM,sCAAsC;AAAA,QACtG,EAAE,OAAO,OAAO,OAAO,cAAc,MAAM,sCAAsC;AAAA,MACnF,EAAE,CAAC;AACH,gBAAU,MAAM;AAAG,oBAAc;AAAA,IACnC;AACA,eAAW,MAAM;AAAA,MACf;AAAA,MACA;AAAA,MACA,CAAC,UAAU,OAAO,KAAK,KAAK,IAAI,SAAY;AAAA,IAC9C;AACA,QAAI,CAAC,gBAAgB;AACnB,YAAM,WAAW,uBAAuB;AACxC,YAAM,SAAS,MAAM,OAAuB,EAAE,SAAS,mBAAmB,cAAc,UAAU,SAAS,iBAAiB,IAAI,CAAC,WAAW,EAAE,OAAO,OAAO,MAAM,EAAE,EAAE,CAAC;AACvK,gBAAU,MAAM;AAAG,uBAAiB;AAAA,IACtC;AACA,QAAI,KAAK,MAAM,YAAY,MAAM,MAAM;AACrC,YAAM,SAAS,MAAM,QAAQ,EAAE,SAAS,yBAAyB,cAAc,KAAK,CAAC;AACrF,gBAAU,MAAM;AAAG,gBAAU;AAAA,IAC/B;AAAA,EACF;AAEA,cAAY,OAAO,aAAa,EAAE,EAAE,KAAK;AACzC,kBAAgB;AAChB,aAAW;AACX,qBAAmB,uBAAuB;AAC1C,cAAY;AACZ,QAAM,WAAW,YAAY,OAAO;AACpC,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,sCAAsC;AACtE,MAAI,SAAU,OAAM,IAAI,MAAM,QAAQ;AACtC,MAAI,CAAC,OAAO,KAAK,MAAM,EAAG,OAAM,IAAI,MAAM,8CAA8C;AAExF,MAAI;AACJ,MAAI,oBAAoB,CAAC,gBAAgB;AACvC,UAAM,EAAE,QAAQ,IAAI,MAAM,oBAAoB,OAAO;AACrD,QAAI,aAAa;AACjB,QAAI,CAAC,YAAY;AACf,YAAM,YAAY,oBAAoB,OAAO;AAC7C,YAAM,SAAS,MAAM,OAAe;AAAA,QAClC,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,QAAQ,OAAO,oBAAoB;AAAA,UAC5C,GAAG,UAAU,IAAI,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,OAAO,KAAK,cAAc,MAAM,KAAK,YAAY,EAAE;AAAA,QACnG;AAAA,MACF,CAAC;AACD,gBAAU,MAAM;AAChB,mBAAa,WAAW,SAAS,SAAY;AAAA,IAC/C;AACA,QAAI,WAAY,WAAU,MAAM,eAAe,SAAS,SAAS,UAAU;AAAA,EAC7E;AAEA,MAAI,gBAAgB,qBAAqB;AACvC,UAAM,eAAe,KAAK,MAAM,eAAe;AAC/C,QAAI,gBAAgB,CAAC,cAAc,KAAK,YAAY,EAAG,OAAM,IAAI,MAAM,kEAA6D;AACpI,WAAO,EAAE,WAAW,aAAa,QAAQ,gBAAgB,SAAS,SAAS,SAAS,aAAa;AAAA,EACnG;AAEA,QAAM,SAAS;AAAA,IACb,SAAS,KAAK,MAAM,UAAU;AAAA,IAC9B,YAAY,KAAK,MAAM,aAAa;AAAA,IACpC,gBAAgB,KAAK,MAAM,kBAAkB;AAAA,EAC/C;AACA,MAAI,OAAO,WAAW,OAAO,WAAY,OAAM,IAAI,MAAM,mDAAmD;AAC5G,MAAI,OAAO,WAAW,CAAC,KAAK,KAAK,OAAO,OAAO,EAAG,OAAM,IAAI,MAAM,kCAAkC;AACpG,MAAI,OAAO,kBAAkB,CAAC,KAAK,KAAK,OAAO,cAAc,EAAG,OAAM,IAAI,MAAM,0CAA0C;AAC1H,MAAI,OAAO,cAAc,CAAC,kCAAkC,KAAK,OAAO,UAAU,GAAG;AACnF,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AACA,SAAO,EAAE,WAAW,aAAa,QAAQ,gBAAgB,SAAS,SAAS,SAAS,GAAG,OAAO;AAChG;;;AFzIA,SAAS,cAAc,gBAAwB,QAAwB;AACrE,MAAI,mBAAmB,MAAO,QAAO,WAAW,MAAM;AACtD,MAAI,mBAAmB,MAAO,QAAO,WAAW,MAAM;AACtD,SAAO,GAAG,cAAc,IAAI,MAAM;AACpC;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,eAAe;AAC5B,MAAI,KAAK,MAAM,MAAM;AACnB,IAAAC,SAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAChC;AAAA,EACF;AACA,QAAM,qBAAqB;AAC3B,QAAM,UAAU,MAAM,eAAe,IAAI;AACzC,QAAM,YAAY,UAAU,OAAO;AACnC,MAAIA,SAAQ,IAAI,6BAA6B;AAC3C,kBAAcA,SAAQ,IAAI,6BAA6B,GAAG,KAAK,UAAU;AAAA,MACvE,GAAG;AAAA,MACH,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ;AAAA,MACrB,gBAAgB,QAAQ;AAAA,IAC1B,CAAC,CAAC;AAAA,GAAM,EAAE,MAAM,IAAM,CAAC;AAAA,EACzB;AACA,QAAM,WAAW,UAAU,UAAU,WAAW,GAAGA,SAAQ,IAAI,CAAC,GAAG,IAC/D,UAAU,UAAU,MAAMA,SAAQ,IAAI,EAAE,SAAS,CAAC,IAClD,UAAU;AACd,QAAM,UAAU,GAAG,QAAQ,cAAc;AACzC,QAAM,mBAAmB,QAAQ,gBAAgB,QAAQ,UAAU;AACnE,QAAM;AAAA,IACJ,WAAW,UAAU,WAAW;AAAA,IAChC;AAAA,IACA,QAAQ,QAAQ;AAAA,IAChB,KAAK,OAAO,GAAG,QAAQ,UAAU,0BAA0B,EAAE;AAAA,IAC7D,KAAK,cAAc,QAAQ,gBAAgB,KAAK,CAAC;AAAA,IACjD,KAAK,cAAc,QAAQ,gBAAgB,OAAO,CAAC;AAAA,IACnD,KAAK,cAAc,QAAQ,gBAAgB,gBAAgB,CAAC;AAAA,EAC9D,EAAE,KAAK,IAAI,CAAC;AACd;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,EAAAA,SAAQ,OAAO,MAAM,wBAAwB,OAAO;AAAA,CAAI;AACxD,EAAAA,SAAQ,WAAW;AACrB,CAAC;","names":["process","process","process","process"]}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,17 @@
1
1
  declare const INTEGRATIONS: readonly ["client-deployment", "bff"];
2
2
  declare const PACKAGE_MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
3
- declare const STARTERS: readonly ["rag"];
4
3
  declare const DEFAULT_PRESET = "b2D1FHzlY";
5
4
  type Integration = (typeof INTEGRATIONS)[number];
6
5
  type PackageManager = (typeof PACKAGE_MANAGERS)[number];
7
- type Starter = (typeof STARTERS)[number];
6
+ type Starter = string;
7
+ type TemplateSelection = {
8
+ id: Starter;
9
+ version: string;
10
+ displayName: string;
11
+ sha256: string;
12
+ catalogRevision: string;
13
+ files: Map<string, string>;
14
+ };
8
15
  type CreateAppOptions = {
9
16
  directory: string;
10
17
  integration: Integration;
@@ -12,7 +19,7 @@ type CreateAppOptions = {
12
19
  packageManager: PackageManager;
13
20
  install: boolean;
14
21
  baseUrl: string;
15
- starter?: Starter;
22
+ starter?: TemplateSelection;
16
23
  deploymentId?: string;
17
24
  agentId?: string;
18
25
  agentAlias?: string;
@@ -26,4 +33,31 @@ type GeneratedApp = {
26
33
  declare function installDependencies(directory: string, packageManager: PackageManager): void;
27
34
  declare function createApp(options: CreateAppOptions): GeneratedApp;
28
35
 
29
- export { type CreateAppOptions, DEFAULT_PRESET, type GeneratedApp, INTEGRATIONS, type Integration, PACKAGE_MANAGERS, type PackageManager, STARTERS, type Starter, createApp, installDependencies };
36
+ type CatalogTemplate = {
37
+ id: string;
38
+ version: string;
39
+ display_name: string;
40
+ description: string;
41
+ compatibility: {
42
+ min_generator_version?: string;
43
+ resource_package_schema?: string;
44
+ };
45
+ archive: {
46
+ sha256: string;
47
+ size: number;
48
+ download_url: string;
49
+ };
50
+ };
51
+ type Catalog = {
52
+ schema_version: "agents24.template-catalog.v1";
53
+ revision: string;
54
+ templates: CatalogTemplate[];
55
+ };
56
+ declare function loadTemplateCatalog(baseUrl: string): Promise<{
57
+ catalog: Catalog;
58
+ live: boolean;
59
+ }>;
60
+ declare function compatibleTemplates(catalog: Catalog): CatalogTemplate[];
61
+ declare function selectTemplate(baseUrl: string, catalog: Catalog, id: string): Promise<TemplateSelection>;
62
+
63
+ export { type CreateAppOptions, DEFAULT_PRESET, type GeneratedApp, INTEGRATIONS, type Integration, PACKAGE_MANAGERS, type PackageManager, type Starter, type TemplateSelection, compatibleTemplates, createApp, installDependencies, loadTemplateCatalog, selectTemplate };
package/dist/index.js CHANGED
@@ -3,16 +3,20 @@ import {
3
3
  DEFAULT_PRESET,
4
4
  INTEGRATIONS,
5
5
  PACKAGE_MANAGERS,
6
- STARTERS,
6
+ compatibleTemplates,
7
7
  createApp,
8
- installDependencies
9
- } from "./chunk-UBR5T75X.js";
8
+ installDependencies,
9
+ loadTemplateCatalog,
10
+ selectTemplate
11
+ } from "./chunk-ADXMZ3TT.js";
10
12
  export {
11
13
  DEFAULT_PRESET,
12
14
  INTEGRATIONS,
13
15
  PACKAGE_MANAGERS,
14
- STARTERS,
16
+ compatibleTemplates,
15
17
  createApp,
16
- installDependencies
18
+ installDependencies,
19
+ loadTemplateCatalog,
20
+ selectTemplate
17
21
  };
18
22
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  import type { ChatHitlPart, ChatMessage as ChatMessageModel } from "@agents24/react"
2
2
  import type { FeedbackReason, HitlResponse } from "@agents24/client"
3
3
  import type { AgentChatRuntimeHitlActionState } from "@agents24/chat-react/runtime"
4
- import { AgentChatDefaultActions, ChatAttachmentRows, type ChatAttachmentContentResolver } from "@agents24/chat-react/ui"
4
+ import { AgentChatDefaultActions, AgentChatUserMessageActionRow, ChatAttachmentRows, type ChatAttachmentContentResolver } from "@agents24/chat-react/ui"
5
5
  import * as React from "react"
6
6
 
7
7
  import { MessageParts } from "./message-parts"
@@ -37,7 +37,7 @@ export function ChatMessage({
37
37
  const isUser = message.role === "user"
38
38
  return (
39
39
  <Message align={isUser ? "end" : "start"}>
40
- <MessageContent>
40
+ <MessageContent className={isUser ? "gap-0" : undefined}>
41
41
  {isUser && message.attachments?.length ? (
42
42
  <ChatAttachmentRows
43
43
  attachments={message.attachments}
@@ -56,6 +56,16 @@ export function ChatMessage({
56
56
  />
57
57
  </BubbleContent>
58
58
  </Bubble>
59
+ {isUser && (
60
+ <AgentChatUserMessageActionRow>
61
+ <AgentChatDefaultActions
62
+ handlers={{
63
+ onCopy: (content) => { void navigator.clipboard.writeText(content).catch(() => undefined) },
64
+ }}
65
+ message={message}
66
+ />
67
+ </AgentChatUserMessageActionRow>
68
+ )}
59
69
  {!isUser && message.isFinal !== false && (
60
70
  <MessageFooter className="gap-1 opacity-70 transition-opacity group-hover/message:opacity-100">
61
71
  <AgentChatDefaultActions
@@ -105,6 +105,22 @@ export function ChatShell({
105
105
  const activeTitle = controller.threads.find((thread) => thread.id === controller.activeThreadId)?.title
106
106
  const hasBlockingError = Boolean(runtime.fatalError && controller.messages.length === 0)
107
107
  const isEmptyState = controller.activeThreadId === null && controller.messages.length === 0 && !hasBlockingError
108
+ const composerOverlayRef = React.useRef<HTMLDivElement>(null)
109
+ const [composerOverlayHeight, setComposerOverlayHeight] = React.useState(192)
110
+
111
+ React.useEffect(() => {
112
+ const overlay = composerOverlayRef.current
113
+ if (!overlay || isEmptyState) return
114
+
115
+ const updateHeight = () => {
116
+ setComposerOverlayHeight(Math.ceil(overlay.getBoundingClientRect().height))
117
+ }
118
+
119
+ updateHeight()
120
+ const resizeObserver = new ResizeObserver(updateHeight)
121
+ resizeObserver.observe(overlay)
122
+ return () => resizeObserver.disconnect()
123
+ }, [isEmptyState])
108
124
 
109
125
  return (
110
126
  <SidebarProvider
@@ -127,7 +143,7 @@ export function ChatShell({
127
143
  />}
128
144
  <SidebarInset className="h-svh min-h-0 overflow-hidden bg-background">
129
145
  <header
130
- className="flex h-12 shrink-0 items-center gap-2 border-b border-border/30 px-3 sm:px-4"
146
+ className="flex h-12 shrink-0 items-center gap-2 border-b border-border/50 px-3 sm:px-4"
131
147
  data-agents24-chat-header=""
132
148
  >
133
149
  <CollapsedHeaderActions onNew={runtime.newThread} />
@@ -184,7 +200,8 @@ export function ChatShell({
184
200
  <MessageScroller className="relative min-h-0 flex-1">
185
201
  <MessageScrollerViewport preserveScrollOnPrepend>
186
202
  <MessageScrollerContent
187
- className="mx-auto w-full max-w-3xl gap-7 px-4 pt-8 pb-16 sm:px-6 sm:pt-12"
203
+ className="mx-auto w-full max-w-3xl gap-3 px-4 pt-8 pb-0 sm:px-6 sm:pt-12"
204
+ style={{ paddingBottom: composerOverlayHeight + 72 }}
188
205
  >
189
206
  {controller.hasOlderTurns && (
190
207
  <Button className="self-center" variant="ghost" size="sm" disabled={controller.isLoadingOlder} onClick={() => { void controller.loadOlder().catch(() => undefined) }}>
@@ -231,36 +248,47 @@ export function ChatShell({
231
248
  </MessageScrollerContent>
232
249
  </MessageScrollerViewport>
233
250
  <TurnOutline messages={controller.messages} />
234
- <MessageScrollerButton />
235
251
  </MessageScroller>
252
+
253
+ <div
254
+ ref={composerOverlayRef}
255
+ className="pointer-events-none absolute inset-x-0 bottom-0 z-30 overflow-visible pt-10"
256
+ style={{
257
+ background: "linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--background) 85%, transparent) 45%, var(--background) 65%, var(--background) 100%)",
258
+ }}
259
+ >
260
+ <div className="pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3">
261
+ <MessageScrollerButton className="!relative !inset-auto !translate-x-0 rtl:!translate-x-0" />
262
+ </div>
263
+ <div className="pointer-events-auto">
264
+ <ChatComposer
265
+ inputContract={runtime.inputContract || LOADING_INPUT_CONTRACT}
266
+ contextWindow={runtime.contextWindow}
267
+ disabled={runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError || isUploading}
268
+ focusKey={controller.activeThreadId}
269
+ isCancelling={isCancelling}
270
+ isRunning={isRunning}
271
+ agentId={runtime.agentId}
272
+ agents={runtime.agents}
273
+ onAgentChange={(agentId) => { void runtime.changeAgent(agentId) }}
274
+ onStop={() => { void controller.cancelRun().catch(() => undefined) }}
275
+ modelId={runtime.modelId}
276
+ models={runtime.models}
277
+ onModelChange={runtime.changeModel}
278
+ onSubmit={(text, files) => runtime.submit({
279
+ text,
280
+ files: files.map((file) => ({
281
+ data: file.source,
282
+ mediaType: file.mediaType,
283
+ name: file.filename,
284
+ })),
285
+ attachments: files,
286
+ })}
287
+ utilityRow="below"
288
+ />
289
+ </div>
290
+ </div>
236
291
  </MessageScrollerProvider>
237
- <div className="relative z-30 shrink-0 bg-background pt-3">
238
- <ChatComposer
239
- inputContract={runtime.inputContract || LOADING_INPUT_CONTRACT}
240
- contextWindow={runtime.contextWindow}
241
- disabled={runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError || isUploading}
242
- focusKey={controller.activeThreadId}
243
- isCancelling={isCancelling}
244
- isRunning={isRunning}
245
- agentId={runtime.agentId}
246
- agents={runtime.agents}
247
- onAgentChange={(agentId) => { void runtime.changeAgent(agentId) }}
248
- onStop={() => { void controller.cancelRun().catch(() => undefined) }}
249
- modelId={runtime.modelId}
250
- models={runtime.models}
251
- onModelChange={runtime.changeModel}
252
- onSubmit={(text, files) => runtime.submit({
253
- text,
254
- files: files.map((file) => ({
255
- data: file.source,
256
- mediaType: file.mediaType,
257
- name: file.filename,
258
- })),
259
- attachments: files,
260
- })}
261
- utilityRow="below"
262
- />
263
- </div>
264
292
  </>
265
293
  )}
266
294
  </section>
@@ -1,73 +1,31 @@
1
+ import { LatestThreadScroller, type LatestThreadScrollerOutlineItem } from "@agents24/chat-react"
1
2
  import type { ChatMessage } from "@agents24/react"
2
- import { useState } from "react"
3
3
 
4
- import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"
5
- import { useMessageScroller, useMessageScrollerVisibility } from "../ui/message-scroller"
6
- import { cn } from "../../lib/utils"
7
-
8
- type Turn = { id: string; label: string; messageIds: string[]; response: string }
9
-
10
- function turnsFromMessages(messages: ChatMessage[]): Turn[] {
11
- return messages.reduce<Turn[]>((turns, message) => {
4
+ function turnsFromMessages(messages: ChatMessage[]): LatestThreadScrollerOutlineItem[] {
5
+ return messages.reduce<LatestThreadScrollerOutlineItem[]>((turns, message) => {
12
6
  if (message.role === "user") {
13
- turns.push({ id: message.id, label: message.content.trim() || `Turn ${turns.length + 1}`, messageIds: [message.id], response: "" })
7
+ turns.push({
8
+ id: message.id,
9
+ label: message.content.trim() || `Turn ${turns.length + 1}`,
10
+ messageIds: [message.id],
11
+ responsePreview: "",
12
+ })
14
13
  } else if (turns.length) {
15
14
  const turn = turns[turns.length - 1]
16
- turn.messageIds.push(message.id)
17
- if (!turn.response) turn.response = message.content.trim()
15
+ turn.messageIds?.push(message.id)
16
+ if (!turn.responsePreview) turn.responsePreview = message.content.trim()
18
17
  }
19
18
  return turns
20
19
  }, [])
21
20
  }
22
21
 
23
22
  export function TurnOutline({ messages }: { messages: ChatMessage[] }) {
24
- const turns = turnsFromMessages(messages)
25
- const { scrollToMessage } = useMessageScroller()
26
- const { currentAnchorId, visibleMessageIds } = useMessageScrollerVisibility()
27
- const visible = new Set(visibleMessageIds)
28
- const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
29
- const focusIndex = hoveredIndex ?? -1
30
- if (turns.length < 2) return null
31
-
32
23
  return (
33
- <nav aria-label="Transcript outline" className="pointer-events-none absolute end-2 top-1/2 z-20 hidden max-h-72 w-14 -translate-y-1/2 md:block xl:end-5">
34
- <div className="pointer-events-auto flex flex-col items-end gap-0.5 py-2">
35
- {turns.map((turn, index) => {
36
- const active = turn.messageIds.some((id) => visible.has(id) || currentAnchorId === id)
37
- const distance = focusIndex >= 0 ? Math.abs(index - focusIndex) : Number.POSITIVE_INFINITY
38
- const barWidth = focusIndex < 0
39
- ? 12
40
- : distance === 0 ? 50 : distance === 1 ? 36 : distance === 2 ? 23 : 10
41
- const barOpacity = focusIndex < 0
42
- ? active ? 1 : 0.4
43
- : distance === 0 ? 1 : distance === 1 ? 0.78 : distance === 2 ? 0.58 : 0.36
44
- return (
45
- <Tooltip key={turn.id}>
46
- <TooltipTrigger asChild>
47
- <button
48
- type="button"
49
- aria-label={`Jump to ${turn.label}`}
50
- className="group relative flex h-2 w-14 items-center justify-end outline-none after:pointer-events-auto after:absolute after:-inset-y-0.5 after:inset-x-0 after:content-['']"
51
- onBlur={() => setHoveredIndex(null)}
52
- onFocus={() => setHoveredIndex(index)}
53
- onMouseEnter={() => setHoveredIndex(index)}
54
- onMouseLeave={() => setHoveredIndex(null)}
55
- onClick={() => scrollToMessage(turn.id, { align: "start", behavior: "smooth" })}
56
- >
57
- <span
58
- className={cn("h-0.5 rounded-full bg-muted-foreground/40 transition-[width,background-color,opacity] duration-150 ease-out group-hover:bg-foreground group-focus-visible:bg-foreground", active && "bg-foreground")}
59
- style={{ opacity: barOpacity, width: barWidth }}
60
- />
61
- </button>
62
- </TooltipTrigger>
63
- <TooltipContent side="left" className="w-64 flex-col items-stretch gap-0 overflow-hidden p-3">
64
- <p className="line-clamp-2 max-w-full wrap-break-word text-sm font-medium">{turn.label}</p>
65
- {turn.response && <p className="mt-1 line-clamp-2 max-w-full wrap-break-word text-xs opacity-70">{turn.response}</p>}
66
- </TooltipContent>
67
- </Tooltip>
68
- )
69
- })}
70
- </div>
71
- </nav>
24
+ <LatestThreadScroller.Outline
25
+ items={turnsFromMessages(messages)}
26
+ minSideGutterForRail={0}
27
+ side="left"
28
+ verticalOffset="3.5rem"
29
+ />
72
30
  )
73
31
  }
@@ -55,7 +55,7 @@ function MessageScrollerContent({
55
55
  return (
56
56
  <MessageScrollerPrimitive.Content
57
57
  data-slot="message-scroller-content"
58
- className={cn("flex h-max min-h-full flex-col gap-8", className)}
58
+ className={cn("flex h-max min-h-full flex-col gap-3", className)}
59
59
  {...props}
60
60
  />
61
61
  )
@@ -74,7 +74,7 @@ function MessageFooter({ className, ...props }: React.ComponentProps<"div">) {
74
74
  <div
75
75
  data-slot="message-footer"
76
76
  className={cn(
77
- "flex max-w-full min-w-0 items-center px-3.5 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
77
+ "flex max-w-full min-w-0 items-center pl-3.5 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
78
78
  className
79
79
  )}
80
80
  {...props}
@@ -215,7 +215,7 @@ function Sidebar({
215
215
  // Adjust the padding for floating and inset variants.
216
216
  variant === "floating" || variant === "inset"
217
217
  ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
218
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
218
+ : "border-border/50 group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
219
219
  className
220
220
  )}
221
221
  {...props}
@@ -20,7 +20,7 @@
20
20
  "tailwindcss": "^4.1.16"
21
21
  },
22
22
  "source": "packages/agents24-chat-react/scaffold",
23
- "sha256": "05a8b9cb10207bbe4cdf23d40196c020d1c542f2b071edfc618bc8993fa26a00",
23
+ "sha256": "8327db5822a239a119e1dc5e1c6ce8cce9ada218b1baf0a7de32bcfc38f87a14",
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.1.8",
3
+ "version": "0.2.1",
4
4
  "description": "Create a production-ready Agents24 React application.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,6 +33,7 @@
33
33
  "provenance": false
34
34
  },
35
35
  "dependencies": {
36
+ "@agents24/cli": "0.3.3",
36
37
  "@clack/prompts": "1.7.0",
37
38
  "shadcn": "4.13.1"
38
39
  },
package/versions.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "agents24": {
3
3
  "@agents24/client": "^0.2.4",
4
4
  "@agents24/react": "^0.2.4",
5
- "@agents24/chat-react": "^0.5.6",
6
- "@agents24/node": "^0.5.1"
5
+ "@agents24/chat-react": "^0.5.7",
6
+ "@agents24/node": "^0.5.3"
7
7
  },
8
8
  "runtime": {
9
9
  "react": "^19.2.3",
@@ -1 +0,0 @@
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 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 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, 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 if (options.starter) copyLayer(`starters/${options.starter}`, staging);\n replaceTemplateValues(staging, {\n \"__APP_NAME__\": name,\n \"__PACKAGE_ID__\": `pkg_${randomBytes(16).toString(\"hex\")}`,\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"],"mappings":"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","names":["require"]}
@@ -1,12 +0,0 @@
1
- ---
2
- schema: agents24.agent/v1
3
- name: Customer Support Agent
4
- description: Answers questions using the managed knowledge base when relevant.
5
- model: $models.primary
6
- model_selectable: true
7
- tools:
8
- - kind: rag
9
- uses: ../rag/knowledge.yaml
10
- ---
11
-
12
- You are a helpful assistant. Search the knowledge base when it can improve the answer. If the knowledge base has no relevant content, say so plainly and continue with the information available to you.
@@ -1,23 +0,0 @@
1
- schema: agents24.package/v2
2
- package_id: __PACKAGE_ID__
3
- name: __APP_NAME__-rag
4
- description: A conversational Agent backed by a managed Knowledge Store.
5
- resources:
6
- - key: support-agent
7
- path: workflows/main.yaml
8
- - key: support-rag
9
- path: rag/knowledge.yaml
10
- - key: support-store
11
- path: stores/knowledge.yaml
12
- requires:
13
- models:
14
- embedding:
15
- required: true
16
- capability: embedding
17
- match:
18
- canonical_key: openai/text-embedding-3-small
19
- primary:
20
- required: true
21
- capability: chat
22
- match:
23
- canonical_key: openai/gpt-5.6-luna
@@ -1,3 +0,0 @@
1
- # Getting started
2
-
3
- Replace this file with your product knowledge. Files under `knowledge/` are mirrored exactly into the managed Knowledge Store on each apply.
@@ -1,32 +0,0 @@
1
- schema: agents24.rag/v1
2
- name: Customer Support RAG
3
- description: Searches the managed knowledge store.
4
- mode: retrieval
5
- inputs:
6
- text: string
7
- outputs:
8
- results: array
9
- steps:
10
- query:
11
- uses: query_input
12
- embed:
13
- uses: model_embedder
14
- with:
15
- model_id: $models.embedding
16
- search:
17
- uses: vector_search
18
- with:
19
- knowledge_store_id: ../stores/knowledge.yaml
20
- top_k: 5
21
- result:
22
- uses: retrieval_result
23
- flow:
24
- - from: query
25
- to: embed
26
- - from: embed
27
- to: search
28
- - from: search
29
- to: result
30
- tool:
31
- name: Search Knowledge
32
- description: Search the managed knowledge base for relevant information.
@@ -1,12 +0,0 @@
1
- schema: agents24.store/v1
2
- name: Customer Support Knowledge
3
- description: Managed knowledge for customer-support answers.
4
- embedding_model: $models.embedding
5
- chunking:
6
- strategy: recursive
7
- chunk_size: 512
8
- chunk_overlap: 50
9
- retrieval_policy: semantic_only
10
- default_namespace: knowledge
11
- content:
12
- - ../knowledge/**
@@ -1,16 +0,0 @@
1
- schema: agents24.workflow/v1
2
- name: Customer Support Agent
3
- description: Answers questions with an attached knowledge search tool.
4
- inputs:
5
- text: string
6
- outputs:
7
- response: string
8
- entry: assistant
9
- nodes:
10
- assistant:
11
- uses: ../agents/assistant.md
12
- inputs:
13
- - text
14
- flow:
15
- - from: assistant.output_text
16
- to: output.response