create-agents24-app 0.1.4 → 0.1.6
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 +5 -3
- package/dist/{chunk-3P5GRBYP.js → chunk-UBR5T75X.js} +15 -7
- package/dist/chunk-UBR5T75X.js.map +1 -0
- package/dist/cli.js +9 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/scaffold/src/app.tsx +2 -1
- package/dist/scaffold/src/chat.css +13 -1
- package/dist/scaffold/src/components/chat/chat-composer.tsx +65 -9
- package/dist/scaffold/src/components/chat/chat-shell.tsx +14 -4
- package/dist/scaffold/src/components/ui/button.tsx +1 -1
- package/dist/scaffold/src/components/ui/dropdown-menu.tsx +1 -1
- package/dist/scaffold/src/components/ui/sidebar.tsx +4 -4
- package/dist/scaffold-manifest.json +1 -1
- package/package.json +1 -1
- package/templates/integrations/bff/server/env.ts +56 -4
- package/templates/integrations/bff/server/index.ts +3 -2
- package/templates/integrations/bff/src/main.tsx +2 -1
- package/templates/starters/rag/agents24/agents/assistant.md +1 -0
- package/templates/starters/rag/agents24/agents24.yaml +1 -0
- package/templates/starters/rag/agents24/rag/knowledge.yaml +1 -1
- package/versions.json +4 -4
- package/dist/chunk-3P5GRBYP.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# create-agents24-app
|
|
2
2
|
|
|
3
|
-
Last Updated: 2026-08-
|
|
3
|
+
Last Updated: 2026-08-20
|
|
4
4
|
|
|
5
5
|
Create a canonical Agents24 React/Vite application:
|
|
6
6
|
|
|
@@ -16,11 +16,13 @@ cd my-agent
|
|
|
16
16
|
agents24 prepare ./agents24
|
|
17
17
|
agents24 plan ./agents24
|
|
18
18
|
agents24 apply ./agents24
|
|
19
|
+
agents24 status ./agents24
|
|
19
20
|
agents24 publish ./agents24
|
|
21
|
+
agents24 status ./agents24
|
|
20
22
|
pnpm dev
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
The starter adds an editable Package V2 source tree containing an Agent, managed Knowledge Store, retrieval pipeline, and managed content. `apply` creates or updates drafts
|
|
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.
|
|
24
26
|
|
|
25
27
|
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.
|
|
26
28
|
|
|
@@ -49,4 +51,4 @@ points to the same canonical scaffold and package guidance.
|
|
|
49
51
|
|
|
50
52
|
## Maintainer development
|
|
51
53
|
|
|
52
|
-
From the repository root, `pnpm dev:agents24` incrementally prepares the current coordinated package train, publishes it to an ephemeral loopback registry, launches this packed interactive CLI, installs the selected app, and starts it. Use `pnpm dev:agents24 -- --rag` to generate the RAG starter and run its `agents24/` package through the locally packed `prepare`, `plan`, and `
|
|
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`.
|
|
@@ -110,8 +110,9 @@ function generatedManifest(options, name) {
|
|
|
110
110
|
devDependencies
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
-
function envFiles(options) {
|
|
113
|
+
function envFiles(options, appName) {
|
|
114
114
|
const value = (input) => JSON.stringify(String(input || ""));
|
|
115
|
+
const jsonValue = (input) => JSON.stringify(input);
|
|
115
116
|
const baseUrlOverride = options.baseUrl === "https://api.agents24.dev" ? [] : [
|
|
116
117
|
`${options.integration === "client-deployment" ? "VITE_" : ""}AGENTS24_BASE_URL=${value(options.baseUrl)}`
|
|
117
118
|
];
|
|
@@ -125,8 +126,11 @@ function envFiles(options) {
|
|
|
125
126
|
example: [
|
|
126
127
|
"# AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override",
|
|
127
128
|
"AGENTS24_API_KEY=your_server_only_api_key",
|
|
128
|
-
"
|
|
129
|
-
|
|
129
|
+
"# agentVersion accepts draft, latest, or an exact published version such as v1",
|
|
130
|
+
'AGENTS24_AGENTS=[{"agentAlias":"your-agent-alias","agentVersion":"v1"}]',
|
|
131
|
+
"# agentId remains supported instead of agentAlias when UUID configuration is preferred",
|
|
132
|
+
"AGENTS24_INTEGRATION_ID=generate_one_stable_random_value",
|
|
133
|
+
"AGENTS24_INTEGRATION_NAME=your_app_name # optional",
|
|
130
134
|
"# AGENTS24_RUNTIME_TARGET=draft # optional server-only override",
|
|
131
135
|
"SESSION_COOKIE_SECRET=generate_at_least_32_random_bytes",
|
|
132
136
|
"PORT=3001",
|
|
@@ -134,8 +138,11 @@ function envFiles(options) {
|
|
|
134
138
|
].join("\n"),
|
|
135
139
|
local: [
|
|
136
140
|
...baseUrlOverride,
|
|
137
|
-
...options.
|
|
138
|
-
|
|
141
|
+
...options.agentAlias || options.agentId ? [
|
|
142
|
+
`AGENTS24_AGENTS=${jsonValue([{ ...options.agentAlias ? { agentAlias: options.agentAlias } : { agentId: options.agentId }, ...options.agentVersionId ? { agentVersionId: options.agentVersionId } : {} }])}`
|
|
143
|
+
] : [],
|
|
144
|
+
`AGENTS24_INTEGRATION_ID=${value(randomBytes(24).toString("base64url"))}`,
|
|
145
|
+
`AGENTS24_INTEGRATION_NAME=${value(appName)}`,
|
|
139
146
|
`SESSION_COOKIE_SECRET=${value(randomBytes(32).toString("base64url"))}`,
|
|
140
147
|
"PORT=3001",
|
|
141
148
|
""
|
|
@@ -207,6 +214,7 @@ function createApp(options) {
|
|
|
207
214
|
if (options.starter) copyLayer(`starters/${options.starter}`, staging);
|
|
208
215
|
replaceTemplateValues(staging, {
|
|
209
216
|
"__APP_NAME__": name,
|
|
217
|
+
"__PACKAGE_ID__": `pkg_${randomBytes(16).toString("hex")}`,
|
|
210
218
|
"__PRESET__": options.preset,
|
|
211
219
|
"__INTEGRATION__": options.integration,
|
|
212
220
|
"__CONNECT_SOURCE__": options.integration === "client-deployment" ? " __AGENTS24_CONNECT_SOURCE__" : "",
|
|
@@ -223,7 +231,7 @@ This repository includes an editable Resource Package in \`agents24/\`. For a BF
|
|
|
223
231
|
writeFileSync(join(staging, "package.json"), `${JSON.stringify(generatedManifest(options, name), null, 2)}
|
|
224
232
|
`);
|
|
225
233
|
applyShadcnPreset(staging, options.preset);
|
|
226
|
-
const env = envFiles(options);
|
|
234
|
+
const env = envFiles(options, name);
|
|
227
235
|
writeFileSync(join(staging, ".env.example"), env.example);
|
|
228
236
|
if (options.install) installDependencies(staging, options.packageManager);
|
|
229
237
|
writeFileSync(join(staging, ".env.local"), env.local, { mode: 384 });
|
|
@@ -245,4 +253,4 @@ export {
|
|
|
245
253
|
installDependencies,
|
|
246
254
|
createApp
|
|
247
255
|
};
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
256
|
+
//# sourceMappingURL=chunk-UBR5T75X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/generator.ts"],"sourcesContent":["export const INTEGRATIONS = [\"client-deployment\", \"bff\"] as const;\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const;\nexport const STARTERS = [\"rag\"] as const;\nexport const DEFAULT_PRESET = \"b2D1FHzlY\";\n\nexport type Integration = (typeof INTEGRATIONS)[number];\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\nexport type Starter = (typeof STARTERS)[number];\n\nexport type CreateAppOptions = {\n directory: string;\n integration: Integration;\n preset: string;\n packageManager: PackageManager;\n install: boolean;\n baseUrl: string;\n starter?: Starter;\n deploymentId?: string;\n agentId?: string;\n 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"]}
|
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
PACKAGE_MANAGERS,
|
|
6
6
|
STARTERS,
|
|
7
7
|
createApp
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UBR5T75X.js";
|
|
9
9
|
|
|
10
10
|
// src/cli.ts
|
|
11
11
|
import { writeFileSync } from "fs";
|
|
@@ -21,6 +21,7 @@ var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
|
21
21
|
"base-url",
|
|
22
22
|
"deployment-id",
|
|
23
23
|
"agent-id",
|
|
24
|
+
"agent-alias",
|
|
24
25
|
"agent-version-id",
|
|
25
26
|
"starter"
|
|
26
27
|
]);
|
|
@@ -61,6 +62,7 @@ Options:
|
|
|
61
62
|
--base-url <url>
|
|
62
63
|
--deployment-id <acd_...> Client deployment mode
|
|
63
64
|
--agent-id <uuid> BFF mode
|
|
65
|
+
--agent-alias <alias> BFF mode; preferred human-readable selector
|
|
64
66
|
--agent-version-id <uuid> Optional pinned BFF version
|
|
65
67
|
--starter <rag> Include an editable Agent + RAG source package
|
|
66
68
|
--no-install
|
|
@@ -166,11 +168,14 @@ async function resolveOptions(args) {
|
|
|
166
168
|
}
|
|
167
169
|
const fields = {
|
|
168
170
|
agentId: flag(args, "agent-id"),
|
|
171
|
+
agentAlias: flag(args, "agent-alias"),
|
|
169
172
|
agentVersionId: flag(args, "agent-version-id")
|
|
170
173
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
if (fields.agentId && fields.agentAlias) throw new Error("Use either --agent-id or --agent-alias, not both.");
|
|
175
|
+
if (fields.agentId && !UUID.test(fields.agentId)) throw new Error("--agent-id must be a valid UUID.");
|
|
176
|
+
if (fields.agentVersionId && !UUID.test(fields.agentVersionId)) throw new Error("--agent-version-id must be a valid UUID.");
|
|
177
|
+
if (fields.agentAlias && !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(fields.agentAlias)) {
|
|
178
|
+
throw new Error("--agent-alias must be lowercase kebab-case.");
|
|
174
179
|
}
|
|
175
180
|
return { directory, integration, preset, packageManager, install, baseUrl, starter, ...fields };
|
|
176
181
|
}
|
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-version-id\",\n \"starter\",\n]);\nconst BOOLEAN_FLAGS = new Set([\"yes\", \"no-install\", \"help\"]);\n\nexport function parseArguments(argv = process.argv.slice(2)): ParsedArguments {\n const flags: Record<string, string | boolean> = {};\n let directory: string | undefined;\n for (let index = 0; index < argv.length; index += 1) {\n const argument = argv[index] || \"\";\n if (!argument.startsWith(\"--\")) {\n if (directory) throw new Error(\"Only one destination directory may be provided.\");\n directory = argument;\n continue;\n }\n const [rawName, inlineValue] = argument.slice(2).split(\"=\", 2);\n if (BOOLEAN_FLAGS.has(rawName)) {\n if (inlineValue !== undefined) throw new Error(`--${rawName} does not accept a value.`);\n flags[rawName] = true;\n continue;\n }\n if (!VALUE_FLAGS.has(rawName)) throw new Error(`Unknown option: --${rawName}`);\n const value = inlineValue ?? argv[index + 1];\n if (!value || value.startsWith(\"--\")) throw new Error(`--${rawName} requires a value.`);\n flags[rawName] = value;\n if (inlineValue === undefined) index += 1;\n }\n return { ...(directory ? { directory } : {}), flags };\n}\n\nexport const HELP = `Create an Agents24 React application.\n\nUsage:\n npm create agents24-app@latest [directory] [options]\n\nOptions:\n --integration <client-deployment|bff>\n --preset <shadcn-preset-code> Defaults to b2D1FHzlY\n --package-manager <pnpm|npm|yarn|bun>\n --base-url <url>\n --deployment-id <acd_...> Client deployment mode\n --agent-id <uuid> BFF mode\n --agent-version-id <uuid> Optional pinned BFF version\n --starter <rag> Include an editable Agent + RAG source package\n --no-install\n --yes Disable prompts; required values must be supplied\n --help\n\nRun agents24 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 agentVersionId: flag(args, \"agent-version-id\"),\n };\n for (const [name, value] of Object.entries(fields)) {\n if (!value) continue;\n if (!UUID.test(value)) throw new Error(`--${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)} must be a valid UUID.`);\n }\n return { directory, integration, preset, packageManager, install, baseUrl, starter, ...fields } as CreateAppOptions;\n}\n"],"mappings":"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","names":["process","process","process","process"]}
|
|
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"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ export type Agents24ChatAppProps = {
|
|
|
30
30
|
onModelChange?: (modelId: string) => void
|
|
31
31
|
identity?: Agents24ChatIdentity
|
|
32
32
|
components?: Agents24ChatScaffoldComponents
|
|
33
|
+
sidebar?: React.ReactNode
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export type Agents24ChatScaffoldComponents = {
|
|
@@ -58,7 +59,7 @@ function RuntimeChat({
|
|
|
58
59
|
),
|
|
59
60
|
})
|
|
60
61
|
|
|
61
|
-
return <ChatShell components={components} identity={identity} runtime={runtime} />
|
|
62
|
+
return <ChatShell components={components} identity={identity} runtime={runtime} sidebar={props.sidebar} />
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export function App(props: Agents24ChatAppProps) {
|
|
@@ -10,12 +10,24 @@
|
|
|
10
10
|
[data-agents24-theme-root],
|
|
11
11
|
[data-agents24-theme-root] * {
|
|
12
12
|
box-sizing: border-box;
|
|
13
|
+
-ms-overflow-style: none;
|
|
14
|
+
scrollbar-width: none;
|
|
15
|
+
--tw-inset-ring-shadow: 0 0 #0000 !important;
|
|
16
|
+
--tw-ring-shadow: 0 0 #0000 !important;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
[data-agents24-theme-root] ::-webkit-scrollbar {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-agents24-theme-root] :focus-visible {
|
|
24
|
+
outline: none !important;
|
|
13
25
|
}
|
|
14
26
|
|
|
15
27
|
[data-agents24-theme-root] .a24-message-response {
|
|
16
28
|
max-width: 100%;
|
|
17
29
|
min-width: 0;
|
|
18
|
-
padding-inline:
|
|
30
|
+
padding-inline: 6px;
|
|
19
31
|
width: 100%;
|
|
20
32
|
}
|
|
21
33
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { ArrowUp, LoaderCircle, Mic, Square, X } from "lucide-react"
|
|
1
|
+
import { ArrowUp, ChevronDown, LoaderCircle, Mic, Square, X } from "lucide-react"
|
|
2
2
|
import * as React from "react"
|
|
3
3
|
import { AgentChatContextStatus, useAudioRecorder } from "@agents24/chat-react/ui"
|
|
4
4
|
import { canonicalInputMimeType, inputMimeTypes, validateAgentChatSubmission, type AgentChatInputContract } from "@agents24/chat-react/runtime"
|
|
5
5
|
import type { ContextWindow } from "@agents24/client/protocol"
|
|
6
6
|
|
|
7
7
|
import { Button } from "../ui/button"
|
|
8
|
+
import {
|
|
9
|
+
DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem,
|
|
10
|
+
DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger,
|
|
11
|
+
} from "../ui/dropdown-menu"
|
|
8
12
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"
|
|
9
13
|
import { Textarea } from "../ui/textarea"
|
|
10
14
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"
|
|
@@ -14,12 +18,16 @@ type ChatComposerProps = {
|
|
|
14
18
|
inputContract: AgentChatInputContract
|
|
15
19
|
disabled?: boolean
|
|
16
20
|
contextWindow?: ContextWindow | null
|
|
21
|
+
focusKey?: string | null
|
|
17
22
|
forceExpanded?: boolean
|
|
18
23
|
isCancelling?: boolean
|
|
19
24
|
isRunning: boolean
|
|
25
|
+
agentId: string | null
|
|
26
|
+
agents: Array<{ id: string; label: string }>
|
|
20
27
|
modelId: string | null
|
|
21
28
|
models: Array<{ id: string; label: string }>
|
|
22
29
|
onModelChange: (modelId: string) => void
|
|
30
|
+
onAgentChange: (agentId: string) => void
|
|
23
31
|
onStop: () => void
|
|
24
32
|
onSubmit: (text: string, files: File[]) => Promise<void>
|
|
25
33
|
utilityRow?: "inline" | "below"
|
|
@@ -29,12 +37,16 @@ export function ChatComposer({
|
|
|
29
37
|
inputContract,
|
|
30
38
|
disabled,
|
|
31
39
|
contextWindow,
|
|
40
|
+
focusKey,
|
|
32
41
|
forceExpanded = false,
|
|
33
42
|
isCancelling = false,
|
|
34
43
|
isRunning,
|
|
44
|
+
agentId,
|
|
45
|
+
agents,
|
|
35
46
|
modelId,
|
|
36
47
|
models,
|
|
37
48
|
onModelChange,
|
|
49
|
+
onAgentChange,
|
|
38
50
|
onStop,
|
|
39
51
|
onSubmit,
|
|
40
52
|
utilityRow = "inline",
|
|
@@ -49,6 +61,11 @@ export function ChatComposer({
|
|
|
49
61
|
const attachmentMimeTypes = inputMimeTypes(inputContract)
|
|
50
62
|
const allowAttachments = attachmentMimeTypes.length > 0
|
|
51
63
|
const recordingAllowed = inputContract.modalities.audio.recording_enabled
|
|
64
|
+
React.useEffect(() => {
|
|
65
|
+
if (disabled || isRunning) return
|
|
66
|
+
const frame = window.requestAnimationFrame(() => textareaRef.current?.focus({ preventScroll: true }))
|
|
67
|
+
return () => window.cancelAnimationFrame(frame)
|
|
68
|
+
}, [disabled, focusKey, isRunning])
|
|
52
69
|
const addRecording = React.useCallback((file: File) => {
|
|
53
70
|
draftRevisionRef.current += 1
|
|
54
71
|
setFiles((current) => [...current, file])
|
|
@@ -61,13 +78,11 @@ export function ChatComposer({
|
|
|
61
78
|
files.map((file) => ({ data: file, mediaType: file.type })),
|
|
62
79
|
)
|
|
63
80
|
|
|
81
|
+
const selectedAgent = agents.find((item) => item.id === agentId)
|
|
82
|
+
const selectedModel = models.find((item) => item.id === modelId)
|
|
64
83
|
const modelSelector = models.length > 0 ? (
|
|
65
84
|
<div className="w-fit max-w-40">
|
|
66
|
-
<Select
|
|
67
|
-
disabled={disabled || isRunning}
|
|
68
|
-
onValueChange={onModelChange}
|
|
69
|
-
value={modelId || undefined}
|
|
70
|
-
>
|
|
85
|
+
<Select disabled={disabled || isRunning} onValueChange={onModelChange} value={modelId || undefined}>
|
|
71
86
|
<SelectTrigger aria-label="Runtime model">
|
|
72
87
|
<SelectValue placeholder="Model" />
|
|
73
88
|
</SelectTrigger>
|
|
@@ -77,6 +92,47 @@ export function ChatComposer({
|
|
|
77
92
|
</Select>
|
|
78
93
|
</div>
|
|
79
94
|
) : null
|
|
95
|
+
const runtimeSelector = agents.length > 1 ? (
|
|
96
|
+
<DropdownMenu>
|
|
97
|
+
<DropdownMenuTrigger asChild>
|
|
98
|
+
<Button
|
|
99
|
+
variant="ghost"
|
|
100
|
+
className="h-8 max-w-64 gap-1.5 bg-transparent px-2.5 text-xs font-normal hover:bg-muted/40 disabled:opacity-100"
|
|
101
|
+
disabled={disabled || isRunning}
|
|
102
|
+
aria-label="Runtime configuration"
|
|
103
|
+
>
|
|
104
|
+
<span className="truncate">
|
|
105
|
+
{[selectedAgent?.label, selectedModel?.label].filter(Boolean).join(" · ") || "Runtime"}
|
|
106
|
+
</span>
|
|
107
|
+
<ChevronDown className="size-3.5 text-muted-foreground" />
|
|
108
|
+
</Button>
|
|
109
|
+
</DropdownMenuTrigger>
|
|
110
|
+
<DropdownMenuContent align="start" className="w-64 rounded-lg">
|
|
111
|
+
<DropdownMenuSub>
|
|
112
|
+
<DropdownMenuSubTrigger className="rounded-lg">
|
|
113
|
+
<span>Agent</span><span className="ml-auto max-w-32 truncate text-muted-foreground">{selectedAgent?.label}</span>
|
|
114
|
+
</DropdownMenuSubTrigger>
|
|
115
|
+
<DropdownMenuSubContent className="w-56 rounded-lg">
|
|
116
|
+
<DropdownMenuRadioGroup value={agentId || undefined} onValueChange={onAgentChange}>
|
|
117
|
+
{agents.map((agent) => <DropdownMenuRadioItem className="rounded-lg" key={agent.id} value={agent.id}>{agent.label}</DropdownMenuRadioItem>)}
|
|
118
|
+
</DropdownMenuRadioGroup>
|
|
119
|
+
</DropdownMenuSubContent>
|
|
120
|
+
</DropdownMenuSub>
|
|
121
|
+
{models.length > 0 ? (
|
|
122
|
+
<DropdownMenuSub>
|
|
123
|
+
<DropdownMenuSubTrigger className="rounded-lg">
|
|
124
|
+
<span>Model</span><span className="ml-auto max-w-32 truncate text-muted-foreground">{selectedModel?.label}</span>
|
|
125
|
+
</DropdownMenuSubTrigger>
|
|
126
|
+
<DropdownMenuSubContent className="max-h-64 w-56 rounded-lg">
|
|
127
|
+
<DropdownMenuRadioGroup value={modelId || undefined} onValueChange={onModelChange}>
|
|
128
|
+
{models.map((model) => <DropdownMenuRadioItem className="rounded-lg" key={model.id} value={model.id}>{model.label}</DropdownMenuRadioItem>)}
|
|
129
|
+
</DropdownMenuRadioGroup>
|
|
130
|
+
</DropdownMenuSubContent>
|
|
131
|
+
</DropdownMenuSub>
|
|
132
|
+
) : null}
|
|
133
|
+
</DropdownMenuContent>
|
|
134
|
+
</DropdownMenu>
|
|
135
|
+
) : modelSelector
|
|
80
136
|
const hasContextWindow = Number.isFinite(Number(contextWindow?.max_tokens)) && Number(contextWindow?.max_tokens) > 0
|
|
81
137
|
const showUtilityRow = utilityRow === "below"
|
|
82
138
|
|
|
@@ -185,7 +241,7 @@ export function ChatComposer({
|
|
|
185
241
|
/>
|
|
186
242
|
<div className="agents24-composer-actions flex items-center gap-1">
|
|
187
243
|
{utilityRow === "inline" ? <AgentChatContextStatus contextWindow={contextWindow} /> : null}
|
|
188
|
-
{utilityRow === "inline" ?
|
|
244
|
+
{utilityRow === "inline" ? runtimeSelector : null}
|
|
189
245
|
{recordingAllowed ? (
|
|
190
246
|
<Button
|
|
191
247
|
variant={recorder.isRecording ? "default" : "ghost"}
|
|
@@ -224,11 +280,11 @@ export function ChatComposer({
|
|
|
224
280
|
</div>
|
|
225
281
|
{showUtilityRow ? (
|
|
226
282
|
<div
|
|
227
|
-
aria-hidden={!
|
|
283
|
+
aria-hidden={!runtimeSelector && !hasContextWindow ? "true" : undefined}
|
|
228
284
|
className="mt-2 flex min-h-8 items-center justify-between gap-2 px-1"
|
|
229
285
|
data-agents24-chat-composer-utility=""
|
|
230
286
|
>
|
|
231
|
-
<div className="min-w-0">{
|
|
287
|
+
<div className="min-w-0">{runtimeSelector}</div>
|
|
232
288
|
<AgentChatContextStatus contextWindow={contextWindow} />
|
|
233
289
|
</div>
|
|
234
290
|
) : null}
|
|
@@ -87,10 +87,12 @@ export function ChatShell({
|
|
|
87
87
|
components,
|
|
88
88
|
identity,
|
|
89
89
|
runtime,
|
|
90
|
+
sidebar,
|
|
90
91
|
}: {
|
|
91
92
|
components?: Agents24ChatScaffoldComponents
|
|
92
93
|
identity: Agents24ChatIdentity
|
|
93
94
|
runtime: AgentChatRuntime
|
|
95
|
+
sidebar?: React.ReactNode
|
|
94
96
|
}) {
|
|
95
97
|
const { controller } = runtime
|
|
96
98
|
const isRunning =
|
|
@@ -111,7 +113,7 @@ export function ChatShell({
|
|
|
111
113
|
data-agents24-chat-layout=""
|
|
112
114
|
>
|
|
113
115
|
<PersistentSidebarTrigger />
|
|
114
|
-
<ThreadSidebar
|
|
116
|
+
{sidebar || <ThreadSidebar
|
|
115
117
|
activeThreadId={controller.activeThreadId}
|
|
116
118
|
hasMore={controller.hasMoreThreads}
|
|
117
119
|
identity={identity}
|
|
@@ -122,7 +124,7 @@ export function ChatShell({
|
|
|
122
124
|
onLoadMore={controller.loadMoreThreads}
|
|
123
125
|
onNew={runtime.newThread}
|
|
124
126
|
onOpen={runtime.openThread}
|
|
125
|
-
/>
|
|
127
|
+
/>}
|
|
126
128
|
<SidebarInset className="h-svh min-h-0 overflow-hidden bg-background">
|
|
127
129
|
<header
|
|
128
130
|
className="flex h-12 shrink-0 items-center gap-2 border-b border-border/30 px-3 sm:px-4"
|
|
@@ -149,10 +151,14 @@ export function ChatShell({
|
|
|
149
151
|
<ChatComposer
|
|
150
152
|
inputContract={runtime.inputContract || LOADING_INPUT_CONTRACT}
|
|
151
153
|
contextWindow={runtime.contextWindow}
|
|
152
|
-
disabled={runtime.isBootstrapping}
|
|
154
|
+
disabled={runtime.isBootstrapping || runtime.isChangingAgent}
|
|
155
|
+
focusKey={controller.activeThreadId}
|
|
153
156
|
forceExpanded
|
|
154
157
|
isCancelling={isCancelling}
|
|
155
158
|
isRunning={isRunning}
|
|
159
|
+
agentId={runtime.agentId}
|
|
160
|
+
agents={runtime.agents}
|
|
161
|
+
onAgentChange={(agentId) => { void runtime.changeAgent(agentId) }}
|
|
156
162
|
onStop={() => { void controller.cancelRun().catch(() => undefined) }}
|
|
157
163
|
modelId={runtime.modelId}
|
|
158
164
|
models={runtime.models}
|
|
@@ -230,9 +236,13 @@ export function ChatShell({
|
|
|
230
236
|
<ChatComposer
|
|
231
237
|
inputContract={runtime.inputContract || LOADING_INPUT_CONTRACT}
|
|
232
238
|
contextWindow={runtime.contextWindow}
|
|
233
|
-
disabled={runtime.isBootstrapping || hasBlockingError}
|
|
239
|
+
disabled={runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError}
|
|
240
|
+
focusKey={controller.activeThreadId}
|
|
234
241
|
isCancelling={isCancelling}
|
|
235
242
|
isRunning={isRunning}
|
|
243
|
+
agentId={runtime.agentId}
|
|
244
|
+
agents={runtime.agents}
|
|
245
|
+
onAgentChange={(agentId) => { void runtime.changeAgent(agentId) }}
|
|
236
246
|
onStop={() => { void controller.cancelRun().catch(() => undefined) }}
|
|
237
247
|
modelId={runtime.modelId}
|
|
238
248
|
models={runtime.models}
|
|
@@ -5,7 +5,7 @@ import { Slot } from "radix-ui"
|
|
|
5
5
|
import { cn } from "../../lib/utils"
|
|
6
6
|
|
|
7
7
|
const buttonVariants = cva(
|
|
8
|
-
"group/button inline-flex shrink-0 items-center justify-center rounded-4xl border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none
|
|
8
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-4xl border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
@@ -246,7 +246,7 @@ function DropdownMenuSubContent({
|
|
|
246
246
|
return (
|
|
247
247
|
<DropdownMenuPrimitive.SubContent
|
|
248
248
|
data-slot="dropdown-menu-sub-content"
|
|
249
|
-
className={cn("z-50 min-w-36 origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-3xl bg-popover p-1.5 text-popover-foreground shadow-lg ring-1 ring-foreground/5 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
|
|
249
|
+
className={cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-36 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-3xl bg-popover p-1.5 text-popover-foreground shadow-lg ring-1 ring-foreground/5 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
|
|
250
250
|
{...props}
|
|
251
251
|
/>
|
|
252
252
|
)
|
|
@@ -451,7 +451,7 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
const sidebarMenuButtonVariants = cva(
|
|
454
|
-
"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-xl px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
|
|
454
|
+
"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-xl px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
|
|
455
455
|
{
|
|
456
456
|
variants: {
|
|
457
457
|
variant: {
|
|
@@ -540,7 +540,7 @@ function SidebarMenuAction({
|
|
|
540
540
|
className={cn(
|
|
541
541
|
"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-xl p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-2 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
|
|
542
542
|
showOnHover &&
|
|
543
|
-
"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
|
|
543
|
+
"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
|
|
544
544
|
className
|
|
545
545
|
)}
|
|
546
546
|
{...props}
|
|
@@ -557,7 +557,7 @@ function SidebarMenuBadge({
|
|
|
557
557
|
data-slot="sidebar-menu-badge"
|
|
558
558
|
data-sidebar="menu-badge"
|
|
559
559
|
className={cn(
|
|
560
|
-
"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-xl px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground",
|
|
560
|
+
"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-xl px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
|
|
561
561
|
className
|
|
562
562
|
)}
|
|
563
563
|
{...props}
|
|
@@ -641,7 +641,7 @@ function SidebarMenuSubButton({
|
|
|
641
641
|
data-size={size}
|
|
642
642
|
data-active={isActive}
|
|
643
643
|
className={cn(
|
|
644
|
-
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-xl px-3 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
|
|
644
|
+
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-xl px-3 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
|
|
645
645
|
className
|
|
646
646
|
)}
|
|
647
647
|
{...props}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"tailwindcss": "^4.1.16"
|
|
21
21
|
},
|
|
22
22
|
"source": "packages/agents24-chat-react/scaffold",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "27ba7f14a44f9cbdf2b1eb1f5d624f168a986e0fcabf6ef76003dab1e346e307",
|
|
24
24
|
"files": [
|
|
25
25
|
"components.json",
|
|
26
26
|
"manifest.json",
|
package/package.json
CHANGED
|
@@ -7,7 +7,8 @@ catch (error) {
|
|
|
7
7
|
|
|
8
8
|
const REQUIRED = [
|
|
9
9
|
"AGENTS24_API_KEY",
|
|
10
|
-
"
|
|
10
|
+
"AGENTS24_AGENTS",
|
|
11
|
+
"AGENTS24_INTEGRATION_ID",
|
|
11
12
|
"SESSION_COOKIE_SECRET",
|
|
12
13
|
] as const;
|
|
13
14
|
|
|
@@ -17,14 +18,65 @@ function required(name: (typeof REQUIRED)[number]): string {
|
|
|
17
18
|
return value;
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
type RuntimeTarget = "draft" | "published";
|
|
22
|
+
type ConfiguredAgent = ({ agentId: string; agentAlias?: never } | { agentAlias: string; agentId?: never }) & { agentVersionId?: string };
|
|
23
|
+
|
|
24
|
+
function agentsConfig(): {
|
|
25
|
+
agents: ConfiguredAgent[];
|
|
26
|
+
impliedRuntimeTarget?: RuntimeTarget;
|
|
27
|
+
} {
|
|
28
|
+
let value: unknown;
|
|
29
|
+
try { value = JSON.parse(required("AGENTS24_AGENTS")); } catch { throw new Error("AGENTS24_AGENTS must be valid JSON."); }
|
|
30
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 50) throw new Error("AGENTS24_AGENTS must contain between one and 50 Agents.");
|
|
31
|
+
|
|
32
|
+
const impliedTargets = new Set<RuntimeTarget>();
|
|
33
|
+
const agents = value.map((item): ConfiguredAgent => {
|
|
34
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) throw new Error("AGENTS24_AGENTS entries must be objects.");
|
|
35
|
+
const record = item as Record<string, unknown>;
|
|
36
|
+
const agentId = String(record.agentId || "").trim();
|
|
37
|
+
const agentAlias = String(record.agentAlias || "").trim();
|
|
38
|
+
const agentVersion = String(record.agentVersion ?? "").trim().toLowerCase();
|
|
39
|
+
const legacyAgentVersionId = String(record.agentVersionId ?? "").trim();
|
|
40
|
+
if (Boolean(agentId) === Boolean(agentAlias)) throw new Error("Each AGENTS24_AGENTS entry requires exactly one of agentId or agentAlias.");
|
|
41
|
+
if (agentAlias && !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(agentAlias)) throw new Error("Each agentAlias must be lowercase kebab-case.");
|
|
42
|
+
if (agentVersion && legacyAgentVersionId) throw new Error("Use either agentVersion or legacy agentVersionId, not both.");
|
|
43
|
+
|
|
44
|
+
if (agentVersion && !/^(?:draft|latest|v[1-9]\d*|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i.test(agentVersion)) {
|
|
45
|
+
throw new Error("Each AGENTS24_AGENTS agentVersion must be draft, latest, a published label such as v1, or a UUID.");
|
|
46
|
+
}
|
|
47
|
+
if (legacyAgentVersionId && !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(legacyAgentVersionId)) {
|
|
48
|
+
throw new Error("Each legacy agentVersionId must be a UUID.");
|
|
49
|
+
}
|
|
50
|
+
const selector = agentVersion || legacyAgentVersionId;
|
|
51
|
+
if (selector === "draft") impliedTargets.add("draft");
|
|
52
|
+
else if (selector) impliedTargets.add("published");
|
|
53
|
+
|
|
54
|
+
const agentVersionId = selector && !["draft", "latest"].includes(selector) ? selector : undefined;
|
|
55
|
+
return agentAlias
|
|
56
|
+
? { agentAlias, ...(agentVersionId ? { agentVersionId } : {}) }
|
|
57
|
+
: { agentId, ...(agentVersionId ? { agentVersionId } : {}) };
|
|
58
|
+
});
|
|
59
|
+
const selectors = agents.map((agent) => "agentAlias" in agent ? `alias:${agent.agentAlias}` : `id:${agent.agentId}`);
|
|
60
|
+
if (new Set(selectors).size !== agents.length) throw new Error("AGENTS24_AGENTS must contain unique selectors.");
|
|
61
|
+
if (impliedTargets.size > 1) throw new Error("AGENTS24_AGENTS cannot mix draft selectors with latest or pinned published selectors.");
|
|
62
|
+
return { agents, impliedRuntimeTarget: impliedTargets.values().next().value };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const parsedAgents = agentsConfig();
|
|
66
|
+
const explicitRuntimeTarget = String(process.env.AGENTS24_RUNTIME_TARGET || "").trim() || undefined;
|
|
67
|
+
if (explicitRuntimeTarget && !["draft", "published"].includes(explicitRuntimeTarget)) throw new Error("AGENTS24_RUNTIME_TARGET must be draft or published.");
|
|
68
|
+
if (explicitRuntimeTarget && parsedAgents.impliedRuntimeTarget && explicitRuntimeTarget !== parsedAgents.impliedRuntimeTarget) {
|
|
69
|
+
throw new Error("AGENTS24_RUNTIME_TARGET conflicts with the configured agentVersion selectors.");
|
|
70
|
+
}
|
|
71
|
+
|
|
20
72
|
export const env = {
|
|
21
73
|
...Object.fromEntries(REQUIRED.map((name) => [name, required(name)])) as Record<(typeof REQUIRED)[number], string>,
|
|
22
74
|
AGENTS24_BASE_URL: String(process.env.AGENTS24_BASE_URL || "https://api.agents24.dev").trim(),
|
|
23
|
-
|
|
24
|
-
AGENTS24_RUNTIME_TARGET:
|
|
75
|
+
AGENTS24_AGENTS: parsedAgents.agents,
|
|
76
|
+
AGENTS24_RUNTIME_TARGET: explicitRuntimeTarget || parsedAgents.impliedRuntimeTarget,
|
|
77
|
+
AGENTS24_INTEGRATION_NAME: String(process.env.AGENTS24_INTEGRATION_NAME || "").trim() || undefined,
|
|
25
78
|
PORT: Number(process.env.PORT || 3001),
|
|
26
79
|
};
|
|
27
80
|
|
|
28
81
|
if (!Number.isInteger(env.PORT) || env.PORT < 1 || env.PORT > 65535) throw new Error("PORT must be a valid port.");
|
|
29
82
|
if (env.SESSION_COOKIE_SECRET.length < 32) throw new Error("SESSION_COOKIE_SECRET must contain at least 32 characters.");
|
|
30
|
-
if (env.AGENTS24_RUNTIME_TARGET && !["draft", "published"].includes(env.AGENTS24_RUNTIME_TARGET)) throw new Error("AGENTS24_RUNTIME_TARGET must be draft or published.");
|
|
@@ -15,8 +15,9 @@ const client = new Agents24({
|
|
|
15
15
|
});
|
|
16
16
|
const agents24 = createAgents24BffHandler({
|
|
17
17
|
client,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
agents: env.AGENTS24_AGENTS,
|
|
19
|
+
integrationId: env.AGENTS24_INTEGRATION_ID,
|
|
20
|
+
integrationName: env.AGENTS24_INTEGRATION_NAME,
|
|
20
21
|
runtimeTarget: (env.AGENTS24_RUNTIME_TARGET || (process.env.NODE_ENV === "production" ? "published" : "draft")) as "draft" | "published",
|
|
21
22
|
resolvePrincipal: resolveAgents24Principal,
|
|
22
23
|
revokePrincipal: (request) => revokeAgents24Principal(request),
|
|
@@ -14,7 +14,8 @@ function GeneratedChatApp() {
|
|
|
14
14
|
<Agents24ChatScaffold
|
|
15
15
|
client={client}
|
|
16
16
|
identity={getHostIdentity()}
|
|
17
|
-
{
|
|
17
|
+
activeThreadId={navigation.activeThreadId}
|
|
18
|
+
onActiveThreadIdChange={navigation.onActiveThreadIdChange}
|
|
18
19
|
completeMcpAuthorization={async ({ completion, serverId }) => {
|
|
19
20
|
if (completion.serverId !== serverId || !completion.connectionId) {
|
|
20
21
|
throw new Error("MCP authorization did not return the expected connection.");
|
package/versions.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"agents24": {
|
|
3
|
-
"@agents24/client": "^0.2.
|
|
4
|
-
"@agents24/react": "^0.2.
|
|
5
|
-
"@agents24/chat-react": "^0.5.
|
|
6
|
-
"@agents24/node": "^0.
|
|
3
|
+
"@agents24/client": "^0.2.3",
|
|
4
|
+
"@agents24/react": "^0.2.3",
|
|
5
|
+
"@agents24/chat-react": "^0.5.5",
|
|
6
|
+
"@agents24/node": "^0.5.0"
|
|
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 agentVersionId?: string;\n};\n\nexport type GeneratedApp = {\n directory: string;\n packageName: string;\n};\n","import { spawnSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n chmodSync,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createRequire } from \"node:module\";\n\nimport { DEFAULT_PRESET, type CreateAppOptions, type GeneratedApp, type PackageManager } from \"./types.js\";\n\ntype Versions = {\n agents24: Record<string, string>;\n runtime: Record<string, string>;\n development: Record<string, string>;\n};\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), \"..\");\nconst templateRoot = join(packageRoot, \"templates\");\nconst scaffoldRoot = join(packageRoot, \"dist/scaffold\");\nconst scaffoldManifest = JSON.parse(readFileSync(join(packageRoot, \"dist/scaffold-manifest.json\"), \"utf8\")) as {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n sha256: string;\n};\nconst versions = JSON.parse(readFileSync(join(packageRoot, \"versions.json\"), \"utf8\")) as Versions;\nconst require = createRequire(import.meta.url);\n\nfunction packageName(directory: string): string {\n const value = basename(resolve(directory))\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\");\n if (!value || !/^[a-z0-9]/.test(value)) throw new Error(\"The destination does not produce a valid npm package name.\");\n return value;\n}\n\nfunction assertDestination(destination: string): void {\n if (!existsSync(destination)) return;\n if (!statSync(destination).isDirectory()) throw new Error(\"The destination already exists and is not a directory.\");\n if (readdirSync(destination).length > 0) throw new Error(\"The destination directory must be empty.\");\n}\n\nfunction walk(directory: string): string[] {\n return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {\n const path = join(directory, entry.name);\n return entry.isDirectory() ? walk(path) : [path];\n });\n}\n\nfunction replaceTemplateValues(directory: string, replacements: Record<string, string>): void {\n for (const file of walk(directory)) {\n if (file.endsWith(\".png\") || file.endsWith(\".ico\")) continue;\n let content = readFileSync(file, \"utf8\");\n for (const [token, value] of Object.entries(replacements)) content = content.split(token).join(value);\n writeFileSync(file, content);\n }\n}\n\nfunction copyLayer(name: string, destination: string): void {\n cpSync(join(templateRoot, name), destination, { recursive: true, force: true });\n}\n\nfunction generatedManifest(options: CreateAppOptions, name: string): Record<string, unknown> {\n const dependencies: Record<string, string> = {\n \"@agents24/client\": versions.agents24[\"@agents24/client\"]!,\n \"@agents24/react\": versions.agents24[\"@agents24/react\"]!,\n \"@agents24/chat-react\": versions.agents24[\"@agents24/chat-react\"]!,\n ...scaffoldManifest.dependencies,\n react: versions.runtime.react!,\n \"react-dom\": versions.runtime[\"react-dom\"]!,\n };\n const devDependencies: Record<string, string> = {\n \"@types/node\": versions.development[\"@types/node\"]!,\n \"@types/react\": versions.development[\"@types/react\"]!,\n \"@types/react-dom\": versions.development[\"@types/react-dom\"]!,\n \"@vitejs/plugin-react\": versions.development[\"@vitejs/plugin-react\"]!,\n ...scaffoldManifest.devDependencies,\n typescript: versions.development.typescript!,\n vite: versions.development.vite!,\n };\n const scripts: Record<string, string> = {\n dev: \"vite\",\n build: \"tsc --noEmit && vite build\",\n preview: \"vite preview\",\n preset: \"node scripts/apply-preset.mjs\",\n };\n if (options.integration === \"bff\") {\n dependencies[\"@agents24/node\"] = versions.agents24[\"@agents24/node\"]!;\n dependencies.hono = versions.runtime.hono!;\n dependencies[\"@hono/node-server\"] = versions.runtime[\"@hono/node-server\"]!;\n devDependencies.concurrently = versions.development.concurrently!;\n devDependencies.tsx = versions.development.tsx!;\n devDependencies.tsup = \"^8.5.1\";\n scripts.dev = \"concurrently -k -n web,bff \\\"vite\\\" \\\"tsx watch server/index.ts\\\"\";\n scripts.build = \"tsc --noEmit && vite build && tsup server/index.ts --format esm --platform node --out-dir server-dist --external @agents24/node --external hono --external @hono/node-server\";\n scripts.start = \"node server-dist/index.js --production\";\n }\n return {\n name,\n private: true,\n version: \"0.0.0\",\n type: \"module\",\n engines: { node: \"^22.0.0 || ^24.0.0\" },\n agents24: {\n integration: options.integration,\n package_manager: options.packageManager,\n preset: options.preset,\n scaffold_sha256: scaffoldManifest.sha256,\n ...(options.starter ? { starter: options.starter } : {}),\n },\n scripts,\n dependencies,\n devDependencies,\n };\n}\n\nfunction envFiles(options: CreateAppOptions): { example: string; local: string } {\n const value = (input: string | undefined) => JSON.stringify(String(input || \"\"));\n const baseUrlOverride = options.baseUrl === \"https://api.agents24.dev\" ? [] : [\n `${options.integration === \"client-deployment\" ? \"VITE_\" : \"\"}AGENTS24_BASE_URL=${value(options.baseUrl)}`,\n ];\n if (options.integration === \"client-deployment\") {\n return {\n example: \"# VITE_AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\\nVITE_AGENTS24_DEPLOYMENT_ID=acd_your_public_deployment_id\\n\",\n local: [...baseUrlOverride, ...(options.deploymentId ? [`VITE_AGENTS24_DEPLOYMENT_ID=${value(options.deploymentId)}`] : []), \"\"].join(\"\\n\"),\n };\n }\n return {\n example: [\n \"# AGENTS24_BASE_URL=http://localhost:8026 # optional advanced override\",\n \"AGENTS24_API_KEY=your_server_only_api_key\",\n \"AGENTS24_AGENT_ID=your_agent_uuid\",\n \"AGENTS24_AGENT_VERSION_ID=\",\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.agentId ? [`AGENTS24_AGENT_ID=${value(options.agentId)}`] : []),\n ...(options.agentVersionId ? [`AGENTS24_AGENT_VERSION_ID=${value(options.agentVersionId)}`] : []),\n `SESSION_COOKIE_SECRET=${value(randomBytes(32).toString(\"base64url\"))}`,\n \"PORT=3001\",\n \"\",\n ].join(\"\\n\"),\n };\n}\n\nfunction installCommand(packageManager: PackageManager): [string, string[]] {\n if (packageManager === \"npm\") return [\"npm\", [\"install\"]];\n if (packageManager === \"yarn\") return [\"yarn\", []];\n if (packageManager === \"bun\") return [\"bun\", [\"install\"]];\n return [\"pnpm\", [\"install\", \"--ignore-workspace\"]];\n}\n\nfunction runScriptCommand(packageManager: PackageManager, script: string): string {\n if (packageManager === \"npm\") return `npm run ${script}`;\n if (packageManager === \"bun\") return `bun run ${script}`;\n return `${packageManager} ${script}`;\n}\n\nexport function installDependencies(directory: string, packageManager: PackageManager): void {\n const [command, args] = installCommand(packageManager);\n const { AGENTS24_API_KEY: _apiKey, ...installerEnvironment } = process.env;\n const result = spawnSync(command, args, { cwd: directory, stdio: \"inherit\", env: installerEnvironment });\n if (result.error) throw new Error(`Could not start ${command}: ${result.error.message}`);\n if (result.status !== 0) throw new Error(`${command} ${args.join(\" \")} failed with exit ${result.status}.`);\n}\n\nfunction clearPresetInstallArtifacts(directory: string): void {\n for (const name of [\"node_modules\", \"bun.lock\", \"bun.lockb\", \"package-lock.json\", \"pnpm-lock.yaml\", \"yarn.lock\"]) {\n rmSync(join(directory, name), { recursive: true, force: true });\n }\n}\n\nfunction applyShadcnPreset(directory: string, preset: string): void {\n if (preset === DEFAULT_PRESET) return;\n const executable = require.resolve(\"shadcn\");\n const { AGENTS24_API_KEY: _apiKey, ...presetEnvironment } = process.env;\n const result = spawnSync(\n process.execPath,\n [executable, \"apply\", preset, \"--yes\", \"--silent\", \"--cwd\", directory],\n { cwd: directory, encoding: \"utf8\", env: presetEnvironment },\n );\n if (result.error) throw new Error(`Could not start Shadcn preset materialization: ${result.error.message}`);\n if (result.status !== 0) {\n const detail = String(result.stderr || result.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Shadcn could not apply preset ${preset}.`);\n }\n const scopeResult = spawnSync(\n process.execPath,\n [join(directory, \"scripts/scope-preset-theme.mjs\")],\n { cwd: directory, encoding: \"utf8\" },\n );\n if (scopeResult.error) throw new Error(`Could not scope the selected Shadcn preset: ${scopeResult.error.message}`);\n if (scopeResult.status !== 0) {\n const detail = String(scopeResult.stderr || scopeResult.stdout || \"\").trim().split(\"\\n\").at(-1);\n throw new Error(detail || `Could not scope Shadcn preset ${preset}.`);\n }\n clearPresetInstallArtifacts(directory);\n}\n\nexport function createApp(options: CreateAppOptions): GeneratedApp {\n const destination = resolve(options.directory);\n assertDestination(destination);\n const name = packageName(destination);\n const parent = dirname(destination);\n mkdirSync(parent, { recursive: true });\n const staging = join(parent, `.${name}.agents24-${randomBytes(6).toString(\"hex\")}`);\n try {\n mkdirSync(staging, { mode: 0o700 });\n cpSync(scaffoldRoot, staging, { recursive: true, force: true });\n rmSync(join(staging, \"manifest.json\"), { force: true });\n copyLayer(\"common\", staging);\n copyLayer(`integrations/${options.integration}`, staging);\n if (options.starter) copyLayer(`starters/${options.starter}`, staging);\n replaceTemplateValues(staging, {\n \"__APP_NAME__\": name,\n \"__PRESET__\": options.preset,\n \"__INTEGRATION__\": options.integration,\n \"__CONNECT_SOURCE__\": options.integration === \"client-deployment\" ? \" __AGENTS24_CONNECT_SOURCE__\" : \"\",\n \"__PM_DEV__\": runScriptCommand(options.packageManager, \"dev\"),\n \"__PM_BUILD__\": runScriptCommand(options.packageManager, \"build\"),\n \"__PM_PRODUCTION__\": runScriptCommand(options.packageManager, options.integration === \"bff\" ? \"start\" : \"preview\"),\n \"__PM_PRESET__\": `${runScriptCommand(options.packageManager, \"preset\")} --`,\n \"__STARTER_SETUP__\": options.starter\n ? `## 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);\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"]}
|