@agentskit/cli 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs CHANGED
@@ -2700,6 +2700,311 @@ out
2700
2700
  "README.md": readmeFor(ctx)
2701
2701
  };
2702
2702
  }
2703
+ function expoStarter(ctx) {
2704
+ const deps = {
2705
+ expo: "^54.0.0",
2706
+ "expo-router": "^7.0.0",
2707
+ "expo-secure-store": "^15.0.0",
2708
+ react: "^19.0.0",
2709
+ "react-native": "^0.84.0"
2710
+ };
2711
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2712
+ const adapterCallStr = adapterCall(ctx.provider);
2713
+ const adapterImport2 = ctx.provider === "demo" ? "" : `import { ${PROVIDER_IMPORT[ctx.provider]} } from '@agentskit/adapters'
2714
+ `;
2715
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2716
+ return {
2717
+ "package.json": JSON.stringify(
2718
+ {
2719
+ name: "agentskit-expo-app",
2720
+ version: "1.0.0",
2721
+ main: "expo-router/entry",
2722
+ scripts: {
2723
+ start: "expo start",
2724
+ android: "expo start --android",
2725
+ ios: "expo start --ios",
2726
+ web: "expo start --web"
2727
+ },
2728
+ dependencies: deps,
2729
+ devDependencies: {
2730
+ "@types/react": "^19.0.0",
2731
+ typescript: "^5.5.0"
2732
+ }
2733
+ },
2734
+ null,
2735
+ 2
2736
+ ) + "\n",
2737
+ "app.json": JSON.stringify(
2738
+ {
2739
+ expo: {
2740
+ name: "AgentsKit Expo Starter",
2741
+ slug: "agentskit-expo",
2742
+ scheme: "agentskit",
2743
+ plugins: ["expo-router", "expo-secure-store"],
2744
+ ios: { bundleIdentifier: "com.example.agentskit" },
2745
+ android: { package: "com.example.agentskit" }
2746
+ }
2747
+ },
2748
+ null,
2749
+ 2
2750
+ ) + "\n",
2751
+ "tsconfig.json": JSON.stringify(
2752
+ { extends: "expo/tsconfig.base", compilerOptions: { strict: true } },
2753
+ null,
2754
+ 2
2755
+ ) + "\n",
2756
+ "app/_layout.tsx": `import { Stack } from 'expo-router'
2757
+ import { AuthProvider } from '../lib/auth'
2758
+
2759
+ export default function RootLayout() {
2760
+ return (
2761
+ <AuthProvider>
2762
+ <Stack />
2763
+ </AuthProvider>
2764
+ )
2765
+ }
2766
+ `,
2767
+ "app/index.tsx": `import { useState } from 'react'
2768
+ import { Text, TextInput, View, Pressable, ScrollView } from 'react-native'
2769
+ import { useAuth } from '../lib/auth'
2770
+ ${adapterImport2}${demoSnippet}export default function Chat() {
2771
+ const { token, signIn, signOut } = useAuth()
2772
+ const [messages, setMessages] = useState<{ role: 'user' | 'assistant'; content: string }[]>([])
2773
+ const [input, setInput] = useState('')
2774
+
2775
+ if (!token) {
2776
+ return (
2777
+ <View style={{ flex: 1, justifyContent: 'center', padding: 24 }}>
2778
+ <Text style={{ fontSize: 20, marginBottom: 12 }}>Sign in to chat</Text>
2779
+ <Pressable onPress={() => signIn('demo-token')}><Text>Sign in</Text></Pressable>
2780
+ </View>
2781
+ )
2782
+ }
2783
+
2784
+ async function send() {
2785
+ if (!input.trim()) return
2786
+ const next = [...messages, { role: 'user' as const, content: input }]
2787
+ setMessages(next)
2788
+ setInput('')
2789
+ const adapter = ${adapterCallStr}
2790
+ const source = adapter.createSource({ messages: next.map((m, i) => ({
2791
+ id: String(i), role: m.role, content: m.content,
2792
+ status: 'complete' as const, createdAt: new Date(0),
2793
+ })) })
2794
+ let acc = ''
2795
+ for await (const chunk of source.stream()) {
2796
+ if (chunk.type === 'text') {
2797
+ acc += chunk.content
2798
+ setMessages([...next, { role: 'assistant', content: acc }])
2799
+ }
2800
+ }
2801
+ }
2802
+
2803
+ return (
2804
+ <View style={{ flex: 1, padding: 16 }}>
2805
+ <Pressable onPress={signOut}><Text>Sign out</Text></Pressable>
2806
+ <ScrollView style={{ flex: 1 }}>
2807
+ {messages.map((m, i) => (
2808
+ <Text key={i} style={{ marginVertical: 4 }}>{m.role}: {m.content}</Text>
2809
+ ))}
2810
+ </ScrollView>
2811
+ <TextInput value={input} onChangeText={setInput} onSubmitEditing={send} placeholder="Ask anything\u2026" />
2812
+ </View>
2813
+ )
2814
+ }
2815
+ `,
2816
+ "lib/auth.tsx": `import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'
2817
+ import * as SecureStore from 'expo-secure-store'
2818
+
2819
+ interface AuthValue { token: string | null; signIn: (t: string) => void; signOut: () => void }
2820
+ const AuthCtx = createContext<AuthValue>({ token: null, signIn: () => {}, signOut: () => {} })
2821
+
2822
+ export function AuthProvider({ children }: { children: ReactNode }) {
2823
+ const [token, setToken] = useState<string | null>(null)
2824
+
2825
+ useEffect(() => {
2826
+ SecureStore.getItemAsync('agentskit_token').then(setToken).catch(() => {})
2827
+ }, [])
2828
+
2829
+ return (
2830
+ <AuthCtx.Provider
2831
+ value={{
2832
+ token,
2833
+ signIn: (t) => { SecureStore.setItemAsync('agentskit_token', t); setToken(t) },
2834
+ signOut: () => { SecureStore.deleteItemAsync('agentskit_token'); setToken(null) },
2835
+ }}
2836
+ >
2837
+ {children}
2838
+ </AuthCtx.Provider>
2839
+ )
2840
+ }
2841
+
2842
+ export const useAuth = () => useContext(AuthCtx)
2843
+ `,
2844
+ ".env.example": envExampleFor(ctx.provider),
2845
+ ".gitignore": "node_modules\n.expo\ndist\n.env\n.env.local\n",
2846
+ "README.md": readmeFor(ctx)
2847
+ };
2848
+ }
2849
+ function denoDeployStarter(ctx) {
2850
+ const adapterCallEdge = ctx.provider === "demo" ? "demoAdapter()" : ctx.provider === "ollama" ? `ollama({ model: '${PROVIDER_DEFAULT_MODEL[ctx.provider]}' })` : `${PROVIDER_IMPORT[ctx.provider]}({ apiKey: Deno.env.get('${PROVIDER_ENV_KEY[ctx.provider]}') ?? '', model: '${PROVIDER_DEFAULT_MODEL[ctx.provider]}' })`;
2851
+ const adapterImport2 = ctx.provider === "demo" ? "" : `import { ${PROVIDER_IMPORT[ctx.provider]} } from 'npm:@agentskit/adapters'
2852
+ `;
2853
+ const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
2854
+ return {
2855
+ "deno.json": JSON.stringify(
2856
+ {
2857
+ tasks: {
2858
+ dev: "deno run --allow-net --allow-env --watch main.ts",
2859
+ start: "deno run --allow-net --allow-env main.ts",
2860
+ deploy: "deployctl deploy --project=agentskit-deno main.ts"
2861
+ },
2862
+ imports: {
2863
+ "@agentskit/adapters": "npm:@agentskit/adapters@^0.4.0"
2864
+ }
2865
+ },
2866
+ null,
2867
+ 2
2868
+ ) + "\n",
2869
+ "main.ts": `${adapterImport2}${demoSnippet}const adapter = ${adapterCallEdge}
2870
+
2871
+ Deno.serve(async (request) => {
2872
+ const url = new URL(request.url)
2873
+ if (request.method === 'POST' && url.pathname === '/chat') {
2874
+ const { messages } = await request.json() as { messages: Array<{ role: string; content: string }> }
2875
+ const source = adapter.createSource({ messages: messages.map((m, i) => ({
2876
+ id: String(i), role: m.role as 'user' | 'assistant' | 'system',
2877
+ content: m.content, status: 'complete' as const, createdAt: new Date(0),
2878
+ })) })
2879
+ const stream = new ReadableStream<Uint8Array>({
2880
+ async start(controller) {
2881
+ const encoder = new TextEncoder()
2882
+ for await (const chunk of source.stream()) {
2883
+ if (chunk.type === 'text') controller.enqueue(encoder.encode(chunk.content))
2884
+ }
2885
+ controller.close()
2886
+ },
2887
+ })
2888
+ return new Response(stream, { headers: { 'content-type': 'text/plain; charset=utf-8' } })
2889
+ }
2890
+ return new Response(\`<!doctype html><title>AgentsKit Deno Deploy starter</title>
2891
+ <body><pre>POST /chat with { messages: [...] }</pre></body>\`, {
2892
+ headers: { 'content-type': 'text/html' },
2893
+ })
2894
+ })
2895
+ `,
2896
+ ".env.example": envExampleFor(ctx.provider),
2897
+ ".gitignore": ".env\n.env.local\n",
2898
+ "README.md": readmeFor(ctx)
2899
+ };
2900
+ }
2901
+ function angularStarter(ctx) {
2902
+ const deps = {
2903
+ "@agentskit/angular": "^0.4.0",
2904
+ "@angular/core": "^21.0.0",
2905
+ "@angular/common": "^21.0.0",
2906
+ "@angular/compiler": "^21.0.0",
2907
+ "@angular/platform-browser": "^21.0.0",
2908
+ "@angular/platform-browser-dynamic": "^21.0.0",
2909
+ rxjs: "^7.8.0",
2910
+ "zone.js": "^0.16.1"
2911
+ };
2912
+ if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
2913
+ return {
2914
+ "package.json": JSON.stringify(
2915
+ {
2916
+ name: "agentskit-angular-app",
2917
+ private: true,
2918
+ scripts: {
2919
+ dev: "ng serve",
2920
+ build: "ng build",
2921
+ start: "ng serve"
2922
+ },
2923
+ dependencies: deps,
2924
+ devDependencies: {
2925
+ "@angular/cli": "^21.0.0",
2926
+ "@angular/compiler-cli": "^21.0.0",
2927
+ typescript: "^5.5.0"
2928
+ }
2929
+ },
2930
+ null,
2931
+ 2
2932
+ ) + "\n",
2933
+ "angular.json": JSON.stringify(
2934
+ {
2935
+ $schema: "./node_modules/@angular/cli/lib/config/schema.json",
2936
+ version: 1,
2937
+ projects: {
2938
+ app: {
2939
+ projectType: "application",
2940
+ root: "",
2941
+ sourceRoot: "src",
2942
+ prefix: "ak",
2943
+ architect: {
2944
+ build: {
2945
+ builder: "@angular/build:application",
2946
+ options: { browser: "src/main.ts", tsConfig: "tsconfig.json", index: "src/index.html" }
2947
+ },
2948
+ serve: { builder: "@angular/build:dev-server", options: { buildTarget: "app:build" } }
2949
+ }
2950
+ }
2951
+ }
2952
+ },
2953
+ null,
2954
+ 2
2955
+ ) + "\n",
2956
+ "tsconfig.json": JSON.stringify(
2957
+ {
2958
+ compilerOptions: {
2959
+ target: "ES2022",
2960
+ module: "preserve",
2961
+ moduleResolution: "bundler",
2962
+ strict: true,
2963
+ experimentalDecorators: true,
2964
+ useDefineForClassFields: false,
2965
+ lib: ["ES2022", "DOM"]
2966
+ },
2967
+ include: ["src/**/*.ts"]
2968
+ },
2969
+ null,
2970
+ 2
2971
+ ) + "\n",
2972
+ "src/index.html": `<!doctype html>
2973
+ <html><head><title>AgentsKit Angular</title></head>
2974
+ <body><ak-root></ak-root></body></html>
2975
+ `,
2976
+ "src/main.ts": `import { bootstrapApplication } from '@angular/platform-browser'
2977
+ import 'zone.js'
2978
+ import { AppComponent } from './app'
2979
+
2980
+ bootstrapApplication(AppComponent)
2981
+ `,
2982
+ "src/app.ts": `import { Component, signal } from '@angular/core'
2983
+ import { CommonModule } from '@angular/common'
2984
+
2985
+ @Component({
2986
+ selector: 'ak-root',
2987
+ standalone: true,
2988
+ imports: [CommonModule],
2989
+ template: \`
2990
+ <main style="max-width: 640px; margin: 2rem auto;">
2991
+ <h1>AgentsKit \xB7 Angular standalone</h1>
2992
+ <p>Wire @agentskit/angular here. See the docs for the chat service binding.</p>
2993
+ <p>Counter (sanity): {{ count() }}</p>
2994
+ <button (click)="bump()">+1</button>
2995
+ </main>
2996
+ \`,
2997
+ })
2998
+ export class AppComponent {
2999
+ readonly count = signal(0)
3000
+ bump() { this.count.update(n => n + 1) }
3001
+ }
3002
+ `,
3003
+ ".env.example": envExampleFor(ctx.provider),
3004
+ ".gitignore": "node_modules\ndist\n.angular\n.env\n.env.local\n",
3005
+ "README.md": readmeFor(ctx)
3006
+ };
3007
+ }
2703
3008
  function readmeFor(ctx) {
2704
3009
  const installCmd = ctx.pm === "npm" ? "npm install" : `${ctx.pm} install`;
2705
3010
  const runCmd = ctx.pm === "npm" ? "npm run dev" : `${ctx.pm} dev`;
@@ -2745,7 +3050,10 @@ var TEMPLATE_FN = {
2745
3050
  nuxt: nuxtStarter,
2746
3051
  "vite-ink": viteInkStarter,
2747
3052
  "cloudflare-workers": cloudflareWorkersStarter,
2748
- bun: bunStarter
3053
+ bun: bunStarter,
3054
+ expo: expoStarter,
3055
+ "deno-deploy": denoDeployStarter,
3056
+ angular: angularStarter
2749
3057
  };
2750
3058
  async function writeStarterProject(options) {
2751
3059
  const ctx = {
@@ -2793,6 +3101,9 @@ ${kleur__default.default.bold().green("\u25B2")} ${kleur__default.default.bold("
2793
3101
  { name: "Vite + Ink (terminal, hot-reload)", value: "vite-ink", description: "Ink chat with vite-node hot reload" },
2794
3102
  { name: "Cloudflare Workers (edge)", value: "cloudflare-workers", description: "Edge runtime with itty-router + streaming" },
2795
3103
  { name: "Bun server", value: "bun", description: "Bun.serve with hot reload" },
3104
+ { name: "Deno Deploy", value: "deno-deploy", description: "Deno.serve with deployctl + npm: imports" },
3105
+ { name: "Expo + auth (mobile)", value: "expo", description: "expo-router + expo-secure-store + chat screen" },
3106
+ { name: "Angular standalone", value: "angular", description: "Angular 21 standalone bootstrap with @agentskit/angular" },
2796
3107
  { name: "Runtime (headless agent, no UI)", value: "runtime", description: "Autonomous task \u2192 result" },
2797
3108
  { name: "Multi-agent (planner + delegates)", value: "multi-agent", description: "Supervisor pattern, ready to extend" }
2798
3109
  ]
@@ -2901,7 +3212,7 @@ function printNextSteps(options) {
2901
3212
 
2902
3213
  // src/commands/init.ts
2903
3214
  function registerInitCommand(program) {
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) => {
3215
+ 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|deno-deploy|expo|angular|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) => {
2905
3216
  const isCi = !process.stdout.isTTY || rawOptions.yes || rawOptions.template;
2906
3217
  let resolved;
2907
3218
  if (isCi) {