agdi 3.2.0 → 3.3.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 +1 -0
- package/dist/index.js +265 -316
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
# 🦸 AGDI
|
|
7
7
|
### The Autonomous AI Software Squad in Your Terminal
|
|
8
|
+
#### v3.3.0: New Mission Control TUI
|
|
8
9
|
|
|
9
10
|
[](https://www.npmjs.com/package/agdi)
|
|
10
11
|
[](https://github.com/anassagd432/Agdi-dev)
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
-
import
|
|
9
|
+
import chalk14 from "chalk";
|
|
10
10
|
import ora6 from "ora";
|
|
11
11
|
|
|
12
12
|
// src/core/llm/index.ts
|
|
@@ -449,8 +449,8 @@ async function smartConfirm(message, defaultValue = false) {
|
|
|
449
449
|
console.warn(chalk.yellow("\u26A0\uFE0F Non-interactive session detected. Use --yes to approve actions."));
|
|
450
450
|
return false;
|
|
451
451
|
}
|
|
452
|
-
const { confirm
|
|
453
|
-
return
|
|
452
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
453
|
+
return confirm({ message, default: defaultValue });
|
|
454
454
|
}
|
|
455
455
|
async function smartSelect(message, choices, defaultValue) {
|
|
456
456
|
if (!process.stdout.isTTY || flags.headless) {
|
|
@@ -460,8 +460,8 @@ async function smartSelect(message, choices, defaultValue) {
|
|
|
460
460
|
}
|
|
461
461
|
return result || null;
|
|
462
462
|
}
|
|
463
|
-
const { select:
|
|
464
|
-
return
|
|
463
|
+
const { select: select3 } = await import("@inquirer/prompts");
|
|
464
|
+
return select3({ message, choices });
|
|
465
465
|
}
|
|
466
466
|
var ui = {
|
|
467
467
|
renderBanner,
|
|
@@ -1782,8 +1782,8 @@ async function runOnboarding() {
|
|
|
1782
1782
|
console.log(chalk7.gray("We collect anonymous error logs (like a ") + chalk7.yellow("'Check Engine'") + chalk7.gray(" light)"));
|
|
1783
1783
|
console.log(chalk7.gray("to fix bugs faster. We ") + chalk7.green.bold("never") + chalk7.gray(" see your code or keys.\n"));
|
|
1784
1784
|
console.log(chalk7.dim("Verify anytime: agdi config telemetry --dry-run\n"));
|
|
1785
|
-
const { confirm
|
|
1786
|
-
const enableTelemetry = await
|
|
1785
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
1786
|
+
const enableTelemetry = await confirm({
|
|
1787
1787
|
message: "Enable crash reporting? (helps us fix bugs)",
|
|
1788
1788
|
default: false
|
|
1789
1789
|
});
|
|
@@ -4075,225 +4075,19 @@ ${msg}
|
|
|
4075
4075
|
}
|
|
4076
4076
|
}
|
|
4077
4077
|
|
|
4078
|
-
// src/commands/wizard.ts
|
|
4079
|
-
import { input as input5, select as select3, confirm, password as password3 } from "@inquirer/prompts";
|
|
4080
|
-
import chalk13 from "chalk";
|
|
4081
|
-
import path6 from "path";
|
|
4082
|
-
import os from "os";
|
|
4083
|
-
import fs6 from "fs";
|
|
4084
|
-
async function runWizard() {
|
|
4085
|
-
await checkSafety();
|
|
4086
|
-
if (needsOnboarding()) {
|
|
4087
|
-
await runOnboarding();
|
|
4088
|
-
}
|
|
4089
|
-
await setupOptionalTools();
|
|
4090
|
-
const wantsSaas = await confirm({
|
|
4091
|
-
message: "Enable SaaS Blueprint mode? (Next.js + Prisma + Postgres + Stripe)",
|
|
4092
|
-
default: true
|
|
4093
|
-
});
|
|
4094
|
-
if (wantsSaas) {
|
|
4095
|
-
ui.setFlags({ saas: true });
|
|
4096
|
-
}
|
|
4097
|
-
console.log(chalk13.cyan.bold("\n\u{1F3AF} Mission Control"));
|
|
4098
|
-
console.log(chalk13.gray("Describe your app in detail. The Agdi Squad will handle the rest."));
|
|
4099
|
-
let prompt = await input5({
|
|
4100
|
-
message: "What are we building today?",
|
|
4101
|
-
validate: (value) => value.length > 5 ? true : "Please provide more detail (min 5 chars)"
|
|
4102
|
-
});
|
|
4103
|
-
if (wantsSaas) {
|
|
4104
|
-
prompt = `${prompt}
|
|
4105
|
-
|
|
4106
|
-
Constraints: Build a production SaaS using Next.js App Router, Prisma, Postgres, and Stripe. Include auth, billing, multi-tenant orgs, and a dashboard.`;
|
|
4107
|
-
}
|
|
4108
|
-
const activeConfig = getActiveProvider();
|
|
4109
|
-
if (!activeConfig) {
|
|
4110
|
-
console.log(chalk13.red("\u274C No API key configured. Run: agdi auth"));
|
|
4111
|
-
return;
|
|
4112
|
-
}
|
|
4113
|
-
const llm = createLLMProvider(activeConfig.provider, {
|
|
4114
|
-
apiKey: activeConfig.apiKey,
|
|
4115
|
-
model: activeConfig.model
|
|
4116
|
-
});
|
|
4117
|
-
console.log(chalk13.cyan("\n\u{1F914} Analyzing requirements..."));
|
|
4118
|
-
try {
|
|
4119
|
-
const analysis = await llm.generate(prompt, `
|
|
4120
|
-
You are a Senior Product Manager. Analyze this app idea.
|
|
4121
|
-
If it is vague (e.g., "make a CRM"), generate 3 specific questions to clarify scope, tech stack, and features.
|
|
4122
|
-
If it is detailed enough, return "DETAILED".
|
|
4123
|
-
|
|
4124
|
-
Format:
|
|
4125
|
-
Questions:
|
|
4126
|
-
1. [Question 1]
|
|
4127
|
-
2. [Question 2]
|
|
4128
|
-
3. [Question 3]
|
|
4129
|
-
`);
|
|
4130
|
-
if (!analysis.text.includes("DETAILED")) {
|
|
4131
|
-
console.log(chalk13.yellow("\n\u{1F4A1} I need a few more details to build exactly what you want:"));
|
|
4132
|
-
const questions = analysis.text.split("\n").filter((line) => line.match(/^\d+\./));
|
|
4133
|
-
const answers = [];
|
|
4134
|
-
for (const q of questions.slice(0, 3)) {
|
|
4135
|
-
const answer = await input5({ message: q.replace(/^\d+\.\s*/, "") });
|
|
4136
|
-
answers.push({ q, a: answer });
|
|
4137
|
-
}
|
|
4138
|
-
console.log(chalk13.cyan("\n\u{1F504} Synthesizing Master Plan..."));
|
|
4139
|
-
const synthesis = await llm.generate(
|
|
4140
|
-
`Original Request: ${prompt}
|
|
4141
|
-
|
|
4142
|
-
Clarifications:
|
|
4143
|
-
${answers.map((x) => `Q: ${x.q}
|
|
4144
|
-
A: ${x.a}`).join("\n")}
|
|
4145
|
-
|
|
4146
|
-
Rewrite the original request into a comprehensive technical specification for a developer squad.`,
|
|
4147
|
-
"You are a Technical Architect."
|
|
4148
|
-
);
|
|
4149
|
-
prompt = synthesis.text;
|
|
4150
|
-
console.log(chalk13.gray("\nUpdated Spec: " + prompt.substring(0, 100) + "...\n"));
|
|
4151
|
-
}
|
|
4152
|
-
} catch (err) {
|
|
4153
|
-
console.log(chalk13.gray("Skipping analysis (API unreachable), proceeding with raw prompt."));
|
|
4154
|
-
}
|
|
4155
|
-
console.log(chalk13.cyan("\n\u{1F680} Assembling the Squad..."));
|
|
4156
|
-
console.log(chalk13.gray("Frontend, Backend, QA, and DevOps agents are coming online.\n"));
|
|
4157
|
-
const config = loadConfig();
|
|
4158
|
-
const canDeploy = !!(config.vercelToken || config.netlifyToken || config.railwayToken);
|
|
4159
|
-
await runSquadCommand(prompt, llm, {
|
|
4160
|
-
deploy: canDeploy,
|
|
4161
|
-
// Auto-deploy if configured
|
|
4162
|
-
output: "./",
|
|
4163
|
-
// Current directory (safe because we checked safety earlier)
|
|
4164
|
-
verbose: true
|
|
4165
|
-
});
|
|
4166
|
-
if (ui.flags.saas) {
|
|
4167
|
-
console.log(chalk13.cyan("\nSaaS Quick Start:"));
|
|
4168
|
-
console.log(chalk13.gray(" 1) npm install"));
|
|
4169
|
-
console.log(chalk13.gray(" 2) cp .env.example .env"));
|
|
4170
|
-
console.log(chalk13.gray(" 3) npx prisma generate"));
|
|
4171
|
-
console.log(chalk13.gray(" 4) npx prisma db push"));
|
|
4172
|
-
console.log(chalk13.gray(" 5) npm run dev\n"));
|
|
4173
|
-
}
|
|
4174
|
-
}
|
|
4175
|
-
async function checkSafety() {
|
|
4176
|
-
const cwd = process.cwd();
|
|
4177
|
-
const home = os.homedir();
|
|
4178
|
-
const root = path6.parse(cwd).root;
|
|
4179
|
-
const isUnsafe = cwd === home || cwd === root;
|
|
4180
|
-
if (isUnsafe) {
|
|
4181
|
-
console.log(chalk13.yellow.bold("\n\u26A0\uFE0F Safety Warning"));
|
|
4182
|
-
console.log(chalk13.gray(`You are running Agdi in ${chalk13.cyan(cwd)}.`));
|
|
4183
|
-
console.log(chalk13.gray("Agdi writes files and runs commands. It needs its own space.\n"));
|
|
4184
|
-
const action = await select3({
|
|
4185
|
-
message: "What would you like to do?",
|
|
4186
|
-
choices: [
|
|
4187
|
-
{ name: "\u{1F4C2} Create a new project folder (Recommended)", value: "create" },
|
|
4188
|
-
{ name: "\u{1F525} Run here anyway (Dangerous)", value: "unsafe" },
|
|
4189
|
-
{ name: "\u274C Cancel", value: "cancel" }
|
|
4190
|
-
]
|
|
4191
|
-
});
|
|
4192
|
-
if (action === "cancel") {
|
|
4193
|
-
ui.safeExit(0);
|
|
4194
|
-
}
|
|
4195
|
-
if (action === "create") {
|
|
4196
|
-
const folderName = await input5({
|
|
4197
|
-
message: "Project name:",
|
|
4198
|
-
default: "my-agdi-app",
|
|
4199
|
-
validate: (v) => /^[a-z0-9-_]+$/i.test(v) ? true : "Invalid folder name"
|
|
4200
|
-
});
|
|
4201
|
-
const newPath = path6.join(cwd, folderName);
|
|
4202
|
-
if (!fs6.existsSync(newPath)) {
|
|
4203
|
-
fs6.mkdirSync(newPath);
|
|
4204
|
-
}
|
|
4205
|
-
process.chdir(newPath);
|
|
4206
|
-
console.log(chalk13.green(`
|
|
4207
|
-
\u{1F4C2} Switched to: ${chalk13.cyan(newPath)}
|
|
4208
|
-
`));
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
}
|
|
4212
|
-
async function setupOptionalTools() {
|
|
4213
|
-
const config = loadConfig();
|
|
4214
|
-
let configChanged = false;
|
|
4215
|
-
if (!config.searchApiKey) {
|
|
4216
|
-
console.log(chalk13.white.bold("\n\u{1F310} Web Access (Optional)\n"));
|
|
4217
|
-
console.log(chalk13.gray("Giving Agdi web access allows it to find up-to-date docs and fix tricky bugs."));
|
|
4218
|
-
const wantsSearch = await confirm({
|
|
4219
|
-
message: "Enable web search capabilities?",
|
|
4220
|
-
default: true
|
|
4221
|
-
});
|
|
4222
|
-
if (wantsSearch) {
|
|
4223
|
-
const provider = await select3({
|
|
4224
|
-
message: "Select Search Provider:",
|
|
4225
|
-
choices: [
|
|
4226
|
-
{ name: "Brave Search (Recommended)", value: "brave" },
|
|
4227
|
-
{ name: "Tavily", value: "tavily" }
|
|
4228
|
-
]
|
|
4229
|
-
});
|
|
4230
|
-
const keyUrl = provider === "brave" ? "https://brave.com/search/api/" : "https://tavily.com/";
|
|
4231
|
-
console.log(chalk13.gray(`Get your key at: ${chalk13.cyan(keyUrl)}
|
|
4232
|
-
`));
|
|
4233
|
-
const apiKey = await password3({
|
|
4234
|
-
message: `Enter your ${provider} API key:`,
|
|
4235
|
-
mask: "*"
|
|
4236
|
-
});
|
|
4237
|
-
if (apiKey) {
|
|
4238
|
-
config.searchApiKey = apiKey;
|
|
4239
|
-
config.searchProvider = provider;
|
|
4240
|
-
config.searchEnabled = true;
|
|
4241
|
-
configChanged = true;
|
|
4242
|
-
console.log(chalk13.green("\u2705 Web search enabled!"));
|
|
4243
|
-
}
|
|
4244
|
-
}
|
|
4245
|
-
}
|
|
4246
|
-
if (!config.vercelToken && !config.netlifyToken && !config.railwayToken) {
|
|
4247
|
-
console.log(chalk13.white.bold("\n\u{1F680} Deployment (Optional)\n"));
|
|
4248
|
-
console.log(chalk13.gray("Agdi can automatically deploy your app to the cloud when finished."));
|
|
4249
|
-
const wantsDeploy = await confirm({
|
|
4250
|
-
message: "Enable auto-deployment?",
|
|
4251
|
-
default: true
|
|
4252
|
-
});
|
|
4253
|
-
if (wantsDeploy) {
|
|
4254
|
-
const provider = await select3({
|
|
4255
|
-
message: "Select Deployment Target:",
|
|
4256
|
-
choices: [
|
|
4257
|
-
{ name: "Vercel", value: "vercel" },
|
|
4258
|
-
{ name: "Railway", value: "railway" },
|
|
4259
|
-
{ name: "Netlify", value: "netlify" }
|
|
4260
|
-
]
|
|
4261
|
-
});
|
|
4262
|
-
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";
|
|
4263
|
-
console.log(chalk13.gray(`Get your key at: ${chalk13.cyan(keyUrl)}
|
|
4264
|
-
`));
|
|
4265
|
-
const apiKey = await password3({
|
|
4266
|
-
message: `Enter your ${provider} API token:`,
|
|
4267
|
-
mask: "*"
|
|
4268
|
-
});
|
|
4269
|
-
if (apiKey) {
|
|
4270
|
-
if (provider === "vercel") config.vercelToken = apiKey;
|
|
4271
|
-
if (provider === "netlify") config.netlifyToken = apiKey;
|
|
4272
|
-
if (provider === "railway") config.railwayToken = apiKey;
|
|
4273
|
-
config.deploymentProvider = provider;
|
|
4274
|
-
configChanged = true;
|
|
4275
|
-
console.log(chalk13.green("\u2705 Auto-deployment enabled!"));
|
|
4276
|
-
}
|
|
4277
|
-
}
|
|
4278
|
-
}
|
|
4279
|
-
if (configChanged) {
|
|
4280
|
-
saveConfig(config);
|
|
4281
|
-
}
|
|
4282
|
-
}
|
|
4283
|
-
|
|
4284
4078
|
// src/commands/replay.ts
|
|
4285
|
-
import
|
|
4286
|
-
import * as
|
|
4287
|
-
import * as
|
|
4079
|
+
import chalk13 from "chalk";
|
|
4080
|
+
import * as fs6 from "fs/promises";
|
|
4081
|
+
import * as path6 from "path";
|
|
4288
4082
|
async function runReplayCommand(runId, llm, options = {}) {
|
|
4289
4083
|
const workspaceRoot = options.workspace || process.cwd();
|
|
4290
|
-
const runConfigPath =
|
|
4291
|
-
const outputsDir =
|
|
4084
|
+
const runConfigPath = path6.join(workspaceRoot, "runs", runId, "run.json");
|
|
4085
|
+
const outputsDir = path6.join(workspaceRoot, "runs", runId, "outputs");
|
|
4292
4086
|
try {
|
|
4293
|
-
const raw = await
|
|
4087
|
+
const raw = await fs6.readFile(runConfigPath, "utf-8");
|
|
4294
4088
|
const runConfig = JSON.parse(raw);
|
|
4295
4089
|
if (!runConfig.prompt) {
|
|
4296
|
-
console.log(
|
|
4090
|
+
console.log(chalk13.red("\u274C Invalid run.json (missing prompt)"));
|
|
4297
4091
|
return null;
|
|
4298
4092
|
}
|
|
4299
4093
|
const config = {
|
|
@@ -4302,31 +4096,31 @@ async function runReplayCommand(runId, llm, options = {}) {
|
|
|
4302
4096
|
verbose: options.verbose ?? runConfig.config?.verbose ?? true,
|
|
4303
4097
|
autoDeploy: options.deploy ?? runConfig.config?.autoDeploy ?? false
|
|
4304
4098
|
};
|
|
4305
|
-
console.log(
|
|
4099
|
+
console.log(chalk13.cyan(`
|
|
4306
4100
|
\u{1F501} Replaying run ${runId}`));
|
|
4307
4101
|
if (options.exact !== false) {
|
|
4308
4102
|
try {
|
|
4309
|
-
const entries = await
|
|
4103
|
+
const entries = await fs6.readdir(outputsDir, { withFileTypes: true });
|
|
4310
4104
|
if (entries.length === 0) {
|
|
4311
4105
|
throw new Error("No outputs found");
|
|
4312
4106
|
}
|
|
4313
4107
|
const copyOutputs = async (dir, rel = "") => {
|
|
4314
|
-
const files = await
|
|
4108
|
+
const files = await fs6.readdir(dir, { withFileTypes: true });
|
|
4315
4109
|
for (const file of files) {
|
|
4316
|
-
const sourcePath =
|
|
4317
|
-
const targetRel =
|
|
4318
|
-
const targetPath =
|
|
4110
|
+
const sourcePath = path6.join(dir, file.name);
|
|
4111
|
+
const targetRel = path6.join(rel, file.name);
|
|
4112
|
+
const targetPath = path6.join(workspaceRoot, targetRel);
|
|
4319
4113
|
if (file.isDirectory()) {
|
|
4320
4114
|
await copyOutputs(sourcePath, targetRel);
|
|
4321
4115
|
} else if (file.isFile()) {
|
|
4322
|
-
await
|
|
4323
|
-
const content = await
|
|
4324
|
-
await
|
|
4116
|
+
await fs6.mkdir(path6.dirname(targetPath), { recursive: true });
|
|
4117
|
+
const content = await fs6.readFile(sourcePath, "utf-8");
|
|
4118
|
+
await fs6.writeFile(targetPath, content, "utf-8");
|
|
4325
4119
|
}
|
|
4326
4120
|
}
|
|
4327
4121
|
};
|
|
4328
4122
|
await copyOutputs(outputsDir);
|
|
4329
|
-
console.log(
|
|
4123
|
+
console.log(chalk13.green("\u2705 Exact replay applied from stored outputs."));
|
|
4330
4124
|
return {
|
|
4331
4125
|
success: true,
|
|
4332
4126
|
projectSpec: { name: "replay", description: "Exact replay", type: "web-app", stack: {}, features: [] },
|
|
@@ -4337,34 +4131,190 @@ async function runReplayCommand(runId, llm, options = {}) {
|
|
|
4337
4131
|
errors: []
|
|
4338
4132
|
};
|
|
4339
4133
|
} catch (error) {
|
|
4340
|
-
console.log(
|
|
4341
|
-
console.log(
|
|
4134
|
+
console.log(chalk13.yellow("\u26A0\uFE0F Exact replay failed, falling back to rerun."));
|
|
4135
|
+
console.log(chalk13.gray(String(error)));
|
|
4342
4136
|
}
|
|
4343
4137
|
}
|
|
4344
4138
|
if (!llm) {
|
|
4345
|
-
console.log(
|
|
4139
|
+
console.log(chalk13.red("\u274C No LLM provider available for replay."));
|
|
4346
4140
|
return null;
|
|
4347
4141
|
}
|
|
4348
4142
|
const orchestrator = new SquadOrchestrator(llm, config);
|
|
4349
4143
|
return await orchestrator.run(runConfig.prompt);
|
|
4350
4144
|
} catch (error) {
|
|
4351
|
-
console.log(
|
|
4352
|
-
console.log(
|
|
4145
|
+
console.log(chalk13.red("\u274C Failed to load run config for replay"));
|
|
4146
|
+
console.log(chalk13.gray(String(error)));
|
|
4353
4147
|
return null;
|
|
4354
4148
|
}
|
|
4355
4149
|
}
|
|
4356
4150
|
|
|
4151
|
+
// src/commands/tui-entry.tsx
|
|
4152
|
+
import { render } from "ink";
|
|
4153
|
+
|
|
4154
|
+
// src/ui/tui.tsx
|
|
4155
|
+
import { useState, useEffect } from "react";
|
|
4156
|
+
import { Box, Text, useApp } from "ink";
|
|
4157
|
+
import BigText from "ink-big-text";
|
|
4158
|
+
import TextInput from "ink-text-input";
|
|
4159
|
+
import fs7 from "fs";
|
|
4160
|
+
import path7 from "path";
|
|
4161
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4162
|
+
var BootScreen = ({ onComplete }) => {
|
|
4163
|
+
const [progress, setProgress] = useState(0);
|
|
4164
|
+
const [log, setLog] = useState("");
|
|
4165
|
+
const logs = [
|
|
4166
|
+
"Initializing core systems...",
|
|
4167
|
+
"Loading neural modules...",
|
|
4168
|
+
"Connecting to Agdi Cloud...",
|
|
4169
|
+
"Verifying agent credentials...",
|
|
4170
|
+
"Mounting virtual filesystem...",
|
|
4171
|
+
"Establishing secure uplink...",
|
|
4172
|
+
"Syncing global state...",
|
|
4173
|
+
"Boot sequence complete."
|
|
4174
|
+
];
|
|
4175
|
+
useEffect(() => {
|
|
4176
|
+
const timer = setInterval(() => {
|
|
4177
|
+
setProgress((prev) => {
|
|
4178
|
+
const next = prev + 2;
|
|
4179
|
+
if (next >= 100) {
|
|
4180
|
+
clearInterval(timer);
|
|
4181
|
+
setTimeout(onComplete, 500);
|
|
4182
|
+
return 100;
|
|
4183
|
+
}
|
|
4184
|
+
return next;
|
|
4185
|
+
});
|
|
4186
|
+
const index = Math.floor(progress / 100 * logs.length);
|
|
4187
|
+
setLog(logs[index] || logs[logs.length - 1]);
|
|
4188
|
+
}, 30);
|
|
4189
|
+
return () => clearInterval(timer);
|
|
4190
|
+
}, [progress]);
|
|
4191
|
+
const width = 60;
|
|
4192
|
+
const filled = Math.floor(width * progress / 100);
|
|
4193
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
|
|
4194
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "center", justifyContent: "center", height: 20, children: [
|
|
4195
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(BigText, { text: "AGDI OS", font: "block", align: "center", colors: ["cyan", "blue"] }) }),
|
|
4196
|
+
/* @__PURE__ */ jsx(Box, { marginY: 1, children: /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
4197
|
+
bar,
|
|
4198
|
+
" ",
|
|
4199
|
+
progress,
|
|
4200
|
+
"%"
|
|
4201
|
+
] }) }),
|
|
4202
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
4203
|
+
"\u279C ",
|
|
4204
|
+
log
|
|
4205
|
+
] })
|
|
4206
|
+
] });
|
|
4207
|
+
};
|
|
4208
|
+
var FileExplorer = ({ cwd }) => {
|
|
4209
|
+
const [files, setFiles] = useState([]);
|
|
4210
|
+
useEffect(() => {
|
|
4211
|
+
try {
|
|
4212
|
+
const list = fs7.readdirSync(cwd).filter((f) => !f.startsWith(".")).slice(0, 15);
|
|
4213
|
+
setFiles(list);
|
|
4214
|
+
} catch {
|
|
4215
|
+
setFiles(["<Error reading dir>"]);
|
|
4216
|
+
}
|
|
4217
|
+
}, [cwd]);
|
|
4218
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", title: " FILESYSTEM ", width: "30%", children: [
|
|
4219
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
|
|
4220
|
+
" ",
|
|
4221
|
+
cwd
|
|
4222
|
+
] }),
|
|
4223
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
4224
|
+
files.map((f, i) => /* @__PURE__ */ jsxs(Text, { color: "white", children: [
|
|
4225
|
+
fs7.statSync(path7.join(cwd, f)).isDirectory() ? "\u{1F4C1} " : "\u{1F4C4} ",
|
|
4226
|
+
f
|
|
4227
|
+
] }, i)),
|
|
4228
|
+
files.length === 0 && /* @__PURE__ */ jsx(Text, { color: "gray", children: " (empty)" })
|
|
4229
|
+
] })
|
|
4230
|
+
] });
|
|
4231
|
+
};
|
|
4232
|
+
var LogPanel = ({ logs }) => {
|
|
4233
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", title: " AGENT LOGS ", width: "70%", marginLeft: 1, children: [
|
|
4234
|
+
logs.slice(-10).map((log, i) => /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4235
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
4236
|
+
"[",
|
|
4237
|
+
(/* @__PURE__ */ new Date()).toLocaleTimeString(),
|
|
4238
|
+
"]"
|
|
4239
|
+
] }),
|
|
4240
|
+
" ",
|
|
4241
|
+
log
|
|
4242
|
+
] }, i)),
|
|
4243
|
+
logs.length === 0 && /* @__PURE__ */ jsx(Text, { color: "gray", children: "Waiting for agent activity..." })
|
|
4244
|
+
] });
|
|
4245
|
+
};
|
|
4246
|
+
var ChatPanel = ({ history, onSend }) => {
|
|
4247
|
+
const [query, setQuery] = useState("");
|
|
4248
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", title: " MISSION CONTROL ", height: 12, children: [
|
|
4249
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, justifyContent: "flex-end", children: history.slice(-5).map((msg, i) => /* @__PURE__ */ jsxs(Box, { marginY: 0, children: [
|
|
4250
|
+
/* @__PURE__ */ jsx(Text, { color: msg.role === "user" ? "cyan" : "magenta", bold: true, children: msg.role === "user" ? "YOU \u203A " : "AGDI \u203A " }),
|
|
4251
|
+
/* @__PURE__ */ jsx(Text, { children: msg.text })
|
|
4252
|
+
] }, i)) }),
|
|
4253
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "gray", marginTop: 1, children: [
|
|
4254
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u279C " }),
|
|
4255
|
+
/* @__PURE__ */ jsx(
|
|
4256
|
+
TextInput,
|
|
4257
|
+
{
|
|
4258
|
+
value: query,
|
|
4259
|
+
onChange: setQuery,
|
|
4260
|
+
onSubmit: (val) => {
|
|
4261
|
+
onSend(val);
|
|
4262
|
+
setQuery("");
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
)
|
|
4266
|
+
] })
|
|
4267
|
+
] });
|
|
4268
|
+
};
|
|
4269
|
+
var Dashboard = () => {
|
|
4270
|
+
const { exit } = useApp();
|
|
4271
|
+
const [logs, setLogs] = useState(["System ready.", "Waiting for instructions."]);
|
|
4272
|
+
const [chatHistory, setChatHistory] = useState([]);
|
|
4273
|
+
const addLog = (msg) => setLogs((prev) => [...prev, msg]);
|
|
4274
|
+
const handleCommand = (cmd) => {
|
|
4275
|
+
if (cmd === "/exit") exit();
|
|
4276
|
+
setChatHistory((prev) => [...prev, { role: "user", text: cmd }]);
|
|
4277
|
+
addLog(`Processing command: ${cmd}`);
|
|
4278
|
+
setTimeout(() => {
|
|
4279
|
+
setChatHistory((prev) => [...prev, { role: "ai", text: `I'm analyzing your request to "${cmd}"...` }]);
|
|
4280
|
+
addLog("Agent [Manager] started planning phase.");
|
|
4281
|
+
}, 800);
|
|
4282
|
+
};
|
|
4283
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, height: "100%", children: [
|
|
4284
|
+
/* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
4285
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "AGDI v3.3.0 [ONLINE]" }),
|
|
4286
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "CPU: 12% | MEM: 450MB | NET: CONNECTED" })
|
|
4287
|
+
] }),
|
|
4288
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", flexGrow: 1, children: [
|
|
4289
|
+
/* @__PURE__ */ jsx(FileExplorer, { cwd: process.cwd() }),
|
|
4290
|
+
/* @__PURE__ */ jsx(LogPanel, { logs })
|
|
4291
|
+
] }),
|
|
4292
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(ChatPanel, { history: chatHistory, onSend: handleCommand }) })
|
|
4293
|
+
] });
|
|
4294
|
+
};
|
|
4295
|
+
var App = () => {
|
|
4296
|
+
const [screen, setScreen] = useState("boot");
|
|
4297
|
+
return screen === "boot" ? /* @__PURE__ */ jsx(BootScreen, { onComplete: () => setScreen("dashboard") }) : /* @__PURE__ */ jsx(Dashboard, {});
|
|
4298
|
+
};
|
|
4299
|
+
|
|
4300
|
+
// src/commands/tui-entry.tsx
|
|
4301
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
4302
|
+
function runTUI() {
|
|
4303
|
+
console.clear();
|
|
4304
|
+
render(/* @__PURE__ */ jsx2(App, {}));
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4357
4307
|
// src/index.ts
|
|
4358
4308
|
var BANNER = `
|
|
4359
|
-
${
|
|
4360
|
-
${
|
|
4361
|
-
${
|
|
4362
|
-
${
|
|
4363
|
-
${
|
|
4364
|
-
${
|
|
4309
|
+
${chalk14.cyan(` ___ __ _ `)}
|
|
4310
|
+
${chalk14.cyan(` / | ____ _____/ /(_) `)}
|
|
4311
|
+
${chalk14.cyan(` / /| | / __ \`/ __ // / `)}
|
|
4312
|
+
${chalk14.cyan(` / ___ |/ /_/ / /_/ // / `)}
|
|
4313
|
+
${chalk14.cyan(`/_/ |_|\\_, /\\__,_//_/ `)}
|
|
4314
|
+
${chalk14.cyan(` /____/ `)}
|
|
4365
4315
|
`;
|
|
4366
4316
|
var program = new Command();
|
|
4367
|
-
program.name("agdi").description(
|
|
4317
|
+
program.name("agdi").description(chalk14.cyan("\u{1F9B8} The Autonomous AI Employee")).version("3.3.0").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)");
|
|
4368
4318
|
program.hook("preAction", (thisCommand) => {
|
|
4369
4319
|
const opts = thisCommand.opts();
|
|
4370
4320
|
if (opts.yes) {
|
|
@@ -4381,15 +4331,14 @@ program.hook("preAction", (thisCommand) => {
|
|
|
4381
4331
|
}
|
|
4382
4332
|
});
|
|
4383
4333
|
program.addHelpText("beforeAll", () => {
|
|
4384
|
-
return BANNER + "\n" +
|
|
4334
|
+
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");
|
|
4385
4335
|
});
|
|
4386
4336
|
program.action(async () => {
|
|
4387
4337
|
try {
|
|
4388
|
-
|
|
4389
|
-
await runWizard();
|
|
4338
|
+
runTUI();
|
|
4390
4339
|
} catch (error) {
|
|
4391
4340
|
if (error.name === "ExitPromptError") {
|
|
4392
|
-
console.log(
|
|
4341
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
4393
4342
|
try {
|
|
4394
4343
|
ui.safeExit(0);
|
|
4395
4344
|
} catch {
|
|
@@ -4411,7 +4360,7 @@ program.command("auth").description("Configure API keys").option("--status", "Sh
|
|
|
4411
4360
|
}
|
|
4412
4361
|
} catch (error) {
|
|
4413
4362
|
if (error.name === "ExitPromptError") {
|
|
4414
|
-
console.log(
|
|
4363
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4415
4364
|
try {
|
|
4416
4365
|
ui.safeExit(0);
|
|
4417
4366
|
} catch {
|
|
@@ -4429,7 +4378,7 @@ program.command("model").alias("models").description("Change AI model").action(a
|
|
|
4429
4378
|
await selectModel();
|
|
4430
4379
|
} catch (error) {
|
|
4431
4380
|
if (error.name === "ExitPromptError") {
|
|
4432
|
-
console.log(
|
|
4381
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4433
4382
|
try {
|
|
4434
4383
|
ui.safeExit(0);
|
|
4435
4384
|
} catch {
|
|
@@ -4450,7 +4399,7 @@ program.command("chat").description("Start a chat session").action(async () => {
|
|
|
4450
4399
|
await startChat();
|
|
4451
4400
|
} catch (error) {
|
|
4452
4401
|
if (error.name === "ExitPromptError") {
|
|
4453
|
-
console.log(
|
|
4402
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
4454
4403
|
try {
|
|
4455
4404
|
ui.safeExit(0);
|
|
4456
4405
|
} catch {
|
|
@@ -4468,7 +4417,7 @@ program.command("run [directory]").description("Run a generated project").action
|
|
|
4468
4417
|
await runProject(directory);
|
|
4469
4418
|
} catch (error) {
|
|
4470
4419
|
if (error.name === "ExitPromptError") {
|
|
4471
|
-
console.log(
|
|
4420
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4472
4421
|
try {
|
|
4473
4422
|
ui.safeExit(0);
|
|
4474
4423
|
} catch {
|
|
@@ -4491,7 +4440,7 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4491
4440
|
}
|
|
4492
4441
|
const activeConfig = getActiveProvider();
|
|
4493
4442
|
if (!activeConfig) {
|
|
4494
|
-
console.log(
|
|
4443
|
+
console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
|
|
4495
4444
|
return;
|
|
4496
4445
|
}
|
|
4497
4446
|
const spinner = ora6("Generating application...").start();
|
|
@@ -4503,52 +4452,52 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4503
4452
|
const pm = new ProjectManager();
|
|
4504
4453
|
pm.create(options.output.replace("./", ""), prompt);
|
|
4505
4454
|
const { plan, files } = await generateApp(prompt, llm, (step, file) => {
|
|
4506
|
-
spinner.text = file ? `${step} ${
|
|
4455
|
+
spinner.text = file ? `${step} ${chalk14.gray(file)}` : step;
|
|
4507
4456
|
});
|
|
4508
4457
|
pm.updateFiles(files);
|
|
4509
4458
|
pm.updateDependencies(plan.dependencies);
|
|
4510
4459
|
if (options.dryRun || ui.flags.dryRun) {
|
|
4511
4460
|
spinner.stop();
|
|
4512
|
-
console.log(
|
|
4513
|
-
console.log(
|
|
4461
|
+
console.log(chalk14.cyan.bold("\n\u{1F6A7} DRY RUN SUMMARY\n"));
|
|
4462
|
+
console.log(chalk14.gray(`Project: ${plan.name}
|
|
4514
4463
|
`));
|
|
4515
|
-
console.log(
|
|
4516
|
-
files.forEach((f) => console.log(
|
|
4517
|
-
console.log(
|
|
4518
|
-
console.log(
|
|
4519
|
-
console.log(
|
|
4464
|
+
console.log(chalk14.cyan("Files to be created:"));
|
|
4465
|
+
files.forEach((f) => console.log(chalk14.gray(` \u{1F4C4} ${f.path}`)));
|
|
4466
|
+
console.log(chalk14.cyan("\nDependencies:"));
|
|
4467
|
+
console.log(chalk14.gray(` \u{1F4E6} ${plan.dependencies.join(", ")}`));
|
|
4468
|
+
console.log(chalk14.green("\n\u2713 Dry run complete. No files written.\n"));
|
|
4520
4469
|
return;
|
|
4521
4470
|
}
|
|
4522
4471
|
await writeProject(pm.get(), options.output);
|
|
4523
|
-
spinner.succeed(
|
|
4524
|
-
console.log(
|
|
4525
|
-
\u{1F4C1} Created ${files.length} files in ${
|
|
4472
|
+
spinner.succeed(chalk14.green("App generated!"));
|
|
4473
|
+
console.log(chalk14.gray(`
|
|
4474
|
+
\u{1F4C1} Created ${files.length} files in ${chalk14.cyan(options.output)}`));
|
|
4526
4475
|
if (ui.flags.saas || options.saas) {
|
|
4527
|
-
console.log(
|
|
4528
|
-
console.log(
|
|
4529
|
-
console.log(
|
|
4530
|
-
console.log(
|
|
4531
|
-
console.log(
|
|
4532
|
-
console.log(
|
|
4533
|
-
console.log(
|
|
4476
|
+
console.log(chalk14.cyan("\nSaaS Quick Start:"));
|
|
4477
|
+
console.log(chalk14.gray(` 1) cd ${options.output}`));
|
|
4478
|
+
console.log(chalk14.gray(" 2) npm install"));
|
|
4479
|
+
console.log(chalk14.gray(" 3) cp .env.example .env"));
|
|
4480
|
+
console.log(chalk14.gray(" 4) npx prisma generate"));
|
|
4481
|
+
console.log(chalk14.gray(" 5) npx prisma db push"));
|
|
4482
|
+
console.log(chalk14.gray(" 6) npm run dev\n"));
|
|
4534
4483
|
} else {
|
|
4535
|
-
console.log(
|
|
4484
|
+
console.log(chalk14.gray("\nNext: cd " + options.output + " && npm install && npm run dev\n"));
|
|
4536
4485
|
}
|
|
4537
4486
|
} catch (error) {
|
|
4538
4487
|
spinner.fail("Generation failed");
|
|
4539
4488
|
const msg = error instanceof Error ? error.message : String(error);
|
|
4540
4489
|
if (msg.includes("429") || msg.includes("quota")) {
|
|
4541
|
-
console.log(
|
|
4490
|
+
console.log(chalk14.yellow("\n\u26A0\uFE0F Quota exceeded. Run: agdi model\n"));
|
|
4542
4491
|
} else if (msg.includes("401") || msg.includes("403")) {
|
|
4543
|
-
console.log(
|
|
4492
|
+
console.log(chalk14.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
|
|
4544
4493
|
} else {
|
|
4545
|
-
console.error(
|
|
4494
|
+
console.error(chalk14.red("\n" + msg + "\n"));
|
|
4546
4495
|
}
|
|
4547
4496
|
ui.safeExit(1);
|
|
4548
4497
|
}
|
|
4549
4498
|
} catch (error) {
|
|
4550
4499
|
if (error.name === "ExitPromptError") {
|
|
4551
|
-
console.log(
|
|
4500
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4552
4501
|
try {
|
|
4553
4502
|
ui.safeExit(0);
|
|
4554
4503
|
} catch {
|
|
@@ -4564,11 +4513,11 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4564
4513
|
program.command("config").description("Show configuration").action(async () => {
|
|
4565
4514
|
const config = loadConfig();
|
|
4566
4515
|
const active = getActiveProvider();
|
|
4567
|
-
console.log(
|
|
4568
|
-
console.log(
|
|
4569
|
-
console.log(
|
|
4570
|
-
console.log(
|
|
4571
|
-
console.log(
|
|
4516
|
+
console.log(chalk14.cyan.bold("\n\u2699\uFE0F Configuration\n"));
|
|
4517
|
+
console.log(chalk14.gray(" Provider: ") + chalk14.cyan(config.defaultProvider || "not set"));
|
|
4518
|
+
console.log(chalk14.gray(" Model: ") + chalk14.cyan(config.defaultModel || "not set"));
|
|
4519
|
+
console.log(chalk14.gray(" Config: ") + chalk14.gray("~/.agdi/config.json"));
|
|
4520
|
+
console.log(chalk14.cyan.bold("\n\u{1F510} API Keys\n"));
|
|
4572
4521
|
const keys = [
|
|
4573
4522
|
["Gemini", config.geminiApiKey],
|
|
4574
4523
|
["OpenRouter", config.openrouterApiKey],
|
|
@@ -4577,13 +4526,13 @@ program.command("config").description("Show configuration").action(async () => {
|
|
|
4577
4526
|
["DeepSeek", config.deepseekApiKey]
|
|
4578
4527
|
];
|
|
4579
4528
|
for (const [name, key] of keys) {
|
|
4580
|
-
const status = key ?
|
|
4529
|
+
const status = key ? chalk14.green("\u2713") : chalk14.gray("\u2717");
|
|
4581
4530
|
console.log(` ${status} ${name}`);
|
|
4582
4531
|
}
|
|
4583
|
-
console.log(
|
|
4532
|
+
console.log(chalk14.cyan.bold("\n\u{1F4CA} Telemetry\n"));
|
|
4584
4533
|
const telemetryEnabled = config.telemetry?.enabled ?? false;
|
|
4585
|
-
console.log(` ${telemetryEnabled ?
|
|
4586
|
-
console.log(
|
|
4534
|
+
console.log(` ${telemetryEnabled ? chalk14.green("\u2713 Enabled") : chalk14.gray("\u2717 Disabled")}`);
|
|
4535
|
+
console.log(chalk14.gray(" Change with: agdi config telemetry --enable | --disable"));
|
|
4587
4536
|
console.log("");
|
|
4588
4537
|
console.log("");
|
|
4589
4538
|
});
|
|
@@ -4591,59 +4540,59 @@ program.command("config:telemetry").alias("telemetry").description("Manage telem
|
|
|
4591
4540
|
const { isTelemetryEnabled, setTelemetryConsent, getTelemetryConfig } = await import("./config-ZFU7TSU2.js");
|
|
4592
4541
|
const { generateSampleEvent, generateSanitizationDemo } = await import("./telemetry-service-OHU5NKON.js");
|
|
4593
4542
|
if (options.dryRun || options.test) {
|
|
4594
|
-
console.log(
|
|
4595
|
-
console.log(
|
|
4596
|
-
console.log(
|
|
4597
|
-
console.log(
|
|
4543
|
+
console.log(chalk14.cyan.bold("\n\u{1F50D} TELEMETRY TRANSPARENCY MODE\n"));
|
|
4544
|
+
console.log(chalk14.gray("This is exactly what Agdi sends. Notice there is"));
|
|
4545
|
+
console.log(chalk14.green.bold("NO source code, file paths, or API keys.\n"));
|
|
4546
|
+
console.log(chalk14.white.bold('\u{1F4CA} Sample "Build Failed" Event:\n'));
|
|
4598
4547
|
const sample = generateSampleEvent();
|
|
4599
|
-
console.log(
|
|
4600
|
-
console.log(
|
|
4601
|
-
console.log(
|
|
4602
|
-
console.log(
|
|
4548
|
+
console.log(chalk14.gray(JSON.stringify(sample, null, 2)));
|
|
4549
|
+
console.log(chalk14.white.bold("\n\u{1F6E1}\uFE0F Sanitization Demo:\n"));
|
|
4550
|
+
console.log(chalk14.gray("Even if sensitive data accidentally enters an error message,"));
|
|
4551
|
+
console.log(chalk14.gray("our sanitization layer strips it before transmission:\n"));
|
|
4603
4552
|
const demo = generateSanitizationDemo();
|
|
4604
|
-
console.log(
|
|
4605
|
-
console.log(
|
|
4553
|
+
console.log(chalk14.red.bold("BEFORE sanitization (never sent):"));
|
|
4554
|
+
console.log(chalk14.gray(JSON.stringify({
|
|
4606
4555
|
errorCode: demo.before.errorCode,
|
|
4607
4556
|
feedback: demo.before.feedback
|
|
4608
4557
|
}, null, 2)));
|
|
4609
|
-
console.log(
|
|
4610
|
-
console.log(
|
|
4558
|
+
console.log(chalk14.green.bold("\nAFTER sanitization (what we actually send):"));
|
|
4559
|
+
console.log(chalk14.gray(JSON.stringify({
|
|
4611
4560
|
errorCode: demo.after.errorCode,
|
|
4612
4561
|
feedback: demo.after.feedback
|
|
4613
4562
|
}, null, 2)));
|
|
4614
|
-
console.log(
|
|
4615
|
-
console.log(
|
|
4563
|
+
console.log(chalk14.cyan("\n\u2705 Your code and secrets are NEVER transmitted."));
|
|
4564
|
+
console.log(chalk14.gray(" Learn more: https://agdi.dev/privacy\n"));
|
|
4616
4565
|
return;
|
|
4617
4566
|
}
|
|
4618
4567
|
if (options.enable) {
|
|
4619
4568
|
setTelemetryConsent(true);
|
|
4620
|
-
console.log(
|
|
4621
|
-
console.log(
|
|
4622
|
-
console.log(
|
|
4623
|
-
console.log(
|
|
4569
|
+
console.log(chalk14.green("\n\u2705 Telemetry enabled"));
|
|
4570
|
+
console.log(chalk14.gray(" We collect: success/fail, error types, model used"));
|
|
4571
|
+
console.log(chalk14.gray(" We NEVER collect: source code, API keys, file paths"));
|
|
4572
|
+
console.log(chalk14.gray(" Verify anytime: agdi config telemetry --dry-run\n"));
|
|
4624
4573
|
} else if (options.disable) {
|
|
4625
4574
|
setTelemetryConsent(false);
|
|
4626
|
-
console.log(
|
|
4627
|
-
console.log(
|
|
4575
|
+
console.log(chalk14.yellow("\n\u{1F4CA} Telemetry disabled"));
|
|
4576
|
+
console.log(chalk14.gray(" You can re-enable anytime with: agdi config telemetry --enable\n"));
|
|
4628
4577
|
} else {
|
|
4629
4578
|
const config = getTelemetryConfig();
|
|
4630
|
-
console.log(
|
|
4631
|
-
console.log(
|
|
4632
|
-
console.log(
|
|
4579
|
+
console.log(chalk14.cyan.bold("\n\u{1F4CA} Telemetry Status\n"));
|
|
4580
|
+
console.log(chalk14.gray(" Enabled: ") + (config.enabled ? chalk14.green("Yes") : chalk14.gray("No")));
|
|
4581
|
+
console.log(chalk14.gray(" Consent: ") + (config.consentAsked ? chalk14.green("Asked") : chalk14.gray("Not asked")));
|
|
4633
4582
|
if (config.anonymousId) {
|
|
4634
|
-
console.log(
|
|
4583
|
+
console.log(chalk14.gray(" ID: ") + chalk14.gray(config.anonymousId.slice(0, 8) + "..."));
|
|
4635
4584
|
}
|
|
4636
4585
|
console.log("");
|
|
4637
|
-
console.log(
|
|
4638
|
-
console.log(
|
|
4639
|
-
console.log(
|
|
4586
|
+
console.log(chalk14.gray(" Enable: agdi config telemetry --enable"));
|
|
4587
|
+
console.log(chalk14.gray(" Disable: agdi config telemetry --disable"));
|
|
4588
|
+
console.log(chalk14.gray(" Verify: agdi config telemetry --dry-run\n"));
|
|
4640
4589
|
}
|
|
4641
4590
|
});
|
|
4642
4591
|
program.command("doctor").alias("doc").description("Run self-diagnosis checks").action(async () => {
|
|
4643
4592
|
try {
|
|
4644
4593
|
await runDoctor();
|
|
4645
4594
|
} catch (error) {
|
|
4646
|
-
console.error(
|
|
4595
|
+
console.error(chalk14.red("Diagnostic failed: " + error));
|
|
4647
4596
|
ui.safeExit(1);
|
|
4648
4597
|
}
|
|
4649
4598
|
});
|
|
@@ -4654,7 +4603,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
|
|
|
4654
4603
|
}
|
|
4655
4604
|
const activeConfig = getActiveProvider();
|
|
4656
4605
|
if (!activeConfig) {
|
|
4657
|
-
console.log(
|
|
4606
|
+
console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
|
|
4658
4607
|
return;
|
|
4659
4608
|
}
|
|
4660
4609
|
const llm = createLLMProvider(activeConfig.provider, {
|
|
@@ -4668,7 +4617,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
|
|
|
4668
4617
|
});
|
|
4669
4618
|
} catch (error) {
|
|
4670
4619
|
if (error.name === "ExitPromptError") {
|
|
4671
|
-
console.log(
|
|
4620
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4672
4621
|
try {
|
|
4673
4622
|
ui.safeExit(0);
|
|
4674
4623
|
} catch {
|
|
@@ -4696,7 +4645,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
|
|
|
4696
4645
|
}
|
|
4697
4646
|
const activeConfig = getActiveProvider();
|
|
4698
4647
|
if (!activeConfig) {
|
|
4699
|
-
console.log(
|
|
4648
|
+
console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
|
|
4700
4649
|
return;
|
|
4701
4650
|
}
|
|
4702
4651
|
const llm = createLLMProvider(activeConfig.provider, {
|
|
@@ -4710,7 +4659,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
|
|
|
4710
4659
|
});
|
|
4711
4660
|
} catch (error) {
|
|
4712
4661
|
if (error.name === "ExitPromptError") {
|
|
4713
|
-
console.log(
|
|
4662
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4714
4663
|
try {
|
|
4715
4664
|
ui.safeExit(0);
|
|
4716
4665
|
} catch {
|
|
@@ -4728,7 +4677,7 @@ program.command("import <url>").alias("i").description("\u{1F4E6} Import a GitHu
|
|
|
4728
4677
|
await runImportCommand(url, options.output);
|
|
4729
4678
|
} catch (error) {
|
|
4730
4679
|
if (error.name === "ExitPromptError") {
|
|
4731
|
-
console.log(
|
|
4680
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4732
4681
|
try {
|
|
4733
4682
|
ui.safeExit(0);
|
|
4734
4683
|
} catch {
|