@taewooopark/agent-blackbox 0.47.2 → 0.47.4
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
CHANGED
|
@@ -2048,7 +2048,7 @@ async function readTraceEvents(filePath) {
|
|
|
2048
2048
|
}
|
|
2049
2049
|
|
|
2050
2050
|
// apps/daemon/dist/server.js
|
|
2051
|
-
import {
|
|
2051
|
+
import { open as open2, stat as stat3 } from "node:fs/promises";
|
|
2052
2052
|
import { createServer as createServer2 } from "node:http";
|
|
2053
2053
|
import { join as join4 } from "node:path";
|
|
2054
2054
|
import { WebSocket, WebSocketServer } from "ws";
|
|
@@ -2642,24 +2642,67 @@ async function loadTraceEvents(eventsFile) {
|
|
|
2642
2642
|
}
|
|
2643
2643
|
}
|
|
2644
2644
|
var SNAPSHOT_EVENT_CAP = 3e4;
|
|
2645
|
+
var eventCaches = /* @__PURE__ */ new Map();
|
|
2646
|
+
var cacheLocks = /* @__PURE__ */ new Map();
|
|
2647
|
+
function withCacheLock(key, run) {
|
|
2648
|
+
const prev = cacheLocks.get(key) ?? Promise.resolve();
|
|
2649
|
+
const result = prev.then(run, run);
|
|
2650
|
+
cacheLocks.set(key, result.then(() => void 0, () => void 0));
|
|
2651
|
+
return result;
|
|
2652
|
+
}
|
|
2645
2653
|
async function loadRecentTraceEvents(eventsFile, cap = SNAPSHOT_EVENT_CAP) {
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2654
|
+
return withCacheLock(eventsFile, async () => {
|
|
2655
|
+
let cache = eventCaches.get(eventsFile);
|
|
2656
|
+
if (!cache) {
|
|
2657
|
+
cache = { offset: 0, buffer: "", events: [] };
|
|
2658
|
+
eventCaches.set(eventsFile, cache);
|
|
2659
|
+
}
|
|
2660
|
+
let size;
|
|
2661
|
+
try {
|
|
2662
|
+
size = (await stat3(eventsFile)).size;
|
|
2663
|
+
} catch (error) {
|
|
2664
|
+
if (isNodeError(error) && error.code === "ENOENT")
|
|
2665
|
+
return [];
|
|
2666
|
+
throw error;
|
|
2667
|
+
}
|
|
2668
|
+
if (size < cache.offset) {
|
|
2669
|
+
cache.offset = 0;
|
|
2670
|
+
cache.buffer = "";
|
|
2671
|
+
cache.events = [];
|
|
2672
|
+
}
|
|
2673
|
+
if (size > cache.offset) {
|
|
2674
|
+
const handle = await open2(eventsFile, "r");
|
|
2675
|
+
try {
|
|
2676
|
+
const length = size - cache.offset;
|
|
2677
|
+
const buf = Buffer.alloc(length);
|
|
2678
|
+
await handle.read(buf, 0, length, cache.offset);
|
|
2679
|
+
cache.offset = size;
|
|
2680
|
+
cache.buffer += buf.toString("utf8");
|
|
2681
|
+
} finally {
|
|
2682
|
+
await handle.close();
|
|
2683
|
+
}
|
|
2684
|
+
const lines = cache.buffer.split("\n");
|
|
2685
|
+
cache.buffer = lines.pop() ?? "";
|
|
2686
|
+
let from = 0;
|
|
2687
|
+
if (cache.events.length === 0 && lines.length > SNAPSHOT_EVENT_CAP) {
|
|
2688
|
+
let kept = 0;
|
|
2689
|
+
from = lines.length;
|
|
2690
|
+
while (from > 0 && kept < SNAPSHOT_EVENT_CAP) {
|
|
2691
|
+
from -= 1;
|
|
2692
|
+
if (lines[from].trim().length > 0)
|
|
2693
|
+
kept += 1;
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
const fresh = parseTraceEvents(lines.slice(from).join("\n"));
|
|
2697
|
+
if (fresh.length > 0) {
|
|
2698
|
+
cache.events.push(...fresh);
|
|
2699
|
+
if (cache.events.length > SNAPSHOT_EVENT_CAP) {
|
|
2700
|
+
cache.events.splice(0, cache.events.length - SNAPSHOT_EVENT_CAP);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
return cap >= cache.events.length ? cache.events.slice() : cache.events.slice(cache.events.length - cap);
|
|
2705
|
+
});
|
|
2663
2706
|
}
|
|
2664
2707
|
async function buildReplaySummary(eventsFile) {
|
|
2665
2708
|
const events = await loadTraceEvents(eventsFile);
|
|
@@ -2785,20 +2828,49 @@ async function broadcastSnapshot(clients, eventsFile) {
|
|
|
2785
2828
|
if (clients.size === 0) {
|
|
2786
2829
|
return;
|
|
2787
2830
|
}
|
|
2788
|
-
|
|
2831
|
+
let frame;
|
|
2832
|
+
try {
|
|
2833
|
+
frame = JSON.stringify({ type: "snapshot", data: await buildTraceSnapshot(eventsFile) });
|
|
2834
|
+
} catch (error) {
|
|
2835
|
+
const errFrame = JSON.stringify({
|
|
2836
|
+
type: "error",
|
|
2837
|
+
error: { message: error instanceof Error ? error.message : String(error) }
|
|
2838
|
+
});
|
|
2839
|
+
for (const client of clients)
|
|
2840
|
+
if (client.readyState === WebSocket.OPEN)
|
|
2841
|
+
client.send(errFrame);
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
for (const client of clients)
|
|
2845
|
+
if (client.readyState === WebSocket.OPEN)
|
|
2846
|
+
client.send(frame);
|
|
2789
2847
|
}
|
|
2790
2848
|
function makeBroadcastScheduler(clients, eventsFile, delayMs = 150) {
|
|
2791
2849
|
let timer = null;
|
|
2792
|
-
|
|
2850
|
+
let building = false;
|
|
2851
|
+
let pending = false;
|
|
2852
|
+
const schedule = () => {
|
|
2853
|
+
if (building) {
|
|
2854
|
+
pending = true;
|
|
2855
|
+
return;
|
|
2856
|
+
}
|
|
2793
2857
|
if (timer)
|
|
2794
2858
|
return;
|
|
2795
2859
|
timer = setTimeout(() => {
|
|
2796
2860
|
timer = null;
|
|
2797
|
-
|
|
2861
|
+
building = true;
|
|
2862
|
+
void broadcastSnapshot(clients, eventsFile).finally(() => {
|
|
2863
|
+
building = false;
|
|
2864
|
+
if (pending) {
|
|
2865
|
+
pending = false;
|
|
2866
|
+
schedule();
|
|
2867
|
+
}
|
|
2868
|
+
});
|
|
2798
2869
|
}, delayMs);
|
|
2799
2870
|
if (typeof timer.unref === "function")
|
|
2800
2871
|
timer.unref();
|
|
2801
2872
|
};
|
|
2873
|
+
return schedule;
|
|
2802
2874
|
}
|
|
2803
2875
|
async function sendSnapshot(client, eventsFile) {
|
|
2804
2876
|
if (client.readyState !== WebSocket.OPEN) {
|
|
@@ -2892,7 +2964,7 @@ function isNodeError(error) {
|
|
|
2892
2964
|
}
|
|
2893
2965
|
|
|
2894
2966
|
// apps/daemon/dist/initOpenCode.js
|
|
2895
|
-
import { mkdir as mkdir3, readFile as
|
|
2967
|
+
import { mkdir as mkdir3, readFile as readFile4, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
2896
2968
|
import { homedir as homedir2 } from "node:os";
|
|
2897
2969
|
import { dirname as dirname3, join as join5 } from "node:path";
|
|
2898
2970
|
var defaultAdapterPackage = "@agent-blackbox/opencode-adapter";
|
|
@@ -2909,7 +2981,7 @@ async function installGlobalRecorder(options) {
|
|
|
2909
2981
|
throw new Error("Self-contained recorder bundle not found. Use the published npx package, or build it from source with `npm run build:cli`.");
|
|
2910
2982
|
}
|
|
2911
2983
|
const pluginPath = globalRecorderPath();
|
|
2912
|
-
const bundle = (await
|
|
2984
|
+
const bundle = (await readFile4(options.pluginBundlePath, "utf8")).replaceAll("__ABB_DAEMON_URL__", options.daemonUrl);
|
|
2913
2985
|
await mkdir3(dirname3(pluginPath), { recursive: true });
|
|
2914
2986
|
await writeFile2(pluginPath, bundle, "utf8");
|
|
2915
2987
|
return { pluginPath };
|
|
@@ -2938,7 +3010,7 @@ async function initOpenCodeProject(options) {
|
|
|
2938
3010
|
throw new Error(`${pluginPath} already exists. Re-run with --force to overwrite it.`);
|
|
2939
3011
|
}
|
|
2940
3012
|
if (options.pluginBundlePath && await pathExists(options.pluginBundlePath)) {
|
|
2941
|
-
const bundle = await
|
|
3013
|
+
const bundle = await readFile4(options.pluginBundlePath, "utf8");
|
|
2942
3014
|
const inlined = bundle.replaceAll("__ABB_DAEMON_URL__", daemonUrl);
|
|
2943
3015
|
await writeFile2(pluginPath, inlined, "utf8");
|
|
2944
3016
|
return { pluginPath, packageJsonPath, adapterPackage, adapterImport };
|
|
@@ -2977,7 +3049,7 @@ function inferAdapterImport(adapterPackage) {
|
|
|
2977
3049
|
}
|
|
2978
3050
|
async function readPackageJson(packageJsonPath) {
|
|
2979
3051
|
try {
|
|
2980
|
-
return JSON.parse(await
|
|
3052
|
+
return JSON.parse(await readFile4(packageJsonPath, "utf8"));
|
|
2981
3053
|
} catch (error) {
|
|
2982
3054
|
if (isNodeError2(error) && error.code === "ENOENT") {
|
|
2983
3055
|
return {};
|
|
@@ -2987,7 +3059,7 @@ async function readPackageJson(packageJsonPath) {
|
|
|
2987
3059
|
}
|
|
2988
3060
|
async function pathExists(path) {
|
|
2989
3061
|
try {
|
|
2990
|
-
await
|
|
3062
|
+
await readFile4(path, "utf8");
|
|
2991
3063
|
return true;
|
|
2992
3064
|
} catch (error) {
|
|
2993
3065
|
if (isNodeError2(error) && error.code === "ENOENT") {
|
|
@@ -3023,7 +3095,7 @@ function describeDaemon() {
|
|
|
3023
3095
|
}
|
|
3024
3096
|
|
|
3025
3097
|
// apps/daemon/dist/initClaudeHooks.js
|
|
3026
|
-
import { mkdir as mkdir4, readFile as
|
|
3098
|
+
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
|
|
3027
3099
|
import { homedir as homedir3 } from "node:os";
|
|
3028
3100
|
import { dirname as dirname5, join as join7 } from "node:path";
|
|
3029
3101
|
function globalClaudeDir() {
|
|
@@ -3046,7 +3118,7 @@ async function uninstallClaudeCodeHooks() {
|
|
|
3046
3118
|
const settingsPath = claudeSettingsPath();
|
|
3047
3119
|
let settings;
|
|
3048
3120
|
try {
|
|
3049
|
-
settings = JSON.parse(await
|
|
3121
|
+
settings = JSON.parse(await readFile5(settingsPath, "utf8"));
|
|
3050
3122
|
} catch (error) {
|
|
3051
3123
|
if (isNotFound(error))
|
|
3052
3124
|
return { settingsPath, removed: false };
|
|
@@ -3060,7 +3132,7 @@ async function uninstallClaudeCodeHooks() {
|
|
|
3060
3132
|
}
|
|
3061
3133
|
async function readSettings(path) {
|
|
3062
3134
|
try {
|
|
3063
|
-
return JSON.parse(await
|
|
3135
|
+
return JSON.parse(await readFile5(path, "utf8"));
|
|
3064
3136
|
} catch (error) {
|
|
3065
3137
|
if (isNotFound(error))
|
|
3066
3138
|
return {};
|