@agentskit/cli 0.8.2 → 0.9.0

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/dist/bin.cjs CHANGED
@@ -2071,6 +2071,635 @@ console.log(\`\\n\u2014 \${result.steps} steps \xB7 \${result.toolCalls.length}
2071
2071
  "README.md": readmeFor(ctx)
2072
2072
  };
2073
2073
  }
2074
+ function buildAdapterServerImport(provider) {
2075
+ if (provider === "demo") return "";
2076
+ return `import { ${PROVIDER_IMPORT[provider]} } from '@agentskit/adapters'
2077
+ `;
2078
+ }
2079
+ function envExampleFor(provider) {
2080
+ const envKey = PROVIDER_ENV_KEY[provider];
2081
+ return envKey ? `${envKey}=
2082
+ ` : "# No API key required for the demo provider\n";
2083
+ }
2084
+ function sveltekitStarter(ctx) {
2085
+ const deps = {
2086
+ "@agentskit/svelte": "^0.4.0",
2087
+ "@sveltejs/kit": "^2.0.0",
2088
+ svelte: "^5.0.0"
2089
+ };
2090
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2091
+ const adapterCallStr = adapterCall(ctx.provider);
2092
+ const adapterImport2 = buildAdapterServerImport(ctx.provider);
2093
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2094
+ return {
2095
+ "package.json": JSON.stringify(
2096
+ {
2097
+ name: "agentskit-sveltekit-app",
2098
+ private: true,
2099
+ type: "module",
2100
+ scripts: {
2101
+ dev: "vite dev",
2102
+ build: "vite build",
2103
+ preview: "vite preview",
2104
+ check: "svelte-check --tsconfig ./tsconfig.json"
2105
+ },
2106
+ dependencies: deps,
2107
+ devDependencies: {
2108
+ "@sveltejs/adapter-auto": "^4.0.0",
2109
+ "@sveltejs/vite-plugin-svelte": "^6.0.0",
2110
+ "svelte-check": "^4.0.0",
2111
+ typescript: "^5.5.0",
2112
+ vite: "^7.0.0"
2113
+ }
2114
+ },
2115
+ null,
2116
+ 2
2117
+ ) + "\n",
2118
+ "svelte.config.js": `import adapter from '@sveltejs/adapter-auto'
2119
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
2120
+
2121
+ export default {
2122
+ preprocess: vitePreprocess(),
2123
+ kit: { adapter: adapter() },
2124
+ }
2125
+ `,
2126
+ "vite.config.ts": `import { sveltekit } from '@sveltejs/kit/vite'
2127
+ import { defineConfig } from 'vite'
2128
+ export default defineConfig({ plugins: [sveltekit()] })
2129
+ `,
2130
+ "tsconfig.json": JSON.stringify(
2131
+ {
2132
+ extends: "./.svelte-kit/tsconfig.json",
2133
+ compilerOptions: {
2134
+ allowJs: true,
2135
+ checkJs: true,
2136
+ esModuleInterop: true,
2137
+ forceConsistentCasingInFileNames: true,
2138
+ resolveJsonModule: true,
2139
+ skipLibCheck: true,
2140
+ sourceMap: true,
2141
+ strict: true,
2142
+ moduleResolution: "bundler"
2143
+ }
2144
+ },
2145
+ null,
2146
+ 2
2147
+ ) + "\n",
2148
+ "src/app.html": `<!doctype html>
2149
+ <html lang="en">
2150
+ <head>
2151
+ <meta charset="utf-8" />
2152
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
2153
+ %sveltekit.head%
2154
+ </head>
2155
+ <body>%sveltekit.body%</body>
2156
+ </html>
2157
+ `,
2158
+ "src/routes/+page.svelte": `<script lang="ts">
2159
+ import { useChat } from '@agentskit/svelte'
2160
+ import '@agentskit/svelte/theme'
2161
+
2162
+ const chat = useChat({ endpoint: '/api/chat' })
2163
+ </script>
2164
+
2165
+ <main>
2166
+ {#each $chat.messages as message (message.id)}
2167
+ <article data-ak-message data-role={message.role}>{message.content}</article>
2168
+ {/each}
2169
+ <form on:submit|preventDefault={() => chat.send($chat.input)}>
2170
+ <input bind:value={$chat.input} />
2171
+ <button>Send</button>
2172
+ </form>
2173
+ </main>
2174
+ `,
2175
+ "src/routes/api/chat/+server.ts": `import type { RequestHandler } from './$types'
2176
+ ${adapterImport2}${demoSnippet}export const POST: RequestHandler = async ({ request }) => {
2177
+ const { messages } = await request.json()
2178
+ const adapter = ${adapterCallStr}
2179
+ const source = adapter.createSource({ messages: messages.map((m: { role: string; content: string }, i: number) => ({
2180
+ id: String(i), role: m.role, content: m.content,
2181
+ status: 'complete' as const, createdAt: new Date(0),
2182
+ })) })
2183
+
2184
+ const stream = new ReadableStream<Uint8Array>({
2185
+ async start(controller) {
2186
+ const encoder = new TextEncoder()
2187
+ for await (const chunk of source.stream()) {
2188
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2189
+ }
2190
+ controller.close()
2191
+ },
2192
+ })
2193
+ return new Response(stream, { headers: { 'content-type': 'text/plain; charset=utf-8' } })
2194
+ }
2195
+ `,
2196
+ ".env.example": envExampleFor(ctx.provider),
2197
+ ".gitignore": "node_modules\n.svelte-kit\nbuild\n.env\n.env.local\n",
2198
+ "README.md": readmeFor(ctx)
2199
+ };
2200
+ }
2201
+ function nuxtStarter(ctx) {
2202
+ const deps = {
2203
+ "@agentskit/vue": "^0.4.0",
2204
+ nuxt: "^4.0.0",
2205
+ vue: "^3.5.0"
2206
+ };
2207
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2208
+ const adapterCallStr = adapterCall(ctx.provider);
2209
+ const adapterImport2 = buildAdapterServerImport(ctx.provider);
2210
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2211
+ return {
2212
+ "package.json": JSON.stringify(
2213
+ {
2214
+ name: "agentskit-nuxt-app",
2215
+ private: true,
2216
+ type: "module",
2217
+ scripts: {
2218
+ dev: "nuxt dev",
2219
+ build: "nuxt build",
2220
+ preview: "nuxt preview",
2221
+ generate: "nuxt generate"
2222
+ },
2223
+ dependencies: deps,
2224
+ devDependencies: { typescript: "^5.5.0" }
2225
+ },
2226
+ null,
2227
+ 2
2228
+ ) + "\n",
2229
+ "nuxt.config.ts": `export default defineNuxtConfig({
2230
+ compatibilityDate: '2026-04-01',
2231
+ modules: [],
2232
+ typescript: { strict: true },
2233
+ })
2234
+ `,
2235
+ "tsconfig.json": JSON.stringify(
2236
+ { extends: "./.nuxt/tsconfig.json" },
2237
+ null,
2238
+ 2
2239
+ ) + "\n",
2240
+ "app.vue": `<script setup lang="ts">
2241
+ import { useChat } from '@agentskit/vue'
2242
+ import '@agentskit/vue/theme'
2243
+
2244
+ const { messages, input, send } = useChat({ endpoint: '/api/chat' })
2245
+ </script>
2246
+
2247
+ <template>
2248
+ <main>
2249
+ <article v-for="message in messages" :key="message.id" :data-role="message.role">
2250
+ {{ message.content }}
2251
+ </article>
2252
+ <form @submit.prevent="send(input)">
2253
+ <input v-model="input" />
2254
+ <button>Send</button>
2255
+ </form>
2256
+ </main>
2257
+ </template>
2258
+ `,
2259
+ "server/api/chat.post.ts": `${adapterImport2}${demoSnippet}export default defineEventHandler(async (event) => {
2260
+ const { messages } = await readBody<{ messages: Array<{ role: string; content: string }> }>(event)
2261
+ const adapter = ${adapterCallStr}
2262
+ const source = adapter.createSource({ messages: messages.map((m, i) => ({
2263
+ id: String(i), role: m.role as 'user' | 'assistant' | 'system',
2264
+ content: m.content, status: 'complete' as const, createdAt: new Date(0),
2265
+ })) })
2266
+
2267
+ setHeader(event, 'content-type', 'text/plain; charset=utf-8')
2268
+ return sendStream(event, new ReadableStream<Uint8Array>({
2269
+ async start(controller) {
2270
+ const encoder = new TextEncoder()
2271
+ for await (const chunk of source.stream()) {
2272
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2273
+ }
2274
+ controller.close()
2275
+ },
2276
+ }))
2277
+ })
2278
+ `,
2279
+ ".env.example": envExampleFor(ctx.provider),
2280
+ ".gitignore": "node_modules\n.nuxt\n.output\n.env\n.env.local\n",
2281
+ "README.md": readmeFor(ctx)
2282
+ };
2283
+ }
2284
+ function viteInkStarter(ctx) {
2285
+ const deps = {
2286
+ "@agentskit/ink": "^0.4.0",
2287
+ ink: "^7.0.0",
2288
+ react: "^19.0.0"
2289
+ };
2290
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2291
+ if (ctx.tools.length > 0) deps["@agentskit/tools"] = "^0.4.0";
2292
+ return {
2293
+ "package.json": JSON.stringify(
2294
+ {
2295
+ name: "agentskit-vite-ink-app",
2296
+ private: true,
2297
+ type: "module",
2298
+ scripts: {
2299
+ dev: "vite-node --watch src/index.tsx",
2300
+ start: "vite-node src/index.tsx",
2301
+ build: "vite build"
2302
+ },
2303
+ dependencies: deps,
2304
+ devDependencies: {
2305
+ "@types/react": "^19.0.0",
2306
+ "vite-node": "^4.0.0",
2307
+ vite: "^7.0.0",
2308
+ typescript: "^5.5.0"
2309
+ }
2310
+ },
2311
+ null,
2312
+ 2
2313
+ ) + "\n",
2314
+ "vite.config.ts": `import { defineConfig } from 'vite'
2315
+ export default defineConfig({
2316
+ build: { ssr: true, target: 'node22', rollupOptions: { input: 'src/index.tsx' } },
2317
+ })
2318
+ `,
2319
+ "tsconfig.json": JSON.stringify(
2320
+ {
2321
+ compilerOptions: {
2322
+ target: "ES2022",
2323
+ module: "ESNext",
2324
+ moduleResolution: "bundler",
2325
+ jsx: "react-jsx",
2326
+ strict: true,
2327
+ noEmit: true,
2328
+ skipLibCheck: true
2329
+ },
2330
+ include: ["src"]
2331
+ },
2332
+ null,
2333
+ 2
2334
+ ) + "\n",
2335
+ "src/index.tsx": `import React from 'react'
2336
+ import { render } from 'ink'
2337
+ import { ChatContainer, InputBar, Message, useChat } from '@agentskit/ink'
2338
+ ${adapterImport(ctx.provider)}${toolImports(ctx.tools)}
2339
+ ${ctx.provider === "demo" ? demoAdapterSnippet() : ""}function App() {
2340
+ const chat = useChat({
2341
+ adapter: ${adapterCall(ctx.provider)},${ctx.tools.length > 0 ? `
2342
+ tools: ${toolList(ctx.tools)},` : ""}
2343
+ })
2344
+
2345
+ return (
2346
+ <ChatContainer>
2347
+ {chat.messages.map(message => (
2348
+ <Message key={message.id} message={message} />
2349
+ ))}
2350
+ <InputBar chat={chat} />
2351
+ </ChatContainer>
2352
+ )
2353
+ }
2354
+
2355
+ render(<App />)
2356
+ `,
2357
+ ".env.example": envExampleFor(ctx.provider),
2358
+ ".gitignore": "node_modules\ndist\n.env\n.env.local\n.agentskit-history.*\n",
2359
+ "README.md": readmeFor(ctx)
2360
+ };
2361
+ }
2362
+ function cloudflareWorkersStarter(ctx) {
2363
+ const deps = {
2364
+ "itty-router": "^5.0.0"
2365
+ };
2366
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2367
+ const adapterCallEdge = ctx.provider === "demo" ? "demoAdapter()" : ctx.provider === "ollama" ? `ollama({ model: '${PROVIDER_DEFAULT_MODEL[ctx.provider]}' })` : `${PROVIDER_IMPORT[ctx.provider]}({ apiKey: env.${PROVIDER_ENV_KEY[ctx.provider]} ?? '', model: '${PROVIDER_DEFAULT_MODEL[ctx.provider]}' })`;
2368
+ const adapterImport2 = buildAdapterServerImport(ctx.provider);
2369
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2370
+ const envKey = PROVIDER_ENV_KEY[ctx.provider];
2371
+ return {
2372
+ "package.json": JSON.stringify(
2373
+ {
2374
+ name: "agentskit-cf-worker",
2375
+ private: true,
2376
+ type: "module",
2377
+ scripts: {
2378
+ dev: "wrangler dev",
2379
+ deploy: "wrangler deploy"
2380
+ },
2381
+ dependencies: deps,
2382
+ devDependencies: {
2383
+ "@cloudflare/workers-types": "^4.0.0",
2384
+ typescript: "^5.5.0",
2385
+ wrangler: "^3.0.0"
2386
+ }
2387
+ },
2388
+ null,
2389
+ 2
2390
+ ) + "\n",
2391
+ "wrangler.toml": `name = "agentskit-cf-worker"
2392
+ main = "src/worker.ts"
2393
+ compatibility_date = "2026-04-01"
2394
+ compatibility_flags = ["nodejs_compat"]
2395
+
2396
+ # Bind D1 + KV when you wire memory:
2397
+ # [[d1_databases]]
2398
+ # binding = "DB"
2399
+ # database_name = "agentskit"
2400
+ #
2401
+ # [[kv_namespaces]]
2402
+ # binding = "KV"
2403
+ # id = "..."
2404
+
2405
+ [vars]
2406
+ ${envKey ? `# Set ${envKey} via 'wrangler secret put ${envKey}'` : "# No API key required for the demo provider"}
2407
+ `,
2408
+ "tsconfig.json": JSON.stringify(
2409
+ {
2410
+ compilerOptions: {
2411
+ target: "ES2022",
2412
+ module: "ESNext",
2413
+ moduleResolution: "bundler",
2414
+ lib: ["ES2022"],
2415
+ types: ["@cloudflare/workers-types"],
2416
+ strict: true,
2417
+ noEmit: true,
2418
+ skipLibCheck: true
2419
+ },
2420
+ include: ["src"]
2421
+ },
2422
+ null,
2423
+ 2
2424
+ ) + "\n",
2425
+ "src/worker.ts": `import { Router } from 'itty-router'
2426
+ ${adapterImport2}
2427
+ ${demoSnippet}interface Env {
2428
+ ${envKey ? `${envKey}: string` : "/* no env vars */"}
2429
+ }
2430
+
2431
+ const router = Router()
2432
+
2433
+ router.post('/chat', async (request: Request, env: Env) => {
2434
+ const { messages } = await request.json() as { messages: Array<{ role: string; content: string }> }
2435
+ const adapter = ${adapterCallEdge}
2436
+ const source = adapter.createSource({ messages: messages.map((m, i) => ({
2437
+ id: String(i), role: m.role as 'user' | 'assistant' | 'system',
2438
+ content: m.content, status: 'complete' as const, createdAt: new Date(0),
2439
+ })) })
2440
+
2441
+ const stream = new ReadableStream<Uint8Array>({
2442
+ async start(controller) {
2443
+ const encoder = new TextEncoder()
2444
+ for await (const chunk of source.stream()) {
2445
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2446
+ }
2447
+ controller.close()
2448
+ },
2449
+ })
2450
+ return new Response(stream, { headers: { 'content-type': 'text/plain; charset=utf-8' } })
2451
+ })
2452
+
2453
+ router.all('*', () => new Response('not found', { status: 404 }))
2454
+
2455
+ export default {
2456
+ fetch: (req: Request, env: Env, ctx: ExecutionContext) => router.handle(req, env, ctx),
2457
+ } satisfies ExportedHandler<Env>
2458
+ `,
2459
+ ".env.example": envExampleFor(ctx.provider),
2460
+ ".gitignore": "node_modules\n.wrangler\n.dev.vars\n.env\n.env.local\n",
2461
+ "README.md": readmeFor(ctx)
2462
+ };
2463
+ }
2464
+ function bunStarter(ctx) {
2465
+ const deps = {};
2466
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2467
+ const adapterCallStr = adapterCall(ctx.provider);
2468
+ const adapterImport2 = buildAdapterServerImport(ctx.provider);
2469
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2470
+ return {
2471
+ "package.json": JSON.stringify(
2472
+ {
2473
+ name: "agentskit-bun-server",
2474
+ private: true,
2475
+ type: "module",
2476
+ scripts: {
2477
+ dev: "bun --hot src/server.ts",
2478
+ start: "bun src/server.ts"
2479
+ },
2480
+ dependencies: deps,
2481
+ devDependencies: { typescript: "^5.5.0" }
2482
+ },
2483
+ null,
2484
+ 2
2485
+ ) + "\n",
2486
+ "tsconfig.json": JSON.stringify(
2487
+ {
2488
+ compilerOptions: {
2489
+ target: "ES2022",
2490
+ module: "ESNext",
2491
+ moduleResolution: "bundler",
2492
+ types: ["bun-types"],
2493
+ strict: true,
2494
+ noEmit: true,
2495
+ skipLibCheck: true
2496
+ },
2497
+ include: ["src"]
2498
+ },
2499
+ null,
2500
+ 2
2501
+ ) + "\n",
2502
+ "src/server.ts": `${adapterImport2}${demoSnippet}const adapter = ${adapterCallStr}
2503
+
2504
+ const server = Bun.serve({
2505
+ port: Number(process.env.PORT ?? 3000),
2506
+ async fetch(request) {
2507
+ const url = new URL(request.url)
2508
+ if (request.method === 'POST' && url.pathname === '/chat') {
2509
+ const { messages } = await request.json() as { messages: Array<{ role: string; content: string }> }
2510
+ const source = adapter.createSource({ messages: messages.map((m, i) => ({
2511
+ id: String(i), role: m.role as 'user' | 'assistant' | 'system',
2512
+ content: m.content, status: 'complete' as const, createdAt: new Date(0),
2513
+ })) })
2514
+ const stream = new ReadableStream<Uint8Array>({
2515
+ async start(controller) {
2516
+ const encoder = new TextEncoder()
2517
+ for await (const chunk of source.stream()) {
2518
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2519
+ }
2520
+ controller.close()
2521
+ },
2522
+ })
2523
+ return new Response(stream, { headers: { 'content-type': 'text/plain; charset=utf-8' } })
2524
+ }
2525
+ if (url.pathname === '/') {
2526
+ return new Response(\`<!doctype html><title>AgentsKit Bun starter</title>
2527
+ <body><pre>POST /chat with { messages: [...] }</pre></body>\`, {
2528
+ headers: { 'content-type': 'text/html' },
2529
+ })
2530
+ }
2531
+ return new Response('not found', { status: 404 })
2532
+ },
2533
+ })
2534
+
2535
+ console.log(\`Listening on http://localhost:\${server.port}\`)
2536
+ `,
2537
+ ".env.example": envExampleFor(ctx.provider),
2538
+ ".gitignore": "node_modules\n.env\n.env.local\nbun.lockb\n",
2539
+ "README.md": readmeFor(ctx)
2540
+ };
2541
+ }
2542
+ function nextjsStarter(ctx) {
2543
+ const deps = {
2544
+ "@agentskit/react": "^0.4.0",
2545
+ next: "^15.0.0",
2546
+ react: "^19.0.0",
2547
+ "react-dom": "^19.0.0"
2548
+ };
2549
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2550
+ if (ctx.tools.length > 0) deps["@agentskit/tools"] = "^0.4.0";
2551
+ const envKey = PROVIDER_ENV_KEY[ctx.provider];
2552
+ const adapter = adapterCall(ctx.provider);
2553
+ const apiAdapterImport = ctx.provider === "demo" ? "" : `import { ${PROVIDER_IMPORT[ctx.provider]} } from '@agentskit/adapters'
2554
+ `;
2555
+ const apiDemoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2556
+ return {
2557
+ "package.json": JSON.stringify(
2558
+ {
2559
+ name: "agentskit-nextjs-app",
2560
+ private: true,
2561
+ type: "module",
2562
+ scripts: {
2563
+ dev: "next dev",
2564
+ build: "next build",
2565
+ start: "next start",
2566
+ lint: "next lint"
2567
+ },
2568
+ dependencies: deps,
2569
+ devDependencies: {
2570
+ "@types/node": "^22.0.0",
2571
+ "@types/react": "^19.0.0",
2572
+ "@types/react-dom": "^19.0.0",
2573
+ typescript: "^5.5.0"
2574
+ }
2575
+ },
2576
+ null,
2577
+ 2
2578
+ ) + "\n",
2579
+ "next.config.mjs": `/** @type {import('next').NextConfig} */
2580
+ const nextConfig = {}
2581
+ export default nextConfig
2582
+ `,
2583
+ "tsconfig.json": JSON.stringify(
2584
+ {
2585
+ compilerOptions: {
2586
+ target: "ES2022",
2587
+ lib: ["dom", "dom.iterable", "ES2022"],
2588
+ allowJs: true,
2589
+ skipLibCheck: true,
2590
+ strict: true,
2591
+ noEmit: true,
2592
+ esModuleInterop: true,
2593
+ module: "ESNext",
2594
+ moduleResolution: "bundler",
2595
+ resolveJsonModule: true,
2596
+ isolatedModules: true,
2597
+ jsx: "preserve",
2598
+ incremental: true,
2599
+ plugins: [{ name: "next" }],
2600
+ paths: { "@/*": ["./*"] }
2601
+ },
2602
+ include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2603
+ exclude: ["node_modules"]
2604
+ },
2605
+ null,
2606
+ 2
2607
+ ) + "\n",
2608
+ "app/layout.tsx": `import type { ReactNode } from 'react'
2609
+ import '@agentskit/react/theme'
2610
+
2611
+ export const metadata = { title: 'AgentsKit \xB7 Next.js Starter' }
2612
+
2613
+ export default function RootLayout({ children }: { children: ReactNode }) {
2614
+ return (
2615
+ <html lang="en">
2616
+ <body>{children}</body>
2617
+ </html>
2618
+ )
2619
+ }
2620
+ `,
2621
+ "app/page.tsx": `'use client'
2622
+
2623
+ import { ChatContainer, InputBar, Message, useChat } from '@agentskit/react'
2624
+ import { genericAdapter } from './chat-adapter'
2625
+
2626
+ export default function Page() {
2627
+ const chat = useChat({ adapter: genericAdapter('/api/chat') })
2628
+
2629
+ return (
2630
+ <main style={{ display: 'grid', placeItems: 'center', minHeight: '100dvh' }}>
2631
+ <ChatContainer>
2632
+ {chat.messages.map(message => (
2633
+ <Message key={message.id} message={message} />
2634
+ ))}
2635
+ <InputBar chat={chat} />
2636
+ </ChatContainer>
2637
+ </main>
2638
+ )
2639
+ }
2640
+ `,
2641
+ "app/chat-adapter.ts": `import { generic } from '@agentskit/adapters'
2642
+
2643
+ export const genericAdapter = (route: string) => generic({
2644
+ fetch: async ({ messages, signal }) => {
2645
+ const response = await fetch(route, {
2646
+ method: 'POST',
2647
+ headers: { 'Content-Type': 'application/json' },
2648
+ body: JSON.stringify({ messages }),
2649
+ signal,
2650
+ })
2651
+ if (!response.body) throw new Error('No body returned from /api/chat')
2652
+ return response
2653
+ },
2654
+ })
2655
+ `,
2656
+ "app/api/chat/route.ts": `${apiAdapterImport}${apiDemoSnippet}export const runtime = 'edge'
2657
+
2658
+ export async function POST(request: Request) {
2659
+ const { messages } = await request.json() as { messages: Array<{ role: string; content: string }> }
2660
+
2661
+ const adapter = ${adapter}
2662
+
2663
+ const source = adapter.createSource({ messages: messages.map((message, index) => ({
2664
+ id: String(index),
2665
+ role: message.role as 'user' | 'assistant' | 'system',
2666
+ content: message.content,
2667
+ status: 'complete' as const,
2668
+ createdAt: new Date(0),
2669
+ })) })
2670
+
2671
+ const stream = new ReadableStream<Uint8Array>({
2672
+ async start(controller) {
2673
+ const encoder = new TextEncoder()
2674
+ try {
2675
+ for await (const chunk of source.stream()) {
2676
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2677
+ }
2678
+ } catch (err) {
2679
+ controller.error(err)
2680
+ return
2681
+ }
2682
+ controller.close()
2683
+ },
2684
+ })
2685
+
2686
+ return new Response(stream, {
2687
+ headers: { 'Content-Type': 'text/plain; charset=utf-8', 'Cache-Control': 'no-cache' },
2688
+ })
2689
+ }
2690
+ `,
2691
+ ".env.example": envKey ? `${envKey}=
2692
+ ` : "# No API key required for the demo provider\n",
2693
+ ".gitignore": `node_modules
2694
+ .next
2695
+ out
2696
+ .env
2697
+ .env.local
2698
+ .agentskit-history.*
2699
+ `,
2700
+ "README.md": readmeFor(ctx)
2701
+ };
2702
+ }
2074
2703
  function readmeFor(ctx) {
2075
2704
  const installCmd = ctx.pm === "npm" ? "npm install" : `${ctx.pm} install`;
2076
2705
  const runCmd = ctx.pm === "npm" ? "npm run dev" : `${ctx.pm} dev`;
@@ -2108,9 +2737,15 @@ ISC
2108
2737
  }
2109
2738
  var TEMPLATE_FN = {
2110
2739
  react: reactStarter,
2740
+ nextjs: nextjsStarter,
2111
2741
  ink: inkStarter,
2112
2742
  runtime: runtimeStarter,
2113
- "multi-agent": multiAgentStarter
2743
+ "multi-agent": multiAgentStarter,
2744
+ sveltekit: sveltekitStarter,
2745
+ nuxt: nuxtStarter,
2746
+ "vite-ink": viteInkStarter,
2747
+ "cloudflare-workers": cloudflareWorkersStarter,
2748
+ bun: bunStarter
2114
2749
  };
2115
2750
  async function writeStarterProject(options) {
2116
2751
  const ctx = {
@@ -2151,7 +2786,13 @@ ${kleur__default.default.bold().green("\u25B2")} ${kleur__default.default.bold("
2151
2786
  default: defaults.template ?? "react",
2152
2787
  choices: [
2153
2788
  { name: "React chat (Vite + browser)", value: "react", description: "Streaming UI with @agentskit/react" },
2789
+ { name: "Next.js chat (App Router + Route Handler)", value: "nextjs", description: "app/api/chat streams to a useChat client" },
2790
+ { name: "SvelteKit chat", value: "sveltekit", description: "@agentskit/svelte client + server route streaming" },
2791
+ { name: "Nuxt chat", value: "nuxt", description: "@agentskit/vue composable + Nitro server route streaming" },
2154
2792
  { name: "Ink chat (terminal UI)", value: "ink", description: "Same chat but in your terminal" },
2793
+ { name: "Vite + Ink (terminal, hot-reload)", value: "vite-ink", description: "Ink chat with vite-node hot reload" },
2794
+ { name: "Cloudflare Workers (edge)", value: "cloudflare-workers", description: "Edge runtime with itty-router + streaming" },
2795
+ { name: "Bun server", value: "bun", description: "Bun.serve with hot reload" },
2155
2796
  { name: "Runtime (headless agent, no UI)", value: "runtime", description: "Autonomous task \u2192 result" },
2156
2797
  { name: "Multi-agent (planner + delegates)", value: "multi-agent", description: "Supervisor pattern, ready to extend" }
2157
2798
  ]
@@ -2260,7 +2901,7 @@ function printNextSteps(options) {
2260
2901
 
2261
2902
  // src/commands/init.ts
2262
2903
  function registerInitCommand(program) {
2263
- program.command("init").description("Generate a starter project. Run with no flags for interactive mode.").option("--template <template>", "Starter template (react|ink|runtime|multi-agent)").option("--dir <directory>", "Target directory", "agentskit-app").option("--provider <provider>", "LLM provider (openai|anthropic|gemini|ollama|demo)").option("--tools <tools>", "Comma-separated tools (web_search,filesystem,shell)").option("--memory <backend>", "Memory backend (none|file|sqlite)").option("--pm <packageManager>", "Package manager (pnpm|npm|yarn|bun)").option("-y, --yes", "Skip interactive prompts; use flag values + defaults").action(async (rawOptions) => {
2904
+ program.command("init").description("Generate a starter project. Run with no flags for interactive mode.").option("--template <template>", "Starter template (react|nextjs|sveltekit|nuxt|ink|vite-ink|cloudflare-workers|bun|runtime|multi-agent)").option("--dir <directory>", "Target directory", "agentskit-app").option("--provider <provider>", "LLM provider (openai|anthropic|gemini|ollama|demo)").option("--tools <tools>", "Comma-separated tools (web_search,filesystem,shell)").option("--memory <backend>", "Memory backend (none|file|sqlite)").option("--pm <packageManager>", "Package manager (pnpm|npm|yarn|bun)").option("-y, --yes", "Skip interactive prompts; use flag values + defaults").action(async (rawOptions) => {
2264
2905
  const isCi = !process.stdout.isTTY || rawOptions.yes || rawOptions.template;
2265
2906
  let resolved;
2266
2907
  if (isCi) {