agdi 3.3.0 → 3.3.2
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/dist/chunk-AEWEBMJY.js +14 -0
- package/dist/event-bus-EDC4P3T5.js +8 -0
- package/dist/index.js +179 -28
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/core/event-bus.ts
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
var agentEventBus = new EventEmitter();
|
|
4
|
+
function emitAgentEvent(event) {
|
|
5
|
+
agentEventBus.emit("agent_event", {
|
|
6
|
+
...event,
|
|
7
|
+
timestamp: Date.now()
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
agentEventBus,
|
|
13
|
+
emitAgentEvent
|
|
14
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
agentEventBus,
|
|
4
|
+
emitAgentEvent
|
|
5
|
+
} from "./chunk-AEWEBMJY.js";
|
|
2
6
|
import {
|
|
3
7
|
loadConfig,
|
|
4
8
|
saveConfig
|
|
@@ -2072,6 +2076,13 @@ var BaseAgent = class {
|
|
|
2072
2076
|
* Log a message (if verbose)
|
|
2073
2077
|
*/
|
|
2074
2078
|
log(message, type = "info") {
|
|
2079
|
+
emitAgentEvent({
|
|
2080
|
+
type: "log",
|
|
2081
|
+
agentName: this.name,
|
|
2082
|
+
role: this.role,
|
|
2083
|
+
message,
|
|
2084
|
+
metadata: { type }
|
|
2085
|
+
});
|
|
2075
2086
|
if (!this.verbose) return;
|
|
2076
2087
|
const prefix = `[${this.name}]`;
|
|
2077
2088
|
switch (type) {
|
|
@@ -2093,7 +2104,20 @@ var BaseAgent = class {
|
|
|
2093
2104
|
*/
|
|
2094
2105
|
async think(prompt) {
|
|
2095
2106
|
this.log("Thinking...", "info");
|
|
2107
|
+
emitAgentEvent({
|
|
2108
|
+
type: "thought",
|
|
2109
|
+
agentName: this.name,
|
|
2110
|
+
role: this.role,
|
|
2111
|
+
message: `Analyzing task...`
|
|
2112
|
+
});
|
|
2096
2113
|
const response = await this.llm.generate(prompt, this.getSystemPrompt());
|
|
2114
|
+
const summary = response.text.split("\n")[0].substring(0, 80) + "...";
|
|
2115
|
+
emitAgentEvent({
|
|
2116
|
+
type: "thought",
|
|
2117
|
+
agentName: this.name,
|
|
2118
|
+
role: this.role,
|
|
2119
|
+
message: `Generated response: ${summary}`
|
|
2120
|
+
});
|
|
2097
2121
|
this.collectSourcesFromText(response.text);
|
|
2098
2122
|
return response.text;
|
|
2099
2123
|
}
|
|
@@ -3568,6 +3592,14 @@ ${qaResult.errors?.join("\n")}`,
|
|
|
3568
3592
|
*/
|
|
3569
3593
|
async executeTask(task) {
|
|
3570
3594
|
this.log(`[${task.assignee}] ${task.title}`, "task");
|
|
3595
|
+
const { emitAgentEvent: emitAgentEvent2 } = await import("./event-bus-EDC4P3T5.js");
|
|
3596
|
+
emitAgentEvent2({
|
|
3597
|
+
type: "handoff",
|
|
3598
|
+
agentName: task.assignee,
|
|
3599
|
+
// e.g. "frontend"
|
|
3600
|
+
role: task.assignee,
|
|
3601
|
+
message: `Taking control for task: ${task.title}`
|
|
3602
|
+
});
|
|
3571
3603
|
await this.appendTrace("task_start", {
|
|
3572
3604
|
id: task.id,
|
|
3573
3605
|
title: task.title,
|
|
@@ -4155,9 +4187,11 @@ import { render } from "ink";
|
|
|
4155
4187
|
import { useState, useEffect } from "react";
|
|
4156
4188
|
import { Box, Text, useApp } from "ink";
|
|
4157
4189
|
import BigText from "ink-big-text";
|
|
4190
|
+
import Spinner from "ink-spinner";
|
|
4158
4191
|
import TextInput from "ink-text-input";
|
|
4159
4192
|
import fs7 from "fs";
|
|
4160
4193
|
import path7 from "path";
|
|
4194
|
+
import os from "os";
|
|
4161
4195
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4162
4196
|
var BootScreen = ({ onComplete }) => {
|
|
4163
4197
|
const [progress, setProgress] = useState(0);
|
|
@@ -4175,10 +4209,10 @@ var BootScreen = ({ onComplete }) => {
|
|
|
4175
4209
|
useEffect(() => {
|
|
4176
4210
|
const timer = setInterval(() => {
|
|
4177
4211
|
setProgress((prev) => {
|
|
4178
|
-
const next = prev +
|
|
4212
|
+
const next = prev + 5;
|
|
4179
4213
|
if (next >= 100) {
|
|
4180
4214
|
clearInterval(timer);
|
|
4181
|
-
setTimeout(onComplete,
|
|
4215
|
+
setTimeout(onComplete, 200);
|
|
4182
4216
|
return 100;
|
|
4183
4217
|
}
|
|
4184
4218
|
return next;
|
|
@@ -4205,20 +4239,25 @@ var BootScreen = ({ onComplete }) => {
|
|
|
4205
4239
|
] })
|
|
4206
4240
|
] });
|
|
4207
4241
|
};
|
|
4208
|
-
var FileExplorer = ({ cwd }) => {
|
|
4242
|
+
var FileExplorer = ({ cwd, lastChange }) => {
|
|
4209
4243
|
const [files, setFiles] = useState([]);
|
|
4210
4244
|
useEffect(() => {
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4245
|
+
const refresh = () => {
|
|
4246
|
+
try {
|
|
4247
|
+
const list = fs7.readdirSync(cwd).filter((f) => !f.startsWith(".")).slice(0, 15);
|
|
4248
|
+
setFiles(list);
|
|
4249
|
+
} catch {
|
|
4250
|
+
setFiles(["<Error reading dir>"]);
|
|
4251
|
+
}
|
|
4252
|
+
};
|
|
4253
|
+
refresh();
|
|
4254
|
+
const timer = setInterval(refresh, 2e3);
|
|
4255
|
+
return () => clearInterval(timer);
|
|
4256
|
+
}, [cwd, lastChange]);
|
|
4218
4257
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", title: " FILESYSTEM ", width: "30%", children: [
|
|
4219
4258
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
|
|
4220
4259
|
" ",
|
|
4221
|
-
cwd
|
|
4260
|
+
cwd.length > 30 ? "..." + cwd.slice(-30) : cwd
|
|
4222
4261
|
] }),
|
|
4223
4262
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
4224
4263
|
files.map((f, i) => /* @__PURE__ */ jsxs(Text, { color: "white", children: [
|
|
@@ -4231,7 +4270,7 @@ var FileExplorer = ({ cwd }) => {
|
|
|
4231
4270
|
};
|
|
4232
4271
|
var LogPanel = ({ logs }) => {
|
|
4233
4272
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", title: " AGENT LOGS ", width: "70%", marginLeft: 1, children: [
|
|
4234
|
-
logs.slice(-
|
|
4273
|
+
logs.slice(-12).map((log, i) => /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4235
4274
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
4236
4275
|
"[",
|
|
4237
4276
|
(/* @__PURE__ */ new Date()).toLocaleTimeString(),
|
|
@@ -4243,11 +4282,11 @@ var LogPanel = ({ logs }) => {
|
|
|
4243
4282
|
logs.length === 0 && /* @__PURE__ */ jsx(Text, { color: "gray", children: "Waiting for agent activity..." })
|
|
4244
4283
|
] });
|
|
4245
4284
|
};
|
|
4246
|
-
var ChatPanel = ({ history, onSend }) => {
|
|
4285
|
+
var ChatPanel = ({ history, onSend, placeholder = "" }) => {
|
|
4247
4286
|
const [query, setQuery] = useState("");
|
|
4248
4287
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", title: " MISSION CONTROL ", height: 12, children: [
|
|
4249
4288
|
/* @__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 " }),
|
|
4289
|
+
/* @__PURE__ */ jsx(Text, { color: msg.role === "user" ? "cyan" : msg.role === "system" ? "yellow" : "magenta", bold: true, children: msg.role === "user" ? "YOU \u203A " : msg.role === "system" ? "SYS \u203A " : "AGDI \u203A " }),
|
|
4251
4290
|
/* @__PURE__ */ jsx(Text, { children: msg.text })
|
|
4252
4291
|
] }, i)) }),
|
|
4253
4292
|
/* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "gray", marginTop: 1, children: [
|
|
@@ -4260,7 +4299,8 @@ var ChatPanel = ({ history, onSend }) => {
|
|
|
4260
4299
|
onSubmit: (val) => {
|
|
4261
4300
|
onSend(val);
|
|
4262
4301
|
setQuery("");
|
|
4263
|
-
}
|
|
4302
|
+
},
|
|
4303
|
+
placeholder
|
|
4264
4304
|
}
|
|
4265
4305
|
)
|
|
4266
4306
|
] })
|
|
@@ -4268,28 +4308,139 @@ var ChatPanel = ({ history, onSend }) => {
|
|
|
4268
4308
|
};
|
|
4269
4309
|
var Dashboard = () => {
|
|
4270
4310
|
const { exit } = useApp();
|
|
4271
|
-
const [
|
|
4311
|
+
const [cwd, setCwd] = useState(process.cwd());
|
|
4312
|
+
const [logs, setLogs] = useState(["System ready.", "Initializing Neural Link..."]);
|
|
4272
4313
|
const [chatHistory, setChatHistory] = useState([]);
|
|
4273
|
-
const
|
|
4274
|
-
const
|
|
4314
|
+
const [step, setStep] = useState("safety");
|
|
4315
|
+
const [pendingAction, setPendingAction] = useState(null);
|
|
4316
|
+
const [lastFileChange, setLastFileChange] = useState(0);
|
|
4317
|
+
const [activeAgent, setActiveAgent] = useState("IDLE");
|
|
4318
|
+
useEffect(() => {
|
|
4319
|
+
const handleEvent = (event) => {
|
|
4320
|
+
if (event.type === "handoff") {
|
|
4321
|
+
setActiveAgent(event.role.toUpperCase());
|
|
4322
|
+
}
|
|
4323
|
+
if (event.type === "log" || event.type === "thought") {
|
|
4324
|
+
setLogs((prev) => [...prev, `[${event.agentName}] ${event.message}`]);
|
|
4325
|
+
}
|
|
4326
|
+
if (event.message.includes("Created:") || event.message.includes("Modified:")) {
|
|
4327
|
+
setLastFileChange(Date.now());
|
|
4328
|
+
}
|
|
4329
|
+
};
|
|
4330
|
+
agentEventBus.on("agent_event", handleEvent);
|
|
4331
|
+
return () => {
|
|
4332
|
+
agentEventBus.off("agent_event", handleEvent);
|
|
4333
|
+
};
|
|
4334
|
+
}, []);
|
|
4335
|
+
useEffect(() => {
|
|
4336
|
+
if (step === "safety") {
|
|
4337
|
+
const home = os.homedir();
|
|
4338
|
+
const root = path7.parse(cwd).root;
|
|
4339
|
+
const isUnsafe = cwd === home || cwd === root;
|
|
4340
|
+
if (isUnsafe) {
|
|
4341
|
+
setChatHistory([
|
|
4342
|
+
{ role: "system", text: `\u26A0\uFE0F SAFETY WARNING: You are running in ${cwd}` },
|
|
4343
|
+
{ role: "ai", text: "It is unsafe to run here. Should I create a new project folder for you? (yes/no)" }
|
|
4344
|
+
]);
|
|
4345
|
+
setPendingAction("safety_confirm");
|
|
4346
|
+
} else {
|
|
4347
|
+
setStep("prompt");
|
|
4348
|
+
setChatHistory([{ role: "ai", text: "Safety check passed. What are we building today?" }]);
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
}, []);
|
|
4352
|
+
const handleCommand = async (cmd) => {
|
|
4275
4353
|
if (cmd === "/exit") exit();
|
|
4276
4354
|
setChatHistory((prev) => [...prev, { role: "user", text: cmd }]);
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4355
|
+
if (step === "safety" && pendingAction === "safety_confirm") {
|
|
4356
|
+
if (cmd.toLowerCase().startsWith("y")) {
|
|
4357
|
+
setChatHistory((prev) => [...prev, { role: "ai", text: "Great. Enter a name for your project folder:" }]);
|
|
4358
|
+
setPendingAction("create_folder");
|
|
4359
|
+
} else {
|
|
4360
|
+
setChatHistory((prev) => [...prev, { role: "ai", text: "Okay, proceeding in current directory (AT YOUR OWN RISK)." }]);
|
|
4361
|
+
setStep("prompt");
|
|
4362
|
+
setPendingAction(null);
|
|
4363
|
+
setTimeout(() => setChatHistory((prev) => [...prev, { role: "ai", text: "What are we building today?" }]), 500);
|
|
4364
|
+
}
|
|
4365
|
+
return;
|
|
4366
|
+
}
|
|
4367
|
+
if (step === "safety" && pendingAction === "create_folder") {
|
|
4368
|
+
const newPath = path7.join(cwd, cmd.replace(/[^a-z0-9-_]/gi, "-"));
|
|
4369
|
+
try {
|
|
4370
|
+
if (!fs7.existsSync(newPath)) fs7.mkdirSync(newPath);
|
|
4371
|
+
process.chdir(newPath);
|
|
4372
|
+
setCwd(newPath);
|
|
4373
|
+
setLogs((prev) => [...prev, `Switched directory to ${newPath}`]);
|
|
4374
|
+
setChatHistory((prev) => [...prev, { role: "system", text: `\u{1F4C2} Switched to ${newPath}` }]);
|
|
4375
|
+
setStep("prompt");
|
|
4376
|
+
setPendingAction(null);
|
|
4377
|
+
setTimeout(() => setChatHistory((prev) => [...prev, { role: "ai", text: "What are we building today?" }]), 500);
|
|
4378
|
+
} catch (e) {
|
|
4379
|
+
setChatHistory((prev) => [...prev, { role: "system", text: `Error creating folder: ${e}` }]);
|
|
4380
|
+
}
|
|
4381
|
+
return;
|
|
4382
|
+
}
|
|
4383
|
+
if (step === "prompt") {
|
|
4384
|
+
setChatHistory((prev) => [...prev, { role: "ai", text: "Analyzing requirements..." }]);
|
|
4385
|
+
setStep("active");
|
|
4386
|
+
setActiveAgent("MANAGER");
|
|
4387
|
+
const activeConfig = getActiveProvider();
|
|
4388
|
+
if (!activeConfig) {
|
|
4389
|
+
setChatHistory((prev) => [...prev, { role: "system", text: '\u274C No API key found. Run "agdi auth" first.' }]);
|
|
4390
|
+
return;
|
|
4391
|
+
}
|
|
4392
|
+
const llm = createLLMProvider(activeConfig.provider, {
|
|
4393
|
+
apiKey: activeConfig.apiKey,
|
|
4394
|
+
model: activeConfig.model
|
|
4395
|
+
});
|
|
4396
|
+
runSquadCommand(cmd, llm, {
|
|
4397
|
+
output: cwd,
|
|
4398
|
+
verbose: false,
|
|
4399
|
+
// We handle logs via event bus now
|
|
4400
|
+
deploy: false
|
|
4401
|
+
}).then(() => {
|
|
4402
|
+
setActiveAgent("IDLE");
|
|
4403
|
+
setChatHistory((prev) => [...prev, { role: "ai", text: "\u{1F680} Mission Complete! Check the files." }]);
|
|
4404
|
+
}).catch((err) => {
|
|
4405
|
+
setActiveAgent("ERROR");
|
|
4406
|
+
setChatHistory((prev) => [...prev, { role: "system", text: `\u274C Error: ${err.message}` }]);
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4409
|
+
};
|
|
4410
|
+
const getStatusColor = () => {
|
|
4411
|
+
switch (activeAgent) {
|
|
4412
|
+
case "MANAGER":
|
|
4413
|
+
return "magenta";
|
|
4414
|
+
case "FRONTEND":
|
|
4415
|
+
return "cyan";
|
|
4416
|
+
case "BACKEND":
|
|
4417
|
+
return "blue";
|
|
4418
|
+
case "QA":
|
|
4419
|
+
return "yellow";
|
|
4420
|
+
case "DEVOPS":
|
|
4421
|
+
return "green";
|
|
4422
|
+
case "ERROR":
|
|
4423
|
+
return "red";
|
|
4424
|
+
default:
|
|
4425
|
+
return "gray";
|
|
4426
|
+
}
|
|
4282
4427
|
};
|
|
4283
4428
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, height: "100%", children: [
|
|
4284
4429
|
/* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
4285
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "AGDI v3.3.
|
|
4286
|
-
/* @__PURE__ */
|
|
4430
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "AGDI v3.3.2 [ONLINE]" }),
|
|
4431
|
+
/* @__PURE__ */ jsxs(Text, { color: getStatusColor(), children: [
|
|
4432
|
+
"AGENT: ",
|
|
4433
|
+
activeAgent,
|
|
4434
|
+
" ",
|
|
4435
|
+
activeAgent !== "IDLE" && /* @__PURE__ */ jsx(Spinner, { type: "dots" })
|
|
4436
|
+
] }),
|
|
4437
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "NET: CONNECTED" })
|
|
4287
4438
|
] }),
|
|
4288
4439
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", flexGrow: 1, children: [
|
|
4289
|
-
/* @__PURE__ */ jsx(FileExplorer, { cwd:
|
|
4440
|
+
/* @__PURE__ */ jsx(FileExplorer, { cwd, lastChange: lastFileChange }),
|
|
4290
4441
|
/* @__PURE__ */ jsx(LogPanel, { logs })
|
|
4291
4442
|
] }),
|
|
4292
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(ChatPanel, { history: chatHistory, onSend: handleCommand }) })
|
|
4443
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(ChatPanel, { history: chatHistory, onSend: handleCommand, placeholder: step === "prompt" ? "Describe your app..." : "" }) })
|
|
4293
4444
|
] });
|
|
4294
4445
|
};
|
|
4295
4446
|
var App = () => {
|
|
@@ -4314,7 +4465,7 @@ ${chalk14.cyan(`/_/ |_|\\_, /\\__,_//_/ `)}
|
|
|
4314
4465
|
${chalk14.cyan(` /____/ `)}
|
|
4315
4466
|
`;
|
|
4316
4467
|
var program = new Command();
|
|
4317
|
-
program.name("agdi").description(chalk14.cyan("\u{1F9B8} The Autonomous AI Employee")).version("3.3.
|
|
4468
|
+
program.name("agdi").description(chalk14.cyan("\u{1F9B8} The Autonomous AI Employee")).version("3.3.2").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)");
|
|
4318
4469
|
program.hook("preAction", (thisCommand) => {
|
|
4319
4470
|
const opts = thisCommand.opts();
|
|
4320
4471
|
if (opts.yes) {
|