@taewooopark/agent-blackbox 0.43.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.
- package/dist/cli.js +117 -12
- 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 {
|
|
1111
|
-
import {
|
|
1110
|
+
import { homedir as homedir2 } from "node:os";
|
|
1111
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
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";
|
|
@@ -1177,6 +1178,11 @@ async function startDashboardServer(options) {
|
|
|
1177
1178
|
};
|
|
1178
1179
|
}
|
|
1179
1180
|
|
|
1181
|
+
// apps/daemon/dist/index.js
|
|
1182
|
+
import { readFileSync } from "node:fs";
|
|
1183
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
1184
|
+
import { fileURLToPath } from "node:url";
|
|
1185
|
+
|
|
1180
1186
|
// packages/storage/src/ndjson.ts
|
|
1181
1187
|
import { appendFile, mkdir, readFile as readFile2 } from "node:fs/promises";
|
|
1182
1188
|
import { dirname } from "node:path";
|
|
@@ -1912,10 +1918,39 @@ function isNodeError(error) {
|
|
|
1912
1918
|
}
|
|
1913
1919
|
|
|
1914
1920
|
// apps/daemon/dist/initOpenCode.js
|
|
1915
|
-
import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
|
|
1916
|
-
import {
|
|
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";
|
|
1917
1924
|
var defaultAdapterPackage = "@agent-blackbox/opencode-adapter";
|
|
1918
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
|
+
}
|
|
1919
1954
|
async function initOpenCodeProject(options) {
|
|
1920
1955
|
const adapterPackage = options.adapterPackage ?? defaultAdapterPackage;
|
|
1921
1956
|
const adapterImport = inferAdapterImport(adapterPackage);
|
|
@@ -1992,18 +2027,38 @@ function isNodeError2(error) {
|
|
|
1992
2027
|
}
|
|
1993
2028
|
|
|
1994
2029
|
// apps/daemon/dist/index.js
|
|
1995
|
-
|
|
2030
|
+
function resolvePackageVersion() {
|
|
2031
|
+
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
2032
|
+
for (let i = 0; i < 6; i += 1) {
|
|
2033
|
+
try {
|
|
2034
|
+
const pkg = JSON.parse(readFileSync(join5(dir, "package.json"), "utf8"));
|
|
2035
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0)
|
|
2036
|
+
return pkg.version;
|
|
2037
|
+
} catch {
|
|
2038
|
+
}
|
|
2039
|
+
const parent = dirname4(dir);
|
|
2040
|
+
if (parent === dir)
|
|
2041
|
+
break;
|
|
2042
|
+
dir = parent;
|
|
2043
|
+
}
|
|
2044
|
+
return "0.0.0";
|
|
2045
|
+
}
|
|
2046
|
+
var AGENT_BLACKBOX_DAEMON_VERSION = resolvePackageVersion();
|
|
1996
2047
|
function describeDaemon() {
|
|
1997
2048
|
return "Agent-Blackbox daemon: local ingest, replay, and dashboard bridge.";
|
|
1998
2049
|
}
|
|
1999
2050
|
|
|
2000
2051
|
// apps/daemon/dist/cli.js
|
|
2001
2052
|
var args = process.argv.slice(2);
|
|
2002
|
-
var cliDir =
|
|
2053
|
+
var cliDir = dirname5(fileURLToPath2(import.meta.url));
|
|
2003
2054
|
var repoRoot = resolve(cliDir, "../../..");
|
|
2004
2055
|
var firstExisting = (paths) => paths.find((p) => existsSync(p));
|
|
2005
2056
|
var dashboardDistDir = firstExisting([resolve(cliDir, "dashboard"), resolve(repoRoot, "apps/dashboard/dist")]) ?? resolve(repoRoot, "apps/dashboard/dist");
|
|
2006
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
|
+
}
|
|
2007
2062
|
void main(args);
|
|
2008
2063
|
async function main(argv) {
|
|
2009
2064
|
if (argv.includes("--version") || argv.includes("-v")) {
|
|
@@ -2020,12 +2075,41 @@ async function main(argv) {
|
|
|
2020
2075
|
return;
|
|
2021
2076
|
}
|
|
2022
2077
|
if (command === "up") {
|
|
2023
|
-
const
|
|
2078
|
+
const projectFlag = readFlag(argv, "--project");
|
|
2079
|
+
const global = projectFlag === void 0;
|
|
2024
2080
|
const port = Number(readFlag(argv, "--port") ?? "47831");
|
|
2025
2081
|
const uiPort = Number(readFlag(argv, "--ui-port") ?? "5173");
|
|
2026
2082
|
const daemonUrl = `http://127.0.0.1:${port}`;
|
|
2027
|
-
const adapterPackage = readFlag(argv, "--adapter-package") ?? `file:${resolve(repoRoot, "packages/opencode-adapter")}`;
|
|
2028
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")}`;
|
|
2029
2113
|
try {
|
|
2030
2114
|
const result = await initOpenCodeProject({
|
|
2031
2115
|
projectDir,
|
|
@@ -2043,7 +2127,7 @@ async function main(argv) {
|
|
|
2043
2127
|
throw error;
|
|
2044
2128
|
}
|
|
2045
2129
|
}
|
|
2046
|
-
|
|
2130
|
+
daemon = await startTraceDaemon({ projectDir, port, suggest });
|
|
2047
2131
|
const ui = await startDashboardServer({ distDir: dashboardDistDir, port: uiPort, daemonUrl });
|
|
2048
2132
|
const dashboardUrl = `http://127.0.0.1:${ui.port}`;
|
|
2049
2133
|
console.log("");
|
|
@@ -2055,11 +2139,29 @@ async function main(argv) {
|
|
|
2055
2139
|
if (!argv.includes("--no-open"))
|
|
2056
2140
|
openInBrowser(dashboardUrl);
|
|
2057
2141
|
console.log("Now run your agent in that project, e.g.:");
|
|
2058
|
-
console.log(`
|
|
2142
|
+
console.log(` opencode # in ${projectDir} (the project-local recorder streams here)`);
|
|
2059
2143
|
console.log("");
|
|
2060
2144
|
console.log("Press Ctrl+C to stop.");
|
|
2061
2145
|
return;
|
|
2062
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
|
+
}
|
|
2063
2165
|
if (command === "replay") {
|
|
2064
2166
|
const eventsFile = argv[1];
|
|
2065
2167
|
if (!eventsFile) {
|
|
@@ -2117,8 +2219,11 @@ function printHelp() {
|
|
|
2117
2219
|
console.log(describeDaemon());
|
|
2118
2220
|
console.log("");
|
|
2119
2221
|
console.log("Usage:");
|
|
2120
|
-
console.log(" agent-blackbox up
|
|
2121
|
-
console.log("
|
|
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");
|
|
2122
2227
|
console.log(" agent-blackbox daemon [--project <dir>] [--port <port>]");
|
|
2123
2228
|
console.log(" agent-blackbox init-opencode [--project <dir>] [--daemon-url <url>] [--adapter-package <specifier>] [--force] [--optimize]");
|
|
2124
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.
|
|
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": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
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
|
}
|