agentflow-dashboard 0.3.0 → 0.3.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 +24 -7
- package/dist/{chunk-2FTN742J.js → chunk-EDHK4NJD.js} +168 -17
- package/dist/cli.cjs +4 -1
- package/dist/cli.js +2 -147
- package/dist/index.cjs +160 -12
- package/dist/index.js +1 -1
- package/dist/public/dashboard.js +401 -25
- package/dist/public/debug.html +43 -0
- package/dist/public/index.html +214 -0
- package/dist/server.cjs +1350 -0
- package/dist/server.js +6 -0
- package/package.json +2 -2
- package/public/dashboard.js +401 -25
- package/public/debug.html +43 -0
- package/public/index.html +214 -0
package/dist/index.cjs
CHANGED
|
@@ -38,9 +38,9 @@ module.exports = __toCommonJS(index_exports);
|
|
|
38
38
|
|
|
39
39
|
// src/server.ts
|
|
40
40
|
var import_express = __toESM(require("express"), 1);
|
|
41
|
-
var
|
|
41
|
+
var fs3 = __toESM(require("fs"), 1);
|
|
42
42
|
var import_http = require("http");
|
|
43
|
-
var
|
|
43
|
+
var path3 = __toESM(require("path"), 1);
|
|
44
44
|
var import_url = require("url");
|
|
45
45
|
var import_ws = require("ws");
|
|
46
46
|
var import_agentflow_core3 = require("agentflow-core");
|
|
@@ -997,10 +997,155 @@ var TraceWatcher = class extends import_events.EventEmitter {
|
|
|
997
997
|
}
|
|
998
998
|
};
|
|
999
999
|
|
|
1000
|
+
// src/cli.ts
|
|
1001
|
+
var fs2 = __toESM(require("fs"), 1);
|
|
1002
|
+
var os = __toESM(require("os"), 1);
|
|
1003
|
+
var path2 = __toESM(require("path"), 1);
|
|
1004
|
+
var VERSION = "0.3.1";
|
|
1005
|
+
function getLanAddress() {
|
|
1006
|
+
const interfaces = os.networkInterfaces();
|
|
1007
|
+
for (const name of Object.keys(interfaces)) {
|
|
1008
|
+
for (const iface of interfaces[name] || []) {
|
|
1009
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
1010
|
+
return iface.address;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
function printBanner(config, traceCount, stats) {
|
|
1017
|
+
var _a;
|
|
1018
|
+
const lan = getLanAddress();
|
|
1019
|
+
const host = config.host || "localhost";
|
|
1020
|
+
const port = config.port;
|
|
1021
|
+
const isPublic = host === "0.0.0.0";
|
|
1022
|
+
console.log(`
|
|
1023
|
+
___ _ _____ _
|
|
1024
|
+
/ _ \\ __ _ ___ _ __ | |_| ___| | _____ __
|
|
1025
|
+
| |_| |/ _\` |/ _ \\ '_ \\| __| |_ | |/ _ \\ \\ /\\ / /
|
|
1026
|
+
| _ | (_| | __/ | | | |_| _| | | (_) \\ V V /
|
|
1027
|
+
|_| |_|\\__, |\\___|_| |_|\\__|_| |_|\\___/ \\_/\\_/
|
|
1028
|
+
|___/ dashboard v${VERSION}
|
|
1029
|
+
|
|
1030
|
+
See your agents think.
|
|
1031
|
+
|
|
1032
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
1033
|
+
\u2502 \u{1F916} Agents \u2502 TRACE FILES \u2502 \u{1F4CA} AgentFlow \u2502 SHOWS YOU \u2502 \u{1F310} Your browser \u2502
|
|
1034
|
+
\u2502 Execute tasks, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Reads traces, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Interactive \u2502
|
|
1035
|
+
\u2502 write JSON \u2502 \u2502 builds graphs, \u2502 \u2502 graph, timeline, \u2502
|
|
1036
|
+
\u2502 trace files. \u2502 \u2502 serves dashboard.\u2502 \u2502 metrics, health. \u2502
|
|
1037
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1038
|
+
|
|
1039
|
+
Runs locally. Your data never leaves your machine.
|
|
1040
|
+
|
|
1041
|
+
Tabs: \u{1F3AF} Graph \xB7 \u23F1\uFE0F Timeline \xB7 \u{1F4CA} Metrics \xB7 \u{1F6E0}\uFE0F Process Health \xB7 \u26A0\uFE0F Errors
|
|
1042
|
+
|
|
1043
|
+
Traces: ${config.tracesDir}${((_a = config.dataDirs) == null ? void 0 : _a.length) ? "\n Data dirs: " + config.dataDirs.join("\n ") : ""}
|
|
1044
|
+
Loaded: ${traceCount} traces \xB7 ${stats.totalAgents} agents \xB7 ${stats.totalExecutions} executions
|
|
1045
|
+
Success: ${stats.globalSuccessRate.toFixed(1)}%${stats.activeAgents > 0 ? ` \xB7 ${stats.activeAgents} active now` : ""}
|
|
1046
|
+
CORS: ${config.enableCors ? "enabled" : "disabled"}
|
|
1047
|
+
WebSocket: live updates enabled
|
|
1048
|
+
|
|
1049
|
+
\u2192 http://localhost:${port}${isPublic && lan ? `
|
|
1050
|
+
\u2192 http://${lan}:${port} (LAN)` : ""}
|
|
1051
|
+
`);
|
|
1052
|
+
}
|
|
1053
|
+
async function startDashboard() {
|
|
1054
|
+
const args = process.argv.slice(2);
|
|
1055
|
+
const config = {
|
|
1056
|
+
port: 3e3,
|
|
1057
|
+
tracesDir: "./traces",
|
|
1058
|
+
host: "localhost",
|
|
1059
|
+
enableCors: false
|
|
1060
|
+
};
|
|
1061
|
+
for (let i = 0; i < args.length; i++) {
|
|
1062
|
+
switch (args[i]) {
|
|
1063
|
+
case "--port":
|
|
1064
|
+
case "-p":
|
|
1065
|
+
config.port = parseInt(args[++i]) || 3e3;
|
|
1066
|
+
break;
|
|
1067
|
+
case "--traces":
|
|
1068
|
+
case "-t":
|
|
1069
|
+
config.tracesDir = args[++i];
|
|
1070
|
+
break;
|
|
1071
|
+
case "--host":
|
|
1072
|
+
case "-h":
|
|
1073
|
+
config.host = args[++i];
|
|
1074
|
+
break;
|
|
1075
|
+
case "--data-dir":
|
|
1076
|
+
if (!config.dataDirs) config.dataDirs = [];
|
|
1077
|
+
config.dataDirs.push(args[++i]);
|
|
1078
|
+
break;
|
|
1079
|
+
case "--cors":
|
|
1080
|
+
config.enableCors = true;
|
|
1081
|
+
break;
|
|
1082
|
+
case "--help":
|
|
1083
|
+
printHelp();
|
|
1084
|
+
process.exit(0);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
const tracesPath = path2.resolve(config.tracesDir);
|
|
1088
|
+
if (!fs2.existsSync(tracesPath)) {
|
|
1089
|
+
fs2.mkdirSync(tracesPath, { recursive: true });
|
|
1090
|
+
}
|
|
1091
|
+
config.tracesDir = tracesPath;
|
|
1092
|
+
console.log("\nStarting AgentFlow Dashboard...\n");
|
|
1093
|
+
const dashboard = new DashboardServer(config);
|
|
1094
|
+
process.on("SIGINT", async () => {
|
|
1095
|
+
console.log("\n\u{1F6D1} Shutting down dashboard...");
|
|
1096
|
+
await dashboard.stop();
|
|
1097
|
+
process.exit(0);
|
|
1098
|
+
});
|
|
1099
|
+
process.on("SIGTERM", async () => {
|
|
1100
|
+
await dashboard.stop();
|
|
1101
|
+
process.exit(0);
|
|
1102
|
+
});
|
|
1103
|
+
try {
|
|
1104
|
+
await dashboard.start();
|
|
1105
|
+
setTimeout(() => {
|
|
1106
|
+
const stats = dashboard.getStats();
|
|
1107
|
+
const traces = dashboard.getTraces();
|
|
1108
|
+
printBanner(config, traces.length, stats);
|
|
1109
|
+
}, 1500);
|
|
1110
|
+
} catch (error) {
|
|
1111
|
+
console.error("\u274C Failed to start dashboard:", error);
|
|
1112
|
+
process.exit(1);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function printHelp() {
|
|
1116
|
+
console.log(`
|
|
1117
|
+
\u{1F4CA} AgentFlow Dashboard v${VERSION} \u2014 See your agents think.
|
|
1118
|
+
|
|
1119
|
+
Usage:
|
|
1120
|
+
agentflow-dashboard [options]
|
|
1121
|
+
npx agentflow-dashboard [options]
|
|
1122
|
+
|
|
1123
|
+
Options:
|
|
1124
|
+
-p, --port <number> Server port (default: 3000)
|
|
1125
|
+
-t, --traces <path> Traces directory (default: ./traces)
|
|
1126
|
+
-h, --host <address> Host address (default: localhost)
|
|
1127
|
+
--data-dir <path> Extra data directory for process discovery (repeatable)
|
|
1128
|
+
--cors Enable CORS headers
|
|
1129
|
+
--help Show this help message
|
|
1130
|
+
|
|
1131
|
+
Examples:
|
|
1132
|
+
agentflow-dashboard --traces ./traces --host 0.0.0.0 --cors
|
|
1133
|
+
agentflow-dashboard -p 8080 -t /var/log/agentflow
|
|
1134
|
+
agentflow-dashboard --traces ./traces --data-dir ./workers --data-dir ./cron
|
|
1135
|
+
|
|
1136
|
+
Tabs:
|
|
1137
|
+
\u{1F3AF} Graph Interactive Cytoscape.js execution graph
|
|
1138
|
+
\u23F1\uFE0F Timeline Waterfall view of node durations
|
|
1139
|
+
\u{1F4CA} Metrics Success rates, durations, node breakdown
|
|
1140
|
+
\u{1F6E0}\uFE0F Process Health PID files, systemd, workers, orphans
|
|
1141
|
+
\u26A0\uFE0F Errors Failed and hung nodes with metadata
|
|
1142
|
+
`);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1000
1145
|
// src/server.ts
|
|
1001
1146
|
var import_meta = {};
|
|
1002
1147
|
var __filename = (0, import_url.fileURLToPath)(import_meta.url);
|
|
1003
|
-
var __dirname =
|
|
1148
|
+
var __dirname = path3.dirname(__filename);
|
|
1004
1149
|
var DashboardServer = class {
|
|
1005
1150
|
constructor(config) {
|
|
1006
1151
|
this.config = config;
|
|
@@ -1030,8 +1175,8 @@ var DashboardServer = class {
|
|
|
1030
1175
|
next();
|
|
1031
1176
|
});
|
|
1032
1177
|
}
|
|
1033
|
-
const publicDir =
|
|
1034
|
-
if (
|
|
1178
|
+
const publicDir = path3.join(__dirname, "../public");
|
|
1179
|
+
if (fs3.existsSync(publicDir)) {
|
|
1035
1180
|
this.app.use(import_express.default.static(publicDir));
|
|
1036
1181
|
}
|
|
1037
1182
|
this.app.get("/api/traces", (req, res) => {
|
|
@@ -1103,7 +1248,7 @@ var DashboardServer = class {
|
|
|
1103
1248
|
}
|
|
1104
1249
|
const discoveryDirs = [
|
|
1105
1250
|
this.config.tracesDir,
|
|
1106
|
-
|
|
1251
|
+
path3.dirname(this.config.tracesDir),
|
|
1107
1252
|
...this.config.dataDirs || []
|
|
1108
1253
|
];
|
|
1109
1254
|
const processConfig = (0, import_agentflow_core3.discoverProcessConfig)(discoveryDirs);
|
|
@@ -1118,8 +1263,8 @@ var DashboardServer = class {
|
|
|
1118
1263
|
}
|
|
1119
1264
|
});
|
|
1120
1265
|
this.app.get("*", (req, res) => {
|
|
1121
|
-
const indexPath =
|
|
1122
|
-
if (
|
|
1266
|
+
const indexPath = path3.join(__dirname, "../public/index.html");
|
|
1267
|
+
if (fs3.existsSync(indexPath)) {
|
|
1123
1268
|
res.sendFile(indexPath);
|
|
1124
1269
|
} else {
|
|
1125
1270
|
res.status(404).send("Dashboard not found - public files may not be built");
|
|
@@ -1176,21 +1321,21 @@ var DashboardServer = class {
|
|
|
1176
1321
|
});
|
|
1177
1322
|
}
|
|
1178
1323
|
async start() {
|
|
1179
|
-
return new Promise((
|
|
1324
|
+
return new Promise((resolve3) => {
|
|
1180
1325
|
const host = this.config.host || "localhost";
|
|
1181
1326
|
this.server.listen(this.config.port, host, () => {
|
|
1182
1327
|
console.log(`AgentFlow Dashboard running at http://${host}:${this.config.port}`);
|
|
1183
1328
|
console.log(`Watching traces in: ${this.config.tracesDir}`);
|
|
1184
|
-
|
|
1329
|
+
resolve3();
|
|
1185
1330
|
});
|
|
1186
1331
|
});
|
|
1187
1332
|
}
|
|
1188
1333
|
async stop() {
|
|
1189
|
-
return new Promise((
|
|
1334
|
+
return new Promise((resolve3) => {
|
|
1190
1335
|
this.watcher.stop();
|
|
1191
1336
|
this.server.close(() => {
|
|
1192
1337
|
console.log("Dashboard server stopped");
|
|
1193
|
-
|
|
1338
|
+
resolve3();
|
|
1194
1339
|
});
|
|
1195
1340
|
});
|
|
1196
1341
|
}
|
|
@@ -1201,6 +1346,9 @@ var DashboardServer = class {
|
|
|
1201
1346
|
return this.watcher.getAllTraces();
|
|
1202
1347
|
}
|
|
1203
1348
|
};
|
|
1349
|
+
if (import_meta.url === `file://${process.argv[1]}`) {
|
|
1350
|
+
startDashboard().catch(console.error);
|
|
1351
|
+
}
|
|
1204
1352
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1205
1353
|
0 && (module.exports = {
|
|
1206
1354
|
AgentStats,
|