agdi 2.5.1 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -23
- package/dist/chunk-NVMD3WL3.js +349 -0
- package/dist/index.js +533 -207
- package/dist/rag-6HO4ZLBN.js +16 -0
- package/package.json +9 -4
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
});
|
|
2
|
+
import {
|
|
3
|
+
__require,
|
|
4
|
+
indexProject,
|
|
5
|
+
searchCodebase
|
|
6
|
+
} from "./chunk-NVMD3WL3.js";
|
|
8
7
|
|
|
9
8
|
// src/index.ts
|
|
10
9
|
import { Command } from "commander";
|
|
11
|
-
import
|
|
10
|
+
import chalk14 from "chalk";
|
|
12
11
|
import ora5 from "ora";
|
|
13
12
|
|
|
14
13
|
// src/core/llm/index.ts
|
|
@@ -1426,12 +1425,115 @@ async function selectModel() {
|
|
|
1426
1425
|
|
|
1427
1426
|
// src/commands/agdi-dev.ts
|
|
1428
1427
|
import { input as input5, confirm as confirm3 } from "@inquirer/prompts";
|
|
1429
|
-
import
|
|
1430
|
-
|
|
1428
|
+
import chalk13 from "chalk";
|
|
1429
|
+
|
|
1430
|
+
// src/utils/ui.ts
|
|
1431
|
+
import chalk8 from "chalk";
|
|
1432
|
+
import gradient from "gradient-string";
|
|
1433
|
+
import boxen from "boxen";
|
|
1434
|
+
import figlet from "figlet";
|
|
1435
|
+
import ora3 from "ora";
|
|
1436
|
+
var THEME = {
|
|
1437
|
+
cyan: "#06b6d4",
|
|
1438
|
+
// Cyan-500
|
|
1439
|
+
purple: "#8b5cf6",
|
|
1440
|
+
// Violet-500
|
|
1441
|
+
red: "#ef4444",
|
|
1442
|
+
// Red-500
|
|
1443
|
+
yellow: "#eab308",
|
|
1444
|
+
// Yellow-500
|
|
1445
|
+
gray: "#71717a",
|
|
1446
|
+
// Zinc-500
|
|
1447
|
+
dim: "#52525b"
|
|
1448
|
+
// Zinc-600
|
|
1449
|
+
};
|
|
1450
|
+
var brandGradient = gradient([THEME.cyan, THEME.purple]);
|
|
1451
|
+
var errorGradient = gradient([THEME.red, "#b91c1c"]);
|
|
1452
|
+
var goldGradient = gradient([THEME.yellow, "#fbbf24"]);
|
|
1453
|
+
async function renderBanner(version = "v2.6.0") {
|
|
1454
|
+
console.clear();
|
|
1455
|
+
const text = await new Promise((resolve5) => {
|
|
1456
|
+
figlet("AGDI", { font: "Slant" }, (err, data) => {
|
|
1457
|
+
resolve5(data || "AGDI");
|
|
1458
|
+
});
|
|
1459
|
+
});
|
|
1460
|
+
console.log(brandGradient.multiline(text));
|
|
1461
|
+
console.log(chalk8.hex(THEME.dim)(` ${version} [ARCHITECT ONLINE]
|
|
1462
|
+
`));
|
|
1463
|
+
}
|
|
1464
|
+
function renderBox(title, content, style = "info") {
|
|
1465
|
+
let borderColor = THEME.cyan;
|
|
1466
|
+
let titleColor = chalk8.cyan;
|
|
1467
|
+
if (style === "success") {
|
|
1468
|
+
borderColor = THEME.cyan;
|
|
1469
|
+
} else if (style === "warning") {
|
|
1470
|
+
borderColor = THEME.yellow;
|
|
1471
|
+
titleColor = chalk8.yellow;
|
|
1472
|
+
} else if (style === "error") {
|
|
1473
|
+
borderColor = THEME.red;
|
|
1474
|
+
titleColor = chalk8.red;
|
|
1475
|
+
}
|
|
1476
|
+
const box = boxen(content, {
|
|
1477
|
+
title: titleColor.bold(title),
|
|
1478
|
+
padding: 1,
|
|
1479
|
+
margin: 1,
|
|
1480
|
+
borderStyle: "round",
|
|
1481
|
+
borderColor,
|
|
1482
|
+
dimBorder: false,
|
|
1483
|
+
float: "left"
|
|
1484
|
+
});
|
|
1485
|
+
console.log(box);
|
|
1486
|
+
}
|
|
1487
|
+
function renderAlert(title, message) {
|
|
1488
|
+
console.log("");
|
|
1489
|
+
const box = boxen(chalk8.white(message), {
|
|
1490
|
+
title: chalk8.red.bold(`\u{1F6E1}\uFE0F ${title.toUpperCase()} `),
|
|
1491
|
+
padding: 1,
|
|
1492
|
+
borderStyle: "double",
|
|
1493
|
+
borderColor: "red",
|
|
1494
|
+
textAlignment: "center"
|
|
1495
|
+
});
|
|
1496
|
+
console.log(box);
|
|
1497
|
+
console.log("");
|
|
1498
|
+
}
|
|
1499
|
+
function printUserMessage(message) {
|
|
1500
|
+
console.log("");
|
|
1501
|
+
console.log(chalk8.cyan.bold("\u{1F464} YOU \u203A ") + chalk8.white(message));
|
|
1502
|
+
console.log("");
|
|
1503
|
+
}
|
|
1504
|
+
function printAIMessage(message) {
|
|
1505
|
+
console.log("");
|
|
1506
|
+
console.log(brandGradient.multiline("\u26A1 AGDI \u203A "));
|
|
1507
|
+
console.log(message.trim());
|
|
1508
|
+
console.log("");
|
|
1509
|
+
}
|
|
1510
|
+
function createSpinner(text) {
|
|
1511
|
+
return ora3({
|
|
1512
|
+
text: chalk8.hex(THEME.gray)(text),
|
|
1513
|
+
color: "cyan",
|
|
1514
|
+
spinner: "dots",
|
|
1515
|
+
discardStdin: false
|
|
1516
|
+
// Important for allowing interruption if needed
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
function printIter() {
|
|
1520
|
+
console.log(chalk8.hex(THEME.dim)("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1521
|
+
}
|
|
1522
|
+
var ui = {
|
|
1523
|
+
renderBanner,
|
|
1524
|
+
renderBox,
|
|
1525
|
+
renderAlert,
|
|
1526
|
+
printUserMessage,
|
|
1527
|
+
printAIMessage,
|
|
1528
|
+
createSpinner,
|
|
1529
|
+
printIter,
|
|
1530
|
+
brandGradient,
|
|
1531
|
+
THEME
|
|
1532
|
+
};
|
|
1431
1533
|
|
|
1432
1534
|
// src/actions/plan-executor.ts
|
|
1433
1535
|
import { select as select4, confirm } from "@inquirer/prompts";
|
|
1434
|
-
import
|
|
1536
|
+
import chalk11 from "chalk";
|
|
1435
1537
|
import { spawn as spawn2 } from "child_process";
|
|
1436
1538
|
import { resolve as resolve4 } from "path";
|
|
1437
1539
|
|
|
@@ -1566,7 +1668,7 @@ import { existsSync as existsSync3 } from "fs";
|
|
|
1566
1668
|
import { resolve, dirname, relative, isAbsolute } from "path";
|
|
1567
1669
|
|
|
1568
1670
|
// src/security/execution-env.ts
|
|
1569
|
-
import
|
|
1671
|
+
import chalk9 from "chalk";
|
|
1570
1672
|
import { platform } from "os";
|
|
1571
1673
|
import { existsSync, readFileSync } from "fs";
|
|
1572
1674
|
function detectWSL() {
|
|
@@ -1675,11 +1777,11 @@ function formatNetwork(policy, domains) {
|
|
|
1675
1777
|
function formatTrust(trust) {
|
|
1676
1778
|
switch (trust) {
|
|
1677
1779
|
case "untrusted":
|
|
1678
|
-
return
|
|
1780
|
+
return chalk9.red("untrusted (read-only mode)");
|
|
1679
1781
|
case "session":
|
|
1680
|
-
return
|
|
1782
|
+
return chalk9.yellow("session trusted");
|
|
1681
1783
|
case "persistent":
|
|
1682
|
-
return
|
|
1784
|
+
return chalk9.green("trusted");
|
|
1683
1785
|
}
|
|
1684
1786
|
}
|
|
1685
1787
|
function displaySessionHeader(env) {
|
|
@@ -1693,12 +1795,12 @@ function displaySessionHeader(env) {
|
|
|
1693
1795
|
`Network: ${formatNetwork(env.networkPolicy, env.allowedDomains)}`,
|
|
1694
1796
|
`Trust: ${formatTrust(env.trustLevel)}`
|
|
1695
1797
|
];
|
|
1696
|
-
console.log(
|
|
1798
|
+
console.log(chalk9.cyan(topBorder));
|
|
1697
1799
|
for (const line of lines) {
|
|
1698
1800
|
const padding = " ".repeat(Math.max(0, boxWidth - stripAnsi(line).length - 2));
|
|
1699
|
-
console.log(
|
|
1801
|
+
console.log(chalk9.cyan("\u2502 ") + line + padding + chalk9.cyan(" \u2502"));
|
|
1700
1802
|
}
|
|
1701
|
-
console.log(
|
|
1803
|
+
console.log(chalk9.cyan(bottomBorder));
|
|
1702
1804
|
console.log("");
|
|
1703
1805
|
}
|
|
1704
1806
|
function truncatePath(path4, maxLen) {
|
|
@@ -2697,7 +2799,7 @@ function getRiskDescription(tier, argv) {
|
|
|
2697
2799
|
|
|
2698
2800
|
// src/security/workspace-trust.ts
|
|
2699
2801
|
import { select as select3 } from "@inquirer/prompts";
|
|
2700
|
-
import
|
|
2802
|
+
import chalk10 from "chalk";
|
|
2701
2803
|
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
2702
2804
|
import { join as join3, resolve as resolve3 } from "path";
|
|
2703
2805
|
import { homedir as homedir4 } from "os";
|
|
@@ -2746,14 +2848,14 @@ function trustWorkspace(workspacePath) {
|
|
|
2746
2848
|
}
|
|
2747
2849
|
async function promptWorkspaceTrust(workspacePath) {
|
|
2748
2850
|
if (isWorkspaceTrusted(workspacePath)) {
|
|
2749
|
-
console.log(
|
|
2851
|
+
console.log(chalk10.green("\u2713 Workspace is trusted\n"));
|
|
2750
2852
|
return "persistent";
|
|
2751
2853
|
}
|
|
2752
|
-
console.log(
|
|
2753
|
-
console.log(
|
|
2854
|
+
console.log(chalk10.yellow("\n\u26A0\uFE0F Untrusted Workspace"));
|
|
2855
|
+
console.log(chalk10.gray(` ${workspacePath}
|
|
2754
2856
|
`));
|
|
2755
|
-
console.log(
|
|
2756
|
-
console.log(
|
|
2857
|
+
console.log(chalk10.gray("Agdi can run commands in this workspace."));
|
|
2858
|
+
console.log(chalk10.gray("Do you trust the contents of this folder?\n"));
|
|
2757
2859
|
const choice = await select3({
|
|
2758
2860
|
message: "Trust this workspace?",
|
|
2759
2861
|
choices: [
|
|
@@ -2781,15 +2883,15 @@ async function handleTrustFlow(workspacePath) {
|
|
|
2781
2883
|
switch (choice) {
|
|
2782
2884
|
case "session":
|
|
2783
2885
|
updateEnvironment({ trustLevel: "session" });
|
|
2784
|
-
console.log(
|
|
2886
|
+
console.log(chalk10.green("\u2713 Trusted for this session\n"));
|
|
2785
2887
|
return "session";
|
|
2786
2888
|
case "persistent":
|
|
2787
2889
|
trustWorkspace(workspacePath);
|
|
2788
2890
|
updateEnvironment({ trustLevel: "persistent" });
|
|
2789
|
-
console.log(
|
|
2891
|
+
console.log(chalk10.green("\u2713 Workspace trusted and remembered\n"));
|
|
2790
2892
|
return "persistent";
|
|
2791
2893
|
case "exit":
|
|
2792
|
-
console.log(
|
|
2894
|
+
console.log(chalk10.yellow("\n\u{1F44B} Exiting. Workspace not trusted.\n"));
|
|
2793
2895
|
return null;
|
|
2794
2896
|
}
|
|
2795
2897
|
}
|
|
@@ -2857,53 +2959,33 @@ async function downloadImageAsBase64(url) {
|
|
|
2857
2959
|
// src/actions/plan-executor.ts
|
|
2858
2960
|
function displayPlanSummary(plan) {
|
|
2859
2961
|
const summary = summarizePlan(plan);
|
|
2860
|
-
const boxWidth = 56;
|
|
2861
|
-
console.log("");
|
|
2862
|
-
console.log(chalk10.cyan("\u256D\u2500 Action Plan \u2500" + "\u2500".repeat(boxWidth - 15) + "\u256E"));
|
|
2863
|
-
console.log(chalk10.cyan("\u2502 ") + chalk10.white(`Project: ${plan.projectName}`.padEnd(boxWidth - 2)) + chalk10.cyan(" \u2502"));
|
|
2864
|
-
console.log(chalk10.cyan("\u2502 ") + "\u2500".repeat(boxWidth - 2) + chalk10.cyan(" \u2502"));
|
|
2865
2962
|
const lines = [];
|
|
2866
|
-
if (summary.dirsCreated > 0) {
|
|
2867
|
-
|
|
2868
|
-
}
|
|
2869
|
-
if (summary.
|
|
2870
|
-
|
|
2871
|
-
}
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
}
|
|
2875
|
-
if (summary.commandsToRun > 0) {
|
|
2876
|
-
lines.push(`\u26A1 Run ${summary.commandsToRun} commands`);
|
|
2877
|
-
}
|
|
2878
|
-
if (summary.domains.length > 0) {
|
|
2879
|
-
lines.push(`\u{1F310} Network: ${summary.domains.join(", ")}`);
|
|
2880
|
-
}
|
|
2881
|
-
if (summary.ports.length > 0) {
|
|
2882
|
-
lines.push(`\u{1F50C} Ports: ${summary.ports.join(", ")}`);
|
|
2883
|
-
}
|
|
2884
|
-
for (const line of lines) {
|
|
2885
|
-
console.log(chalk10.cyan("\u2502 ") + chalk10.gray(line.padEnd(boxWidth - 2)) + chalk10.cyan(" \u2502"));
|
|
2886
|
-
}
|
|
2887
|
-
console.log(chalk10.cyan("\u2570" + "\u2500".repeat(boxWidth) + "\u256F"));
|
|
2888
|
-
console.log("");
|
|
2963
|
+
if (summary.dirsCreated > 0) lines.push(`\u{1F4C1} Create ${summary.dirsCreated} directories`);
|
|
2964
|
+
if (summary.filesCreated > 0) lines.push(`\u{1F4C4} Create ${summary.filesCreated} files`);
|
|
2965
|
+
if (summary.filesDeleted > 0) lines.push(`\u{1F5D1}\uFE0F Delete ${summary.filesDeleted} files`);
|
|
2966
|
+
if (summary.commandsToRun > 0) lines.push(`\u26A1 Run ${summary.commandsToRun} commands`);
|
|
2967
|
+
if (summary.domains.length > 0) lines.push(`\u{1F310} Network: ${summary.domains.join(", ")}`);
|
|
2968
|
+
if (summary.ports.length > 0) lines.push(`\u{1F50C} Ports: ${summary.ports.join(", ")}`);
|
|
2969
|
+
const content = lines.join("\n");
|
|
2970
|
+
ui.renderBox(`PLAN: ${plan.projectName}`, content, "info");
|
|
2889
2971
|
}
|
|
2890
2972
|
function displayActionProgress(action, index, total) {
|
|
2891
2973
|
const num = `[${index + 1}/${total}]`;
|
|
2892
2974
|
switch (action.type) {
|
|
2893
2975
|
case "mkdir":
|
|
2894
|
-
console.log(
|
|
2976
|
+
console.log(chalk11.gray(`${num} Creating directory: ${action.path}`));
|
|
2895
2977
|
break;
|
|
2896
2978
|
case "writeFile":
|
|
2897
|
-
console.log(
|
|
2979
|
+
console.log(chalk11.gray(`${num} Writing file: ${action.path}`));
|
|
2898
2980
|
break;
|
|
2899
2981
|
case "deleteFile":
|
|
2900
|
-
console.log(
|
|
2982
|
+
console.log(chalk11.gray(`${num} Deleting file: ${action.path}`));
|
|
2901
2983
|
break;
|
|
2902
2984
|
case "exec":
|
|
2903
|
-
console.log(
|
|
2985
|
+
console.log(chalk11.blue(`${num} Running: ${action.argv.join(" ")}`));
|
|
2904
2986
|
break;
|
|
2905
2987
|
case "generateImage":
|
|
2906
|
-
console.log(
|
|
2988
|
+
console.log(chalk11.magenta(`${num} \u{1F3A8} Generating image: ${action.savePath}`));
|
|
2907
2989
|
break;
|
|
2908
2990
|
}
|
|
2909
2991
|
}
|
|
@@ -3014,16 +3096,16 @@ async function executeAction(action) {
|
|
|
3014
3096
|
};
|
|
3015
3097
|
}
|
|
3016
3098
|
try {
|
|
3017
|
-
console.log(
|
|
3099
|
+
console.log(chalk11.gray(` Prompt: "${action.prompt.slice(0, 50)}..."`));
|
|
3018
3100
|
const result = await generateImage(action.prompt, apiKey, { style: action.style });
|
|
3019
3101
|
if (result.url) {
|
|
3020
3102
|
const base64Data = await downloadImageAsBase64(result.url);
|
|
3021
3103
|
const imageBuffer = Buffer.from(base64Data, "base64");
|
|
3022
3104
|
await writeFileTool(action.savePath, imageBuffer.toString("base64"));
|
|
3023
|
-
console.log(
|
|
3105
|
+
console.log(chalk11.green(` \u2713 Saved to ${action.savePath}`));
|
|
3024
3106
|
} else if (result.base64) {
|
|
3025
3107
|
await writeFileTool(action.savePath, result.base64);
|
|
3026
|
-
console.log(
|
|
3108
|
+
console.log(chalk11.green(` \u2713 Saved to ${action.savePath}`));
|
|
3027
3109
|
}
|
|
3028
3110
|
return {
|
|
3029
3111
|
action,
|
|
@@ -3049,18 +3131,19 @@ async function executePlan(plan) {
|
|
|
3049
3131
|
displayPlanSummary(plan);
|
|
3050
3132
|
const dryRun = await dryRunActions(plan);
|
|
3051
3133
|
if (!dryRun.canProceed) {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
console.log(chalk10.red(` - ${result.command}: ${result.reason}`));
|
|
3056
|
-
errors.push(result.reason);
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3134
|
+
const errorLines = dryRun.gateResults.filter((r) => r.decision === "deny").map((r) => `\u2022 ${r.command}: ${r.reason}`);
|
|
3135
|
+
ui.renderBox("BLOCKED ACTIONS", errorLines.join("\n"), "error");
|
|
3136
|
+
dryRun.gateResults.filter((r) => r.decision === "deny").forEach((r) => errors.push(r.reason));
|
|
3059
3137
|
return { success: false, results, filesCreated, commandsRun, errors };
|
|
3060
3138
|
}
|
|
3061
3139
|
if (dryRun.requiresTrust) {
|
|
3062
|
-
|
|
3063
|
-
|
|
3140
|
+
ui.renderAlert(
|
|
3141
|
+
"UNTRUSTED WORKSPACE",
|
|
3142
|
+
`The agent wants to execute ${plan.actions.length} actions in this folder.
|
|
3143
|
+
This includes writing files and/or running commands.
|
|
3144
|
+
|
|
3145
|
+
Target: ${env.workspaceRoot}`
|
|
3146
|
+
);
|
|
3064
3147
|
const trustChoice = await select4({
|
|
3065
3148
|
message: "Trust this workspace?",
|
|
3066
3149
|
choices: [
|
|
@@ -3070,16 +3153,16 @@ async function executePlan(plan) {
|
|
|
3070
3153
|
]
|
|
3071
3154
|
});
|
|
3072
3155
|
if (trustChoice === "cancel") {
|
|
3073
|
-
console.log(
|
|
3156
|
+
console.log(chalk11.yellow("\n\u{1F44B} Plan cancelled.\n"));
|
|
3074
3157
|
return { success: false, results, filesCreated, commandsRun, errors: ["User cancelled"] };
|
|
3075
3158
|
}
|
|
3076
3159
|
if (trustChoice === "persistent") {
|
|
3077
3160
|
trustWorkspace(env.workspaceRoot);
|
|
3078
3161
|
updateEnvironment({ trustLevel: "persistent" });
|
|
3079
|
-
console.log(
|
|
3162
|
+
console.log(chalk11.green("\u2713 Workspace trusted and remembered\n"));
|
|
3080
3163
|
} else {
|
|
3081
3164
|
updateEnvironment({ trustLevel: "session" });
|
|
3082
|
-
console.log(
|
|
3165
|
+
console.log(chalk11.green("\u2713 Trusted for this session\n"));
|
|
3083
3166
|
}
|
|
3084
3167
|
}
|
|
3085
3168
|
const approved = await confirm({
|
|
@@ -3087,7 +3170,7 @@ async function executePlan(plan) {
|
|
|
3087
3170
|
default: true
|
|
3088
3171
|
});
|
|
3089
3172
|
if (!approved) {
|
|
3090
|
-
console.log(
|
|
3173
|
+
console.log(chalk11.yellow("\n\u{1F44B} Plan cancelled.\n"));
|
|
3091
3174
|
return { success: false, results, filesCreated, commandsRun, errors: ["User cancelled"] };
|
|
3092
3175
|
}
|
|
3093
3176
|
logEvent({
|
|
@@ -3098,7 +3181,7 @@ async function executePlan(plan) {
|
|
|
3098
3181
|
summary: summarizePlan(plan)
|
|
3099
3182
|
}
|
|
3100
3183
|
});
|
|
3101
|
-
console.log(
|
|
3184
|
+
console.log(chalk11.cyan("\n\u25B6 Executing plan...\n"));
|
|
3102
3185
|
for (let i = 0; i < plan.actions.length; i++) {
|
|
3103
3186
|
const action = plan.actions[i];
|
|
3104
3187
|
displayActionProgress(action, i, plan.actions.length);
|
|
@@ -3113,24 +3196,24 @@ async function executePlan(plan) {
|
|
|
3113
3196
|
}
|
|
3114
3197
|
} else {
|
|
3115
3198
|
errors.push(result.error || "Unknown error");
|
|
3116
|
-
console.log(
|
|
3199
|
+
console.log(chalk11.red(` \u2717 Failed: ${result.error}`));
|
|
3117
3200
|
}
|
|
3118
3201
|
}
|
|
3119
3202
|
const success = errors.length === 0;
|
|
3120
3203
|
if (success) {
|
|
3121
|
-
console.log(
|
|
3204
|
+
console.log(chalk11.green(`
|
|
3122
3205
|
\u2713 Plan executed successfully!`));
|
|
3123
|
-
console.log(
|
|
3124
|
-
console.log(
|
|
3206
|
+
console.log(chalk11.gray(` Created ${filesCreated.length} files`));
|
|
3207
|
+
console.log(chalk11.gray(` Ran ${commandsRun.length} commands
|
|
3125
3208
|
`));
|
|
3126
3209
|
} else {
|
|
3127
|
-
console.log(
|
|
3210
|
+
console.log(chalk11.red(`
|
|
3128
3211
|
\u2717 Plan completed with ${errors.length} errors
|
|
3129
3212
|
`));
|
|
3130
3213
|
}
|
|
3131
3214
|
if (plan.nextSteps) {
|
|
3132
|
-
console.log(
|
|
3133
|
-
console.log(
|
|
3215
|
+
console.log(chalk11.cyan("Next steps:"));
|
|
3216
|
+
console.log(chalk11.gray(` ${plan.nextSteps}
|
|
3134
3217
|
`));
|
|
3135
3218
|
}
|
|
3136
3219
|
logEvent({
|
|
@@ -3150,7 +3233,7 @@ async function executePlan(plan) {
|
|
|
3150
3233
|
async function parseAndExecutePlan(response) {
|
|
3151
3234
|
const plan = parseActionPlan(response);
|
|
3152
3235
|
if (!plan) {
|
|
3153
|
-
console.log(
|
|
3236
|
+
console.log(chalk11.yellow("\n\u26A0\uFE0F Could not parse action plan from response.\n"));
|
|
3154
3237
|
return null;
|
|
3155
3238
|
}
|
|
3156
3239
|
return executePlan(plan);
|
|
@@ -3720,8 +3803,8 @@ function clearConversation() {
|
|
|
3720
3803
|
// src/core/file-editor.ts
|
|
3721
3804
|
import { readFile as readFile2 } from "fs/promises";
|
|
3722
3805
|
import { existsSync as existsSync9 } from "fs";
|
|
3723
|
-
import
|
|
3724
|
-
import
|
|
3806
|
+
import chalk12 from "chalk";
|
|
3807
|
+
import ora4 from "ora";
|
|
3725
3808
|
import { input as input4, confirm as confirm2 } from "@inquirer/prompts";
|
|
3726
3809
|
var EDIT_SYSTEM_PROMPT = `You are a surgical code editor. Given a file's content and an edit instruction, output ONLY a unified diff patch.
|
|
3727
3810
|
|
|
@@ -3788,19 +3871,19 @@ function extractDiff(response) {
|
|
|
3788
3871
|
return null;
|
|
3789
3872
|
}
|
|
3790
3873
|
function previewDiff(diff) {
|
|
3791
|
-
console.log(
|
|
3874
|
+
console.log(chalk12.cyan.bold("\n\u{1F4DD} Proposed Changes:\n"));
|
|
3792
3875
|
const lines = diff.split("\n");
|
|
3793
3876
|
for (const line of lines) {
|
|
3794
3877
|
if (line.startsWith("+++") || line.startsWith("---")) {
|
|
3795
|
-
console.log(
|
|
3878
|
+
console.log(chalk12.gray(line));
|
|
3796
3879
|
} else if (line.startsWith("@@")) {
|
|
3797
|
-
console.log(
|
|
3880
|
+
console.log(chalk12.cyan(line));
|
|
3798
3881
|
} else if (line.startsWith("+")) {
|
|
3799
|
-
console.log(
|
|
3882
|
+
console.log(chalk12.green(line));
|
|
3800
3883
|
} else if (line.startsWith("-")) {
|
|
3801
|
-
console.log(
|
|
3884
|
+
console.log(chalk12.red(line));
|
|
3802
3885
|
} else {
|
|
3803
|
-
console.log(
|
|
3886
|
+
console.log(chalk12.gray(line));
|
|
3804
3887
|
}
|
|
3805
3888
|
}
|
|
3806
3889
|
console.log("");
|
|
@@ -3821,35 +3904,35 @@ function countChanges(diff) {
|
|
|
3821
3904
|
async function handleFileEdit(filePath, llm) {
|
|
3822
3905
|
const env = getEnvironment();
|
|
3823
3906
|
if (!fileExists(filePath)) {
|
|
3824
|
-
console.log(
|
|
3907
|
+
console.log(chalk12.red(`
|
|
3825
3908
|
\u2717 File not found: ${filePath}
|
|
3826
3909
|
`));
|
|
3827
3910
|
return { success: false, error: "File not found" };
|
|
3828
3911
|
}
|
|
3829
3912
|
const fileData = await readFileForEdit(filePath);
|
|
3830
3913
|
if (!fileData) {
|
|
3831
|
-
console.log(
|
|
3914
|
+
console.log(chalk12.red(`
|
|
3832
3915
|
\u2717 Could not read file: ${filePath}
|
|
3833
3916
|
`));
|
|
3834
3917
|
return { success: false, error: "Could not read file" };
|
|
3835
3918
|
}
|
|
3836
3919
|
const previewLines = fileData.numbered.split("\n").slice(0, 20);
|
|
3837
|
-
console.log(
|
|
3920
|
+
console.log(chalk12.cyan.bold(`
|
|
3838
3921
|
\u{1F4C4} ${filePath}
|
|
3839
3922
|
`));
|
|
3840
|
-
console.log(
|
|
3923
|
+
console.log(chalk12.gray(previewLines.join("\n")));
|
|
3841
3924
|
if (fileData.content.split("\n").length > 20) {
|
|
3842
|
-
console.log(
|
|
3925
|
+
console.log(chalk12.gray(` ... (${fileData.content.split("\n").length - 20} more lines)`));
|
|
3843
3926
|
}
|
|
3844
3927
|
console.log("");
|
|
3845
3928
|
const instruction = await input4({
|
|
3846
|
-
message:
|
|
3929
|
+
message: chalk12.yellow("Describe the edit:")
|
|
3847
3930
|
});
|
|
3848
3931
|
if (!instruction.trim()) {
|
|
3849
|
-
console.log(
|
|
3932
|
+
console.log(chalk12.gray("\n(no instruction provided)\n"));
|
|
3850
3933
|
return { success: false, error: "No instruction" };
|
|
3851
3934
|
}
|
|
3852
|
-
const spinner =
|
|
3935
|
+
const spinner = ora4("Generating edit...").start();
|
|
3853
3936
|
try {
|
|
3854
3937
|
const prompt = `File: ${filePath}
|
|
3855
3938
|
|
|
@@ -3865,27 +3948,27 @@ Generate the unified diff to make this change.`;
|
|
|
3865
3948
|
spinner.stop();
|
|
3866
3949
|
const diff = extractDiff(response.text);
|
|
3867
3950
|
if (!diff) {
|
|
3868
|
-
console.log(
|
|
3869
|
-
console.log(
|
|
3951
|
+
console.log(chalk12.yellow("\n\u26A0\uFE0F Could not generate a valid diff.\n"));
|
|
3952
|
+
console.log(chalk12.gray("AI response:\n" + response.text.slice(0, 500)));
|
|
3870
3953
|
return { success: false, error: "Invalid diff generated" };
|
|
3871
3954
|
}
|
|
3872
3955
|
previewDiff(diff);
|
|
3873
3956
|
const changes = countChanges(diff);
|
|
3874
|
-
console.log(
|
|
3957
|
+
console.log(chalk12.gray(` ${chalk12.green(`+${changes.added}`)} additions, ${chalk12.red(`-${changes.removed}`)} deletions
|
|
3875
3958
|
`));
|
|
3876
3959
|
const shouldApply = await confirm2({
|
|
3877
3960
|
message: "Apply these changes?",
|
|
3878
3961
|
default: true
|
|
3879
3962
|
});
|
|
3880
3963
|
if (!shouldApply) {
|
|
3881
|
-
console.log(
|
|
3964
|
+
console.log(chalk12.gray("\n\u{1F44B} Edit cancelled.\n"));
|
|
3882
3965
|
return { success: false, error: "Cancelled by user" };
|
|
3883
3966
|
}
|
|
3884
|
-
const applySpinner =
|
|
3967
|
+
const applySpinner = ora4("Applying changes...").start();
|
|
3885
3968
|
const result = await applyPatchTool(filePath, diff);
|
|
3886
3969
|
applySpinner.stop();
|
|
3887
3970
|
if (result.success) {
|
|
3888
|
-
console.log(
|
|
3971
|
+
console.log(chalk12.green(`
|
|
3889
3972
|
\u2713 Successfully edited ${filePath}
|
|
3890
3973
|
`));
|
|
3891
3974
|
logEvent({
|
|
@@ -3900,7 +3983,7 @@ Generate the unified diff to make this change.`;
|
|
|
3900
3983
|
});
|
|
3901
3984
|
return { success: true, linesChanged: changes.added + changes.removed };
|
|
3902
3985
|
} else {
|
|
3903
|
-
console.log(
|
|
3986
|
+
console.log(chalk12.red(`
|
|
3904
3987
|
\u2717 Failed to apply changes: ${result.error}
|
|
3905
3988
|
`));
|
|
3906
3989
|
return { success: false, error: result.error };
|
|
@@ -3908,14 +3991,181 @@ Generate the unified diff to make this change.`;
|
|
|
3908
3991
|
} catch (error) {
|
|
3909
3992
|
spinner.stop();
|
|
3910
3993
|
const msg = error instanceof Error ? error.message : String(error);
|
|
3911
|
-
console.log(
|
|
3994
|
+
console.log(chalk12.red(`
|
|
3912
3995
|
\u2717 Error: ${msg}
|
|
3913
3996
|
`));
|
|
3914
3997
|
return { success: false, error: msg };
|
|
3915
3998
|
}
|
|
3916
3999
|
}
|
|
3917
4000
|
|
|
4001
|
+
// src/core/mcp/tools.ts
|
|
4002
|
+
var tools = /* @__PURE__ */ new Map();
|
|
4003
|
+
function registerTool(tool) {
|
|
4004
|
+
tools.set(tool.name, tool);
|
|
4005
|
+
}
|
|
4006
|
+
function listTools() {
|
|
4007
|
+
return Array.from(tools.values());
|
|
4008
|
+
}
|
|
4009
|
+
registerTool({
|
|
4010
|
+
name: "read_file",
|
|
4011
|
+
description: "Read the contents of a file",
|
|
4012
|
+
category: "filesystem",
|
|
4013
|
+
parameters: [
|
|
4014
|
+
{ name: "path", type: "string", description: "File path to read", required: true }
|
|
4015
|
+
],
|
|
4016
|
+
execute: async (params) => {
|
|
4017
|
+
const { readFileSync: readFileSync8 } = await import("fs");
|
|
4018
|
+
const { resolve: resolve5 } = await import("path");
|
|
4019
|
+
try {
|
|
4020
|
+
const filePath = resolve5(process.cwd(), params.path);
|
|
4021
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
4022
|
+
return {
|
|
4023
|
+
success: true,
|
|
4024
|
+
data: content,
|
|
4025
|
+
display: `Read ${content.split("\n").length} lines from ${params.path}`
|
|
4026
|
+
};
|
|
4027
|
+
} catch (error) {
|
|
4028
|
+
return {
|
|
4029
|
+
success: false,
|
|
4030
|
+
error: `Failed to read file: ${error}`
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
});
|
|
4035
|
+
registerTool({
|
|
4036
|
+
name: "list_dir",
|
|
4037
|
+
description: "List files in a directory",
|
|
4038
|
+
category: "filesystem",
|
|
4039
|
+
parameters: [
|
|
4040
|
+
{ name: "path", type: "string", description: "Directory path", required: false, default: "." }
|
|
4041
|
+
],
|
|
4042
|
+
execute: async (params) => {
|
|
4043
|
+
const { readdirSync: readdirSync2, statSync: statSync2 } = await import("fs");
|
|
4044
|
+
const { resolve: resolve5, join: join8 } = await import("path");
|
|
4045
|
+
try {
|
|
4046
|
+
const dirPath = resolve5(process.cwd(), params.path || ".");
|
|
4047
|
+
const entries = readdirSync2(dirPath);
|
|
4048
|
+
const files = [];
|
|
4049
|
+
const dirs = [];
|
|
4050
|
+
for (const entry of entries) {
|
|
4051
|
+
try {
|
|
4052
|
+
const stat = statSync2(join8(dirPath, entry));
|
|
4053
|
+
if (stat.isDirectory()) {
|
|
4054
|
+
dirs.push(entry + "/");
|
|
4055
|
+
} else {
|
|
4056
|
+
files.push(entry);
|
|
4057
|
+
}
|
|
4058
|
+
} catch {
|
|
4059
|
+
files.push(entry);
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
return {
|
|
4063
|
+
success: true,
|
|
4064
|
+
data: { dirs, files },
|
|
4065
|
+
display: `${dirs.length} directories, ${files.length} files`
|
|
4066
|
+
};
|
|
4067
|
+
} catch (error) {
|
|
4068
|
+
return {
|
|
4069
|
+
success: false,
|
|
4070
|
+
error: `Failed to list directory: ${error}`
|
|
4071
|
+
};
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
});
|
|
4075
|
+
registerTool({
|
|
4076
|
+
name: "search_code",
|
|
4077
|
+
description: "Search for code in the current project",
|
|
4078
|
+
category: "code",
|
|
4079
|
+
parameters: [
|
|
4080
|
+
{ name: "query", type: "string", description: "Search query", required: true },
|
|
4081
|
+
{ name: "limit", type: "number", description: "Max results", required: false, default: 5 }
|
|
4082
|
+
],
|
|
4083
|
+
execute: async (params) => {
|
|
4084
|
+
const { searchCodebase: searchCodebase2 } = await import("./rag-6HO4ZLBN.js");
|
|
4085
|
+
const results = searchCodebase2(
|
|
4086
|
+
process.cwd(),
|
|
4087
|
+
params.query,
|
|
4088
|
+
{ limit: params.limit || 5 }
|
|
4089
|
+
);
|
|
4090
|
+
if (results.length === 0) {
|
|
4091
|
+
return {
|
|
4092
|
+
success: true,
|
|
4093
|
+
data: [],
|
|
4094
|
+
display: "No results found"
|
|
4095
|
+
};
|
|
4096
|
+
}
|
|
4097
|
+
const display = results.map(
|
|
4098
|
+
(r) => `${r.chunk.relativePath}:${r.chunk.startLine} (score: ${r.score.toFixed(2)})`
|
|
4099
|
+
).join("\n");
|
|
4100
|
+
return {
|
|
4101
|
+
success: true,
|
|
4102
|
+
data: results.map((r) => ({
|
|
4103
|
+
file: r.chunk.relativePath,
|
|
4104
|
+
line: r.chunk.startLine,
|
|
4105
|
+
content: r.chunk.content.slice(0, 200)
|
|
4106
|
+
})),
|
|
4107
|
+
display
|
|
4108
|
+
};
|
|
4109
|
+
}
|
|
4110
|
+
});
|
|
4111
|
+
registerTool({
|
|
4112
|
+
name: "run_command",
|
|
4113
|
+
description: "Run a shell command (requires user approval)",
|
|
4114
|
+
category: "system",
|
|
4115
|
+
parameters: [
|
|
4116
|
+
{ name: "command", type: "string", description: "Command to run", required: true }
|
|
4117
|
+
],
|
|
4118
|
+
execute: async (params) => {
|
|
4119
|
+
return {
|
|
4120
|
+
success: false,
|
|
4121
|
+
error: "Shell commands require explicit user approval. Use /build or /exec instead."
|
|
4122
|
+
};
|
|
4123
|
+
}
|
|
4124
|
+
});
|
|
4125
|
+
|
|
4126
|
+
// src/core/memory-store.ts
|
|
4127
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
4128
|
+
import { join as join7 } from "path";
|
|
4129
|
+
import { homedir as homedir6 } from "os";
|
|
4130
|
+
var MEMORY_DIR = join7(homedir6(), ".agdi", "memory");
|
|
4131
|
+
var MEMORY_FILE = join7(MEMORY_DIR, "store.json");
|
|
4132
|
+
function ensureMemoryDir() {
|
|
4133
|
+
if (!existsSync10(MEMORY_DIR)) {
|
|
4134
|
+
mkdirSync5(MEMORY_DIR, { recursive: true });
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
function loadMemoryStore() {
|
|
4138
|
+
ensureMemoryDir();
|
|
4139
|
+
if (existsSync10(MEMORY_FILE)) {
|
|
4140
|
+
try {
|
|
4141
|
+
const data = readFileSync7(MEMORY_FILE, "utf-8");
|
|
4142
|
+
return JSON.parse(data);
|
|
4143
|
+
} catch {
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
return {
|
|
4147
|
+
version: 1,
|
|
4148
|
+
entries: [],
|
|
4149
|
+
userPreferences: {},
|
|
4150
|
+
projectContexts: {}
|
|
4151
|
+
};
|
|
4152
|
+
}
|
|
4153
|
+
function getMemoryStats() {
|
|
4154
|
+
const store = loadMemoryStore();
|
|
4155
|
+
const byType = {};
|
|
4156
|
+
for (const entry of store.entries) {
|
|
4157
|
+
byType[entry.type] = (byType[entry.type] || 0) + 1;
|
|
4158
|
+
}
|
|
4159
|
+
return {
|
|
4160
|
+
totalEntries: store.entries.length,
|
|
4161
|
+
byType,
|
|
4162
|
+
projectCount: Object.keys(store.projectContexts).length,
|
|
4163
|
+
preferenceCount: Object.keys(store.userPreferences).length
|
|
4164
|
+
};
|
|
4165
|
+
}
|
|
4166
|
+
|
|
3918
4167
|
// src/commands/agdi-dev.ts
|
|
4168
|
+
var multiAgentMode = false;
|
|
3919
4169
|
var BASE_CHAT_PROMPT = `You are Agdi dev, an elite AI coding assistant. You help developers write code, debug issues, and build applications.
|
|
3920
4170
|
|
|
3921
4171
|
## Your Capabilities
|
|
@@ -3993,7 +4243,7 @@ For landing pages, portfolios, or apps that need visuals, use generateImage acti
|
|
|
3993
4243
|
async function startCodingMode() {
|
|
3994
4244
|
const activeConfig = getActiveProvider();
|
|
3995
4245
|
if (!activeConfig) {
|
|
3996
|
-
console.log(
|
|
4246
|
+
console.log(chalk13.red("\u274C No API key configured. Run: agdi"));
|
|
3997
4247
|
return;
|
|
3998
4248
|
}
|
|
3999
4249
|
const { provider, apiKey, model } = activeConfig;
|
|
@@ -4005,11 +4255,15 @@ async function startCodingMode() {
|
|
|
4005
4255
|
process.exit(0);
|
|
4006
4256
|
}
|
|
4007
4257
|
logSessionStart(env.workspaceRoot, env.trustLevel);
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4258
|
+
ui.renderBox(
|
|
4259
|
+
"SESSION INFO",
|
|
4260
|
+
`Model: ${chalk13.cyan(model)}
|
|
4261
|
+
Workspace: ${chalk13.cyan(env.workspaceRoot)}
|
|
4262
|
+
Context: ${isGitRepo() ? chalk13.green("Git Repository") : chalk13.gray("Local Folder")}`,
|
|
4263
|
+
"info"
|
|
4264
|
+
);
|
|
4265
|
+
console.log(chalk13.gray("Commands: /status, /diff, /commit, /build, /help..."));
|
|
4266
|
+
ui.printIter();
|
|
4013
4267
|
const pm = new ProjectManager();
|
|
4014
4268
|
let llm = createLLMProvider(provider, { apiKey, model });
|
|
4015
4269
|
const conversation = getConversation();
|
|
@@ -4017,12 +4271,12 @@ async function startCodingMode() {
|
|
|
4017
4271
|
while (true) {
|
|
4018
4272
|
try {
|
|
4019
4273
|
const userInput = await input5({
|
|
4020
|
-
message:
|
|
4274
|
+
message: chalk13.cyan.bold("\u{1F464} YOU \u203A")
|
|
4021
4275
|
});
|
|
4022
4276
|
const trimmed = userInput.trim().toLowerCase();
|
|
4023
4277
|
if (trimmed === "/exit" || trimmed === "exit" || trimmed === "quit") {
|
|
4024
4278
|
logSessionEnd();
|
|
4025
|
-
console.log(
|
|
4279
|
+
console.log(chalk13.gray("\n\u{1F44B} Goodbye!\n"));
|
|
4026
4280
|
break;
|
|
4027
4281
|
}
|
|
4028
4282
|
if (trimmed === "/help") {
|
|
@@ -4037,34 +4291,34 @@ async function startCodingMode() {
|
|
|
4037
4291
|
apiKey: newConfig.apiKey,
|
|
4038
4292
|
model: newConfig.model
|
|
4039
4293
|
});
|
|
4040
|
-
console.log(
|
|
4294
|
+
console.log(chalk13.gray(`Now using: ${chalk13.cyan(newConfig.model)}
|
|
4041
4295
|
`));
|
|
4042
4296
|
}
|
|
4043
4297
|
continue;
|
|
4044
4298
|
}
|
|
4045
4299
|
if (trimmed === "/chat") {
|
|
4046
|
-
console.log(
|
|
4300
|
+
console.log(chalk13.gray("\nSwitching to chat mode. Type /code to return.\n"));
|
|
4047
4301
|
await chatMode(llm);
|
|
4048
4302
|
continue;
|
|
4049
4303
|
}
|
|
4050
4304
|
if (trimmed === "/clear") {
|
|
4051
4305
|
clearConversation();
|
|
4052
4306
|
conversation.setSystemPrompt(buildContextAwarePrompt());
|
|
4053
|
-
console.log(
|
|
4307
|
+
console.log(chalk13.green("\n\u2713 Conversation cleared.\n"));
|
|
4054
4308
|
continue;
|
|
4055
4309
|
}
|
|
4056
4310
|
if (trimmed === "/history") {
|
|
4057
4311
|
const messages = conversation.getMessages();
|
|
4058
4312
|
if (messages.length === 0) {
|
|
4059
|
-
console.log(
|
|
4313
|
+
console.log(chalk13.gray("\n(no conversation history)\n"));
|
|
4060
4314
|
} else {
|
|
4061
|
-
console.log(
|
|
4062
|
-
console.log(
|
|
4315
|
+
console.log(chalk13.cyan.bold("\n\u{1F4DC} Conversation History\n"));
|
|
4316
|
+
console.log(chalk13.gray(conversation.getSummary()));
|
|
4063
4317
|
console.log("");
|
|
4064
4318
|
for (const msg of messages.slice(-6)) {
|
|
4065
|
-
const role = msg.role === "user" ?
|
|
4319
|
+
const role = msg.role === "user" ? chalk13.green("You") : chalk13.cyan("AI");
|
|
4066
4320
|
const preview = msg.content.slice(0, 80) + (msg.content.length > 80 ? "..." : "");
|
|
4067
|
-
console.log(` ${role}: ${
|
|
4321
|
+
console.log(` ${role}: ${chalk13.gray(preview)}`);
|
|
4068
4322
|
}
|
|
4069
4323
|
console.log("");
|
|
4070
4324
|
}
|
|
@@ -4087,16 +4341,79 @@ async function startCodingMode() {
|
|
|
4087
4341
|
if (filePath) {
|
|
4088
4342
|
await handleFileEdit(filePath, llm);
|
|
4089
4343
|
} else {
|
|
4090
|
-
console.log(
|
|
4344
|
+
console.log(chalk13.yellow("\nUsage: /edit <file>\n"));
|
|
4345
|
+
}
|
|
4346
|
+
continue;
|
|
4347
|
+
}
|
|
4348
|
+
if (trimmed === "/index") {
|
|
4349
|
+
const spinner2 = ui.createSpinner("Indexing project...").start();
|
|
4350
|
+
try {
|
|
4351
|
+
const index = indexProject(process.cwd());
|
|
4352
|
+
spinner2.succeed(`Indexed ${index.fileCount} files, ${index.chunkCount} chunks`);
|
|
4353
|
+
} catch (error) {
|
|
4354
|
+
spinner2.fail("Indexing failed: " + (error instanceof Error ? error.message : String(error)));
|
|
4355
|
+
}
|
|
4356
|
+
continue;
|
|
4357
|
+
}
|
|
4358
|
+
if (trimmed.startsWith("/search ")) {
|
|
4359
|
+
const query = userInput.slice(8).trim();
|
|
4360
|
+
if (!query) {
|
|
4361
|
+
console.log(chalk13.yellow("\nUsage: /search <query>\n"));
|
|
4362
|
+
continue;
|
|
4363
|
+
}
|
|
4364
|
+
const results = searchCodebase(process.cwd(), query, { limit: 8 });
|
|
4365
|
+
if (results.length === 0) {
|
|
4366
|
+
console.log(chalk13.gray("\nNo results found. Try /index first.\n"));
|
|
4367
|
+
} else {
|
|
4368
|
+
console.log(chalk13.cyan.bold("\n\u{1F50D} Search Results\n"));
|
|
4369
|
+
for (const r of results) {
|
|
4370
|
+
console.log(chalk13.green(` ${r.chunk.relativePath}:${r.chunk.startLine}`) + chalk13.gray(` (${r.score.toFixed(2)})`));
|
|
4371
|
+
if (r.highlights.length > 0) {
|
|
4372
|
+
console.log(chalk13.gray(` ${r.highlights[0].slice(0, 60)}...`));
|
|
4373
|
+
}
|
|
4374
|
+
}
|
|
4375
|
+
console.log("");
|
|
4091
4376
|
}
|
|
4092
4377
|
continue;
|
|
4093
4378
|
}
|
|
4379
|
+
if (trimmed === "/tools") {
|
|
4380
|
+
const tools2 = listTools();
|
|
4381
|
+
console.log(chalk13.cyan.bold("\n\u{1F527} Available Tools\n"));
|
|
4382
|
+
for (const tool of tools2) {
|
|
4383
|
+
console.log(chalk13.green(` ${tool.name}`) + chalk13.gray(` [${tool.category}]`));
|
|
4384
|
+
console.log(chalk13.gray(` ${tool.description}`));
|
|
4385
|
+
}
|
|
4386
|
+
console.log("");
|
|
4387
|
+
continue;
|
|
4388
|
+
}
|
|
4389
|
+
if (trimmed === "/agent") {
|
|
4390
|
+
multiAgentMode = !multiAgentMode;
|
|
4391
|
+
console.log(chalk13.cyan(`
|
|
4392
|
+
\u{1F916} Multi-agent mode: ${multiAgentMode ? chalk13.green("ON") : chalk13.gray("OFF")}
|
|
4393
|
+
`));
|
|
4394
|
+
if (multiAgentMode) {
|
|
4395
|
+
console.log(chalk13.gray(" Planner \u2192 Coder \u2192 Reviewer pipeline enabled\n"));
|
|
4396
|
+
}
|
|
4397
|
+
continue;
|
|
4398
|
+
}
|
|
4399
|
+
if (trimmed === "/memory") {
|
|
4400
|
+
const stats = getMemoryStats();
|
|
4401
|
+
console.log(chalk13.cyan.bold("\n\u{1F9E0} Memory Stats\n"));
|
|
4402
|
+
console.log(chalk13.gray(` Total entries: ${stats.totalEntries}`));
|
|
4403
|
+
console.log(chalk13.gray(` Projects: ${stats.projectCount}`));
|
|
4404
|
+
console.log(chalk13.gray(` Preferences: ${stats.preferenceCount}`));
|
|
4405
|
+
for (const [type, count] of Object.entries(stats.byType)) {
|
|
4406
|
+
console.log(chalk13.gray(` ${type}: ${count}`));
|
|
4407
|
+
}
|
|
4408
|
+
console.log("");
|
|
4409
|
+
continue;
|
|
4410
|
+
}
|
|
4094
4411
|
if (trimmed.startsWith("/build ") || trimmed.startsWith("build ")) {
|
|
4095
4412
|
const prompt = userInput.replace(/^\/?build\s+/i, "").trim();
|
|
4096
4413
|
if (prompt) {
|
|
4097
4414
|
await buildAppWithPlan(prompt, llm);
|
|
4098
4415
|
} else {
|
|
4099
|
-
console.log(
|
|
4416
|
+
console.log(chalk13.yellow("\nUsage: /build <description>\n"));
|
|
4100
4417
|
}
|
|
4101
4418
|
continue;
|
|
4102
4419
|
}
|
|
@@ -4108,7 +4425,7 @@ async function startCodingMode() {
|
|
|
4108
4425
|
await buildAppWithPlan(userInput, llm);
|
|
4109
4426
|
continue;
|
|
4110
4427
|
}
|
|
4111
|
-
const spinner =
|
|
4428
|
+
const spinner = ui.createSpinner("Thinking...").start();
|
|
4112
4429
|
try {
|
|
4113
4430
|
conversation.addUserMessage(userInput);
|
|
4114
4431
|
let response;
|
|
@@ -4120,7 +4437,7 @@ async function startCodingMode() {
|
|
|
4120
4437
|
}
|
|
4121
4438
|
conversation.addAssistantMessage(response.text);
|
|
4122
4439
|
spinner.stop();
|
|
4123
|
-
|
|
4440
|
+
ui.printAIMessage(formatResponse(response.text));
|
|
4124
4441
|
} catch (error) {
|
|
4125
4442
|
spinner.fail("Error");
|
|
4126
4443
|
handleError(error);
|
|
@@ -4128,7 +4445,7 @@ async function startCodingMode() {
|
|
|
4128
4445
|
} catch (error) {
|
|
4129
4446
|
if (error.name === "ExitPromptError") {
|
|
4130
4447
|
logSessionEnd();
|
|
4131
|
-
console.log(
|
|
4448
|
+
console.log(chalk13.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
4132
4449
|
process.exit(0);
|
|
4133
4450
|
}
|
|
4134
4451
|
throw error;
|
|
@@ -4136,13 +4453,13 @@ async function startCodingMode() {
|
|
|
4136
4453
|
}
|
|
4137
4454
|
}
|
|
4138
4455
|
async function buildAppWithPlan(prompt, llm) {
|
|
4139
|
-
const spinner =
|
|
4456
|
+
const spinner = ui.createSpinner("Generating action plan...").start();
|
|
4140
4457
|
try {
|
|
4141
4458
|
const response = await llm.generate(prompt, BUILD_SYSTEM_PROMPT);
|
|
4142
4459
|
spinner.stop();
|
|
4143
4460
|
const result = await parseAndExecutePlan(response.text);
|
|
4144
4461
|
if (!result) {
|
|
4145
|
-
console.log(
|
|
4462
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F Model did not return an action plan. Showing response:\n"));
|
|
4146
4463
|
console.log(formatResponse(response.text) + "\n");
|
|
4147
4464
|
}
|
|
4148
4465
|
} catch (error) {
|
|
@@ -4154,17 +4471,17 @@ async function chatMode(llm) {
|
|
|
4154
4471
|
while (true) {
|
|
4155
4472
|
try {
|
|
4156
4473
|
const userInput = await input5({
|
|
4157
|
-
message:
|
|
4474
|
+
message: chalk13.blue("\u{1F4AC}")
|
|
4158
4475
|
});
|
|
4159
4476
|
if (userInput.toLowerCase() === "/code" || userInput.toLowerCase() === "/exit") {
|
|
4160
|
-
console.log(
|
|
4477
|
+
console.log(chalk13.gray("\nBack to Agdi dev mode.\n"));
|
|
4161
4478
|
return;
|
|
4162
4479
|
}
|
|
4163
4480
|
if (!userInput.trim()) continue;
|
|
4164
|
-
const spinner =
|
|
4481
|
+
const spinner = ui.createSpinner("Thinking...").start();
|
|
4165
4482
|
const response = await llm.generate(userInput, "You are a helpful assistant. Be friendly and concise.");
|
|
4166
4483
|
spinner.stop();
|
|
4167
|
-
|
|
4484
|
+
ui.printAIMessage(response.text);
|
|
4168
4485
|
} catch (error) {
|
|
4169
4486
|
if (error.name === "ExitPromptError") {
|
|
4170
4487
|
return;
|
|
@@ -4175,10 +4492,10 @@ async function chatMode(llm) {
|
|
|
4175
4492
|
}
|
|
4176
4493
|
async function handleGitStatus(llm) {
|
|
4177
4494
|
if (!isGitRepo()) {
|
|
4178
|
-
console.log(
|
|
4495
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F Not a git repository\n"));
|
|
4179
4496
|
return;
|
|
4180
4497
|
}
|
|
4181
|
-
const spinner =
|
|
4498
|
+
const spinner = ui.createSpinner("Analyzing git status...").start();
|
|
4182
4499
|
try {
|
|
4183
4500
|
const status = getStatus();
|
|
4184
4501
|
const statusText = formatStatusForPrompt(status);
|
|
@@ -4187,10 +4504,10 @@ async function handleGitStatus(llm) {
|
|
|
4187
4504
|
${statusText}`;
|
|
4188
4505
|
const response = await llm.generate(prompt, BASE_CHAT_PROMPT);
|
|
4189
4506
|
spinner.stop();
|
|
4190
|
-
console.log(
|
|
4191
|
-
console.log(
|
|
4192
|
-
console.log(
|
|
4193
|
-
|
|
4507
|
+
console.log(chalk13.cyan.bold("\n\u{1F4CA} Git Status Analysis\n"));
|
|
4508
|
+
console.log(chalk13.gray(statusText));
|
|
4509
|
+
console.log(chalk13.cyan("\n\u2500\u2500\u2500 AI Analysis \u2500\u2500\u2500\n"));
|
|
4510
|
+
ui.printAIMessage(formatResponse(response.text));
|
|
4194
4511
|
} catch (error) {
|
|
4195
4512
|
spinner.fail("Error analyzing status");
|
|
4196
4513
|
handleError(error);
|
|
@@ -4198,16 +4515,16 @@ ${statusText}`;
|
|
|
4198
4515
|
}
|
|
4199
4516
|
async function handleGitDiff(llm) {
|
|
4200
4517
|
if (!isGitRepo()) {
|
|
4201
|
-
console.log(
|
|
4518
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F Not a git repository\n"));
|
|
4202
4519
|
return;
|
|
4203
4520
|
}
|
|
4204
|
-
const spinner =
|
|
4521
|
+
const spinner = ui.createSpinner("Analyzing changes...").start();
|
|
4205
4522
|
try {
|
|
4206
4523
|
const stagedDiff = getDiff(true);
|
|
4207
4524
|
const unstagedDiff = getDiff(false);
|
|
4208
4525
|
if (stagedDiff.files.length === 0 && unstagedDiff.files.length === 0) {
|
|
4209
4526
|
spinner.stop();
|
|
4210
|
-
console.log(
|
|
4527
|
+
console.log(chalk13.gray("\n(no changes to analyze)\n"));
|
|
4211
4528
|
return;
|
|
4212
4529
|
}
|
|
4213
4530
|
let diffContext = "";
|
|
@@ -4222,8 +4539,8 @@ async function handleGitDiff(llm) {
|
|
|
4222
4539
|
${diffContext}`;
|
|
4223
4540
|
const response = await llm.generate(prompt, BASE_CHAT_PROMPT);
|
|
4224
4541
|
spinner.stop();
|
|
4225
|
-
console.log(
|
|
4226
|
-
|
|
4542
|
+
console.log(chalk13.cyan.bold("\n\u{1F50D} Diff Analysis\n"));
|
|
4543
|
+
ui.printAIMessage(formatResponse(response.text));
|
|
4227
4544
|
} catch (error) {
|
|
4228
4545
|
spinner.fail("Error analyzing diff");
|
|
4229
4546
|
handleError(error);
|
|
@@ -4231,15 +4548,15 @@ ${diffContext}`;
|
|
|
4231
4548
|
}
|
|
4232
4549
|
async function handleGitCommit(llm) {
|
|
4233
4550
|
if (!isGitRepo()) {
|
|
4234
|
-
console.log(
|
|
4551
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F Not a git repository\n"));
|
|
4235
4552
|
return;
|
|
4236
4553
|
}
|
|
4237
4554
|
const status = getStatus();
|
|
4238
4555
|
if (status.staged.length === 0) {
|
|
4239
|
-
console.log(
|
|
4556
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F No staged changes. Stage some changes first with `git add`.\n"));
|
|
4240
4557
|
return;
|
|
4241
4558
|
}
|
|
4242
|
-
const spinner =
|
|
4559
|
+
const spinner = ui.createSpinner("Generating commit message...").start();
|
|
4243
4560
|
try {
|
|
4244
4561
|
const stagedDiff = getDiff(true);
|
|
4245
4562
|
const diffText = formatDiffForPrompt(stagedDiff);
|
|
@@ -4254,8 +4571,8 @@ ${diffText}`;
|
|
|
4254
4571
|
const response = await llm.generate(prompt, "You are a git commit message generator. Output ONLY the commit message, no explanation.");
|
|
4255
4572
|
spinner.stop();
|
|
4256
4573
|
const commitMessage = response.text.trim().split("\n")[0];
|
|
4257
|
-
console.log(
|
|
4258
|
-
console.log(
|
|
4574
|
+
console.log(chalk13.cyan.bold("\n\u{1F4AC} Generated Commit Message\n"));
|
|
4575
|
+
console.log(chalk13.white(` ${commitMessage}
|
|
4259
4576
|
`));
|
|
4260
4577
|
const shouldCommit = await confirm3({
|
|
4261
4578
|
message: "Commit with this message?",
|
|
@@ -4269,12 +4586,12 @@ ${diffText}`;
|
|
|
4269
4586
|
cwd: env.workspaceRoot,
|
|
4270
4587
|
stdio: "inherit"
|
|
4271
4588
|
});
|
|
4272
|
-
console.log(
|
|
4589
|
+
console.log(chalk13.green("\n\u2713 Committed successfully!\n"));
|
|
4273
4590
|
} catch (gitError) {
|
|
4274
|
-
console.log(
|
|
4591
|
+
console.log(chalk13.red("\n\u2717 Commit failed. Check git output above.\n"));
|
|
4275
4592
|
}
|
|
4276
4593
|
} else {
|
|
4277
|
-
console.log(
|
|
4594
|
+
console.log(chalk13.gray("\n\u{1F44B} Commit cancelled.\n"));
|
|
4278
4595
|
}
|
|
4279
4596
|
} catch (error) {
|
|
4280
4597
|
spinner.fail("Error generating commit");
|
|
@@ -4283,73 +4600,82 @@ ${diffText}`;
|
|
|
4283
4600
|
}
|
|
4284
4601
|
function formatResponse(text) {
|
|
4285
4602
|
return text.replace(/```(\w+)?\n([\s\S]*?)```/g, (_, lang, code) => {
|
|
4286
|
-
const header = lang ?
|
|
4603
|
+
const header = lang ? chalk13.gray(`\u2500\u2500 ${lang} \u2500\u2500`) : chalk13.gray("\u2500\u2500 code \u2500\u2500");
|
|
4287
4604
|
return `
|
|
4288
4605
|
${header}
|
|
4289
|
-
${
|
|
4290
|
-
${
|
|
4606
|
+
${chalk13.white(code.trim())}
|
|
4607
|
+
${chalk13.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
4291
4608
|
`;
|
|
4292
4609
|
});
|
|
4293
4610
|
}
|
|
4294
4611
|
function showHelp() {
|
|
4295
|
-
console.log(
|
|
4296
|
-
console.log(
|
|
4297
|
-
console.log(
|
|
4298
|
-
console.log(
|
|
4299
|
-
console.log(
|
|
4612
|
+
console.log(chalk13.cyan.bold("\n\u{1F4D6} Commands\n"));
|
|
4613
|
+
console.log(chalk13.cyan(" Git Commands:"));
|
|
4614
|
+
console.log(chalk13.gray(" /status ") + "AI analysis of git status");
|
|
4615
|
+
console.log(chalk13.gray(" /diff ") + "AI explanation of current changes");
|
|
4616
|
+
console.log(chalk13.gray(" /commit ") + "Generate and run git commit");
|
|
4617
|
+
console.log("");
|
|
4618
|
+
console.log(chalk13.cyan(" Build Commands:"));
|
|
4619
|
+
console.log(chalk13.gray(" /build ") + "Generate and execute an application");
|
|
4620
|
+
console.log(chalk13.gray(" /edit ") + "AI-powered surgical file editing");
|
|
4621
|
+
console.log("");
|
|
4622
|
+
console.log(chalk13.cyan(" RAG Commands:"));
|
|
4623
|
+
console.log(chalk13.gray(" /index ") + "Index current project for search");
|
|
4624
|
+
console.log(chalk13.gray(" /search ") + "Semantic code search");
|
|
4300
4625
|
console.log("");
|
|
4301
|
-
console.log(
|
|
4302
|
-
console.log(
|
|
4303
|
-
console.log(
|
|
4626
|
+
console.log(chalk13.cyan(" Advanced:"));
|
|
4627
|
+
console.log(chalk13.gray(" /tools ") + "List available MCP tools");
|
|
4628
|
+
console.log(chalk13.gray(" /agent ") + "Toggle multi-agent mode");
|
|
4629
|
+
console.log(chalk13.gray(" /memory ") + "Show memory stats");
|
|
4304
4630
|
console.log("");
|
|
4305
|
-
console.log(
|
|
4306
|
-
console.log(
|
|
4307
|
-
console.log(
|
|
4631
|
+
console.log(chalk13.cyan(" Conversation:"));
|
|
4632
|
+
console.log(chalk13.gray(" /clear ") + "Clear conversation history");
|
|
4633
|
+
console.log(chalk13.gray(" /history ") + "Show recent conversation");
|
|
4308
4634
|
console.log("");
|
|
4309
|
-
console.log(
|
|
4310
|
-
console.log(
|
|
4311
|
-
console.log(
|
|
4312
|
-
console.log(
|
|
4313
|
-
console.log(
|
|
4314
|
-
console.log(
|
|
4315
|
-
console.log(chalk12.gray('Tip: "Create a todo app" will generate & write files.\n'));
|
|
4635
|
+
console.log(chalk13.cyan(" General:"));
|
|
4636
|
+
console.log(chalk13.gray(" /model ") + "Change AI model");
|
|
4637
|
+
console.log(chalk13.gray(" /chat ") + "Switch to chat mode");
|
|
4638
|
+
console.log(chalk13.gray(" /help ") + "Show this help");
|
|
4639
|
+
console.log(chalk13.gray(" /exit ") + "Exit Agdi");
|
|
4640
|
+
console.log(chalk13.gray("\n Or just type your coding question!\n"));
|
|
4316
4641
|
}
|
|
4317
4642
|
function handleError(error) {
|
|
4318
4643
|
const msg = error instanceof Error ? error.message : String(error);
|
|
4319
4644
|
if (msg.includes("429") || msg.includes("quota")) {
|
|
4320
|
-
console.log(
|
|
4645
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F Quota exceeded. Run /model to switch.\n"));
|
|
4321
4646
|
} else if (msg.includes("401") || msg.includes("403")) {
|
|
4322
|
-
console.log(
|
|
4647
|
+
console.log(chalk13.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
|
|
4323
4648
|
} else {
|
|
4324
|
-
console.log(
|
|
4649
|
+
console.log(chalk13.red("\n" + msg + "\n"));
|
|
4325
4650
|
}
|
|
4326
4651
|
}
|
|
4327
4652
|
|
|
4328
4653
|
// src/index.ts
|
|
4329
4654
|
var BANNER = `
|
|
4330
|
-
${
|
|
4331
|
-
${
|
|
4332
|
-
${
|
|
4333
|
-
${
|
|
4334
|
-
${
|
|
4335
|
-
${
|
|
4655
|
+
${chalk14.cyan(` ___ __ _ `)}
|
|
4656
|
+
${chalk14.cyan(` / | ____ _____/ /(_) `)}
|
|
4657
|
+
${chalk14.cyan(` / /| | / __ \`/ __ // / `)}
|
|
4658
|
+
${chalk14.cyan(` / ___ |/ /_/ / /_/ // / `)}
|
|
4659
|
+
${chalk14.cyan(`/_/ |_|\\_, /\\__,_//_/ `)}
|
|
4660
|
+
${chalk14.cyan(` /____/ `)}
|
|
4336
4661
|
`;
|
|
4337
4662
|
var program = new Command();
|
|
4338
|
-
program.name("agdi").description(
|
|
4663
|
+
program.name("agdi").description(chalk14.cyan("\u{1F680} AI-powered coding assistant")).version("2.6.0").configureHelp({
|
|
4339
4664
|
// Show banner only when help is requested
|
|
4340
4665
|
formatHelp: (cmd, helper) => {
|
|
4341
|
-
return BANNER + "\n" +
|
|
4666
|
+
return BANNER + "\n" + chalk14.gray(" The Open Source AI Architect") + "\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") + "\n" + helper.formatHelp(cmd, helper);
|
|
4342
4667
|
}
|
|
4343
4668
|
});
|
|
4344
4669
|
program.action(async () => {
|
|
4345
4670
|
try {
|
|
4671
|
+
await ui.renderBanner();
|
|
4346
4672
|
if (needsOnboarding()) {
|
|
4347
4673
|
await runOnboarding();
|
|
4348
4674
|
}
|
|
4349
4675
|
await startCodingMode();
|
|
4350
4676
|
} catch (error) {
|
|
4351
4677
|
if (error.name === "ExitPromptError") {
|
|
4352
|
-
console.log(
|
|
4678
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
4353
4679
|
process.exit(0);
|
|
4354
4680
|
}
|
|
4355
4681
|
throw error;
|
|
@@ -4364,7 +4690,7 @@ program.command("auth").description("Configure API keys").option("--status", "Sh
|
|
|
4364
4690
|
}
|
|
4365
4691
|
} catch (error) {
|
|
4366
4692
|
if (error.name === "ExitPromptError") {
|
|
4367
|
-
console.log(
|
|
4693
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4368
4694
|
process.exit(0);
|
|
4369
4695
|
}
|
|
4370
4696
|
throw error;
|
|
@@ -4375,7 +4701,7 @@ program.command("model").alias("models").description("Change AI model").action(a
|
|
|
4375
4701
|
await selectModel();
|
|
4376
4702
|
} catch (error) {
|
|
4377
4703
|
if (error.name === "ExitPromptError") {
|
|
4378
|
-
console.log(
|
|
4704
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4379
4705
|
process.exit(0);
|
|
4380
4706
|
}
|
|
4381
4707
|
throw error;
|
|
@@ -4389,7 +4715,7 @@ program.command("chat").description("Start a chat session").action(async () => {
|
|
|
4389
4715
|
await startChat();
|
|
4390
4716
|
} catch (error) {
|
|
4391
4717
|
if (error.name === "ExitPromptError") {
|
|
4392
|
-
console.log(
|
|
4718
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
4393
4719
|
process.exit(0);
|
|
4394
4720
|
}
|
|
4395
4721
|
throw error;
|
|
@@ -4400,7 +4726,7 @@ program.command("run [directory]").description("Run a generated project").action
|
|
|
4400
4726
|
await runProject(directory);
|
|
4401
4727
|
} catch (error) {
|
|
4402
4728
|
if (error.name === "ExitPromptError") {
|
|
4403
|
-
console.log(
|
|
4729
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4404
4730
|
process.exit(0);
|
|
4405
4731
|
}
|
|
4406
4732
|
throw error;
|
|
@@ -4413,7 +4739,7 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4413
4739
|
}
|
|
4414
4740
|
const activeConfig = getActiveProvider();
|
|
4415
4741
|
if (!activeConfig) {
|
|
4416
|
-
console.log(
|
|
4742
|
+
console.log(chalk14.red("\u274C No API key configured. Run: agdi auth"));
|
|
4417
4743
|
return;
|
|
4418
4744
|
}
|
|
4419
4745
|
const spinner = ora5("Generating application...").start();
|
|
@@ -4425,30 +4751,30 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4425
4751
|
const pm = new ProjectManager();
|
|
4426
4752
|
pm.create(options.output.replace("./", ""), prompt);
|
|
4427
4753
|
const { plan, files } = await generateApp(prompt, llm, (step, file) => {
|
|
4428
|
-
spinner.text = file ? `${step} ${
|
|
4754
|
+
spinner.text = file ? `${step} ${chalk14.gray(file)}` : step;
|
|
4429
4755
|
});
|
|
4430
4756
|
pm.updateFiles(files);
|
|
4431
4757
|
pm.updateDependencies(plan.dependencies);
|
|
4432
4758
|
await writeProject(pm.get(), options.output);
|
|
4433
|
-
spinner.succeed(
|
|
4434
|
-
console.log(
|
|
4435
|
-
\u{1F4C1} Created ${files.length} files in ${
|
|
4436
|
-
console.log(
|
|
4759
|
+
spinner.succeed(chalk14.green("App generated!"));
|
|
4760
|
+
console.log(chalk14.gray(`
|
|
4761
|
+
\u{1F4C1} Created ${files.length} files in ${chalk14.cyan(options.output)}`));
|
|
4762
|
+
console.log(chalk14.gray("\nNext: cd " + options.output + " && npm install && npm run dev\n"));
|
|
4437
4763
|
} catch (error) {
|
|
4438
4764
|
spinner.fail("Generation failed");
|
|
4439
4765
|
const msg = error instanceof Error ? error.message : String(error);
|
|
4440
4766
|
if (msg.includes("429") || msg.includes("quota")) {
|
|
4441
|
-
console.log(
|
|
4767
|
+
console.log(chalk14.yellow("\n\u26A0\uFE0F Quota exceeded. Run: agdi model\n"));
|
|
4442
4768
|
} else if (msg.includes("401") || msg.includes("403")) {
|
|
4443
|
-
console.log(
|
|
4769
|
+
console.log(chalk14.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
|
|
4444
4770
|
} else {
|
|
4445
|
-
console.error(
|
|
4771
|
+
console.error(chalk14.red("\n" + msg + "\n"));
|
|
4446
4772
|
}
|
|
4447
4773
|
process.exit(1);
|
|
4448
4774
|
}
|
|
4449
4775
|
} catch (error) {
|
|
4450
4776
|
if (error.name === "ExitPromptError") {
|
|
4451
|
-
console.log(
|
|
4777
|
+
console.log(chalk14.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
4452
4778
|
process.exit(0);
|
|
4453
4779
|
}
|
|
4454
4780
|
throw error;
|
|
@@ -4457,11 +4783,11 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
4457
4783
|
program.command("config").description("Show configuration").action(async () => {
|
|
4458
4784
|
const config = loadConfig();
|
|
4459
4785
|
const active = getActiveProvider();
|
|
4460
|
-
console.log(
|
|
4461
|
-
console.log(
|
|
4462
|
-
console.log(
|
|
4463
|
-
console.log(
|
|
4464
|
-
console.log(
|
|
4786
|
+
console.log(chalk14.cyan.bold("\n\u2699\uFE0F Configuration\n"));
|
|
4787
|
+
console.log(chalk14.gray(" Provider: ") + chalk14.cyan(config.defaultProvider || "not set"));
|
|
4788
|
+
console.log(chalk14.gray(" Model: ") + chalk14.cyan(config.defaultModel || "not set"));
|
|
4789
|
+
console.log(chalk14.gray(" Config: ") + chalk14.gray("~/.agdi/config.json"));
|
|
4790
|
+
console.log(chalk14.cyan.bold("\n\u{1F510} API Keys\n"));
|
|
4465
4791
|
const keys = [
|
|
4466
4792
|
["Gemini", config.geminiApiKey],
|
|
4467
4793
|
["OpenRouter", config.openrouterApiKey],
|
|
@@ -4470,7 +4796,7 @@ program.command("config").description("Show configuration").action(async () => {
|
|
|
4470
4796
|
["DeepSeek", config.deepseekApiKey]
|
|
4471
4797
|
];
|
|
4472
4798
|
for (const [name, key] of keys) {
|
|
4473
|
-
const status = key ?
|
|
4799
|
+
const status = key ? chalk14.green("\u2713") : chalk14.gray("\u2717");
|
|
4474
4800
|
console.log(` ${status} ${name}`);
|
|
4475
4801
|
}
|
|
4476
4802
|
console.log("");
|