agdi 3.3.4 → 3.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +348 -332
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- agentEventBus,
4
3
  emitAgentEvent
5
4
  } from "./chunk-A5UTYKKM.js";
6
5
  import {
@@ -10,7 +9,7 @@ import {
10
9
 
11
10
  // src/index.ts
12
11
  import { Command } from "commander";
13
- import chalk14 from "chalk";
12
+ import chalk15 from "chalk";
14
13
  import ora6 from "ora";
15
14
 
16
15
  // src/core/llm/index.ts
@@ -453,8 +452,8 @@ async function smartConfirm(message, defaultValue = false) {
453
452
  console.warn(chalk.yellow("\u26A0\uFE0F Non-interactive session detected. Use --yes to approve actions."));
454
453
  return false;
455
454
  }
456
- const { confirm } = await import("@inquirer/prompts");
457
- return confirm({ message, default: defaultValue });
455
+ const { confirm: confirm2 } = await import("@inquirer/prompts");
456
+ return confirm2({ message, default: defaultValue });
458
457
  }
459
458
  async function smartSelect(message, choices, defaultValue) {
460
459
  if (!process.stdout.isTTY || flags.headless) {
@@ -464,8 +463,8 @@ async function smartSelect(message, choices, defaultValue) {
464
463
  }
465
464
  return result || null;
466
465
  }
467
- const { select: select3 } = await import("@inquirer/prompts");
468
- return select3({ message, choices });
466
+ const { select: select4 } = await import("@inquirer/prompts");
467
+ return select4({ message, choices });
469
468
  }
470
469
  var ui = {
471
470
  renderBanner,
@@ -499,7 +498,10 @@ Return a JSON object with:
499
498
  {
500
499
  "name": "app-name",
501
500
  "description": "Brief description",
502
- "files": [{"path": "src/App.tsx", "description": "Main component"}],
501
+ "files": [
502
+ {"path": "src/App.tsx", "description": "Main component"},
503
+ {"path": "README.md", "description": "Project documentation"}
504
+ ],
503
505
  "dependencies": ["react", "tailwindcss"],
504
506
  "architecture": "Component architecture description"
505
507
  }
@@ -1786,8 +1788,8 @@ async function runOnboarding() {
1786
1788
  console.log(chalk7.gray("We collect anonymous error logs (like a ") + chalk7.yellow("'Check Engine'") + chalk7.gray(" light)"));
1787
1789
  console.log(chalk7.gray("to fix bugs faster. We ") + chalk7.green.bold("never") + chalk7.gray(" see your code or keys.\n"));
1788
1790
  console.log(chalk7.dim("Verify anytime: agdi config telemetry --dry-run\n"));
1789
- const { confirm } = await import("@inquirer/prompts");
1790
- const enableTelemetry = await confirm({
1791
+ const { confirm: confirm2 } = await import("@inquirer/prompts");
1792
+ const enableTelemetry = await confirm2({
1791
1793
  message: "Enable crash reporting? (helps us fix bugs)",
1792
1794
  default: false
1793
1795
  });
@@ -4182,19 +4184,243 @@ ${msg}
4182
4184
  }
4183
4185
  }
4184
4186
 
4185
- // src/commands/replay.ts
4187
+ // src/commands/wizard.ts
4188
+ import { input as input5, select as select3, confirm, password as password3 } from "@inquirer/prompts";
4186
4189
  import chalk13 from "chalk";
4187
- import * as fs6 from "fs/promises";
4188
- import * as path6 from "path";
4190
+ import path6 from "path";
4191
+ import os from "os";
4192
+ import fs6 from "fs";
4193
+ async function runWizard() {
4194
+ await checkSafety();
4195
+ if (needsOnboarding()) {
4196
+ await runOnboarding();
4197
+ }
4198
+ await setupOptionalTools();
4199
+ const wantsSaas = await confirm({
4200
+ message: "Enable SaaS Blueprint mode? (Next.js + Prisma + Postgres + Stripe)",
4201
+ default: true
4202
+ });
4203
+ if (wantsSaas) {
4204
+ ui.setFlags({ saas: true });
4205
+ }
4206
+ console.log(chalk13.cyan.bold("\n\u{1F3AF} Mission Control (ClawBot Setup)"));
4207
+ console.log(chalk13.gray("I need to calibrate the squad. Answer these 4 questions to define your build.\n"));
4208
+ const vision = await input5({
4209
+ message: '1. What are we building today? (e.g. "A Kanban board", "Portfolio site")',
4210
+ validate: (value) => value.length > 3 ? true : "Please provide a bit more detail"
4211
+ });
4212
+ const target = await input5({
4213
+ message: "2. Who is this for? (Target Audience)",
4214
+ default: "General users"
4215
+ });
4216
+ const problem = await input5({
4217
+ message: "3. What core problem does this solve?",
4218
+ default: "Simplifying a workflow"
4219
+ });
4220
+ const needsImages = await confirm({
4221
+ message: "4. Do you need generated images or placeholder assets?",
4222
+ default: true
4223
+ });
4224
+ let prompt = `Build an application with the following specification:
4225
+ - **Concept:** ${vision}
4226
+ - **Target Audience:** ${target}
4227
+ - **Problem Solved:** ${problem}
4228
+ - **Asset Requirement:** ${needsImages ? "Include placeholder images and assets" : "Minimalist, code-only layout"}
4229
+ `;
4230
+ if (wantsSaas) {
4231
+ prompt = `${prompt}
4232
+
4233
+ Constraints: Build a production SaaS using Next.js App Router, Prisma, Postgres, and Stripe. Include auth, billing, multi-tenant orgs, and a dashboard.`;
4234
+ }
4235
+ const activeConfig = getActiveProvider();
4236
+ if (!activeConfig) {
4237
+ console.log(chalk13.red("\u274C No API key configured. Run: agdi auth"));
4238
+ return;
4239
+ }
4240
+ const llm = createLLMProvider(activeConfig.provider, {
4241
+ apiKey: activeConfig.apiKey,
4242
+ model: activeConfig.model
4243
+ });
4244
+ console.log(chalk13.cyan("\n\u{1F914} Analyzing requirements..."));
4245
+ try {
4246
+ const analysis = await llm.generate(prompt, `
4247
+ You are a Senior Product Manager. Analyze this app idea.
4248
+ If it is vague (e.g., "make a CRM"), generate 3 specific questions to clarify scope, tech stack, and features.
4249
+ If it is detailed enough, return "DETAILED".
4250
+
4251
+ Format:
4252
+ Questions:
4253
+ 1. [Question 1]
4254
+ 2. [Question 2]
4255
+ 3. [Question 3]
4256
+ `);
4257
+ if (!analysis.text.includes("DETAILED")) {
4258
+ console.log(chalk13.yellow("\n\u{1F4A1} I need a few more details to build exactly what you want:"));
4259
+ const questions = analysis.text.split("\n").filter((line) => line.match(/^\d+\./));
4260
+ const answers = [];
4261
+ for (const q of questions.slice(0, 3)) {
4262
+ const answer = await input5({ message: q.replace(/^\d+\.\s*/, "") });
4263
+ answers.push({ q, a: answer });
4264
+ }
4265
+ console.log(chalk13.cyan("\n\u{1F504} Synthesizing Master Plan..."));
4266
+ const synthesis = await llm.generate(
4267
+ `Original Request: ${prompt}
4268
+
4269
+ Clarifications:
4270
+ ${answers.map((x) => `Q: ${x.q}
4271
+ A: ${x.a}`).join("\n")}
4272
+
4273
+ Rewrite the original request into a comprehensive technical specification for a developer squad.`,
4274
+ "You are a Technical Architect."
4275
+ );
4276
+ prompt = synthesis.text;
4277
+ console.log(chalk13.gray("\nUpdated Spec: " + prompt.substring(0, 100) + "...\n"));
4278
+ }
4279
+ } catch (err) {
4280
+ console.log(chalk13.gray("Skipping analysis (API unreachable), proceeding with raw prompt."));
4281
+ }
4282
+ console.log(chalk13.cyan("\n\u{1F680} Assembling the Squad..."));
4283
+ console.log(chalk13.gray("Frontend, Backend, QA, and DevOps agents are coming online.\n"));
4284
+ const config = loadConfig();
4285
+ const canDeploy = !!(config.vercelToken || config.netlifyToken || config.railwayToken);
4286
+ await runSquadCommand(prompt, llm, {
4287
+ deploy: canDeploy,
4288
+ // Auto-deploy if configured
4289
+ output: "./",
4290
+ // Current directory (safe because we checked safety earlier)
4291
+ verbose: true
4292
+ });
4293
+ if (ui.flags.saas) {
4294
+ console.log(chalk13.cyan("\nSaaS Quick Start:"));
4295
+ console.log(chalk13.gray(" 1) npm install"));
4296
+ console.log(chalk13.gray(" 2) cp .env.example .env"));
4297
+ console.log(chalk13.gray(" 3) npx prisma generate"));
4298
+ console.log(chalk13.gray(" 4) npx prisma db push"));
4299
+ console.log(chalk13.gray(" 5) npm run dev\n"));
4300
+ }
4301
+ }
4302
+ async function checkSafety() {
4303
+ const cwd = process.cwd();
4304
+ const home = os.homedir();
4305
+ const root = path6.parse(cwd).root;
4306
+ const isUnsafe = cwd === home || cwd === root;
4307
+ if (isUnsafe) {
4308
+ console.log(chalk13.yellow.bold("\n\u26A0\uFE0F Safety Warning"));
4309
+ console.log(chalk13.gray(`You are running Agdi in ${chalk13.cyan(cwd)}.`));
4310
+ console.log(chalk13.gray("Agdi writes files and runs commands. It needs its own space.\n"));
4311
+ const action = await select3({
4312
+ message: "What would you like to do?",
4313
+ choices: [
4314
+ { name: "\u{1F4C2} Create a new project folder (Recommended)", value: "create" },
4315
+ { name: "\u{1F525} Run here anyway (Dangerous)", value: "unsafe" },
4316
+ { name: "\u274C Cancel", value: "cancel" }
4317
+ ]
4318
+ });
4319
+ if (action === "cancel") {
4320
+ ui.safeExit(0);
4321
+ }
4322
+ if (action === "create") {
4323
+ const folderName = await input5({
4324
+ message: "Project name:",
4325
+ default: "my-agdi-app",
4326
+ validate: (v) => /^[a-z0-9-_]+$/i.test(v) ? true : "Invalid folder name"
4327
+ });
4328
+ const newPath = path6.join(cwd, folderName);
4329
+ if (!fs6.existsSync(newPath)) {
4330
+ fs6.mkdirSync(newPath);
4331
+ }
4332
+ process.chdir(newPath);
4333
+ console.log(chalk13.green(`
4334
+ \u{1F4C2} Switched to: ${chalk13.cyan(newPath)}
4335
+ `));
4336
+ }
4337
+ }
4338
+ }
4339
+ async function setupOptionalTools() {
4340
+ const config = loadConfig();
4341
+ let configChanged = false;
4342
+ if (!config.searchApiKey) {
4343
+ console.log(chalk13.white.bold("\n\u{1F310} Web Access (Optional)\n"));
4344
+ console.log(chalk13.gray("Giving Agdi web access allows it to find up-to-date docs and fix tricky bugs."));
4345
+ const wantsSearch = await confirm({
4346
+ message: "Enable web search capabilities?",
4347
+ default: true
4348
+ });
4349
+ if (wantsSearch) {
4350
+ const provider = await select3({
4351
+ message: "Select Search Provider:",
4352
+ choices: [
4353
+ { name: "Brave Search (Recommended)", value: "brave" },
4354
+ { name: "Tavily", value: "tavily" }
4355
+ ]
4356
+ });
4357
+ const keyUrl = provider === "brave" ? "https://brave.com/search/api/" : "https://tavily.com/";
4358
+ console.log(chalk13.gray(`Get your key at: ${chalk13.cyan(keyUrl)}
4359
+ `));
4360
+ const apiKey = await password3({
4361
+ message: `Enter your ${provider} API key:`,
4362
+ mask: "*"
4363
+ });
4364
+ if (apiKey) {
4365
+ config.searchApiKey = apiKey;
4366
+ config.searchProvider = provider;
4367
+ config.searchEnabled = true;
4368
+ configChanged = true;
4369
+ console.log(chalk13.green("\u2705 Web search enabled!"));
4370
+ }
4371
+ }
4372
+ }
4373
+ if (!config.vercelToken && !config.netlifyToken && !config.railwayToken) {
4374
+ console.log(chalk13.white.bold("\n\u{1F680} Deployment (Optional)\n"));
4375
+ console.log(chalk13.gray("Agdi can automatically deploy your app to the cloud when finished."));
4376
+ const wantsDeploy = await confirm({
4377
+ message: "Enable auto-deployment?",
4378
+ default: true
4379
+ });
4380
+ if (wantsDeploy) {
4381
+ const provider = await select3({
4382
+ message: "Select Deployment Target:",
4383
+ choices: [
4384
+ { name: "Vercel", value: "vercel" },
4385
+ { name: "Railway", value: "railway" },
4386
+ { name: "Netlify", value: "netlify" }
4387
+ ]
4388
+ });
4389
+ const keyUrl = provider === "vercel" ? "https://vercel.com/account/tokens" : provider === "railway" ? "https://railway.app/account/tokens" : "https://app.netlify.com/user/applications#personal-access-tokens";
4390
+ console.log(chalk13.gray(`Get your key at: ${chalk13.cyan(keyUrl)}
4391
+ `));
4392
+ const apiKey = await password3({
4393
+ message: `Enter your ${provider} API token:`,
4394
+ mask: "*"
4395
+ });
4396
+ if (apiKey) {
4397
+ if (provider === "vercel") config.vercelToken = apiKey;
4398
+ if (provider === "netlify") config.netlifyToken = apiKey;
4399
+ if (provider === "railway") config.railwayToken = apiKey;
4400
+ config.deploymentProvider = provider;
4401
+ configChanged = true;
4402
+ console.log(chalk13.green("\u2705 Auto-deployment enabled!"));
4403
+ }
4404
+ }
4405
+ }
4406
+ if (configChanged) {
4407
+ saveConfig(config);
4408
+ }
4409
+ }
4410
+
4411
+ // src/commands/replay.ts
4412
+ import chalk14 from "chalk";
4413
+ import * as fs7 from "fs/promises";
4414
+ import * as path7 from "path";
4189
4415
  async function runReplayCommand(runId, llm, options = {}) {
4190
4416
  const workspaceRoot = options.workspace || process.cwd();
4191
- const runConfigPath = path6.join(workspaceRoot, "runs", runId, "run.json");
4192
- const outputsDir = path6.join(workspaceRoot, "runs", runId, "outputs");
4417
+ const runConfigPath = path7.join(workspaceRoot, "runs", runId, "run.json");
4418
+ const outputsDir = path7.join(workspaceRoot, "runs", runId, "outputs");
4193
4419
  try {
4194
- const raw = await fs6.readFile(runConfigPath, "utf-8");
4420
+ const raw = await fs7.readFile(runConfigPath, "utf-8");
4195
4421
  const runConfig = JSON.parse(raw);
4196
4422
  if (!runConfig.prompt) {
4197
- console.log(chalk13.red("\u274C Invalid run.json (missing prompt)"));
4423
+ console.log(chalk14.red("\u274C Invalid run.json (missing prompt)"));
4198
4424
  return null;
4199
4425
  }
4200
4426
  const config = {
@@ -4203,31 +4429,31 @@ async function runReplayCommand(runId, llm, options = {}) {
4203
4429
  verbose: options.verbose ?? runConfig.config?.verbose ?? true,
4204
4430
  autoDeploy: options.deploy ?? runConfig.config?.autoDeploy ?? false
4205
4431
  };
4206
- console.log(chalk13.cyan(`
4432
+ console.log(chalk14.cyan(`
4207
4433
  \u{1F501} Replaying run ${runId}`));
4208
4434
  if (options.exact !== false) {
4209
4435
  try {
4210
- const entries = await fs6.readdir(outputsDir, { withFileTypes: true });
4436
+ const entries = await fs7.readdir(outputsDir, { withFileTypes: true });
4211
4437
  if (entries.length === 0) {
4212
4438
  throw new Error("No outputs found");
4213
4439
  }
4214
4440
  const copyOutputs = async (dir, rel = "") => {
4215
- const files = await fs6.readdir(dir, { withFileTypes: true });
4441
+ const files = await fs7.readdir(dir, { withFileTypes: true });
4216
4442
  for (const file of files) {
4217
- const sourcePath = path6.join(dir, file.name);
4218
- const targetRel = path6.join(rel, file.name);
4219
- const targetPath = path6.join(workspaceRoot, targetRel);
4443
+ const sourcePath = path7.join(dir, file.name);
4444
+ const targetRel = path7.join(rel, file.name);
4445
+ const targetPath = path7.join(workspaceRoot, targetRel);
4220
4446
  if (file.isDirectory()) {
4221
4447
  await copyOutputs(sourcePath, targetRel);
4222
4448
  } else if (file.isFile()) {
4223
- await fs6.mkdir(path6.dirname(targetPath), { recursive: true });
4224
- const content = await fs6.readFile(sourcePath, "utf-8");
4225
- await fs6.writeFile(targetPath, content, "utf-8");
4449
+ await fs7.mkdir(path7.dirname(targetPath), { recursive: true });
4450
+ const content = await fs7.readFile(sourcePath, "utf-8");
4451
+ await fs7.writeFile(targetPath, content, "utf-8");
4226
4452
  }
4227
4453
  }
4228
4454
  };
4229
4455
  await copyOutputs(outputsDir);
4230
- console.log(chalk13.green("\u2705 Exact replay applied from stored outputs."));
4456
+ console.log(chalk14.green("\u2705 Exact replay applied from stored outputs."));
4231
4457
  return {
4232
4458
  success: true,
4233
4459
  projectSpec: { name: "replay", description: "Exact replay", type: "web-app", stack: {}, features: [] },
@@ -4238,255 +4464,34 @@ async function runReplayCommand(runId, llm, options = {}) {
4238
4464
  errors: []
4239
4465
  };
4240
4466
  } catch (error) {
4241
- console.log(chalk13.yellow("\u26A0\uFE0F Exact replay failed, falling back to rerun."));
4242
- console.log(chalk13.gray(String(error)));
4467
+ console.log(chalk14.yellow("\u26A0\uFE0F Exact replay failed, falling back to rerun."));
4468
+ console.log(chalk14.gray(String(error)));
4243
4469
  }
4244
4470
  }
4245
4471
  if (!llm) {
4246
- console.log(chalk13.red("\u274C No LLM provider available for replay."));
4472
+ console.log(chalk14.red("\u274C No LLM provider available for replay."));
4247
4473
  return null;
4248
4474
  }
4249
4475
  const orchestrator = new SquadOrchestrator(llm, config);
4250
4476
  return await orchestrator.run(runConfig.prompt);
4251
4477
  } catch (error) {
4252
- console.log(chalk13.red("\u274C Failed to load run config for replay"));
4253
- console.log(chalk13.gray(String(error)));
4478
+ console.log(chalk14.red("\u274C Failed to load run config for replay"));
4479
+ console.log(chalk14.gray(String(error)));
4254
4480
  return null;
4255
4481
  }
4256
4482
  }
4257
4483
 
4258
- // src/commands/tui-entry.tsx
4259
- import { render } from "ink";
4260
-
4261
- // src/ui/tui.tsx
4262
- import { useState, useEffect } from "react";
4263
- import { Box, Text, useApp } from "ink";
4264
- import TextInput from "ink-text-input";
4265
- import fs7 from "fs";
4266
- import path7 from "path";
4267
- import os from "os";
4268
- import { jsx, jsxs } from "react/jsx-runtime";
4269
- var THEME2 = {
4270
- bg: "black",
4271
- border: "gray",
4272
- accent: "blue",
4273
- text: "white",
4274
- dim: "gray",
4275
- success: "green"
4276
- };
4277
- var BootScreen = ({ onComplete }) => {
4278
- const [progress, setProgress] = useState(0);
4279
- useEffect(() => {
4280
- const timer = setInterval(() => {
4281
- setProgress((prev) => {
4282
- const next = prev + 10;
4283
- if (next >= 100) {
4284
- clearInterval(timer);
4285
- setTimeout(onComplete, 100);
4286
- return 100;
4287
- }
4288
- return next;
4289
- });
4290
- }, 20);
4291
- return () => clearInterval(timer);
4292
- }, []);
4293
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "center", justifyContent: "center", height: 15, children: [
4294
- /* @__PURE__ */ jsx(Text, { color: THEME2.accent, bold: true, children: "Initializing Agdi Workspace..." }),
4295
- /* @__PURE__ */ jsxs(Text, { color: THEME2.dim, children: [
4296
- "\u2588",
4297
- "\u2588".repeat(progress / 5)
4298
- ] })
4299
- ] });
4300
- };
4301
- var Sidebar = ({ history }) => {
4302
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 25, borderStyle: "single", borderColor: THEME2.border, paddingX: 1, children: [
4303
- /* @__PURE__ */ jsx(Box, { marginBottom: 1, borderStyle: "single", borderColor: THEME2.accent, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { bold: true, children: "+ New task" }) }),
4304
- /* @__PURE__ */ jsx(Text, { color: THEME2.dim, bold: true, children: "RECENTS" }),
4305
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: history.length === 0 ? /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: "No recent sessions" }) : history.map((h, i) => /* @__PURE__ */ jsx(Text, { color: THEME2.text, children: h }, i)) })
4306
- ] });
4307
- };
4308
- var ContextPanel = ({ files, agentStatus }) => {
4309
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 30, borderStyle: "single", borderColor: THEME2.border, paddingX: 1, children: [
4310
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
4311
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Context" }),
4312
- /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: "WORKING FILES" }),
4313
- files.length === 0 ? /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: "None yet." }) : files.slice(0, 5).map((f, i) => /* @__PURE__ */ jsxs(Text, { color: THEME2.accent, children: [
4314
- "\u{1F4C4} ",
4315
- f
4316
- ] }, i))
4317
- ] }),
4318
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "single", borderColor: THEME2.dim, padding: 0, children: [
4319
- /* @__PURE__ */ jsx(Text, { bold: true, children: " Plugins" }),
4320
- /* @__PURE__ */ jsx(Text, { color: THEME2.success, children: "\u2022 Scheduler" }),
4321
- /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: " Run scheduled jobs" })
4322
- ] }),
4323
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
4324
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Status" }),
4325
- /* @__PURE__ */ jsxs(Text, { color: agentStatus === "IDLE" ? THEME2.dim : THEME2.success, children: [
4326
- "\u2022 ",
4327
- agentStatus
4328
- ] })
4329
- ] })
4330
- ] });
4331
- };
4332
- var ChatArea = ({ history, onSend, placeholder }) => {
4333
- const [query, setQuery] = useState("");
4334
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, borderStyle: "single", borderColor: THEME2.border, marginLeft: 0, marginRight: 0, children: [
4335
- /* @__PURE__ */ jsx(Box, { justifyContent: "center", borderStyle: "single", borderBottomColor: THEME2.border, borderTop: false, borderLeft: false, borderRight: false, paddingBottom: 0, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Start a conversation" }) }),
4336
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, padding: 1, justifyContent: "flex-end", children: history.length === 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "center", justifyContent: "center", height: 10, children: [
4337
- /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: "Describe what you want to do," }),
4338
- /* @__PURE__ */ jsx(Text, { color: THEME2.dim, children: "and Agdi will take it from there." })
4339
- ] }) : history.slice(-8).map((msg, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
4340
- /* @__PURE__ */ jsx(Text, { bold: true, color: msg.role === "user" ? THEME2.text : THEME2.accent, children: msg.role === "user" ? "You" : "Agdi" }),
4341
- /* @__PURE__ */ jsx(Text, { color: THEME2.text, children: msg.text })
4342
- ] }, i)) }),
4343
- /* @__PURE__ */ jsx(Box, { borderStyle: "round", borderColor: THEME2.dim, paddingX: 1, marginX: 1, marginBottom: 1, children: /* @__PURE__ */ jsx(
4344
- TextInput,
4345
- {
4346
- value: query,
4347
- onChange: setQuery,
4348
- onSubmit: (val) => {
4349
- onSend(val);
4350
- setQuery("");
4351
- },
4352
- placeholder
4353
- }
4354
- ) })
4355
- ] });
4356
- };
4357
- var Dashboard = () => {
4358
- const { exit } = useApp();
4359
- const [cwd, setCwd] = useState(process.cwd());
4360
- const [chatHistory, setChatHistory] = useState([]);
4361
- const [step, setStep] = useState("safety");
4362
- const [pendingAction, setPendingAction] = useState(null);
4363
- const [activeFiles, setActiveFiles] = useState([]);
4364
- const [agentStatus, setAgentStatus] = useState("IDLE");
4365
- useEffect(() => {
4366
- const handleEvent = (event) => {
4367
- if (event.type === "handoff") {
4368
- setAgentStatus(event.role.toUpperCase());
4369
- }
4370
- if (event.type === "thought") {
4371
- if (!event.message.startsWith("Analyzing")) {
4372
- setChatHistory((prev) => [...prev, { role: "system", text: `[${event.agentName}] ${event.message}` }]);
4373
- }
4374
- }
4375
- if (event.message.includes("Created:")) {
4376
- const filename = event.message.split("Created:")[1].trim();
4377
- setActiveFiles((prev) => [filename, ...prev].slice(0, 5));
4378
- }
4379
- };
4380
- agentEventBus.on("agent_event", handleEvent);
4381
- return () => {
4382
- agentEventBus.off("agent_event", handleEvent);
4383
- };
4384
- }, []);
4385
- useEffect(() => {
4386
- if (step === "safety") {
4387
- const home = os.homedir();
4388
- const root = path7.parse(cwd).root;
4389
- const isUnsafe = cwd === home || cwd === root;
4390
- if (isUnsafe) {
4391
- setChatHistory([
4392
- { role: "system", text: `\u26A0\uFE0F Safety Check: Running in ${cwd}` },
4393
- { role: "ai", text: "This directory is too broad. Should I create a new project folder? (yes/no)" }
4394
- ]);
4395
- setPendingAction("safety_confirm");
4396
- } else {
4397
- setStep("prompt");
4398
- }
4399
- }
4400
- }, []);
4401
- const handleCommand = async (cmd) => {
4402
- if (cmd === "/exit") exit();
4403
- setChatHistory((prev) => [...prev, { role: "user", text: cmd }]);
4404
- if (step === "safety" && pendingAction === "safety_confirm") {
4405
- if (cmd.toLowerCase().startsWith("y")) {
4406
- setChatHistory((prev) => [...prev, { role: "ai", text: "Name your project:" }]);
4407
- setPendingAction("create_folder");
4408
- } else {
4409
- setChatHistory((prev) => [...prev, { role: "ai", text: "Proceeding in current directory." }]);
4410
- setStep("prompt");
4411
- setPendingAction(null);
4412
- }
4413
- return;
4414
- }
4415
- if (step === "safety" && pendingAction === "create_folder") {
4416
- const newPath = path7.join(cwd, cmd.replace(/[^a-z0-9-_]/gi, "-"));
4417
- try {
4418
- if (!fs7.existsSync(newPath)) fs7.mkdirSync(newPath);
4419
- process.chdir(newPath);
4420
- setCwd(newPath);
4421
- setChatHistory((prev) => [...prev, { role: "system", text: `\u{1F4C2} Switched to ${newPath}` }]);
4422
- setStep("prompt");
4423
- setPendingAction(null);
4424
- } catch (e) {
4425
- setChatHistory((prev) => [...prev, { role: "system", text: `Error: ${e}` }]);
4426
- }
4427
- return;
4428
- }
4429
- if (step === "prompt") {
4430
- setStep("active");
4431
- setAgentStatus("MANAGER");
4432
- const activeConfig = getActiveProvider();
4433
- if (!activeConfig) {
4434
- setChatHistory((prev) => [...prev, { role: "system", text: '\u274C No API key found. Run "agdi auth" first.' }]);
4435
- return;
4436
- }
4437
- const llm = createLLMProvider(activeConfig.provider, {
4438
- apiKey: activeConfig.apiKey,
4439
- model: activeConfig.model
4440
- });
4441
- runSquadCommand(cmd, llm, {
4442
- output: cwd,
4443
- verbose: false,
4444
- deploy: false
4445
- }).then(() => {
4446
- setAgentStatus("IDLE");
4447
- setChatHistory((prev) => [...prev, { role: "ai", text: "Task completed." }]);
4448
- }).catch((err) => {
4449
- setAgentStatus("ERROR");
4450
- setChatHistory((prev) => [...prev, { role: "system", text: `Error: ${err.message}` }]);
4451
- });
4452
- }
4453
- };
4454
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", height: 30, padding: 1, children: [
4455
- /* @__PURE__ */ jsx(Sidebar, { history: ["New session - " + (/* @__PURE__ */ new Date()).toLocaleDateString()] }),
4456
- /* @__PURE__ */ jsx(
4457
- ChatArea,
4458
- {
4459
- history: chatHistory,
4460
- onSend: handleCommand,
4461
- placeholder: step === "prompt" ? "Ask Agdi..." : "Reply..."
4462
- }
4463
- ),
4464
- /* @__PURE__ */ jsx(ContextPanel, { files: activeFiles, agentStatus })
4465
- ] });
4466
- };
4467
- var App = () => {
4468
- const [screen, setScreen] = useState("boot");
4469
- return screen === "boot" ? /* @__PURE__ */ jsx(BootScreen, { onComplete: () => setScreen("dashboard") }) : /* @__PURE__ */ jsx(Dashboard, {});
4470
- };
4471
-
4472
- // src/commands/tui-entry.tsx
4473
- import { jsx as jsx2 } from "react/jsx-runtime";
4474
- function runTUI() {
4475
- console.clear();
4476
- render(/* @__PURE__ */ jsx2(App, {}));
4477
- }
4478
-
4479
4484
  // src/index.ts
4480
4485
  var BANNER = `
4481
- ${chalk14.cyan(` ___ __ _ `)}
4482
- ${chalk14.cyan(` / | ____ _____/ /(_) `)}
4483
- ${chalk14.cyan(` / /| | / __ \`/ __ // / `)}
4484
- ${chalk14.cyan(` / ___ |/ /_/ / /_/ // / `)}
4485
- ${chalk14.cyan(`/_/ |_|\\_, /\\__,_//_/ `)}
4486
- ${chalk14.cyan(` /____/ `)}
4486
+ ${chalk15.cyan(` ___ __ _ `)}
4487
+ ${chalk15.cyan(` / | ____ _____/ /(_) `)}
4488
+ ${chalk15.cyan(` / /| | / __ \`/ __ // / `)}
4489
+ ${chalk15.cyan(` / ___ |/ /_/ / /_/ // / `)}
4490
+ ${chalk15.cyan(`/_/ |_|\\_, /\\__,_//_/ `)}
4491
+ ${chalk15.cyan(` /____/ `)}
4487
4492
  `;
4488
4493
  var program = new Command();
4489
- program.name("agdi").description(chalk14.cyan("\u{1F9B8} The Autonomous AI Employee")).version("3.3.4").option("-y, --yes", "Auto-approve all prompts (headless/CI mode)").option("-m, --minimal", "Generate only the requested file(s), not a full app").option("-d, --dry-run", "Show what would be created without writing files").option("--saas", "Generate a production SaaS blueprint (Next.js + Prisma + Postgres + Stripe)");
4494
+ program.name("agdi").description(chalk15.cyan("\u{1F9B8} The Autonomous AI Employee")).version("3.3.5").option("-y, --yes", "Auto-approve all prompts (headless/CI mode)").option("-m, --minimal", "Generate only the requested file(s), not a full app").option("-d, --dry-run", "Show what would be created without writing files").option("--saas", "Generate a production SaaS blueprint (Next.js + Prisma + Postgres + Stripe)");
4490
4495
  program.hook("preAction", (thisCommand) => {
4491
4496
  const opts = thisCommand.opts();
4492
4497
  if (opts.yes) {
@@ -4503,14 +4508,14 @@ program.hook("preAction", (thisCommand) => {
4503
4508
  }
4504
4509
  });
4505
4510
  program.addHelpText("beforeAll", () => {
4506
- return BANNER + "\n" + chalk14.gray(" The Autonomous AI Employee") + "\n" + chalk14.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
4511
+ return BANNER + "\n" + chalk15.gray(" The Autonomous AI Employee") + "\n" + chalk15.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
4507
4512
  });
4508
4513
  program.action(async () => {
4509
4514
  try {
4510
- runTUI();
4515
+ await runWizard();
4511
4516
  } catch (error) {
4512
4517
  if (error.name === "ExitPromptError") {
4513
- console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
4518
+ console.log(chalk15.gray("\n\n\u{1F44B} Goodbye!\n"));
4514
4519
  try {
4515
4520
  ui.safeExit(0);
4516
4521
  } catch {
@@ -4532,7 +4537,7 @@ program.command("auth").description("Configure API keys").option("--status", "Sh
4532
4537
  }
4533
4538
  } catch (error) {
4534
4539
  if (error.name === "ExitPromptError") {
4535
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4540
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4536
4541
  try {
4537
4542
  ui.safeExit(0);
4538
4543
  } catch {
@@ -4550,7 +4555,7 @@ program.command("model").alias("models").description("Change AI model").action(a
4550
4555
  await selectModel();
4551
4556
  } catch (error) {
4552
4557
  if (error.name === "ExitPromptError") {
4553
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4558
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4554
4559
  try {
4555
4560
  ui.safeExit(0);
4556
4561
  } catch {
@@ -4571,7 +4576,7 @@ program.command("chat").description("Start a chat session").action(async () => {
4571
4576
  await startChat();
4572
4577
  } catch (error) {
4573
4578
  if (error.name === "ExitPromptError") {
4574
- console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
4579
+ console.log(chalk15.gray("\n\n\u{1F44B} Goodbye!\n"));
4575
4580
  try {
4576
4581
  ui.safeExit(0);
4577
4582
  } catch {
@@ -4589,7 +4594,7 @@ program.command("run [directory]").description("Run a generated project").action
4589
4594
  await runProject(directory);
4590
4595
  } catch (error) {
4591
4596
  if (error.name === "ExitPromptError") {
4592
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4597
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4593
4598
  try {
4594
4599
  ui.safeExit(0);
4595
4600
  } catch {
@@ -4612,7 +4617,7 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
4612
4617
  }
4613
4618
  const activeConfig = getActiveProvider();
4614
4619
  if (!activeConfig) {
4615
- console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
4620
+ console.log(chalk15.red("\u274C No API key configured. Run: agdi auth"));
4616
4621
  return;
4617
4622
  }
4618
4623
  const spinner = ora6("Generating application...").start();
@@ -4624,52 +4629,52 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
4624
4629
  const pm = new ProjectManager();
4625
4630
  pm.create(options.output.replace("./", ""), prompt);
4626
4631
  const { plan, files } = await generateApp(prompt, llm, (step, file) => {
4627
- spinner.text = file ? `${step} ${chalk14.gray(file)}` : step;
4632
+ spinner.text = file ? `${step} ${chalk15.gray(file)}` : step;
4628
4633
  });
4629
4634
  pm.updateFiles(files);
4630
4635
  pm.updateDependencies(plan.dependencies);
4631
4636
  if (options.dryRun || ui.flags.dryRun) {
4632
4637
  spinner.stop();
4633
- console.log(chalk14.cyan.bold("\n\u{1F6A7} DRY RUN SUMMARY\n"));
4634
- console.log(chalk14.gray(`Project: ${plan.name}
4638
+ console.log(chalk15.cyan.bold("\n\u{1F6A7} DRY RUN SUMMARY\n"));
4639
+ console.log(chalk15.gray(`Project: ${plan.name}
4635
4640
  `));
4636
- console.log(chalk14.cyan("Files to be created:"));
4637
- files.forEach((f) => console.log(chalk14.gray(` \u{1F4C4} ${f.path}`)));
4638
- console.log(chalk14.cyan("\nDependencies:"));
4639
- console.log(chalk14.gray(` \u{1F4E6} ${plan.dependencies.join(", ")}`));
4640
- console.log(chalk14.green("\n\u2713 Dry run complete. No files written.\n"));
4641
+ console.log(chalk15.cyan("Files to be created:"));
4642
+ files.forEach((f) => console.log(chalk15.gray(` \u{1F4C4} ${f.path}`)));
4643
+ console.log(chalk15.cyan("\nDependencies:"));
4644
+ console.log(chalk15.gray(` \u{1F4E6} ${plan.dependencies.join(", ")}`));
4645
+ console.log(chalk15.green("\n\u2713 Dry run complete. No files written.\n"));
4641
4646
  return;
4642
4647
  }
4643
4648
  await writeProject(pm.get(), options.output);
4644
- spinner.succeed(chalk14.green("App generated!"));
4645
- console.log(chalk14.gray(`
4646
- \u{1F4C1} Created ${files.length} files in ${chalk14.cyan(options.output)}`));
4649
+ spinner.succeed(chalk15.green("App generated!"));
4650
+ console.log(chalk15.gray(`
4651
+ \u{1F4C1} Created ${files.length} files in ${chalk15.cyan(options.output)}`));
4647
4652
  if (ui.flags.saas || options.saas) {
4648
- console.log(chalk14.cyan("\nSaaS Quick Start:"));
4649
- console.log(chalk14.gray(` 1) cd ${options.output}`));
4650
- console.log(chalk14.gray(" 2) npm install"));
4651
- console.log(chalk14.gray(" 3) cp .env.example .env"));
4652
- console.log(chalk14.gray(" 4) npx prisma generate"));
4653
- console.log(chalk14.gray(" 5) npx prisma db push"));
4654
- console.log(chalk14.gray(" 6) npm run dev\n"));
4653
+ console.log(chalk15.cyan("\nSaaS Quick Start:"));
4654
+ console.log(chalk15.gray(` 1) cd ${options.output}`));
4655
+ console.log(chalk15.gray(" 2) npm install"));
4656
+ console.log(chalk15.gray(" 3) cp .env.example .env"));
4657
+ console.log(chalk15.gray(" 4) npx prisma generate"));
4658
+ console.log(chalk15.gray(" 5) npx prisma db push"));
4659
+ console.log(chalk15.gray(" 6) npm run dev\n"));
4655
4660
  } else {
4656
- console.log(chalk14.gray("\nNext: cd " + options.output + " && npm install && npm run dev\n"));
4661
+ console.log(chalk15.gray("\nNext: cd " + options.output + " && npm install && npm run dev\n"));
4657
4662
  }
4658
4663
  } catch (error) {
4659
4664
  spinner.fail("Generation failed");
4660
4665
  const msg = error instanceof Error ? error.message : String(error);
4661
4666
  if (msg.includes("429") || msg.includes("quota")) {
4662
- console.log(chalk14.yellow("\n\u26A0\uFE0F Quota exceeded. Run: agdi model\n"));
4667
+ console.log(chalk15.yellow("\n\u26A0\uFE0F Quota exceeded. Run: agdi model\n"));
4663
4668
  } else if (msg.includes("401") || msg.includes("403")) {
4664
- console.log(chalk14.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
4669
+ console.log(chalk15.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
4665
4670
  } else {
4666
- console.error(chalk14.red("\n" + msg + "\n"));
4671
+ console.error(chalk15.red("\n" + msg + "\n"));
4667
4672
  }
4668
4673
  ui.safeExit(1);
4669
4674
  }
4670
4675
  } catch (error) {
4671
4676
  if (error.name === "ExitPromptError") {
4672
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4677
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4673
4678
  try {
4674
4679
  ui.safeExit(0);
4675
4680
  } catch {
@@ -4685,11 +4690,11 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
4685
4690
  program.command("config").description("Show configuration").action(async () => {
4686
4691
  const config = loadConfig();
4687
4692
  const active = getActiveProvider();
4688
- console.log(chalk14.cyan.bold("\n\u2699\uFE0F Configuration\n"));
4689
- console.log(chalk14.gray(" Provider: ") + chalk14.cyan(config.defaultProvider || "not set"));
4690
- console.log(chalk14.gray(" Model: ") + chalk14.cyan(config.defaultModel || "not set"));
4691
- console.log(chalk14.gray(" Config: ") + chalk14.gray("~/.agdi/config.json"));
4692
- console.log(chalk14.cyan.bold("\n\u{1F510} API Keys\n"));
4693
+ console.log(chalk15.cyan.bold("\n\u2699\uFE0F Configuration\n"));
4694
+ console.log(chalk15.gray(" Provider: ") + chalk15.cyan(config.defaultProvider || "not set"));
4695
+ console.log(chalk15.gray(" Model: ") + chalk15.cyan(config.defaultModel || "not set"));
4696
+ console.log(chalk15.gray(" Config: ") + chalk15.gray("~/.agdi/config.json"));
4697
+ console.log(chalk15.cyan.bold("\n\u{1F510} API Keys\n"));
4693
4698
  const keys = [
4694
4699
  ["Gemini", config.geminiApiKey],
4695
4700
  ["OpenRouter", config.openrouterApiKey],
@@ -4698,13 +4703,13 @@ program.command("config").description("Show configuration").action(async () => {
4698
4703
  ["DeepSeek", config.deepseekApiKey]
4699
4704
  ];
4700
4705
  for (const [name, key] of keys) {
4701
- const status = key ? chalk14.green("\u2713") : chalk14.gray("\u2717");
4706
+ const status = key ? chalk15.green("\u2713") : chalk15.gray("\u2717");
4702
4707
  console.log(` ${status} ${name}`);
4703
4708
  }
4704
- console.log(chalk14.cyan.bold("\n\u{1F4CA} Telemetry\n"));
4709
+ console.log(chalk15.cyan.bold("\n\u{1F4CA} Telemetry\n"));
4705
4710
  const telemetryEnabled = config.telemetry?.enabled ?? false;
4706
- console.log(` ${telemetryEnabled ? chalk14.green("\u2713 Enabled") : chalk14.gray("\u2717 Disabled")}`);
4707
- console.log(chalk14.gray(" Change with: agdi config telemetry --enable | --disable"));
4711
+ console.log(` ${telemetryEnabled ? chalk15.green("\u2713 Enabled") : chalk15.gray("\u2717 Disabled")}`);
4712
+ console.log(chalk15.gray(" Change with: agdi config telemetry --enable | --disable"));
4708
4713
  console.log("");
4709
4714
  console.log("");
4710
4715
  });
@@ -4712,59 +4717,59 @@ program.command("config:telemetry").alias("telemetry").description("Manage telem
4712
4717
  const { isTelemetryEnabled, setTelemetryConsent, getTelemetryConfig } = await import("./config-ZFU7TSU2.js");
4713
4718
  const { generateSampleEvent, generateSanitizationDemo } = await import("./telemetry-service-OHU5NKON.js");
4714
4719
  if (options.dryRun || options.test) {
4715
- console.log(chalk14.cyan.bold("\n\u{1F50D} TELEMETRY TRANSPARENCY MODE\n"));
4716
- console.log(chalk14.gray("This is exactly what Agdi sends. Notice there is"));
4717
- console.log(chalk14.green.bold("NO source code, file paths, or API keys.\n"));
4718
- console.log(chalk14.white.bold('\u{1F4CA} Sample "Build Failed" Event:\n'));
4720
+ console.log(chalk15.cyan.bold("\n\u{1F50D} TELEMETRY TRANSPARENCY MODE\n"));
4721
+ console.log(chalk15.gray("This is exactly what Agdi sends. Notice there is"));
4722
+ console.log(chalk15.green.bold("NO source code, file paths, or API keys.\n"));
4723
+ console.log(chalk15.white.bold('\u{1F4CA} Sample "Build Failed" Event:\n'));
4719
4724
  const sample = generateSampleEvent();
4720
- console.log(chalk14.gray(JSON.stringify(sample, null, 2)));
4721
- console.log(chalk14.white.bold("\n\u{1F6E1}\uFE0F Sanitization Demo:\n"));
4722
- console.log(chalk14.gray("Even if sensitive data accidentally enters an error message,"));
4723
- console.log(chalk14.gray("our sanitization layer strips it before transmission:\n"));
4725
+ console.log(chalk15.gray(JSON.stringify(sample, null, 2)));
4726
+ console.log(chalk15.white.bold("\n\u{1F6E1}\uFE0F Sanitization Demo:\n"));
4727
+ console.log(chalk15.gray("Even if sensitive data accidentally enters an error message,"));
4728
+ console.log(chalk15.gray("our sanitization layer strips it before transmission:\n"));
4724
4729
  const demo = generateSanitizationDemo();
4725
- console.log(chalk14.red.bold("BEFORE sanitization (never sent):"));
4726
- console.log(chalk14.gray(JSON.stringify({
4730
+ console.log(chalk15.red.bold("BEFORE sanitization (never sent):"));
4731
+ console.log(chalk15.gray(JSON.stringify({
4727
4732
  errorCode: demo.before.errorCode,
4728
4733
  feedback: demo.before.feedback
4729
4734
  }, null, 2)));
4730
- console.log(chalk14.green.bold("\nAFTER sanitization (what we actually send):"));
4731
- console.log(chalk14.gray(JSON.stringify({
4735
+ console.log(chalk15.green.bold("\nAFTER sanitization (what we actually send):"));
4736
+ console.log(chalk15.gray(JSON.stringify({
4732
4737
  errorCode: demo.after.errorCode,
4733
4738
  feedback: demo.after.feedback
4734
4739
  }, null, 2)));
4735
- console.log(chalk14.cyan("\n\u2705 Your code and secrets are NEVER transmitted."));
4736
- console.log(chalk14.gray(" Learn more: https://agdi.dev/privacy\n"));
4740
+ console.log(chalk15.cyan("\n\u2705 Your code and secrets are NEVER transmitted."));
4741
+ console.log(chalk15.gray(" Learn more: https://agdi.dev/privacy\n"));
4737
4742
  return;
4738
4743
  }
4739
4744
  if (options.enable) {
4740
4745
  setTelemetryConsent(true);
4741
- console.log(chalk14.green("\n\u2705 Telemetry enabled"));
4742
- console.log(chalk14.gray(" We collect: success/fail, error types, model used"));
4743
- console.log(chalk14.gray(" We NEVER collect: source code, API keys, file paths"));
4744
- console.log(chalk14.gray(" Verify anytime: agdi config telemetry --dry-run\n"));
4746
+ console.log(chalk15.green("\n\u2705 Telemetry enabled"));
4747
+ console.log(chalk15.gray(" We collect: success/fail, error types, model used"));
4748
+ console.log(chalk15.gray(" We NEVER collect: source code, API keys, file paths"));
4749
+ console.log(chalk15.gray(" Verify anytime: agdi config telemetry --dry-run\n"));
4745
4750
  } else if (options.disable) {
4746
4751
  setTelemetryConsent(false);
4747
- console.log(chalk14.yellow("\n\u{1F4CA} Telemetry disabled"));
4748
- console.log(chalk14.gray(" You can re-enable anytime with: agdi config telemetry --enable\n"));
4752
+ console.log(chalk15.yellow("\n\u{1F4CA} Telemetry disabled"));
4753
+ console.log(chalk15.gray(" You can re-enable anytime with: agdi config telemetry --enable\n"));
4749
4754
  } else {
4750
4755
  const config = getTelemetryConfig();
4751
- console.log(chalk14.cyan.bold("\n\u{1F4CA} Telemetry Status\n"));
4752
- console.log(chalk14.gray(" Enabled: ") + (config.enabled ? chalk14.green("Yes") : chalk14.gray("No")));
4753
- console.log(chalk14.gray(" Consent: ") + (config.consentAsked ? chalk14.green("Asked") : chalk14.gray("Not asked")));
4756
+ console.log(chalk15.cyan.bold("\n\u{1F4CA} Telemetry Status\n"));
4757
+ console.log(chalk15.gray(" Enabled: ") + (config.enabled ? chalk15.green("Yes") : chalk15.gray("No")));
4758
+ console.log(chalk15.gray(" Consent: ") + (config.consentAsked ? chalk15.green("Asked") : chalk15.gray("Not asked")));
4754
4759
  if (config.anonymousId) {
4755
- console.log(chalk14.gray(" ID: ") + chalk14.gray(config.anonymousId.slice(0, 8) + "..."));
4760
+ console.log(chalk15.gray(" ID: ") + chalk15.gray(config.anonymousId.slice(0, 8) + "..."));
4756
4761
  }
4757
4762
  console.log("");
4758
- console.log(chalk14.gray(" Enable: agdi config telemetry --enable"));
4759
- console.log(chalk14.gray(" Disable: agdi config telemetry --disable"));
4760
- console.log(chalk14.gray(" Verify: agdi config telemetry --dry-run\n"));
4763
+ console.log(chalk15.gray(" Enable: agdi config telemetry --enable"));
4764
+ console.log(chalk15.gray(" Disable: agdi config telemetry --disable"));
4765
+ console.log(chalk15.gray(" Verify: agdi config telemetry --dry-run\n"));
4761
4766
  }
4762
4767
  });
4763
4768
  program.command("doctor").alias("doc").description("Run self-diagnosis checks").action(async () => {
4764
4769
  try {
4765
4770
  await runDoctor();
4766
4771
  } catch (error) {
4767
- console.error(chalk14.red("Diagnostic failed: " + error));
4772
+ console.error(chalk15.red("Diagnostic failed: " + error));
4768
4773
  ui.safeExit(1);
4769
4774
  }
4770
4775
  });
@@ -4775,7 +4780,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
4775
4780
  }
4776
4781
  const activeConfig = getActiveProvider();
4777
4782
  if (!activeConfig) {
4778
- console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
4783
+ console.log(chalk15.red("\u274C No API key configured. Run: agdi auth"));
4779
4784
  return;
4780
4785
  }
4781
4786
  const llm = createLLMProvider(activeConfig.provider, {
@@ -4789,7 +4794,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
4789
4794
  });
4790
4795
  } catch (error) {
4791
4796
  if (error.name === "ExitPromptError") {
4792
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4797
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4793
4798
  try {
4794
4799
  ui.safeExit(0);
4795
4800
  } catch {
@@ -4817,7 +4822,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
4817
4822
  }
4818
4823
  const activeConfig = getActiveProvider();
4819
4824
  if (!activeConfig) {
4820
- console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
4825
+ console.log(chalk15.red("\u274C No API key configured. Run: agdi auth"));
4821
4826
  return;
4822
4827
  }
4823
4828
  const llm = createLLMProvider(activeConfig.provider, {
@@ -4831,7 +4836,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
4831
4836
  });
4832
4837
  } catch (error) {
4833
4838
  if (error.name === "ExitPromptError") {
4834
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4839
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4835
4840
  try {
4836
4841
  ui.safeExit(0);
4837
4842
  } catch {
@@ -4849,7 +4854,7 @@ program.command("import <url>").alias("i").description("\u{1F4E6} Import a GitHu
4849
4854
  await runImportCommand(url, options.output);
4850
4855
  } catch (error) {
4851
4856
  if (error.name === "ExitPromptError") {
4852
- console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
4857
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4853
4858
  try {
4854
4859
  ui.safeExit(0);
4855
4860
  } catch {
@@ -4859,4 +4864,15 @@ program.command("import <url>").alias("i").description("\u{1F4E6} Import a GitHu
4859
4864
  throw error;
4860
4865
  }
4861
4866
  });
4867
+ program.command("wizard").alias("w").description("\u{1F9D9} Start the ClawBot Setup Wizard").action(async () => {
4868
+ try {
4869
+ await runWizard();
4870
+ } catch (error) {
4871
+ console.log(chalk15.gray("\n\n\u{1F44B} Cancelled.\n"));
4872
+ try {
4873
+ ui.safeExit(0);
4874
+ } catch {
4875
+ }
4876
+ }
4877
+ });
4862
4878
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdi",
3
- "version": "3.3.4",
3
+ "version": "3.3.6",
4
4
  "description": "AI-powered app generator - build full-stack apps from natural language in your terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  "README.md"
19
19
  ],
20
20
  "scripts": {
21
- "build": "tsup src/index.ts --format esm --clean",
21
+ "build": "npx tsup src/index.ts --format esm --clean",
22
22
  "dev": "tsx src/index.ts",
23
23
  "start": "tsx src/dev.ts",
24
24
  "test": "vitest run",