@taewooopark/agent-blackbox 0.46.0 → 0.46.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.
@@ -433,6 +433,7 @@ function normalizeToolBefore(input, output, context) {
433
433
  const agentId = extractAgentId(input);
434
434
  if (agentId) {
435
435
  traceInput.agentId = agentId;
436
+ traceInput.agentRole = extractAgentRole(input);
436
437
  }
437
438
  return createTraceEvent(context.seq, traceInput);
438
439
  }
@@ -466,6 +467,7 @@ function normalizeToolAfter(input, output, context) {
466
467
  const agentId = extractAgentId(input);
467
468
  if (agentId) {
468
469
  traceInput.agentId = agentId;
470
+ traceInput.agentRole = extractAgentRole(input);
469
471
  }
470
472
  }
471
473
  return createTraceEvent(context.seq, traceInput);
@@ -850,9 +852,25 @@ function serializeTraceEvent(event) {
850
852
  return `${JSON.stringify(event)}
851
853
  `;
852
854
  }
855
+ var writeChains = /* @__PURE__ */ new Map();
853
856
  async function appendTraceEvent(filePath, event) {
854
- await mkdir(dirname(filePath), { recursive: true });
855
- await appendFile(filePath, serializeTraceEvent(event), "utf8");
857
+ const line = serializeTraceEvent(event);
858
+ const run = async () => {
859
+ await mkdir(dirname(filePath), { recursive: true });
860
+ await appendFile(filePath, line, "utf8");
861
+ };
862
+ const prev = writeChains.get(filePath) ?? Promise.resolve();
863
+ const next = prev.then(run, run);
864
+ const tail = next.then(
865
+ () => void 0,
866
+ () => void 0
867
+ );
868
+ writeChains.set(filePath, tail);
869
+ try {
870
+ await next;
871
+ } finally {
872
+ if (writeChains.get(filePath) === tail) writeChains.delete(filePath);
873
+ }
856
874
  }
857
875
 
858
876
  // packages/opencode-adapter/dist/sink.js
package/dist/cli.js CHANGED
@@ -1236,9 +1236,25 @@ function parseTraceEvents(input) {
1236
1236
  }
1237
1237
  return events;
1238
1238
  }
1239
+ var writeChains = /* @__PURE__ */ new Map();
1239
1240
  async function appendTraceEvent(filePath, event) {
1240
- await mkdir(dirname(filePath), { recursive: true });
1241
- await appendFile(filePath, serializeTraceEvent(event), "utf8");
1241
+ const line = serializeTraceEvent(event);
1242
+ const run = async () => {
1243
+ await mkdir(dirname(filePath), { recursive: true });
1244
+ await appendFile(filePath, line, "utf8");
1245
+ };
1246
+ const prev = writeChains.get(filePath) ?? Promise.resolve();
1247
+ const next = prev.then(run, run);
1248
+ const tail = next.then(
1249
+ () => void 0,
1250
+ () => void 0
1251
+ );
1252
+ writeChains.set(filePath, tail);
1253
+ try {
1254
+ await next;
1255
+ } finally {
1256
+ if (writeChains.get(filePath) === tail) writeChains.delete(filePath);
1257
+ }
1242
1258
  }
1243
1259
  async function readTraceEvents(filePath) {
1244
1260
  const input = await readFile2(filePath, "utf8");
@@ -1252,7 +1268,7 @@ import { WebSocket, WebSocketServer } from "ws";
1252
1268
 
1253
1269
  // apps/daemon/dist/optimize.js
1254
1270
  import { mkdir as mkdir2, readFile as readFile3, rm, writeFile } from "node:fs/promises";
1255
- import { dirname as dirname2, join as join2 } from "node:path";
1271
+ import { dirname as dirname2, isAbsolute, join as join2 } from "node:path";
1256
1272
  var flaggedIds = (report) => report.metrics.filter((m) => m.status !== "good").map((m) => m.id);
1257
1273
  var joinIds = (ids) => ids.join(", ");
1258
1274
  var REVERT_MARGIN = 3;
@@ -1265,7 +1281,8 @@ async function computeOptimize(options) {
1265
1281
  const eventsFile = options.eventsFile ?? join2(options.projectDir, ".agent-blackbox", "events.ndjson");
1266
1282
  const events = await loadTraceEvents(eventsFile);
1267
1283
  const { runId, events: runEvents } = latestRun(events);
1268
- const targetDir = runEvents.find((e) => typeof e.cwd === "string" && e.cwd.length > 0)?.cwd ?? options.projectDir;
1284
+ const runCwd = runEvents.find((e) => typeof e.cwd === "string" && e.cwd.length > 0)?.cwd;
1285
+ const targetDir = runCwd && isAbsolute(runCwd) ? runCwd : options.projectDir;
1269
1286
  const agentsMdPath = join2(targetDir, "AGENTS.md");
1270
1287
  const statePath = join2(targetDir, ".agent-blackbox", "optimization.json");
1271
1288
  const latestTs = runEvents.reduce((max, e) => e.ts > max ? e.ts : max, "");
@@ -1835,11 +1852,19 @@ async function buildTraceSnapshot(eventsFile, replay = {}) {
1835
1852
  }
1836
1853
  async function handleRequest(request, response, eventsFile, clients, suggestConfig, projectDir) {
1837
1854
  try {
1855
+ applyCors(request, response);
1838
1856
  const url = new URL(request.url ?? "/", "http://127.0.0.1");
1839
1857
  if (request.method === "OPTIONS") {
1840
1858
  sendEmpty(response, 204);
1841
1859
  return;
1842
1860
  }
1861
+ if (request.method === "POST") {
1862
+ const origin = request.headers.origin;
1863
+ if (typeof origin === "string" && !isLoopbackOrigin(origin)) {
1864
+ sendJson(response, 403, { ok: false, error: { message: "cross-site request blocked" } });
1865
+ return;
1866
+ }
1867
+ }
1843
1868
  const replay = parseReplayQuery(url);
1844
1869
  if (request.method === "GET" && url.pathname === "/health") {
1845
1870
  sendJson(response, 200, { ok: true, data: { status: "ok", eventsFile } });
@@ -1957,11 +1982,25 @@ async function readJsonBody(request) {
1957
1982
  throw new BadRequestError("Invalid JSON body");
1958
1983
  }
1959
1984
  }
1985
+ function applyCors(request, response) {
1986
+ const origin = request.headers.origin;
1987
+ if (typeof origin === "string" && isLoopbackOrigin(origin)) {
1988
+ response.setHeader("access-control-allow-origin", origin);
1989
+ response.setHeader("vary", "Origin");
1990
+ }
1991
+ }
1992
+ function isLoopbackOrigin(origin) {
1993
+ try {
1994
+ const { hostname } = new URL(origin);
1995
+ return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "[::1]" || hostname === "::1";
1996
+ } catch {
1997
+ return false;
1998
+ }
1999
+ }
1960
2000
  function sendJson(response, statusCode, payload) {
1961
2001
  response.writeHead(statusCode, {
1962
2002
  "access-control-allow-headers": "content-type",
1963
2003
  "access-control-allow-methods": "GET,POST,OPTIONS",
1964
- "access-control-allow-origin": "*",
1965
2004
  "content-type": "application/json; charset=utf-8"
1966
2005
  });
1967
2006
  response.end(JSON.stringify(payload));
@@ -1969,8 +2008,7 @@ function sendJson(response, statusCode, payload) {
1969
2008
  function sendEmpty(response, statusCode) {
1970
2009
  response.writeHead(statusCode, {
1971
2010
  "access-control-allow-headers": "content-type",
1972
- "access-control-allow-methods": "GET,POST,OPTIONS",
1973
- "access-control-allow-origin": "*"
2011
+ "access-control-allow-methods": "GET,POST,OPTIONS"
1974
2012
  });
1975
2013
  response.end();
1976
2014
  }
@@ -2320,7 +2358,10 @@ function openInBrowser(url) {
2320
2358
  const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
2321
2359
  const args2 = platform === "win32" ? ["/c", "start", "", url] : [url];
2322
2360
  try {
2323
- spawn2(command, args2, { stdio: "ignore", detached: true }).unref();
2361
+ const child = spawn2(command, args2, { stdio: "ignore", detached: true });
2362
+ child.on("error", () => {
2363
+ });
2364
+ child.unref();
2324
2365
  } catch {
2325
2366
  }
2326
2367
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taewooopark/agent-blackbox",
3
- "version": "0.46.0",
3
+ "version": "0.46.2",
4
4
  "description": "Local-first flight recorder + context-efficiency profiler for coding agents (OpenCode). Run with npx.",
5
5
  "type": "module",
6
6
  "license": "MIT",