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 +48 -0
- package/dist/cli.js +540 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +340 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
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
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -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":";AAAA,SAAS,OAAO,WAAW,eAAe;AAC1C,SAAS,kBAAkB;AAC3B,YAAY,UAAU;;;ACAf,SAAS,eAAe,GAA4B;AACzD,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,qBAAqB,GAAqB;AACxD,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,eAAe,GAA2D;AACxF,SAAO;AACT;AAEO,SAAS,oBAAoB,GAAqB;AACvD,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;;;ACxCO,IAAM,kBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC,SAAmD;AAC1D,WAAO,CAAC,EAAE,MAAM,gBAAgB,SAAS,YAAY,IAAI,EAAE,CAAC;AAAA,EAC9D;AACF;AAEA,SAAS,YAAY,MAA+B;AAClD,QAAM,QAAQ,qBAAqB,KAAK,QAAQ;AAChD,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,QAAM,WAAW,SACb,oBAAoB,MAAM;AAAA,2BACL,MAAM;AAAA;AAAA,KAG3B;AAEJ,SAAO;AAAA;AAAA,EAEP,QAAQ;AAAA;AAAA;AAAA;AAAA,mBAIS,KAAK,QAAQ;AAAA,gBAChB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAarB;;;ACtCO,IAAM,oBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC,SAAmD;AAC1D,WAAO,CAAC,EAAE,MAAM,gBAAgB,SAASA,aAAY,IAAI,EAAE,CAAC;AAAA,EAC9D;AACF;AAEA,SAASA,aAAY,MAA+B;AAClD,QAAM,QAAQ,qBAAqB,KAAK,QAAQ;AAChD,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,QAAM,WAAW,SACb,oBAAoB,MAAM;AAAA,2BACL,MAAM;AAAA;AAAA,KAG3B;AAEJ,SAAO;AAAA;AAAA,EAEP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMS,KAAK,QAAQ;AAAA,gBAChB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBrB;;;AC3CO,IAAM,oBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC,SAAmD;AAC1D,WAAO,CAAC,EAAE,MAAM,gBAAgB,SAASC,aAAY,IAAI,EAAE,CAAC;AAAA,EAC9D;AACF;AAEA,SAASA,aAAY,MAA+B;AAClD,QAAM,QAAQ,qBAAqB,KAAK,QAAQ;AAChD,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,QAAM,WAAW,SACb,oBAAoB,MAAM;AAAA,2BACL,MAAM;AAAA;AAAA,KAG3B;AAEJ,SAAO;AAAA;AAAA,EAEP,QAAQ;AAAA;AAAA;AAAA;AAAA,mBAIS,KAAK,QAAQ;AAAA,gBAChB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BrB;;;ACvDA,IAAM,sBAAsB;AAErB,SAAS,kBAAkB,MAAgD;AAChF,QAAM,YAAY,KAAK,WAAW;AAElC,QAAM,cAAc,KAAK;AAAA,IACvB;AAAA,MACE,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,QACP,OAAO,KAAK,mBAAmB,QAAQ,yBAAyB;AAAA,QAChE,WAAW;AAAA,MACb;AAAA,MACA,cAAc;AAAA,QACZ,mBAAmB;AAAA,MACrB;AAAA,MACA,iBAAiB;AAAA,QACf,YAAY;AAAA,QACZ,GAAI,KAAK,mBAAmB,QACxB,EAAE,aAAa,SAAS,IACxB,EAAE,eAAe,WAAW,KAAK,UAAU;AAAA,MACjD;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,MACE,iBAAiB;AAAA,QACf,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,kBAAkB;AAAA,QAClB,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,mBAAmB;AAAA,QACnB,OAAO,KAAK,mBAAmB,QAAQ,CAAC,WAAW,IAAI,CAAC,MAAM;AAAA,MAChE;AAAA,MACA,SAAS,CAAC,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,QAAM,aAAa,SACf,KAAK,oBAAoB,KAAK,QAAQ,CAAC;AAAA,EAAiB,MAAM;AAAA,IAC9D;AAAA;AAAA;AAEJ,QAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASlB,SAAO;AAAA,IACL,EAAE,MAAM,gBAAgB,SAAS,cAAc,KAAK;AAAA,IACpD,EAAE,MAAM,iBAAiB,SAAS,WAAW,KAAK;AAAA,IAClD,EAAE,MAAM,gBAAgB,SAAS,WAAW;AAAA,IAC5C,EAAE,MAAM,cAAc,SAAS,UAAU;AAAA,IACzC,EAAE,MAAM,aAAa,SAAS,aAAa,IAAI,EAAE;AAAA,EACnD;AACF;AAEA,SAAS,aAAa,MAA+B;AACnD,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,QAAM,WAAW,SACb;AAAA,SAAsB,MAAM;AAAA,UAC5B;AAEJ,SAAO,KAAK,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA,kBAIZ,KAAK,QAAQ;AAAA,kBACb,oBAAoB,KAAK,QAAQ,CAAC;AAAA,yBAC3B,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA,EAI1C,QAAQ;AAAA;AAAA;AAAA,EAGR,KAAK,cAAc;AAAA,EACnB,KAAK,mBAAmB,QAAQ,kBAAkB,GAAG,KAAK,cAAc,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQlF;;;AC/FA,IAAM,YAA4C;AAAA,EAChD,SAAS;AAAA,EACT,cAAc;AAAA,EACd,WAAW;AACb;AAEO,SAAS,YAAY,MAA8B;AACxD,SAAO,UAAU,IAAI;AACvB;AAEO,SAAS,gBAAqC;AACnD,SAAO,OAAO,OAAO,SAAS;AAChC;AAEO,SAAS,eAAe,MAAgD;AAC7E,QAAM,MAAM,YAAY,KAAK,QAAQ;AACrC,QAAM,SAAS,kBAAkB,IAAI;AACrC,QAAM,WAAW,IAAI,OAAO,IAAI;AAChC,SAAO,CAAC,GAAG,QAAQ,GAAG,QAAQ;AAChC;;;ANlBA,eAAsB,SAAS,MAAgD;AAC7E,QAAM,YAAiB,aAAQ,KAAK,GAAG;AAEvC,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,UAAU,MAAM,QAAQ,SAAS;AACvC,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,IAAI,MAAM,kCAAkC,SAAS,EAAE;AAAA,IAC/D;AAAA,EACF,OAAO;AACL,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAEA,QAAM,QAAQ,eAAe,IAAI;AACjC,QAAM,UAAoB,CAAC;AAE3B,aAAW,KAAK,OAAO;AACrB,UAAM,OAAY,UAAK,WAAW,EAAE,IAAI;AACxC,UAAM,MAAW,aAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,UAAU,MAAM,EAAE,SAAS,MAAM;AACvC,YAAQ,KAAK,EAAE,IAAI;AAAA,EACrB;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,IACP,WAAW,eAAe,IAAI;AAAA,EAChC;AACF;AAEA,SAAS,eAAe,MAA0C;AAChE,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,MAAM,KAAK,WAAW,EAAE;AACnC,QAAM,KAAK,GAAG,KAAK,cAAc,UAAU;AAE3C,QAAM,SAAS,eAAe,KAAK,QAAQ;AAC3C,MAAI,QAAQ;AACV,UAAM,KAAK,SAAS,MAAM,wBAAwB;AAAA,EACpD,WAAW,KAAK,aAAa,UAAU;AACrC,UAAM,KAAK,gDAAgD;AAAA,EAC7D;AAEA,QAAM,SAAS,KAAK,mBAAmB,QAAQ,kBAAkB,GAAG,KAAK,cAAc;AACvF,QAAM,KAAK,MAAM;AACjB,SAAO;AACT;","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
|
+
}
|