create-reactive-agent 0.11.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/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # create-reactive-agent
2
+
3
+ Scaffold a new [Reactive Agents](https://docs.reactiveagents.dev) project in seconds.
4
+
5
+ ```bash
6
+ npm create reactive-agent my-agent
7
+ # or
8
+ bun create reactive-agent my-agent
9
+ # or
10
+ pnpm create reactive-agent my-agent
11
+ ```
12
+
13
+ ## Templates
14
+
15
+ | Name | Description |
16
+ | --- | --- |
17
+ | `minimal` | Single-file agent, no tools. Best starting point. |
18
+ | `with-tools` | Agent with built-in tools (filesystem, fetch, math, shell). |
19
+ | `streaming` | Token-by-token streaming via `agent.runStream()`. |
20
+
21
+ ## Providers
22
+
23
+ `anthropic` · `openai` · `google` · `ollama` (local, no key).
24
+
25
+ ## Non-interactive
26
+
27
+ ```bash
28
+ npm create reactive-agent my-agent -- \
29
+ --template=streaming \
30
+ --provider=anthropic \
31
+ --pm=bun \
32
+ --yes
33
+ ```
34
+
35
+ ## Flags
36
+
37
+ | Flag | Description |
38
+ | --- | --- |
39
+ | `--template=<name>` | `minimal` \| `with-tools` \| `streaming` |
40
+ | `--provider=<name>` | `anthropic` \| `openai` \| `google` \| `ollama` |
41
+ | `--pm=<manager>` | `bun` \| `npm` \| `pnpm` \| `yarn` |
42
+ | `--yes` | Skip prompts, accept defaults |
43
+ | `--help` | Show help |
44
+ | `--version` | Print version |
45
+
46
+ ## License
47
+
48
+ MIT
package/dist/cli.js ADDED
@@ -0,0 +1,540 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import * as path2 from "path";
5
+
6
+ // src/lib/scaffold.ts
7
+ import { mkdir, writeFile, readdir } from "fs/promises";
8
+ import { existsSync } from "fs";
9
+ import * as path from "path";
10
+
11
+ // src/lib/provider-config.ts
12
+ function providerEnvVar(p) {
13
+ switch (p) {
14
+ case "anthropic":
15
+ return "ANTHROPIC_API_KEY";
16
+ case "openai":
17
+ return "OPENAI_API_KEY";
18
+ case "google":
19
+ return "GOOGLE_API_KEY";
20
+ case "ollama":
21
+ return null;
22
+ }
23
+ }
24
+ function providerDefaultModel(p) {
25
+ switch (p) {
26
+ case "anthropic":
27
+ return "claude-sonnet-4-6";
28
+ case "openai":
29
+ return "gpt-4o-mini";
30
+ case "google":
31
+ return "gemini-2.0-flash";
32
+ case "ollama":
33
+ return "qwen3:14b";
34
+ }
35
+ }
36
+ function providerDisplayName(p) {
37
+ switch (p) {
38
+ case "anthropic":
39
+ return "Anthropic (Claude)";
40
+ case "openai":
41
+ return "OpenAI";
42
+ case "google":
43
+ return "Google (Gemini)";
44
+ case "ollama":
45
+ return "Ollama (local)";
46
+ }
47
+ }
48
+
49
+ // src/templates/minimal.ts
50
+ var minimalTemplate = {
51
+ name: "minimal",
52
+ description: "Single-file agent. No tools. Best starting point.",
53
+ render: (opts) => {
54
+ return [{ path: "src/index.ts", content: renderIndex(opts) }];
55
+ }
56
+ };
57
+ function renderIndex(opts) {
58
+ const model = providerDefaultModel(opts.provider);
59
+ const envVar = providerEnvVar(opts.provider);
60
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
61
+ console.error("Missing ${envVar} in environment. See .env.example.");
62
+ process.exit(1);
63
+ }` : `// Ollama is local \u2014 no API key required.`;
64
+ return `import { ReactiveAgents } from "reactive-agents";
65
+
66
+ ${envCheck}
67
+
68
+ const agent = await ReactiveAgents.create()
69
+ .withName("assistant")
70
+ .withProvider("${opts.provider}")
71
+ .withModel("${model}")
72
+ .withMaxIterations(3)
73
+ .build();
74
+
75
+ const question = process.argv.slice(2).join(" ") || "What is the capital of France?";
76
+
77
+ console.log(\`> \${question}\\n\`);
78
+
79
+ const result = await agent.run(question);
80
+
81
+ console.log(result.output);
82
+ console.log(\`\\nSteps: \${result.metadata.stepsCount} | Cost: $\${result.metadata.cost.toFixed(6)}\`);
83
+ `;
84
+ }
85
+
86
+ // src/templates/with-tools.ts
87
+ var withToolsTemplate = {
88
+ name: "with-tools",
89
+ description: "Agent with built-in tools (filesystem, fetch, calculator).",
90
+ render: (opts) => {
91
+ return [{ path: "src/index.ts", content: renderIndex2(opts) }];
92
+ }
93
+ };
94
+ function renderIndex2(opts) {
95
+ const model = providerDefaultModel(opts.provider);
96
+ const envVar = providerEnvVar(opts.provider);
97
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
98
+ console.error("Missing ${envVar} in environment. See .env.example.");
99
+ process.exit(1);
100
+ }` : `// Ollama is local \u2014 no API key required.`;
101
+ return `import { ReactiveAgents } from "reactive-agents";
102
+
103
+ ${envCheck}
104
+
105
+ // withTools() registers the built-in tool layer: filesystem (file-read/file-write),
106
+ // fetch (http-get), shell, math, and more. The agent picks tools by name.
107
+ const agent = await ReactiveAgents.create()
108
+ .withName("tool-using-assistant")
109
+ .withProvider("${opts.provider}")
110
+ .withModel("${model}")
111
+ .withTools()
112
+ .withReasoning({ defaultStrategy: "reactive" })
113
+ .withMaxIterations(6)
114
+ .build();
115
+
116
+ const task = process.argv.slice(2).join(" ") ||
117
+ "Compute (123 * 456) + (789 / 3) and explain the result.";
118
+
119
+ console.log(\`> \${task}\\n\`);
120
+
121
+ const result = await agent.run(task);
122
+
123
+ console.log(result.output);
124
+ console.log(\`\\nSteps: \${result.metadata.stepsCount} | Strategy: \${result.metadata.strategyUsed ?? "default"} | Cost: $\${result.metadata.cost.toFixed(6)}\`);
125
+ `;
126
+ }
127
+
128
+ // src/templates/streaming.ts
129
+ var streamingTemplate = {
130
+ name: "streaming",
131
+ description: "Token-by-token streaming via agent.runStream().",
132
+ render: (opts) => {
133
+ return [{ path: "src/index.ts", content: renderIndex3(opts) }];
134
+ }
135
+ };
136
+ function renderIndex3(opts) {
137
+ const model = providerDefaultModel(opts.provider);
138
+ const envVar = providerEnvVar(opts.provider);
139
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
140
+ console.error("Missing ${envVar} in environment. See .env.example.");
141
+ process.exit(1);
142
+ }` : `// Ollama is local \u2014 no API key required.`;
143
+ return `import { ReactiveAgents } from "reactive-agents";
144
+
145
+ ${envCheck}
146
+
147
+ const agent = await ReactiveAgents.create()
148
+ .withName("streaming-assistant")
149
+ .withProvider("${opts.provider}")
150
+ .withModel("${model}")
151
+ .withMaxIterations(3)
152
+ .build();
153
+
154
+ const task = process.argv.slice(2).join(" ") || "Write a haiku about token streaming.";
155
+
156
+ console.log(\`> \${task}\\n\`);
157
+
158
+ // runStream() yields AgentStreamEvents as the agent thinks + acts.
159
+ // "text-delta" carries assistant token chunks; "step-complete" marks loop steps.
160
+ for await (const event of agent.runStream(task)) {
161
+ switch (event.type) {
162
+ case "text-delta":
163
+ process.stdout.write(event.delta);
164
+ break;
165
+ case "tool-call":
166
+ console.log(\`\\n[tool] \${event.name}\`);
167
+ break;
168
+ case "step-complete":
169
+ // one full ReAct iteration finished
170
+ break;
171
+ case "completed":
172
+ console.log(\`\\n\\n[done] steps=\${event.metadata.stepsCount} cost=$\${event.metadata.cost.toFixed(6)}\`);
173
+ break;
174
+ case "error":
175
+ console.error(\`\\n[error] \${event.error}\`);
176
+ break;
177
+ }
178
+ }
179
+ `;
180
+ }
181
+
182
+ // src/templates/shared.ts
183
+ var RA_VERSION_FALLBACK = "^0.11.0";
184
+ function renderSharedFiles(opts) {
185
+ const raVersion = opts.version ?? RA_VERSION_FALLBACK;
186
+ const packageJson = JSON.stringify(
187
+ {
188
+ name: opts.projectName,
189
+ version: "0.1.0",
190
+ private: true,
191
+ type: "module",
192
+ scripts: {
193
+ start: opts.packageManager === "bun" ? "bun run src/index.ts" : "tsx src/index.ts",
194
+ typecheck: "tsc --noEmit"
195
+ },
196
+ dependencies: {
197
+ "reactive-agents": raVersion
198
+ },
199
+ devDependencies: {
200
+ typescript: "^5.7.0",
201
+ ...opts.packageManager === "bun" ? { "bun-types": "latest" } : { "@types/node": "^22.0.0", tsx: "^4.19.0" }
202
+ }
203
+ },
204
+ null,
205
+ 2
206
+ );
207
+ const tsconfig = JSON.stringify(
208
+ {
209
+ compilerOptions: {
210
+ target: "ES2022",
211
+ module: "ESNext",
212
+ moduleResolution: "Bundler",
213
+ strict: true,
214
+ esModuleInterop: true,
215
+ skipLibCheck: true,
216
+ resolveJsonModule: true,
217
+ types: opts.packageManager === "bun" ? ["bun-types"] : ["node"]
218
+ },
219
+ include: ["src/**/*"]
220
+ },
221
+ null,
222
+ 2
223
+ );
224
+ const envVar = providerEnvVar(opts.provider);
225
+ const envContent = envVar ? `# ${providerDisplayName(opts.provider)} credentials
226
+ ${envVar}=your-key-here
227
+ ` : `# Ollama runs locally \u2014 no API key needed.
228
+ # Make sure Ollama is running: https://ollama.com
229
+ `;
230
+ const gitignore = `node_modules
231
+ dist
232
+ .env
233
+ .env.*
234
+ !.env.example
235
+ *.log
236
+ .DS_Store
237
+ `;
238
+ return [
239
+ { path: "package.json", content: packageJson + "\n" },
240
+ { path: "tsconfig.json", content: tsconfig + "\n" },
241
+ { path: ".env.example", content: envContent },
242
+ { path: ".gitignore", content: gitignore },
243
+ { path: "README.md", content: renderReadme(opts) }
244
+ ];
245
+ }
246
+ function renderReadme(opts) {
247
+ const envVar = providerEnvVar(opts.provider);
248
+ const envBlock = envVar ? `\`\`\`bash
249
+ export ${envVar}=your-key-here
250
+ \`\`\`` : `Ollama runs locally. Install and start it from <https://ollama.com>.`;
251
+ return `# ${opts.projectName}
252
+
253
+ A Reactive Agents project scaffolded with \`create-reactive-agent\`.
254
+
255
+ - **Template:** ${opts.template}
256
+ - **Provider:** ${providerDisplayName(opts.provider)}
257
+ - **Package manager:** ${opts.packageManager}
258
+
259
+ ## Setup
260
+
261
+ ${envBlock}
262
+
263
+ \`\`\`bash
264
+ ${opts.packageManager} install
265
+ ${opts.packageManager === "npm" ? "npm run start" : `${opts.packageManager} start`}
266
+ \`\`\`
267
+
268
+ ## Learn more
269
+
270
+ - Docs: <https://docs.reactiveagents.dev>
271
+ - GitHub: <https://github.com/tylerjrbuell/reactive-agents-ts>
272
+ `;
273
+ }
274
+
275
+ // src/templates/index.ts
276
+ var TEMPLATES = {
277
+ minimal: minimalTemplate,
278
+ "with-tools": withToolsTemplate,
279
+ streaming: streamingTemplate
280
+ };
281
+ function getTemplate(name) {
282
+ return TEMPLATES[name];
283
+ }
284
+ function listTemplates() {
285
+ return Object.values(TEMPLATES);
286
+ }
287
+ function renderTemplate(opts) {
288
+ const tpl = getTemplate(opts.template);
289
+ const shared = renderSharedFiles(opts);
290
+ const specific = tpl.render(opts);
291
+ return [...shared, ...specific];
292
+ }
293
+
294
+ // src/lib/scaffold.ts
295
+ async function scaffold(opts) {
296
+ const targetDir = path.resolve(opts.dir);
297
+ if (existsSync(targetDir)) {
298
+ const entries = await readdir(targetDir);
299
+ if (entries.length > 0) {
300
+ throw new Error(`Target directory is not empty: ${targetDir}`);
301
+ }
302
+ } else {
303
+ await mkdir(targetDir, { recursive: true });
304
+ }
305
+ const files = renderTemplate(opts);
306
+ const written = [];
307
+ for (const f of files) {
308
+ const full = path.join(targetDir, f.path);
309
+ await mkdir(path.dirname(full), { recursive: true });
310
+ await writeFile(full, f.content, "utf8");
311
+ written.push(f.path);
312
+ }
313
+ return {
314
+ dir: targetDir,
315
+ files: written,
316
+ nextSteps: buildNextSteps(opts)
317
+ };
318
+ }
319
+ function buildNextSteps(opts) {
320
+ const steps = [];
321
+ steps.push(`cd ${opts.projectName}`);
322
+ steps.push(`${opts.packageManager} install`);
323
+ const envVar = providerEnvVar(opts.provider);
324
+ if (envVar) {
325
+ steps.push(`echo "${envVar}=your-key-here" > .env`);
326
+ } else if (opts.provider === "ollama") {
327
+ steps.push("# Ensure Ollama is running: https://ollama.com");
328
+ }
329
+ const runCmd = opts.packageManager === "npm" ? "npm run start" : `${opts.packageManager} start`;
330
+ steps.push(runCmd);
331
+ return steps;
332
+ }
333
+
334
+ // src/lib/prompts.ts
335
+ import * as readline from "readline/promises";
336
+ var COLORS = {
337
+ reset: "\x1B[0m",
338
+ dim: "\x1B[2m",
339
+ cyan: "\x1B[36m",
340
+ green: "\x1B[32m",
341
+ yellow: "\x1B[33m",
342
+ bold: "\x1B[1m"
343
+ };
344
+ function color(s, c) {
345
+ if (!process.stdout.isTTY) return s;
346
+ return `${COLORS[c]}${s}${COLORS.reset}`;
347
+ }
348
+ var defaultIO = { input: process.stdin, output: process.stdout };
349
+ async function promptText(question, fallback, io = defaultIO) {
350
+ const rl = readline.createInterface({ input: io.input, output: io.output });
351
+ try {
352
+ const ans = await rl.question(`${color("?", "cyan")} ${question} ${color(`(${fallback})`, "dim")} `);
353
+ const t = ans.trim();
354
+ return t.length === 0 ? fallback : t;
355
+ } finally {
356
+ rl.close();
357
+ }
358
+ }
359
+ async function promptSelect(question, options, fallback, io = defaultIO) {
360
+ const rl = readline.createInterface({ input: io.input, output: io.output });
361
+ try {
362
+ io.output.write(`${color("?", "cyan")} ${question}
363
+ `);
364
+ options.forEach((o, i) => {
365
+ const marker = o.value === fallback ? color("(default)", "dim") : "";
366
+ io.output.write(` ${color(String(i + 1), "yellow")}) ${o.label} ${marker}
367
+ `);
368
+ });
369
+ const ans = await rl.question(`${color("\u203A", "cyan")} `);
370
+ const t = ans.trim();
371
+ if (t.length === 0) return fallback;
372
+ const n = Number.parseInt(t, 10);
373
+ if (Number.isFinite(n) && n >= 1 && n <= options.length) {
374
+ return options[n - 1].value;
375
+ }
376
+ const byValue = options.find((o) => o.value === t);
377
+ return byValue ? byValue.value : fallback;
378
+ } finally {
379
+ rl.close();
380
+ }
381
+ }
382
+ function logSuccess(msg) {
383
+ process.stdout.write(`${color("\u2713", "green")} ${msg}
384
+ `);
385
+ }
386
+ function logInfo(msg) {
387
+ process.stdout.write(`${color("\u2022", "cyan")} ${msg}
388
+ `);
389
+ }
390
+ function logHeader(msg) {
391
+ process.stdout.write(`
392
+ ${color(msg, "bold")}
393
+ `);
394
+ }
395
+
396
+ // src/cli.ts
397
+ var VERSION = "0.11.0";
398
+ var BOOL_FLAGS = /* @__PURE__ */ new Set(["help", "h", "version", "v", "yes", "y"]);
399
+ function parseArgs(argv) {
400
+ const positional = [];
401
+ const flags = /* @__PURE__ */ new Map();
402
+ for (let i = 0; i < argv.length; i++) {
403
+ const token = argv[i];
404
+ if (token.startsWith("--")) {
405
+ const eq = token.indexOf("=");
406
+ if (eq > 0) {
407
+ flags.set(token.slice(2, eq), token.slice(eq + 1));
408
+ } else {
409
+ const name = token.slice(2);
410
+ const next = argv[i + 1];
411
+ if (!BOOL_FLAGS.has(name) && next !== void 0 && !next.startsWith("-")) {
412
+ flags.set(name, next);
413
+ i++;
414
+ } else {
415
+ flags.set(name, true);
416
+ }
417
+ }
418
+ } else if (token.startsWith("-") && token.length > 1) {
419
+ flags.set(token.slice(1), true);
420
+ } else {
421
+ positional.push(token);
422
+ }
423
+ }
424
+ return { positional, flags };
425
+ }
426
+ function getStr(flags, key) {
427
+ const v = flags.get(key);
428
+ return typeof v === "string" ? v : void 0;
429
+ }
430
+ function printHelp() {
431
+ console.log(`create-reactive-agent v${VERSION}
432
+
433
+ Scaffold a new Reactive Agents project.
434
+
435
+ Usage:
436
+ npm create reactive-agent [dir]
437
+ npm create reactive-agent [dir] -- [options]
438
+
439
+ Options:
440
+ --template=<name> minimal | with-tools | streaming
441
+ --provider=<name> anthropic | openai | google | ollama
442
+ --pm=<manager> bun | npm | pnpm | yarn
443
+ --yes Accept all defaults, skip prompts
444
+ --version Print version
445
+ --help Show this help
446
+
447
+ Templates:
448
+ ${listTemplates().map((t) => ` ${t.name.padEnd(14)} ${t.description}`).join("\n")}
449
+
450
+ Example:
451
+ npm create reactive-agent my-agent -- --template=streaming --provider=anthropic
452
+ `);
453
+ }
454
+ function detectPackageManager() {
455
+ const ua = process.env.npm_config_user_agent ?? "";
456
+ if (ua.startsWith("bun")) return "bun";
457
+ if (ua.startsWith("pnpm")) return "pnpm";
458
+ if (ua.startsWith("yarn")) return "yarn";
459
+ return "npm";
460
+ }
461
+ function isValidTemplate(s) {
462
+ return s === "minimal" || s === "with-tools" || s === "streaming";
463
+ }
464
+ function isValidProvider(s) {
465
+ return s === "anthropic" || s === "openai" || s === "google" || s === "ollama";
466
+ }
467
+ function isValidPM(s) {
468
+ return s === "bun" || s === "npm" || s === "pnpm" || s === "yarn";
469
+ }
470
+ async function main() {
471
+ const argv = process.argv.slice(2);
472
+ const { positional, flags } = parseArgs(argv);
473
+ if (flags.has("help") || flags.has("h")) {
474
+ printHelp();
475
+ return;
476
+ }
477
+ if (flags.has("version") || flags.has("v")) {
478
+ console.log(VERSION);
479
+ return;
480
+ }
481
+ const skipPrompts = flags.has("yes") || flags.has("y") || !process.stdin.isTTY;
482
+ const defaultName = "my-reactive-agent";
483
+ const cliName = positional[0];
484
+ const projectName = cliName ?? (skipPrompts ? defaultName : await promptText("Project name?", defaultName));
485
+ const templateFlag = getStr(flags, "template");
486
+ const template = templateFlag && isValidTemplate(templateFlag) ? templateFlag : skipPrompts ? "minimal" : await promptSelect(
487
+ "Which template?",
488
+ [
489
+ { value: "minimal", label: "minimal \u2014 single-file agent, no tools" },
490
+ { value: "with-tools", label: "with-tools \u2014 agent with built-in tools" },
491
+ { value: "streaming", label: "streaming \u2014 token-by-token streaming" }
492
+ ],
493
+ "minimal"
494
+ );
495
+ const providerFlag = getStr(flags, "provider");
496
+ const provider = providerFlag && isValidProvider(providerFlag) ? providerFlag : skipPrompts ? "anthropic" : await promptSelect(
497
+ "Which LLM provider?",
498
+ [
499
+ { value: "anthropic", label: "Anthropic (Claude)" },
500
+ { value: "openai", label: "OpenAI (GPT)" },
501
+ { value: "google", label: "Google (Gemini)" },
502
+ { value: "ollama", label: "Ollama (local, no key)" }
503
+ ],
504
+ "anthropic"
505
+ );
506
+ const pmFlag = getStr(flags, "pm");
507
+ const packageManager = pmFlag && isValidPM(pmFlag) ? pmFlag : detectPackageManager();
508
+ logHeader("Scaffolding project");
509
+ logInfo(`Name: ${projectName}`);
510
+ logInfo(`Template: ${template}`);
511
+ logInfo(`Provider: ${provider}`);
512
+ logInfo(`PM: ${packageManager}`);
513
+ try {
514
+ const result = await scaffold({
515
+ dir: path2.resolve(process.cwd(), projectName),
516
+ projectName,
517
+ template,
518
+ provider,
519
+ packageManager
520
+ });
521
+ logSuccess(`Created ${result.files.length} files in ${result.dir}`);
522
+ logHeader("Next steps");
523
+ for (const step of result.nextSteps) {
524
+ console.log(` ${step}`);
525
+ }
526
+ console.log();
527
+ logInfo("Docs: https://docs.reactiveagents.dev");
528
+ } catch (err) {
529
+ const msg = err instanceof Error ? err.message : String(err);
530
+ console.error(`
531
+ Error: ${msg}`);
532
+ process.exit(1);
533
+ }
534
+ }
535
+ main().catch((err) => {
536
+ const msg = err instanceof Error ? err.message : String(err);
537
+ console.error(`
538
+ Fatal: ${msg}`);
539
+ process.exit(1);
540
+ });
@@ -0,0 +1,37 @@
1
+ type Provider = "anthropic" | "openai" | "google" | "ollama";
2
+ type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
3
+ type TemplateName = "minimal" | "with-tools" | "streaming";
4
+ interface ScaffoldOptions {
5
+ readonly dir: string;
6
+ readonly projectName: string;
7
+ readonly template: TemplateName;
8
+ readonly provider: Provider;
9
+ readonly packageManager: PackageManager;
10
+ readonly version?: string;
11
+ }
12
+ interface TemplateFile {
13
+ readonly path: string;
14
+ readonly content: string;
15
+ }
16
+ interface Template {
17
+ readonly name: TemplateName;
18
+ readonly description: string;
19
+ readonly render: (opts: ScaffoldOptions) => readonly TemplateFile[];
20
+ }
21
+ interface ScaffoldResult {
22
+ readonly dir: string;
23
+ readonly files: readonly string[];
24
+ readonly nextSteps: readonly string[];
25
+ }
26
+
27
+ declare function scaffold(opts: ScaffoldOptions): Promise<ScaffoldResult>;
28
+
29
+ declare function getTemplate(name: TemplateName): Template;
30
+ declare function listTemplates(): readonly Template[];
31
+ declare function renderTemplate(opts: ScaffoldOptions): readonly TemplateFile[];
32
+
33
+ declare function providerEnvVar(p: Provider): string | null;
34
+ declare function providerDefaultModel(p: Provider): string;
35
+ declare function providerImport(p: Provider): "anthropic" | "openai" | "google" | "ollama";
36
+
37
+ export { type PackageManager, type Provider, type ScaffoldOptions, type ScaffoldResult, type Template, type TemplateFile, type TemplateName, getTemplate, listTemplates, providerDefaultModel, providerEnvVar, providerImport, renderTemplate, scaffold };
package/dist/index.js ADDED
@@ -0,0 +1,340 @@
1
+ // src/lib/scaffold.ts
2
+ import { mkdir, writeFile, readdir } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import * as path from "path";
5
+
6
+ // src/lib/provider-config.ts
7
+ function providerEnvVar(p) {
8
+ switch (p) {
9
+ case "anthropic":
10
+ return "ANTHROPIC_API_KEY";
11
+ case "openai":
12
+ return "OPENAI_API_KEY";
13
+ case "google":
14
+ return "GOOGLE_API_KEY";
15
+ case "ollama":
16
+ return null;
17
+ }
18
+ }
19
+ function providerDefaultModel(p) {
20
+ switch (p) {
21
+ case "anthropic":
22
+ return "claude-sonnet-4-6";
23
+ case "openai":
24
+ return "gpt-4o-mini";
25
+ case "google":
26
+ return "gemini-2.0-flash";
27
+ case "ollama":
28
+ return "qwen3:14b";
29
+ }
30
+ }
31
+ function providerImport(p) {
32
+ return p;
33
+ }
34
+ function providerDisplayName(p) {
35
+ switch (p) {
36
+ case "anthropic":
37
+ return "Anthropic (Claude)";
38
+ case "openai":
39
+ return "OpenAI";
40
+ case "google":
41
+ return "Google (Gemini)";
42
+ case "ollama":
43
+ return "Ollama (local)";
44
+ }
45
+ }
46
+
47
+ // src/templates/minimal.ts
48
+ var minimalTemplate = {
49
+ name: "minimal",
50
+ description: "Single-file agent. No tools. Best starting point.",
51
+ render: (opts) => {
52
+ return [{ path: "src/index.ts", content: renderIndex(opts) }];
53
+ }
54
+ };
55
+ function renderIndex(opts) {
56
+ const model = providerDefaultModel(opts.provider);
57
+ const envVar = providerEnvVar(opts.provider);
58
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
59
+ console.error("Missing ${envVar} in environment. See .env.example.");
60
+ process.exit(1);
61
+ }` : `// Ollama is local \u2014 no API key required.`;
62
+ return `import { ReactiveAgents } from "reactive-agents";
63
+
64
+ ${envCheck}
65
+
66
+ const agent = await ReactiveAgents.create()
67
+ .withName("assistant")
68
+ .withProvider("${opts.provider}")
69
+ .withModel("${model}")
70
+ .withMaxIterations(3)
71
+ .build();
72
+
73
+ const question = process.argv.slice(2).join(" ") || "What is the capital of France?";
74
+
75
+ console.log(\`> \${question}\\n\`);
76
+
77
+ const result = await agent.run(question);
78
+
79
+ console.log(result.output);
80
+ console.log(\`\\nSteps: \${result.metadata.stepsCount} | Cost: $\${result.metadata.cost.toFixed(6)}\`);
81
+ `;
82
+ }
83
+
84
+ // src/templates/with-tools.ts
85
+ var withToolsTemplate = {
86
+ name: "with-tools",
87
+ description: "Agent with built-in tools (filesystem, fetch, calculator).",
88
+ render: (opts) => {
89
+ return [{ path: "src/index.ts", content: renderIndex2(opts) }];
90
+ }
91
+ };
92
+ function renderIndex2(opts) {
93
+ const model = providerDefaultModel(opts.provider);
94
+ const envVar = providerEnvVar(opts.provider);
95
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
96
+ console.error("Missing ${envVar} in environment. See .env.example.");
97
+ process.exit(1);
98
+ }` : `// Ollama is local \u2014 no API key required.`;
99
+ return `import { ReactiveAgents } from "reactive-agents";
100
+
101
+ ${envCheck}
102
+
103
+ // withTools() registers the built-in tool layer: filesystem (file-read/file-write),
104
+ // fetch (http-get), shell, math, and more. The agent picks tools by name.
105
+ const agent = await ReactiveAgents.create()
106
+ .withName("tool-using-assistant")
107
+ .withProvider("${opts.provider}")
108
+ .withModel("${model}")
109
+ .withTools()
110
+ .withReasoning({ defaultStrategy: "reactive" })
111
+ .withMaxIterations(6)
112
+ .build();
113
+
114
+ const task = process.argv.slice(2).join(" ") ||
115
+ "Compute (123 * 456) + (789 / 3) and explain the result.";
116
+
117
+ console.log(\`> \${task}\\n\`);
118
+
119
+ const result = await agent.run(task);
120
+
121
+ console.log(result.output);
122
+ console.log(\`\\nSteps: \${result.metadata.stepsCount} | Strategy: \${result.metadata.strategyUsed ?? "default"} | Cost: $\${result.metadata.cost.toFixed(6)}\`);
123
+ `;
124
+ }
125
+
126
+ // src/templates/streaming.ts
127
+ var streamingTemplate = {
128
+ name: "streaming",
129
+ description: "Token-by-token streaming via agent.runStream().",
130
+ render: (opts) => {
131
+ return [{ path: "src/index.ts", content: renderIndex3(opts) }];
132
+ }
133
+ };
134
+ function renderIndex3(opts) {
135
+ const model = providerDefaultModel(opts.provider);
136
+ const envVar = providerEnvVar(opts.provider);
137
+ const envCheck = envVar ? `if (!process.env.${envVar}) {
138
+ console.error("Missing ${envVar} in environment. See .env.example.");
139
+ process.exit(1);
140
+ }` : `// Ollama is local \u2014 no API key required.`;
141
+ return `import { ReactiveAgents } from "reactive-agents";
142
+
143
+ ${envCheck}
144
+
145
+ const agent = await ReactiveAgents.create()
146
+ .withName("streaming-assistant")
147
+ .withProvider("${opts.provider}")
148
+ .withModel("${model}")
149
+ .withMaxIterations(3)
150
+ .build();
151
+
152
+ const task = process.argv.slice(2).join(" ") || "Write a haiku about token streaming.";
153
+
154
+ console.log(\`> \${task}\\n\`);
155
+
156
+ // runStream() yields AgentStreamEvents as the agent thinks + acts.
157
+ // "text-delta" carries assistant token chunks; "step-complete" marks loop steps.
158
+ for await (const event of agent.runStream(task)) {
159
+ switch (event.type) {
160
+ case "text-delta":
161
+ process.stdout.write(event.delta);
162
+ break;
163
+ case "tool-call":
164
+ console.log(\`\\n[tool] \${event.name}\`);
165
+ break;
166
+ case "step-complete":
167
+ // one full ReAct iteration finished
168
+ break;
169
+ case "completed":
170
+ console.log(\`\\n\\n[done] steps=\${event.metadata.stepsCount} cost=$\${event.metadata.cost.toFixed(6)}\`);
171
+ break;
172
+ case "error":
173
+ console.error(\`\\n[error] \${event.error}\`);
174
+ break;
175
+ }
176
+ }
177
+ `;
178
+ }
179
+
180
+ // src/templates/shared.ts
181
+ var RA_VERSION_FALLBACK = "^0.11.0";
182
+ function renderSharedFiles(opts) {
183
+ const raVersion = opts.version ?? RA_VERSION_FALLBACK;
184
+ const packageJson = JSON.stringify(
185
+ {
186
+ name: opts.projectName,
187
+ version: "0.1.0",
188
+ private: true,
189
+ type: "module",
190
+ scripts: {
191
+ start: opts.packageManager === "bun" ? "bun run src/index.ts" : "tsx src/index.ts",
192
+ typecheck: "tsc --noEmit"
193
+ },
194
+ dependencies: {
195
+ "reactive-agents": raVersion
196
+ },
197
+ devDependencies: {
198
+ typescript: "^5.7.0",
199
+ ...opts.packageManager === "bun" ? { "bun-types": "latest" } : { "@types/node": "^22.0.0", tsx: "^4.19.0" }
200
+ }
201
+ },
202
+ null,
203
+ 2
204
+ );
205
+ const tsconfig = JSON.stringify(
206
+ {
207
+ compilerOptions: {
208
+ target: "ES2022",
209
+ module: "ESNext",
210
+ moduleResolution: "Bundler",
211
+ strict: true,
212
+ esModuleInterop: true,
213
+ skipLibCheck: true,
214
+ resolveJsonModule: true,
215
+ types: opts.packageManager === "bun" ? ["bun-types"] : ["node"]
216
+ },
217
+ include: ["src/**/*"]
218
+ },
219
+ null,
220
+ 2
221
+ );
222
+ const envVar = providerEnvVar(opts.provider);
223
+ const envContent = envVar ? `# ${providerDisplayName(opts.provider)} credentials
224
+ ${envVar}=your-key-here
225
+ ` : `# Ollama runs locally \u2014 no API key needed.
226
+ # Make sure Ollama is running: https://ollama.com
227
+ `;
228
+ const gitignore = `node_modules
229
+ dist
230
+ .env
231
+ .env.*
232
+ !.env.example
233
+ *.log
234
+ .DS_Store
235
+ `;
236
+ return [
237
+ { path: "package.json", content: packageJson + "\n" },
238
+ { path: "tsconfig.json", content: tsconfig + "\n" },
239
+ { path: ".env.example", content: envContent },
240
+ { path: ".gitignore", content: gitignore },
241
+ { path: "README.md", content: renderReadme(opts) }
242
+ ];
243
+ }
244
+ function renderReadme(opts) {
245
+ const envVar = providerEnvVar(opts.provider);
246
+ const envBlock = envVar ? `\`\`\`bash
247
+ export ${envVar}=your-key-here
248
+ \`\`\`` : `Ollama runs locally. Install and start it from <https://ollama.com>.`;
249
+ return `# ${opts.projectName}
250
+
251
+ A Reactive Agents project scaffolded with \`create-reactive-agent\`.
252
+
253
+ - **Template:** ${opts.template}
254
+ - **Provider:** ${providerDisplayName(opts.provider)}
255
+ - **Package manager:** ${opts.packageManager}
256
+
257
+ ## Setup
258
+
259
+ ${envBlock}
260
+
261
+ \`\`\`bash
262
+ ${opts.packageManager} install
263
+ ${opts.packageManager === "npm" ? "npm run start" : `${opts.packageManager} start`}
264
+ \`\`\`
265
+
266
+ ## Learn more
267
+
268
+ - Docs: <https://docs.reactiveagents.dev>
269
+ - GitHub: <https://github.com/tylerjrbuell/reactive-agents-ts>
270
+ `;
271
+ }
272
+
273
+ // src/templates/index.ts
274
+ var TEMPLATES = {
275
+ minimal: minimalTemplate,
276
+ "with-tools": withToolsTemplate,
277
+ streaming: streamingTemplate
278
+ };
279
+ function getTemplate(name) {
280
+ return TEMPLATES[name];
281
+ }
282
+ function listTemplates() {
283
+ return Object.values(TEMPLATES);
284
+ }
285
+ function renderTemplate(opts) {
286
+ const tpl = getTemplate(opts.template);
287
+ const shared = renderSharedFiles(opts);
288
+ const specific = tpl.render(opts);
289
+ return [...shared, ...specific];
290
+ }
291
+
292
+ // src/lib/scaffold.ts
293
+ async function scaffold(opts) {
294
+ const targetDir = path.resolve(opts.dir);
295
+ if (existsSync(targetDir)) {
296
+ const entries = await readdir(targetDir);
297
+ if (entries.length > 0) {
298
+ throw new Error(`Target directory is not empty: ${targetDir}`);
299
+ }
300
+ } else {
301
+ await mkdir(targetDir, { recursive: true });
302
+ }
303
+ const files = renderTemplate(opts);
304
+ const written = [];
305
+ for (const f of files) {
306
+ const full = path.join(targetDir, f.path);
307
+ await mkdir(path.dirname(full), { recursive: true });
308
+ await writeFile(full, f.content, "utf8");
309
+ written.push(f.path);
310
+ }
311
+ return {
312
+ dir: targetDir,
313
+ files: written,
314
+ nextSteps: buildNextSteps(opts)
315
+ };
316
+ }
317
+ function buildNextSteps(opts) {
318
+ const steps = [];
319
+ steps.push(`cd ${opts.projectName}`);
320
+ steps.push(`${opts.packageManager} install`);
321
+ const envVar = providerEnvVar(opts.provider);
322
+ if (envVar) {
323
+ steps.push(`echo "${envVar}=your-key-here" > .env`);
324
+ } else if (opts.provider === "ollama") {
325
+ steps.push("# Ensure Ollama is running: https://ollama.com");
326
+ }
327
+ const runCmd = opts.packageManager === "npm" ? "npm run start" : `${opts.packageManager} start`;
328
+ steps.push(runCmd);
329
+ return steps;
330
+ }
331
+ export {
332
+ getTemplate,
333
+ listTemplates,
334
+ providerDefaultModel,
335
+ providerEnvVar,
336
+ providerImport,
337
+ renderTemplate,
338
+ scaffold
339
+ };
340
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/scaffold.ts","../src/lib/provider-config.ts","../src/templates/minimal.ts","../src/templates/with-tools.ts","../src/templates/streaming.ts","../src/templates/shared.ts","../src/templates/index.ts"],"sourcesContent":["import { mkdir, writeFile, readdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ScaffoldOptions, ScaffoldResult } from \"../types.js\";\nimport { renderTemplate } from \"../templates/index.js\";\nimport { providerEnvVar } from \"./provider-config.js\";\n\nexport async function scaffold(opts: ScaffoldOptions): Promise<ScaffoldResult> {\n const targetDir = path.resolve(opts.dir);\n\n if (existsSync(targetDir)) {\n const entries = await readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDir}`);\n }\n } else {\n await mkdir(targetDir, { recursive: true });\n }\n\n const files = renderTemplate(opts);\n const written: string[] = [];\n\n for (const f of files) {\n const full = path.join(targetDir, f.path);\n await mkdir(path.dirname(full), { recursive: true });\n await writeFile(full, f.content, \"utf8\");\n written.push(f.path);\n }\n\n return {\n dir: targetDir,\n files: written,\n nextSteps: buildNextSteps(opts),\n };\n}\n\nfunction buildNextSteps(opts: ScaffoldOptions): readonly string[] {\n const steps: string[] = [];\n steps.push(`cd ${opts.projectName}`);\n steps.push(`${opts.packageManager} install`);\n\n const envVar = providerEnvVar(opts.provider);\n if (envVar) {\n steps.push(`echo \"${envVar}=your-key-here\" > .env`);\n } else if (opts.provider === \"ollama\") {\n steps.push(\"# Ensure Ollama is running: https://ollama.com\");\n }\n\n const runCmd = opts.packageManager === \"npm\" ? \"npm run start\" : `${opts.packageManager} start`;\n steps.push(runCmd);\n return steps;\n}\n","import type { Provider } from \"../types.js\";\n\nexport function providerEnvVar(p: Provider): string | null {\n switch (p) {\n case \"anthropic\":\n return \"ANTHROPIC_API_KEY\";\n case \"openai\":\n return \"OPENAI_API_KEY\";\n case \"google\":\n return \"GOOGLE_API_KEY\";\n case \"ollama\":\n return null;\n }\n}\n\nexport function providerDefaultModel(p: Provider): string {\n switch (p) {\n case \"anthropic\":\n return \"claude-sonnet-4-6\";\n case \"openai\":\n return \"gpt-4o-mini\";\n case \"google\":\n return \"gemini-2.0-flash\";\n case \"ollama\":\n return \"qwen3:14b\";\n }\n}\n\nexport function providerImport(p: Provider): \"anthropic\" | \"openai\" | \"google\" | \"ollama\" {\n return p;\n}\n\nexport function providerDisplayName(p: Provider): string {\n switch (p) {\n case \"anthropic\":\n return \"Anthropic (Claude)\";\n case \"openai\":\n return \"OpenAI\";\n case \"google\":\n return \"Google (Gemini)\";\n case \"ollama\":\n return \"Ollama (local)\";\n }\n}\n","import type { ScaffoldOptions, Template, TemplateFile } from \"../types.js\";\nimport { providerDefaultModel, providerEnvVar } from \"../lib/provider-config.js\";\n\nexport const minimalTemplate: Template = {\n name: \"minimal\",\n description: \"Single-file agent. No tools. Best starting point.\",\n render: (opts: ScaffoldOptions): readonly TemplateFile[] => {\n return [{ path: \"src/index.ts\", content: renderIndex(opts) }];\n },\n};\n\nfunction renderIndex(opts: ScaffoldOptions): string {\n const model = providerDefaultModel(opts.provider);\n const envVar = providerEnvVar(opts.provider);\n const envCheck = envVar\n ? `if (!process.env.${envVar}) {\n console.error(\"Missing ${envVar} in environment. See .env.example.\");\n process.exit(1);\n}`\n : `// Ollama is local — no API key required.`;\n\n return `import { ReactiveAgents } from \"reactive-agents\";\n\n${envCheck}\n\nconst agent = await ReactiveAgents.create()\n .withName(\"assistant\")\n .withProvider(\"${opts.provider}\")\n .withModel(\"${model}\")\n .withMaxIterations(3)\n .build();\n\nconst question = process.argv.slice(2).join(\" \") || \"What is the capital of France?\";\n\nconsole.log(\\`> \\${question}\\\\n\\`);\n\nconst result = await agent.run(question);\n\nconsole.log(result.output);\nconsole.log(\\`\\\\nSteps: \\${result.metadata.stepsCount} | Cost: $\\${result.metadata.cost.toFixed(6)}\\`);\n`;\n}\n","import type { ScaffoldOptions, Template, TemplateFile } from \"../types.js\";\nimport { providerDefaultModel, providerEnvVar } from \"../lib/provider-config.js\";\n\nexport const withToolsTemplate: Template = {\n name: \"with-tools\",\n description: \"Agent with built-in tools (filesystem, fetch, calculator).\",\n render: (opts: ScaffoldOptions): readonly TemplateFile[] => {\n return [{ path: \"src/index.ts\", content: renderIndex(opts) }];\n },\n};\n\nfunction renderIndex(opts: ScaffoldOptions): string {\n const model = providerDefaultModel(opts.provider);\n const envVar = providerEnvVar(opts.provider);\n const envCheck = envVar\n ? `if (!process.env.${envVar}) {\n console.error(\"Missing ${envVar} in environment. See .env.example.\");\n process.exit(1);\n}`\n : `// Ollama is local — no API key required.`;\n\n return `import { ReactiveAgents } from \"reactive-agents\";\n\n${envCheck}\n\n// withTools() registers the built-in tool layer: filesystem (file-read/file-write),\n// fetch (http-get), shell, math, and more. The agent picks tools by name.\nconst agent = await ReactiveAgents.create()\n .withName(\"tool-using-assistant\")\n .withProvider(\"${opts.provider}\")\n .withModel(\"${model}\")\n .withTools()\n .withReasoning({ defaultStrategy: \"reactive\" })\n .withMaxIterations(6)\n .build();\n\nconst task = process.argv.slice(2).join(\" \") ||\n \"Compute (123 * 456) + (789 / 3) and explain the result.\";\n\nconsole.log(\\`> \\${task}\\\\n\\`);\n\nconst result = await agent.run(task);\n\nconsole.log(result.output);\nconsole.log(\\`\\\\nSteps: \\${result.metadata.stepsCount} | Strategy: \\${result.metadata.strategyUsed ?? \"default\"} | Cost: $\\${result.metadata.cost.toFixed(6)}\\`);\n`;\n}\n","import type { ScaffoldOptions, Template, TemplateFile } from \"../types.js\";\nimport { providerDefaultModel, providerEnvVar } from \"../lib/provider-config.js\";\n\nexport const streamingTemplate: Template = {\n name: \"streaming\",\n description: \"Token-by-token streaming via agent.runStream().\",\n render: (opts: ScaffoldOptions): readonly TemplateFile[] => {\n return [{ path: \"src/index.ts\", content: renderIndex(opts) }];\n },\n};\n\nfunction renderIndex(opts: ScaffoldOptions): string {\n const model = providerDefaultModel(opts.provider);\n const envVar = providerEnvVar(opts.provider);\n const envCheck = envVar\n ? `if (!process.env.${envVar}) {\n console.error(\"Missing ${envVar} in environment. See .env.example.\");\n process.exit(1);\n}`\n : `// Ollama is local — no API key required.`;\n\n return `import { ReactiveAgents } from \"reactive-agents\";\n\n${envCheck}\n\nconst agent = await ReactiveAgents.create()\n .withName(\"streaming-assistant\")\n .withProvider(\"${opts.provider}\")\n .withModel(\"${model}\")\n .withMaxIterations(3)\n .build();\n\nconst task = process.argv.slice(2).join(\" \") || \"Write a haiku about token streaming.\";\n\nconsole.log(\\`> \\${task}\\\\n\\`);\n\n// runStream() yields AgentStreamEvents as the agent thinks + acts.\n// \"text-delta\" carries assistant token chunks; \"step-complete\" marks loop steps.\nfor await (const event of agent.runStream(task)) {\n switch (event.type) {\n case \"text-delta\":\n process.stdout.write(event.delta);\n break;\n case \"tool-call\":\n console.log(\\`\\\\n[tool] \\${event.name}\\`);\n break;\n case \"step-complete\":\n // one full ReAct iteration finished\n break;\n case \"completed\":\n console.log(\\`\\\\n\\\\n[done] steps=\\${event.metadata.stepsCount} cost=$\\${event.metadata.cost.toFixed(6)}\\`);\n break;\n case \"error\":\n console.error(\\`\\\\n[error] \\${event.error}\\`);\n break;\n }\n}\n`;\n}\n","import type { ScaffoldOptions, TemplateFile } from \"../types.js\";\nimport { providerEnvVar, providerDisplayName } from \"../lib/provider-config.js\";\n\nconst RA_VERSION_FALLBACK = \"^0.11.0\";\n\nexport function renderSharedFiles(opts: ScaffoldOptions): readonly TemplateFile[] {\n const raVersion = opts.version ?? RA_VERSION_FALLBACK;\n\n const packageJson = JSON.stringify(\n {\n name: opts.projectName,\n version: \"0.1.0\",\n private: true,\n type: \"module\",\n scripts: {\n start: opts.packageManager === \"bun\" ? \"bun run src/index.ts\" : \"tsx src/index.ts\",\n typecheck: \"tsc --noEmit\",\n },\n dependencies: {\n \"reactive-agents\": raVersion,\n },\n devDependencies: {\n typescript: \"^5.7.0\",\n ...(opts.packageManager === \"bun\"\n ? { \"bun-types\": \"latest\" }\n : { \"@types/node\": \"^22.0.0\", tsx: \"^4.19.0\" }),\n },\n },\n null,\n 2,\n );\n\n const tsconfig = JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n types: opts.packageManager === \"bun\" ? [\"bun-types\"] : [\"node\"],\n },\n include: [\"src/**/*\"],\n },\n null,\n 2,\n );\n\n const envVar = providerEnvVar(opts.provider);\n const envContent = envVar\n ? `# ${providerDisplayName(opts.provider)} credentials\\n${envVar}=your-key-here\\n`\n : `# Ollama runs locally — no API key needed.\\n# Make sure Ollama is running: https://ollama.com\\n`;\n\n const gitignore = `node_modules\ndist\n.env\n.env.*\n!.env.example\n*.log\n.DS_Store\n`;\n\n return [\n { path: \"package.json\", content: packageJson + \"\\n\" },\n { path: \"tsconfig.json\", content: tsconfig + \"\\n\" },\n { path: \".env.example\", content: envContent },\n { path: \".gitignore\", content: gitignore },\n { path: \"README.md\", content: renderReadme(opts) },\n ];\n}\n\nfunction renderReadme(opts: ScaffoldOptions): string {\n const envVar = providerEnvVar(opts.provider);\n const envBlock = envVar\n ? `\\`\\`\\`bash\\nexport ${envVar}=your-key-here\\n\\`\\`\\``\n : `Ollama runs locally. Install and start it from <https://ollama.com>.`;\n\n return `# ${opts.projectName}\n\nA Reactive Agents project scaffolded with \\`create-reactive-agent\\`.\n\n- **Template:** ${opts.template}\n- **Provider:** ${providerDisplayName(opts.provider)}\n- **Package manager:** ${opts.packageManager}\n\n## Setup\n\n${envBlock}\n\n\\`\\`\\`bash\n${opts.packageManager} install\n${opts.packageManager === \"npm\" ? \"npm run start\" : `${opts.packageManager} start`}\n\\`\\`\\`\n\n## Learn more\n\n- Docs: <https://docs.reactiveagents.dev>\n- GitHub: <https://github.com/tylerjrbuell/reactive-agents-ts>\n`;\n}\n","import type { ScaffoldOptions, Template, TemplateFile, TemplateName } from \"../types.js\";\nimport { minimalTemplate } from \"./minimal.js\";\nimport { withToolsTemplate } from \"./with-tools.js\";\nimport { streamingTemplate } from \"./streaming.js\";\nimport { renderSharedFiles } from \"./shared.js\";\n\nconst TEMPLATES: Record<TemplateName, Template> = {\n minimal: minimalTemplate,\n \"with-tools\": withToolsTemplate,\n streaming: streamingTemplate,\n};\n\nexport function getTemplate(name: TemplateName): Template {\n return TEMPLATES[name];\n}\n\nexport function listTemplates(): readonly Template[] {\n return Object.values(TEMPLATES);\n}\n\nexport function renderTemplate(opts: ScaffoldOptions): readonly TemplateFile[] {\n const tpl = getTemplate(opts.template);\n const shared = renderSharedFiles(opts);\n const specific = tpl.render(opts);\n return [...shared, ...specific];\n}\n"],"mappings":"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","names":["renderIndex","renderIndex"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "create-reactive-agent",
3
+ "version": "0.11.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "create-reactive-agent": "./dist/cli.js"
9
+ },
10
+ "description": "Scaffold a new Reactive Agents project in seconds. Run `npm create reactive-agent`.",
11
+ "keywords": [
12
+ "create",
13
+ "scaffold",
14
+ "starter",
15
+ "reactive-agents",
16
+ "ai-agents",
17
+ "cli"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup --config ../../tsup.config.base.ts && tsup src/cli.ts --format esm --out-dir dist",
21
+ "typecheck": "tsc --noEmit",
22
+ "test": "bun test --reporter=dots"
23
+ },
24
+ "dependencies": {},
25
+ "devDependencies": {
26
+ "typescript": "^6.0.3",
27
+ "bun-types": "latest",
28
+ "tsup": "*"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "bun": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js",
35
+ "default": "./dist/index.js"
36
+ }
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/tylerjrbuell/reactive-agents-ts.git",
47
+ "directory": "packages/create-reactive-agent"
48
+ },
49
+ "homepage": "https://docs.reactiveagents.dev/",
50
+ "bugs": {
51
+ "url": "https://github.com/tylerjrbuell/reactive-agents-ts/issues"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ }
56
+ }