@bivy/bivy 0.7.0-staging.103 → 0.7.0-staging.105
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/runtime/index.js +36 -4
- package/dist/server.js +4 -1
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -116,14 +116,27 @@ function claudeCodeInfo() {
|
|
|
116
116
|
},
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
+
// Memoized CLI probes. `commandAvailable`/`resolveCommandPath`/`probeHelpText`
|
|
120
|
+
// each shell out with a BLOCKING spawnSync, and the runtime catalog that calls
|
|
121
|
+
// them (cliAgentInfo → prefersAcp/acpSupportedByBinary) is rebuilt often — on
|
|
122
|
+
// every advertise and every runtimes.list send. Re-probing per build stalled the
|
|
123
|
+
// event loop for seconds at a time (a synchronous spawn storm). A CLI's presence
|
|
124
|
+
// is effectively constant for the daemon's run, so cache per command for the
|
|
125
|
+
// process lifetime and clear on install (invalidateCliProbeCache).
|
|
126
|
+
const COMMAND_AVAILABLE_CACHE = new Map();
|
|
119
127
|
function commandAvailable(command) {
|
|
120
128
|
if (!command.trim())
|
|
121
129
|
return false;
|
|
130
|
+
const cached = COMMAND_AVAILABLE_CACHE.get(command);
|
|
131
|
+
if (cached !== undefined)
|
|
132
|
+
return cached;
|
|
122
133
|
const result = spawnSync(process.platform === "win32" ? "where" : "command", process.platform === "win32" ? [command] : ["-v", command], {
|
|
123
134
|
shell: process.platform !== "win32",
|
|
124
135
|
stdio: "ignore",
|
|
125
136
|
});
|
|
126
|
-
|
|
137
|
+
const available = result.status === 0;
|
|
138
|
+
COMMAND_AVAILABLE_CACHE.set(command, available);
|
|
139
|
+
return available;
|
|
127
140
|
}
|
|
128
141
|
function genericCliInfo() {
|
|
129
142
|
const options = processRuntimeFromEnv();
|
|
@@ -869,17 +882,23 @@ function cliThinkingConfig(id) {
|
|
|
869
882
|
* Used to key the help-probe cache: caching by the bare NAME would keep serving a
|
|
870
883
|
* stale answer after the binary behind that name changed (a CLI upgraded or
|
|
871
884
|
* installed while the daemon is running, or a different PATH entry winning).
|
|
885
|
+
* Memoized per command (see COMMAND_AVAILABLE_CACHE) — it spawnSyncs, and is hit
|
|
886
|
+
* on every catalog build.
|
|
872
887
|
*/
|
|
888
|
+
const COMMAND_PATH_CACHE = new Map();
|
|
873
889
|
function resolveCommandPath(command) {
|
|
874
890
|
if (!command.trim())
|
|
875
891
|
return null;
|
|
892
|
+
const cached = COMMAND_PATH_CACHE.get(command);
|
|
893
|
+
if (cached !== undefined)
|
|
894
|
+
return cached;
|
|
876
895
|
const res = spawnSync(process.platform === "win32" ? "where" : "command", process.platform === "win32" ? [command] : ["-v", command], {
|
|
877
896
|
shell: process.platform !== "win32",
|
|
878
897
|
encoding: "utf8",
|
|
879
898
|
});
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return
|
|
899
|
+
const resolved = res.status !== 0 ? null : ((res.stdout ?? "").split(/\r?\n/)[0]?.trim() || null);
|
|
900
|
+
COMMAND_PATH_CACHE.set(command, resolved);
|
|
901
|
+
return resolved;
|
|
883
902
|
}
|
|
884
903
|
const HELP_PROBE_CACHE = new Map();
|
|
885
904
|
function probeHelpText(command) {
|
|
@@ -898,6 +917,19 @@ function probeHelpText(command) {
|
|
|
898
917
|
HELP_PROBE_CACHE.set(key, text);
|
|
899
918
|
return text;
|
|
900
919
|
}
|
|
920
|
+
/**
|
|
921
|
+
* Drop every memoized CLI probe (availability, resolved path, --help text). These
|
|
922
|
+
* probes shell out with a blocking spawnSync and are cached for the process
|
|
923
|
+
* lifetime to keep the frequently-rebuilt runtime catalog off the event loop, so a
|
|
924
|
+
* CLI installed/updated mid-run wouldn't otherwise be noticed until a restart.
|
|
925
|
+
* Call this right after Bivy installs a runtime so the next catalog build re-probes
|
|
926
|
+
* and reflects the new binary immediately.
|
|
927
|
+
*/
|
|
928
|
+
export function invalidateCliProbeCache() {
|
|
929
|
+
COMMAND_AVAILABLE_CACHE.clear();
|
|
930
|
+
COMMAND_PATH_CACHE.clear();
|
|
931
|
+
HELP_PROBE_CACHE.clear();
|
|
932
|
+
}
|
|
901
933
|
// A resume template mixes launch flags (`-p`, `--force`) with the resume-specific
|
|
902
934
|
// token(s) (`--resume`, `threads continue`, `-s`, `--restore`, …). Only the latter
|
|
903
935
|
// evidence resume support, so we match on those — otherwise a shared launch flag
|
package/dist/server.js
CHANGED
|
@@ -8,7 +8,7 @@ import { randomUUID, randomBytes, timingSafeEqual, createHash } from "node:crypt
|
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import express from "express";
|
|
10
10
|
import { WebSocketServer, WebSocket } from "ws";
|
|
11
|
-
import { listRuntimes, catalogRuntimes, cliInstallSpec, isCliAgentId } from "./runtime/index.js";
|
|
11
|
+
import { listRuntimes, catalogRuntimes, cliInstallSpec, invalidateCliProbeCache, isCliAgentId } from "./runtime/index.js";
|
|
12
12
|
import { createRunPolicy } from "./policy/run-policy.js";
|
|
13
13
|
import { DEFAULT_BACKOFF } from "./policy/ruleset.js";
|
|
14
14
|
import { SessionRerouteController } from "./policy/session-reroute.js";
|
|
@@ -3217,6 +3217,9 @@ const RELAY_COMMANDS = {
|
|
|
3217
3217
|
const before = runtimeList().find((runtime) => runtime.id === spec.id);
|
|
3218
3218
|
if (before?.status !== "available")
|
|
3219
3219
|
await runInstallCommand(spec);
|
|
3220
|
+
// The just-installed binary changes what the CLI probes would report, so drop
|
|
3221
|
+
// their (process-lifetime) cache and let the catalog below re-probe it.
|
|
3222
|
+
invalidateCliProbeCache();
|
|
3220
3223
|
const activeAgent = active?.runtimeId ?? defaultRuntimeId;
|
|
3221
3224
|
const runtimes = runtimeList(activeAgent);
|
|
3222
3225
|
relay?.sendEvent({ type: "runtime.install.done", id: spec.id, runtimes });
|
package/package.json
CHANGED