@taewooopark/agent-blackbox 0.42.0 → 0.44.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/dist/cli.js +271 -233
- package/dist/dashboard/assets/index-Ck9bKtYh.css +1 -0
- package/dist/dashboard/assets/index-D1NSYhKy.js +12 -0
- package/dist/dashboard/index.html +2 -2
- package/package.json +1 -1
- package/dist/dashboard/assets/index-Bg3QRJRt.css +0 -1
- package/dist/dashboard/assets/index-CEKyCY1L.js +0 -12
package/dist/cli.js
CHANGED
|
@@ -1107,8 +1107,8 @@ function removeManagedBlock(content) {
|
|
|
1107
1107
|
// apps/daemon/dist/cli.js
|
|
1108
1108
|
import { spawn as spawn2 } from "node:child_process";
|
|
1109
1109
|
import { existsSync } from "node:fs";
|
|
1110
|
-
import { fileURLToPath } from "node:url";
|
|
1111
|
-
import { dirname as
|
|
1110
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1111
|
+
import { dirname as dirname4, resolve } from "node:path";
|
|
1112
1112
|
|
|
1113
1113
|
// apps/daemon/dist/dashboardServer.js
|
|
1114
1114
|
import { createReadStream } from "node:fs";
|
|
@@ -1177,6 +1177,11 @@ async function startDashboardServer(options) {
|
|
|
1177
1177
|
};
|
|
1178
1178
|
}
|
|
1179
1179
|
|
|
1180
|
+
// apps/daemon/dist/index.js
|
|
1181
|
+
import { readFileSync } from "node:fs";
|
|
1182
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
1183
|
+
import { fileURLToPath } from "node:url";
|
|
1184
|
+
|
|
1180
1185
|
// packages/storage/src/ndjson.ts
|
|
1181
1186
|
import { appendFile, mkdir, readFile as readFile2 } from "node:fs/promises";
|
|
1182
1187
|
import { dirname } from "node:path";
|
|
@@ -1204,9 +1209,227 @@ async function readTraceEvents(filePath) {
|
|
|
1204
1209
|
|
|
1205
1210
|
// apps/daemon/dist/server.js
|
|
1206
1211
|
import { createServer as createServer2 } from "node:http";
|
|
1207
|
-
import { join as
|
|
1212
|
+
import { join as join3 } from "node:path";
|
|
1208
1213
|
import { WebSocket, WebSocketServer } from "ws";
|
|
1209
1214
|
|
|
1215
|
+
// apps/daemon/dist/optimize.js
|
|
1216
|
+
import { mkdir as mkdir2, readFile as readFile3, rm, writeFile } from "node:fs/promises";
|
|
1217
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
1218
|
+
var flaggedIds = (report) => report.metrics.filter((m) => m.status !== "good").map((m) => m.id);
|
|
1219
|
+
var joinIds = (ids) => ids.join(", ");
|
|
1220
|
+
var REVERT_MARGIN = 3;
|
|
1221
|
+
async function runOptimize(options) {
|
|
1222
|
+
const result = await computeOptimize(options);
|
|
1223
|
+
const content = await readMaybe(result.agentsMdPath);
|
|
1224
|
+
return { ...result, applied: content !== null && hasManagedBlock(content) };
|
|
1225
|
+
}
|
|
1226
|
+
async function computeOptimize(options) {
|
|
1227
|
+
const eventsFile = options.eventsFile ?? join2(options.projectDir, ".agent-blackbox", "events.ndjson");
|
|
1228
|
+
const agentsMdPath = join2(options.projectDir, "AGENTS.md");
|
|
1229
|
+
const statePath = join2(options.projectDir, ".agent-blackbox", "optimization.json");
|
|
1230
|
+
const events = await loadTraceEvents(eventsFile);
|
|
1231
|
+
const { runId, events: runEvents } = latestRun(events);
|
|
1232
|
+
const latestTs = runEvents.reduce((max, e) => e.ts > max ? e.ts : max, "");
|
|
1233
|
+
const report = runEvents.length > 0 ? computeEfficiencyReport(runEvents) : null;
|
|
1234
|
+
const score = report ? report.overallScore : null;
|
|
1235
|
+
if (options.mode === "revert") {
|
|
1236
|
+
return revert(agentsMdPath, statePath, score);
|
|
1237
|
+
}
|
|
1238
|
+
const block = report ? buildEfficiencyMemory(report, { verifiedCommands: verifiedCommands(runEvents) }) : null;
|
|
1239
|
+
if (options.mode === "preview") {
|
|
1240
|
+
return {
|
|
1241
|
+
mode: "preview",
|
|
1242
|
+
action: block ? "Preview only \u2014 re-run with --apply to write this to AGENTS.md." : "This run is clean \u2014 nothing worth pinning.",
|
|
1243
|
+
score,
|
|
1244
|
+
baselineScore: null,
|
|
1245
|
+
reclaimableTokens: report?.reclaimableTokens,
|
|
1246
|
+
block,
|
|
1247
|
+
agentsMdPath,
|
|
1248
|
+
changed: false
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
if (options.mode === "apply") {
|
|
1252
|
+
if (!block || !report || score === null || runId === null) {
|
|
1253
|
+
return { mode: "apply", action: "This run is clean \u2014 nothing to apply.", score, baselineScore: null, block: null, agentsMdPath, changed: false };
|
|
1254
|
+
}
|
|
1255
|
+
const prior = await readMaybe(agentsMdPath);
|
|
1256
|
+
const next = upsertManagedBlock(prior ?? "", block);
|
|
1257
|
+
await writeFile(agentsMdPath, next, "utf8");
|
|
1258
|
+
await writeState(statePath, {
|
|
1259
|
+
runId: runId ?? "",
|
|
1260
|
+
baselineScore: score,
|
|
1261
|
+
baselineLatestTs: latestTs,
|
|
1262
|
+
baselineFlagged: flaggedIds(report),
|
|
1263
|
+
fileExisted: prior !== null,
|
|
1264
|
+
appliedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1265
|
+
});
|
|
1266
|
+
return {
|
|
1267
|
+
mode: "apply",
|
|
1268
|
+
action: `Wrote efficiency memory to AGENTS.md \u2014 targets ~${report.reclaimableTokens} reclaimable tokens on similar future runs (no re-run needed). Optional: re-run the same task + \`optimize --check\` to benchmark the gain.`,
|
|
1269
|
+
score,
|
|
1270
|
+
baselineScore: score,
|
|
1271
|
+
reclaimableTokens: report.reclaimableTokens,
|
|
1272
|
+
block,
|
|
1273
|
+
agentsMdPath,
|
|
1274
|
+
changed: prior !== next
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
const state = await readState(statePath);
|
|
1278
|
+
if (!state) {
|
|
1279
|
+
return { mode: "check", action: "Nothing applied yet \u2014 run `optimize --apply` first.", score, baselineScore: null, block: null, agentsMdPath, changed: false };
|
|
1280
|
+
}
|
|
1281
|
+
if (runId === null) {
|
|
1282
|
+
return { mode: "check", action: "No runs recorded yet.", score, baselineScore: state.baselineScore, block: null, agentsMdPath, changed: false };
|
|
1283
|
+
}
|
|
1284
|
+
if (latestTs <= state.baselineLatestTs) {
|
|
1285
|
+
return {
|
|
1286
|
+
mode: "check",
|
|
1287
|
+
action: "No new run since apply. Run your agent with the memory in place, then re-check.",
|
|
1288
|
+
score,
|
|
1289
|
+
baselineScore: state.baselineScore,
|
|
1290
|
+
block: null,
|
|
1291
|
+
agentsMdPath,
|
|
1292
|
+
changed: false
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
const delta = (score ?? 0) - state.baselineScore;
|
|
1296
|
+
const nowFlagged = report ? flaggedIds(report) : [];
|
|
1297
|
+
const baseFlagged = state.baselineFlagged ?? [];
|
|
1298
|
+
const cleared = baseFlagged.filter((id) => !nowFlagged.includes(id));
|
|
1299
|
+
const appeared = nowFlagged.filter((id) => !baseFlagged.includes(id));
|
|
1300
|
+
const metricDiff = [cleared.length ? `cleared ${joinIds(cleared)}` : "", appeared.length ? `new ${joinIds(appeared)}` : ""].filter(Boolean).join("; ");
|
|
1301
|
+
const diffSuffix = metricDiff ? ` [${metricDiff}]` : "";
|
|
1302
|
+
if (delta < -REVERT_MARGIN) {
|
|
1303
|
+
const changed = await restore(agentsMdPath, state.fileExisted);
|
|
1304
|
+
await rm(statePath, { force: true });
|
|
1305
|
+
return {
|
|
1306
|
+
mode: "check",
|
|
1307
|
+
action: `Score dropped ${state.baselineScore} \u2192 ${score ?? "?"} (\u0394${delta})${diffSuffix} on the new run \u2014 rolled the memory back.`,
|
|
1308
|
+
score,
|
|
1309
|
+
baselineScore: state.baselineScore,
|
|
1310
|
+
block: null,
|
|
1311
|
+
agentsMdPath,
|
|
1312
|
+
changed
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1315
|
+
return {
|
|
1316
|
+
mode: "check",
|
|
1317
|
+
action: `Score ${state.baselineScore} \u2192 ${score ?? "?"} (\u0394${delta >= 0 ? "+" : ""}${delta})${diffSuffix} \u2014 kept the memory.`,
|
|
1318
|
+
score,
|
|
1319
|
+
baselineScore: state.baselineScore,
|
|
1320
|
+
block: null,
|
|
1321
|
+
agentsMdPath,
|
|
1322
|
+
changed: false
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
async function revert(agentsMdPath, statePath, score) {
|
|
1326
|
+
const state = await readState(statePath);
|
|
1327
|
+
const changed = await restore(agentsMdPath, state ? state.fileExisted : true);
|
|
1328
|
+
if (state)
|
|
1329
|
+
await rm(statePath, { force: true });
|
|
1330
|
+
return {
|
|
1331
|
+
mode: "revert",
|
|
1332
|
+
action: changed ? "Removed the managed efficiency block from AGENTS.md." : "Nothing to revert.",
|
|
1333
|
+
score,
|
|
1334
|
+
baselineScore: state ? state.baselineScore : null,
|
|
1335
|
+
block: null,
|
|
1336
|
+
agentsMdPath,
|
|
1337
|
+
changed
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
async function restore(agentsMdPath, fileExisted) {
|
|
1341
|
+
const current = await readMaybe(agentsMdPath);
|
|
1342
|
+
if (current === null)
|
|
1343
|
+
return false;
|
|
1344
|
+
const next = removeManagedBlock(current);
|
|
1345
|
+
if (next === current)
|
|
1346
|
+
return false;
|
|
1347
|
+
if (next.trim() === "" && !fileExisted) {
|
|
1348
|
+
await rm(agentsMdPath, { force: true });
|
|
1349
|
+
return true;
|
|
1350
|
+
}
|
|
1351
|
+
await writeFile(agentsMdPath, next, "utf8");
|
|
1352
|
+
return true;
|
|
1353
|
+
}
|
|
1354
|
+
function latestRun(events) {
|
|
1355
|
+
let latest;
|
|
1356
|
+
for (const e of events)
|
|
1357
|
+
if (!latest || e.ts > latest.ts)
|
|
1358
|
+
latest = e;
|
|
1359
|
+
if (!latest)
|
|
1360
|
+
return { runId: null, events: [] };
|
|
1361
|
+
const runId = latest.runId;
|
|
1362
|
+
return { runId, events: events.filter((e) => e.runId === runId) };
|
|
1363
|
+
}
|
|
1364
|
+
var NAV_VERBS = /* @__PURE__ */ new Set([
|
|
1365
|
+
"ls",
|
|
1366
|
+
"pwd",
|
|
1367
|
+
"cat",
|
|
1368
|
+
"find",
|
|
1369
|
+
"grep",
|
|
1370
|
+
"rg",
|
|
1371
|
+
"fd",
|
|
1372
|
+
"head",
|
|
1373
|
+
"tail",
|
|
1374
|
+
"echo",
|
|
1375
|
+
"which",
|
|
1376
|
+
"env",
|
|
1377
|
+
"cd",
|
|
1378
|
+
"tree",
|
|
1379
|
+
"stat",
|
|
1380
|
+
"wc",
|
|
1381
|
+
"sort",
|
|
1382
|
+
"uniq",
|
|
1383
|
+
"clear",
|
|
1384
|
+
"sleep",
|
|
1385
|
+
"true",
|
|
1386
|
+
"false"
|
|
1387
|
+
]);
|
|
1388
|
+
function verifiedCommands(events) {
|
|
1389
|
+
const out = [];
|
|
1390
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1391
|
+
for (const e of events) {
|
|
1392
|
+
if (e.kind !== "bash")
|
|
1393
|
+
continue;
|
|
1394
|
+
const payload = e.payload;
|
|
1395
|
+
if (!payload || payload.exitCode !== 0)
|
|
1396
|
+
continue;
|
|
1397
|
+
const command = typeof payload.command === "string" ? payload.command.trim() : "";
|
|
1398
|
+
if (!command || seen.has(command))
|
|
1399
|
+
continue;
|
|
1400
|
+
const verb = command.split(/\s+/)[0] ?? "";
|
|
1401
|
+
if (NAV_VERBS.has(verb))
|
|
1402
|
+
continue;
|
|
1403
|
+
seen.add(command);
|
|
1404
|
+
out.push(command);
|
|
1405
|
+
}
|
|
1406
|
+
return out;
|
|
1407
|
+
}
|
|
1408
|
+
async function readMaybe(path) {
|
|
1409
|
+
try {
|
|
1410
|
+
return await readFile3(path, "utf8");
|
|
1411
|
+
} catch (error) {
|
|
1412
|
+
if (error.code === "ENOENT")
|
|
1413
|
+
return null;
|
|
1414
|
+
throw error;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
async function readState(path) {
|
|
1418
|
+
const raw = await readMaybe(path);
|
|
1419
|
+
if (!raw)
|
|
1420
|
+
return null;
|
|
1421
|
+
try {
|
|
1422
|
+
return JSON.parse(raw);
|
|
1423
|
+
} catch {
|
|
1424
|
+
return null;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
async function writeState(path, state) {
|
|
1428
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
1429
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}
|
|
1430
|
+
`, "utf8");
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1210
1433
|
// apps/daemon/dist/suggestionProvider.js
|
|
1211
1434
|
import { spawn } from "node:child_process";
|
|
1212
1435
|
var TIMEOUT_MS = 45e3;
|
|
@@ -1458,11 +1681,11 @@ function extractJsonObject(text) {
|
|
|
1458
1681
|
|
|
1459
1682
|
// apps/daemon/dist/server.js
|
|
1460
1683
|
async function startTraceDaemon(options) {
|
|
1461
|
-
const eventsFile = options.eventsFile ??
|
|
1684
|
+
const eventsFile = options.eventsFile ?? join3(options.projectDir, ".agent-blackbox", "events.ndjson");
|
|
1462
1685
|
const suggestConfig = options.suggest ?? { mode: "auto" };
|
|
1463
1686
|
const clients = /* @__PURE__ */ new Set();
|
|
1464
1687
|
const server = createServer2((request, response) => {
|
|
1465
|
-
void handleRequest(request, response, eventsFile, clients, suggestConfig);
|
|
1688
|
+
void handleRequest(request, response, eventsFile, clients, suggestConfig, options.projectDir);
|
|
1466
1689
|
});
|
|
1467
1690
|
const streamServer = new WebSocketServer({ noServer: true });
|
|
1468
1691
|
server.on("upgrade", (request, socket, head) => {
|
|
@@ -1542,7 +1765,7 @@ async function buildTraceSnapshot(eventsFile, replay = {}) {
|
|
|
1542
1765
|
}
|
|
1543
1766
|
};
|
|
1544
1767
|
}
|
|
1545
|
-
async function handleRequest(request, response, eventsFile, clients, suggestConfig) {
|
|
1768
|
+
async function handleRequest(request, response, eventsFile, clients, suggestConfig, projectDir) {
|
|
1546
1769
|
try {
|
|
1547
1770
|
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
1548
1771
|
const replay = parseReplayQuery(url);
|
|
@@ -1588,6 +1811,18 @@ async function handleRequest(request, response, eventsFile, clients, suggestConf
|
|
|
1588
1811
|
sendJson(response, 200, { ok: true, data: result });
|
|
1589
1812
|
return;
|
|
1590
1813
|
}
|
|
1814
|
+
if (request.method === "GET" && url.pathname === "/optimize") {
|
|
1815
|
+
sendJson(response, 200, { ok: true, data: await runOptimize({ projectDir, eventsFile, mode: "preview" }) });
|
|
1816
|
+
return;
|
|
1817
|
+
}
|
|
1818
|
+
if (request.method === "POST" && url.pathname === "/optimize/apply") {
|
|
1819
|
+
sendJson(response, 200, { ok: true, data: await runOptimize({ projectDir, eventsFile, mode: "apply" }) });
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
if (request.method === "POST" && url.pathname === "/optimize/revert") {
|
|
1823
|
+
sendJson(response, 200, { ok: true, data: await runOptimize({ projectDir, eventsFile, mode: "revert" }) });
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1591
1826
|
if (request.method === "POST" && url.pathname === "/events") {
|
|
1592
1827
|
const body = await readJsonBody(request);
|
|
1593
1828
|
const validation = validateTraceEvent(body);
|
|
@@ -1682,29 +1917,29 @@ function isNodeError(error) {
|
|
|
1682
1917
|
}
|
|
1683
1918
|
|
|
1684
1919
|
// apps/daemon/dist/initOpenCode.js
|
|
1685
|
-
import { mkdir as
|
|
1686
|
-
import { join as
|
|
1920
|
+
import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
|
|
1921
|
+
import { join as join4 } from "node:path";
|
|
1687
1922
|
var defaultAdapterPackage = "@agent-blackbox/opencode-adapter";
|
|
1688
1923
|
var defaultDaemonUrl = "http://127.0.0.1:47831";
|
|
1689
1924
|
async function initOpenCodeProject(options) {
|
|
1690
1925
|
const adapterPackage = options.adapterPackage ?? defaultAdapterPackage;
|
|
1691
1926
|
const adapterImport = inferAdapterImport(adapterPackage);
|
|
1692
1927
|
const daemonUrl = options.daemonUrl ?? defaultDaemonUrl;
|
|
1693
|
-
const opencodeDir =
|
|
1694
|
-
const pluginsDir =
|
|
1695
|
-
const pluginPath =
|
|
1696
|
-
const packageJsonPath =
|
|
1697
|
-
await
|
|
1928
|
+
const opencodeDir = join4(options.projectDir, ".opencode");
|
|
1929
|
+
const pluginsDir = join4(opencodeDir, "plugins");
|
|
1930
|
+
const pluginPath = join4(pluginsDir, "agent-blackbox.ts");
|
|
1931
|
+
const packageJsonPath = join4(opencodeDir, "package.json");
|
|
1932
|
+
await mkdir3(pluginsDir, { recursive: true });
|
|
1698
1933
|
if (!options.force && await pathExists(pluginPath)) {
|
|
1699
1934
|
throw new Error(`${pluginPath} already exists. Re-run with --force to overwrite it.`);
|
|
1700
1935
|
}
|
|
1701
1936
|
if (options.pluginBundlePath && await pathExists(options.pluginBundlePath)) {
|
|
1702
|
-
const bundle = await
|
|
1937
|
+
const bundle = await readFile4(options.pluginBundlePath, "utf8");
|
|
1703
1938
|
const inlined = bundle.replaceAll("__ABB_DAEMON_URL__", daemonUrl);
|
|
1704
|
-
await
|
|
1939
|
+
await writeFile2(pluginPath, inlined, "utf8");
|
|
1705
1940
|
return { pluginPath, packageJsonPath, adapterPackage, adapterImport };
|
|
1706
1941
|
}
|
|
1707
|
-
await
|
|
1942
|
+
await writeFile2(pluginPath, renderOpenCodePlugin({ adapterImport, daemonUrl, optimize: options.optimize ?? false }), "utf8");
|
|
1708
1943
|
await writePackageJson(packageJsonPath, adapterPackage, adapterImport);
|
|
1709
1944
|
return {
|
|
1710
1945
|
pluginPath,
|
|
@@ -1727,7 +1962,7 @@ async function writePackageJson(packageJsonPath, adapterPackage, adapterImport)
|
|
|
1727
1962
|
...existing.dependencies ?? {},
|
|
1728
1963
|
[adapterImport]: adapterPackage
|
|
1729
1964
|
};
|
|
1730
|
-
await
|
|
1965
|
+
await writeFile2(packageJsonPath, `${JSON.stringify({ ...existing, dependencies }, null, 2)}
|
|
1731
1966
|
`, "utf8");
|
|
1732
1967
|
}
|
|
1733
1968
|
function inferAdapterImport(adapterPackage) {
|
|
@@ -1738,7 +1973,7 @@ function inferAdapterImport(adapterPackage) {
|
|
|
1738
1973
|
}
|
|
1739
1974
|
async function readPackageJson(packageJsonPath) {
|
|
1740
1975
|
try {
|
|
1741
|
-
return JSON.parse(await
|
|
1976
|
+
return JSON.parse(await readFile4(packageJsonPath, "utf8"));
|
|
1742
1977
|
} catch (error) {
|
|
1743
1978
|
if (isNodeError2(error) && error.code === "ENOENT") {
|
|
1744
1979
|
return {};
|
|
@@ -1748,7 +1983,7 @@ async function readPackageJson(packageJsonPath) {
|
|
|
1748
1983
|
}
|
|
1749
1984
|
async function pathExists(path) {
|
|
1750
1985
|
try {
|
|
1751
|
-
await
|
|
1986
|
+
await readFile4(path, "utf8");
|
|
1752
1987
|
return true;
|
|
1753
1988
|
} catch (error) {
|
|
1754
1989
|
if (isNodeError2(error) && error.code === "ENOENT") {
|
|
@@ -1762,227 +1997,30 @@ function isNodeError2(error) {
|
|
|
1762
1997
|
}
|
|
1763
1998
|
|
|
1764
1999
|
// apps/daemon/dist/index.js
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
var flaggedIds = (report) => report.metrics.filter((m) => m.status !== "good").map((m) => m.id);
|
|
1774
|
-
var joinIds = (ids) => ids.join(", ");
|
|
1775
|
-
var REVERT_MARGIN = 3;
|
|
1776
|
-
async function runOptimize(options) {
|
|
1777
|
-
const eventsFile = join4(options.projectDir, ".agent-blackbox", "events.ndjson");
|
|
1778
|
-
const agentsMdPath = join4(options.projectDir, "AGENTS.md");
|
|
1779
|
-
const statePath = join4(options.projectDir, ".agent-blackbox", "optimization.json");
|
|
1780
|
-
const events = await loadTraceEvents(eventsFile);
|
|
1781
|
-
const { runId, events: runEvents } = latestRun(events);
|
|
1782
|
-
const latestTs = runEvents.reduce((max, e) => e.ts > max ? e.ts : max, "");
|
|
1783
|
-
const report = runEvents.length > 0 ? computeEfficiencyReport(runEvents) : null;
|
|
1784
|
-
const score = report ? report.overallScore : null;
|
|
1785
|
-
if (options.mode === "revert") {
|
|
1786
|
-
return revert(agentsMdPath, statePath, score);
|
|
1787
|
-
}
|
|
1788
|
-
const block = report ? buildEfficiencyMemory(report, { verifiedCommands: verifiedCommands(runEvents) }) : null;
|
|
1789
|
-
if (options.mode === "preview") {
|
|
1790
|
-
return {
|
|
1791
|
-
mode: "preview",
|
|
1792
|
-
action: block ? "Preview only \u2014 re-run with --apply to write this to AGENTS.md." : "This run is clean \u2014 nothing worth pinning.",
|
|
1793
|
-
score,
|
|
1794
|
-
baselineScore: null,
|
|
1795
|
-
reclaimableTokens: report?.reclaimableTokens,
|
|
1796
|
-
block,
|
|
1797
|
-
agentsMdPath,
|
|
1798
|
-
changed: false
|
|
1799
|
-
};
|
|
1800
|
-
}
|
|
1801
|
-
if (options.mode === "apply") {
|
|
1802
|
-
if (!block || !report || score === null || runId === null) {
|
|
1803
|
-
return { mode: "apply", action: "This run is clean \u2014 nothing to apply.", score, baselineScore: null, block: null, agentsMdPath, changed: false };
|
|
2000
|
+
function resolvePackageVersion() {
|
|
2001
|
+
let dir = dirname3(fileURLToPath(import.meta.url));
|
|
2002
|
+
for (let i = 0; i < 6; i += 1) {
|
|
2003
|
+
try {
|
|
2004
|
+
const pkg = JSON.parse(readFileSync(join5(dir, "package.json"), "utf8"));
|
|
2005
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0)
|
|
2006
|
+
return pkg.version;
|
|
2007
|
+
} catch {
|
|
1804
2008
|
}
|
|
1805
|
-
const
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
runId: runId ?? "",
|
|
1810
|
-
baselineScore: score,
|
|
1811
|
-
baselineLatestTs: latestTs,
|
|
1812
|
-
baselineFlagged: flaggedIds(report),
|
|
1813
|
-
fileExisted: prior !== null,
|
|
1814
|
-
appliedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1815
|
-
});
|
|
1816
|
-
return {
|
|
1817
|
-
mode: "apply",
|
|
1818
|
-
action: `Wrote efficiency memory to AGENTS.md \u2014 targets ~${report.reclaimableTokens} reclaimable tokens on similar future runs (no re-run needed). Optional: re-run the same task + \`optimize --check\` to benchmark the gain.`,
|
|
1819
|
-
score,
|
|
1820
|
-
baselineScore: score,
|
|
1821
|
-
reclaimableTokens: report.reclaimableTokens,
|
|
1822
|
-
block,
|
|
1823
|
-
agentsMdPath,
|
|
1824
|
-
changed: prior !== next
|
|
1825
|
-
};
|
|
1826
|
-
}
|
|
1827
|
-
const state = await readState(statePath);
|
|
1828
|
-
if (!state) {
|
|
1829
|
-
return { mode: "check", action: "Nothing applied yet \u2014 run `optimize --apply` first.", score, baselineScore: null, block: null, agentsMdPath, changed: false };
|
|
1830
|
-
}
|
|
1831
|
-
if (runId === null) {
|
|
1832
|
-
return { mode: "check", action: "No runs recorded yet.", score, baselineScore: state.baselineScore, block: null, agentsMdPath, changed: false };
|
|
1833
|
-
}
|
|
1834
|
-
if (latestTs <= state.baselineLatestTs) {
|
|
1835
|
-
return {
|
|
1836
|
-
mode: "check",
|
|
1837
|
-
action: "No new run since apply. Run your agent with the memory in place, then re-check.",
|
|
1838
|
-
score,
|
|
1839
|
-
baselineScore: state.baselineScore,
|
|
1840
|
-
block: null,
|
|
1841
|
-
agentsMdPath,
|
|
1842
|
-
changed: false
|
|
1843
|
-
};
|
|
1844
|
-
}
|
|
1845
|
-
const delta = (score ?? 0) - state.baselineScore;
|
|
1846
|
-
const nowFlagged = report ? flaggedIds(report) : [];
|
|
1847
|
-
const baseFlagged = state.baselineFlagged ?? [];
|
|
1848
|
-
const cleared = baseFlagged.filter((id) => !nowFlagged.includes(id));
|
|
1849
|
-
const appeared = nowFlagged.filter((id) => !baseFlagged.includes(id));
|
|
1850
|
-
const metricDiff = [cleared.length ? `cleared ${joinIds(cleared)}` : "", appeared.length ? `new ${joinIds(appeared)}` : ""].filter(Boolean).join("; ");
|
|
1851
|
-
const diffSuffix = metricDiff ? ` [${metricDiff}]` : "";
|
|
1852
|
-
if (delta < -REVERT_MARGIN) {
|
|
1853
|
-
const changed = await restore(agentsMdPath, state.fileExisted);
|
|
1854
|
-
await rm(statePath, { force: true });
|
|
1855
|
-
return {
|
|
1856
|
-
mode: "check",
|
|
1857
|
-
action: `Score dropped ${state.baselineScore} \u2192 ${score ?? "?"} (\u0394${delta})${diffSuffix} on the new run \u2014 rolled the memory back.`,
|
|
1858
|
-
score,
|
|
1859
|
-
baselineScore: state.baselineScore,
|
|
1860
|
-
block: null,
|
|
1861
|
-
agentsMdPath,
|
|
1862
|
-
changed
|
|
1863
|
-
};
|
|
1864
|
-
}
|
|
1865
|
-
return {
|
|
1866
|
-
mode: "check",
|
|
1867
|
-
action: `Score ${state.baselineScore} \u2192 ${score ?? "?"} (\u0394${delta >= 0 ? "+" : ""}${delta})${diffSuffix} \u2014 kept the memory.`,
|
|
1868
|
-
score,
|
|
1869
|
-
baselineScore: state.baselineScore,
|
|
1870
|
-
block: null,
|
|
1871
|
-
agentsMdPath,
|
|
1872
|
-
changed: false
|
|
1873
|
-
};
|
|
1874
|
-
}
|
|
1875
|
-
async function revert(agentsMdPath, statePath, score) {
|
|
1876
|
-
const state = await readState(statePath);
|
|
1877
|
-
const changed = await restore(agentsMdPath, state ? state.fileExisted : true);
|
|
1878
|
-
if (state)
|
|
1879
|
-
await rm(statePath, { force: true });
|
|
1880
|
-
return {
|
|
1881
|
-
mode: "revert",
|
|
1882
|
-
action: changed ? "Removed the managed efficiency block from AGENTS.md." : "Nothing to revert.",
|
|
1883
|
-
score,
|
|
1884
|
-
baselineScore: state ? state.baselineScore : null,
|
|
1885
|
-
block: null,
|
|
1886
|
-
agentsMdPath,
|
|
1887
|
-
changed
|
|
1888
|
-
};
|
|
1889
|
-
}
|
|
1890
|
-
async function restore(agentsMdPath, fileExisted) {
|
|
1891
|
-
const current = await readMaybe(agentsMdPath);
|
|
1892
|
-
if (current === null)
|
|
1893
|
-
return false;
|
|
1894
|
-
const next = removeManagedBlock(current);
|
|
1895
|
-
if (next === current)
|
|
1896
|
-
return false;
|
|
1897
|
-
if (next.trim() === "" && !fileExisted) {
|
|
1898
|
-
await rm(agentsMdPath, { force: true });
|
|
1899
|
-
return true;
|
|
1900
|
-
}
|
|
1901
|
-
await writeFile2(agentsMdPath, next, "utf8");
|
|
1902
|
-
return true;
|
|
1903
|
-
}
|
|
1904
|
-
function latestRun(events) {
|
|
1905
|
-
let latest;
|
|
1906
|
-
for (const e of events)
|
|
1907
|
-
if (!latest || e.ts > latest.ts)
|
|
1908
|
-
latest = e;
|
|
1909
|
-
if (!latest)
|
|
1910
|
-
return { runId: null, events: [] };
|
|
1911
|
-
const runId = latest.runId;
|
|
1912
|
-
return { runId, events: events.filter((e) => e.runId === runId) };
|
|
1913
|
-
}
|
|
1914
|
-
var NAV_VERBS = /* @__PURE__ */ new Set([
|
|
1915
|
-
"ls",
|
|
1916
|
-
"pwd",
|
|
1917
|
-
"cat",
|
|
1918
|
-
"find",
|
|
1919
|
-
"grep",
|
|
1920
|
-
"rg",
|
|
1921
|
-
"fd",
|
|
1922
|
-
"head",
|
|
1923
|
-
"tail",
|
|
1924
|
-
"echo",
|
|
1925
|
-
"which",
|
|
1926
|
-
"env",
|
|
1927
|
-
"cd",
|
|
1928
|
-
"tree",
|
|
1929
|
-
"stat",
|
|
1930
|
-
"wc",
|
|
1931
|
-
"sort",
|
|
1932
|
-
"uniq",
|
|
1933
|
-
"clear",
|
|
1934
|
-
"sleep",
|
|
1935
|
-
"true",
|
|
1936
|
-
"false"
|
|
1937
|
-
]);
|
|
1938
|
-
function verifiedCommands(events) {
|
|
1939
|
-
const out = [];
|
|
1940
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1941
|
-
for (const e of events) {
|
|
1942
|
-
if (e.kind !== "bash")
|
|
1943
|
-
continue;
|
|
1944
|
-
const payload = e.payload;
|
|
1945
|
-
if (!payload || payload.exitCode !== 0)
|
|
1946
|
-
continue;
|
|
1947
|
-
const command = typeof payload.command === "string" ? payload.command.trim() : "";
|
|
1948
|
-
if (!command || seen.has(command))
|
|
1949
|
-
continue;
|
|
1950
|
-
const verb = command.split(/\s+/)[0] ?? "";
|
|
1951
|
-
if (NAV_VERBS.has(verb))
|
|
1952
|
-
continue;
|
|
1953
|
-
seen.add(command);
|
|
1954
|
-
out.push(command);
|
|
1955
|
-
}
|
|
1956
|
-
return out;
|
|
1957
|
-
}
|
|
1958
|
-
async function readMaybe(path) {
|
|
1959
|
-
try {
|
|
1960
|
-
return await readFile4(path, "utf8");
|
|
1961
|
-
} catch (error) {
|
|
1962
|
-
if (error.code === "ENOENT")
|
|
1963
|
-
return null;
|
|
1964
|
-
throw error;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
async function readState(path) {
|
|
1968
|
-
const raw = await readMaybe(path);
|
|
1969
|
-
if (!raw)
|
|
1970
|
-
return null;
|
|
1971
|
-
try {
|
|
1972
|
-
return JSON.parse(raw);
|
|
1973
|
-
} catch {
|
|
1974
|
-
return null;
|
|
2009
|
+
const parent = dirname3(dir);
|
|
2010
|
+
if (parent === dir)
|
|
2011
|
+
break;
|
|
2012
|
+
dir = parent;
|
|
1975
2013
|
}
|
|
2014
|
+
return "0.0.0";
|
|
1976
2015
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
`, "utf8");
|
|
2016
|
+
var AGENT_BLACKBOX_DAEMON_VERSION = resolvePackageVersion();
|
|
2017
|
+
function describeDaemon() {
|
|
2018
|
+
return "Agent-Blackbox daemon: local ingest, replay, and dashboard bridge.";
|
|
1981
2019
|
}
|
|
1982
2020
|
|
|
1983
2021
|
// apps/daemon/dist/cli.js
|
|
1984
2022
|
var args = process.argv.slice(2);
|
|
1985
|
-
var cliDir =
|
|
2023
|
+
var cliDir = dirname4(fileURLToPath2(import.meta.url));
|
|
1986
2024
|
var repoRoot = resolve(cliDir, "../../..");
|
|
1987
2025
|
var firstExisting = (paths) => paths.find((p) => existsSync(p));
|
|
1988
2026
|
var dashboardDistDir = firstExisting([resolve(cliDir, "dashboard"), resolve(repoRoot, "apps/dashboard/dist")]) ?? resolve(repoRoot, "apps/dashboard/dist");
|