@taewooopark/agent-blackbox 0.44.0 → 0.45.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.
Files changed (2) hide show
  1. package/dist/cli.js +97 -13
  2. package/package.json +20 -7
package/dist/cli.js CHANGED
@@ -1107,8 +1107,9 @@ 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 { homedir as homedir2 } from "node:os";
1110
1111
  import { fileURLToPath as fileURLToPath2 } from "node:url";
1111
- import { dirname as dirname4, resolve } from "node:path";
1112
+ import { dirname as dirname5, join as join6, resolve } from "node:path";
1112
1113
 
1113
1114
  // apps/daemon/dist/dashboardServer.js
1114
1115
  import { createReadStream } from "node:fs";
@@ -1179,7 +1180,7 @@ async function startDashboardServer(options) {
1179
1180
 
1180
1181
  // apps/daemon/dist/index.js
1181
1182
  import { readFileSync } from "node:fs";
1182
- import { dirname as dirname3, join as join5 } from "node:path";
1183
+ import { dirname as dirname4, join as join5 } from "node:path";
1183
1184
  import { fileURLToPath } from "node:url";
1184
1185
 
1185
1186
  // packages/storage/src/ndjson.ts
@@ -1917,10 +1918,39 @@ function isNodeError(error) {
1917
1918
  }
1918
1919
 
1919
1920
  // apps/daemon/dist/initOpenCode.js
1920
- import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
1921
- import { join as join4 } from "node:path";
1921
+ import { mkdir as mkdir3, readFile as readFile4, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
1922
+ import { homedir } from "node:os";
1923
+ import { dirname as dirname3, join as join4 } from "node:path";
1922
1924
  var defaultAdapterPackage = "@agent-blackbox/opencode-adapter";
1923
1925
  var defaultDaemonUrl = "http://127.0.0.1:47831";
1926
+ function globalOpenCodeDir() {
1927
+ const xdg = process.env.XDG_CONFIG_HOME;
1928
+ return xdg && xdg.length > 0 ? join4(xdg, "opencode") : join4(homedir(), ".config", "opencode");
1929
+ }
1930
+ function globalRecorderPath() {
1931
+ return join4(globalOpenCodeDir(), "plugins", "agent-blackbox.js");
1932
+ }
1933
+ async function installGlobalRecorder(options) {
1934
+ if (!await pathExists(options.pluginBundlePath)) {
1935
+ throw new Error("Self-contained recorder bundle not found. Use the published npx package, or build it from source with `npm run build:cli`.");
1936
+ }
1937
+ const pluginPath = globalRecorderPath();
1938
+ const bundle = (await readFile4(options.pluginBundlePath, "utf8")).replaceAll("__ABB_DAEMON_URL__", options.daemonUrl);
1939
+ await mkdir3(dirname3(pluginPath), { recursive: true });
1940
+ await writeFile2(pluginPath, bundle, "utf8");
1941
+ return { pluginPath };
1942
+ }
1943
+ async function uninstallGlobalRecorder() {
1944
+ const pluginPath = globalRecorderPath();
1945
+ try {
1946
+ await rm2(pluginPath);
1947
+ return { pluginPath, removed: true };
1948
+ } catch (error) {
1949
+ if (isNodeError2(error) && error.code === "ENOENT")
1950
+ return { pluginPath, removed: false };
1951
+ throw error;
1952
+ }
1953
+ }
1924
1954
  async function initOpenCodeProject(options) {
1925
1955
  const adapterPackage = options.adapterPackage ?? defaultAdapterPackage;
1926
1956
  const adapterImport = inferAdapterImport(adapterPackage);
@@ -1998,7 +2028,7 @@ function isNodeError2(error) {
1998
2028
 
1999
2029
  // apps/daemon/dist/index.js
2000
2030
  function resolvePackageVersion() {
2001
- let dir = dirname3(fileURLToPath(import.meta.url));
2031
+ let dir = dirname4(fileURLToPath(import.meta.url));
2002
2032
  for (let i = 0; i < 6; i += 1) {
2003
2033
  try {
2004
2034
  const pkg = JSON.parse(readFileSync(join5(dir, "package.json"), "utf8"));
@@ -2006,7 +2036,7 @@ function resolvePackageVersion() {
2006
2036
  return pkg.version;
2007
2037
  } catch {
2008
2038
  }
2009
- const parent = dirname3(dir);
2039
+ const parent = dirname4(dir);
2010
2040
  if (parent === dir)
2011
2041
  break;
2012
2042
  dir = parent;
@@ -2020,11 +2050,15 @@ function describeDaemon() {
2020
2050
 
2021
2051
  // apps/daemon/dist/cli.js
2022
2052
  var args = process.argv.slice(2);
2023
- var cliDir = dirname4(fileURLToPath2(import.meta.url));
2053
+ var cliDir = dirname5(fileURLToPath2(import.meta.url));
2024
2054
  var repoRoot = resolve(cliDir, "../../..");
2025
2055
  var firstExisting = (paths) => paths.find((p) => existsSync(p));
2026
2056
  var dashboardDistDir = firstExisting([resolve(cliDir, "dashboard"), resolve(repoRoot, "apps/dashboard/dist")]) ?? resolve(repoRoot, "apps/dashboard/dist");
2027
2057
  var pluginBundlePath = firstExisting([resolve(cliDir, "agent-blackbox.plugin.mjs")]);
2058
+ function globalDataDir() {
2059
+ const xdg = process.env.XDG_DATA_HOME;
2060
+ return xdg && xdg.length > 0 ? join6(xdg, "agent-blackbox") : join6(homedir2(), ".local", "share", "agent-blackbox");
2061
+ }
2028
2062
  void main(args);
2029
2063
  async function main(argv) {
2030
2064
  if (argv.includes("--version") || argv.includes("-v")) {
@@ -2041,12 +2075,41 @@ async function main(argv) {
2041
2075
  return;
2042
2076
  }
2043
2077
  if (command === "up") {
2044
- const projectDir = resolve(readFlag(argv, "--project") ?? process.cwd());
2078
+ const projectFlag = readFlag(argv, "--project");
2079
+ const global = projectFlag === void 0;
2045
2080
  const port = Number(readFlag(argv, "--port") ?? "47831");
2046
2081
  const uiPort = Number(readFlag(argv, "--ui-port") ?? "5173");
2047
2082
  const daemonUrl = `http://127.0.0.1:${port}`;
2048
- const adapterPackage = readFlag(argv, "--adapter-package") ?? `file:${resolve(repoRoot, "packages/opencode-adapter")}`;
2049
2083
  const suggest = readSuggestConfig(argv);
2084
+ let daemon;
2085
+ if (global) {
2086
+ if (!pluginBundlePath) {
2087
+ throw new Error("Global install needs the self-contained recorder bundle. Use the published npx package, or `npm run build:cli` then `node packages/cli/dist/cli.js up`.\n(Or scope to one project with: agent-blackbox up --project <dir>.)");
2088
+ }
2089
+ const { pluginPath } = await installGlobalRecorder({ daemonUrl, pluginBundlePath });
2090
+ const dataDir = globalDataDir();
2091
+ const eventsFile = join6(dataDir, "events.ndjson");
2092
+ daemon = await startTraceDaemon({ projectDir: dataDir, port, eventsFile, suggest });
2093
+ const ui2 = await startDashboardServer({ distDir: dashboardDistDir, port: uiPort, daemonUrl });
2094
+ const dashboardUrl2 = `http://127.0.0.1:${ui2.port}`;
2095
+ console.log(`\u2713 Global OpenCode recorder installed: ${pluginPath}`);
2096
+ console.log(`\u2713 Agent-Blackbox is up (recording all OpenCode sessions)`);
2097
+ console.log(` Dashboard: ${dashboardUrl2}`);
2098
+ console.log(` Daemon API: ${daemonUrl} (trace: ${daemon.eventsFile})`);
2099
+ console.log(` Suggestions: ${suggest.mode}${suggest.model ? ` (${suggest.model})` : ""}`);
2100
+ console.log("");
2101
+ if (!argv.includes("--no-open"))
2102
+ openInBrowser(dashboardUrl2);
2103
+ console.log("Now use OpenCode however you already do \u2014 the dashboard fills in live:");
2104
+ console.log(" opencode # in any folder (terminal), or");
2105
+ console.log(" the OpenCode desktop app # open any project");
2106
+ console.log("");
2107
+ console.log("Stop recording any time with: agent-blackbox uninstall");
2108
+ console.log("Press Ctrl+C to stop the daemon + dashboard.");
2109
+ return;
2110
+ }
2111
+ const projectDir = resolve(projectFlag);
2112
+ const adapterPackage = readFlag(argv, "--adapter-package") ?? `file:${resolve(repoRoot, "packages/opencode-adapter")}`;
2050
2113
  try {
2051
2114
  const result = await initOpenCodeProject({
2052
2115
  projectDir,
@@ -2064,7 +2127,7 @@ async function main(argv) {
2064
2127
  throw error;
2065
2128
  }
2066
2129
  }
2067
- const daemon = await startTraceDaemon({ projectDir, port, suggest });
2130
+ daemon = await startTraceDaemon({ projectDir, port, suggest });
2068
2131
  const ui = await startDashboardServer({ distDir: dashboardDistDir, port: uiPort, daemonUrl });
2069
2132
  const dashboardUrl = `http://127.0.0.1:${ui.port}`;
2070
2133
  console.log("");
@@ -2076,11 +2139,29 @@ async function main(argv) {
2076
2139
  if (!argv.includes("--no-open"))
2077
2140
  openInBrowser(dashboardUrl);
2078
2141
  console.log("Now run your agent in that project, e.g.:");
2079
- console.log(` AGENT_BLACKBOX_DAEMON_URL=${daemonUrl} opencode run --dir ${projectDir} "Read the code, run tests, summarize."`);
2142
+ console.log(` opencode # in ${projectDir} (the project-local recorder streams here)`);
2080
2143
  console.log("");
2081
2144
  console.log("Press Ctrl+C to stop.");
2082
2145
  return;
2083
2146
  }
2147
+ if (command === "install") {
2148
+ const port = Number(readFlag(argv, "--port") ?? "47831");
2149
+ const daemonUrl = `http://127.0.0.1:${port}`;
2150
+ if (!pluginBundlePath) {
2151
+ throw new Error("Global install needs the self-contained recorder bundle. Use the published npx package, or `npm run build:cli` first.");
2152
+ }
2153
+ const { pluginPath } = await installGlobalRecorder({ daemonUrl, pluginBundlePath });
2154
+ console.log(`\u2713 Global OpenCode recorder installed: ${pluginPath}`);
2155
+ console.log(` Every OpenCode session (any folder, terminal, or the app) now streams to ${daemonUrl}.`);
2156
+ console.log(` Start the dashboard with: agent-blackbox up`);
2157
+ console.log(` Remove with: agent-blackbox uninstall`);
2158
+ return;
2159
+ }
2160
+ if (command === "uninstall") {
2161
+ const { pluginPath, removed } = await uninstallGlobalRecorder();
2162
+ console.log(removed ? `\u2713 Removed global OpenCode recorder: ${pluginPath}` : `Nothing to remove \u2014 ${pluginPath} is not present.`);
2163
+ return;
2164
+ }
2084
2165
  if (command === "replay") {
2085
2166
  const eventsFile = argv[1];
2086
2167
  if (!eventsFile) {
@@ -2138,8 +2219,11 @@ function printHelp() {
2138
2219
  console.log(describeDaemon());
2139
2220
  console.log("");
2140
2221
  console.log("Usage:");
2141
- console.log(" agent-blackbox up [--project <dir>] [--port <port>] [--ui-port <port>] # plugin + daemon + dashboard, one command");
2142
- console.log(" [--suggest auto|free|off|ollama|opencode|openai-compat] [--suggest-model <id>] [--suggest-base-url <url>] [--optimize] [--no-open]");
2222
+ console.log(" agent-blackbox up # GLOBAL: record every OpenCode session (any folder / the app) + daemon + dashboard");
2223
+ console.log(" agent-blackbox up --project <dir> # scope the recorder to one project instead");
2224
+ console.log(" [--port <port>] [--ui-port <port>] [--suggest auto|free|off|ollama|opencode|openai-compat] [--suggest-model <id>] [--optimize] [--no-open]");
2225
+ console.log(" agent-blackbox install [--port <port>] # install the global recorder only (no daemon)");
2226
+ console.log(" agent-blackbox uninstall # remove the global recorder");
2143
2227
  console.log(" agent-blackbox daemon [--project <dir>] [--port <port>]");
2144
2228
  console.log(" agent-blackbox init-opencode [--project <dir>] [--daemon-url <url>] [--adapter-package <specifier>] [--force] [--optimize]");
2145
2229
  console.log(" agent-blackbox optimize [--project <dir>] [--apply | --check | --revert] # write/measure/rollback AGENTS.md efficiency memory");
package/package.json CHANGED
@@ -1,13 +1,26 @@
1
1
  {
2
2
  "name": "@taewooopark/agent-blackbox",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
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",
7
- "repository": { "type": "git", "url": "git+https://github.com/TaewoooPark/Agent-Blackbox.git" },
8
- "bin": { "agent-blackbox": "dist/cli.js" },
9
- "files": ["dist"],
10
- "engines": { "node": ">=20" },
11
- "dependencies": { "ws": "^8.21.0" },
12
- "scripts": { "bundle": "node build.mjs" }
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/TaewoooPark/Agent-Blackbox.git"
10
+ },
11
+ "bin": {
12
+ "agent-blackbox": "dist/cli.js"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "engines": {
18
+ "node": ">=20"
19
+ },
20
+ "dependencies": {
21
+ "ws": "^8.21.0"
22
+ },
23
+ "scripts": {
24
+ "bundle": "node build.mjs"
25
+ }
13
26
  }