@raysonmeng/agentbridge 0.1.14 → 0.1.16
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/.claude-plugin/marketplace.json +1 -1
- package/README.md +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/cli.js +106 -16
- package/dist/daemon.js +6 -6
- package/package.json +1 -1
- package/plugins/agentbridge/.claude-plugin/plugin.json +1 -1
- package/plugins/agentbridge/server/bridge-server.js +3 -3
- package/plugins/agentbridge/server/daemon.js +6 -6
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
{
|
|
13
13
|
"name": "agentbridge",
|
|
14
14
|
"description": "Bridge Claude Code and Codex through a shared daemon, push channel delivery, and reply/get_messages tools.",
|
|
15
|
-
"version": "0.1.
|
|
15
|
+
"version": "0.1.16",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "AgentBridge Contributors",
|
|
18
18
|
"email": "raysonmeng@qq.com"
|
package/README.md
CHANGED
|
@@ -266,6 +266,7 @@ agent_bridge/
|
|
|
266
266
|
| `AGENTBRIDGE_DAEMON_ENTRY` | `./daemon.ts` | Override daemon entry point (used by plugin bundles) |
|
|
267
267
|
| `NO_UPDATE_NOTIFIER` | unset | Set to any value to disable the "update available" notice (ecosystem-standard opt-out) |
|
|
268
268
|
| `AGENTBRIDGE_NO_UPDATE_NOTIFIER` | unset | Namespaced opt-out for the update notice (same effect as `NO_UPDATE_NOTIFIER`) |
|
|
269
|
+
| `AGENTBRIDGE_UPDATE_PROMPT` | unset | Set to `0` to disable the interactive update prompt and keep pure notice-only behavior |
|
|
269
270
|
| `AGENTBRIDGE_UPDATE_CHECK_INTERVAL_MS` | `86400000` | How often `abg claude`/`abg codex` may check npm for a newer version (default once/day). The notice is otherwise printed from cache — zero network on most runs |
|
|
270
271
|
|
|
271
272
|
### Update notifications
|
|
@@ -278,7 +279,7 @@ agent_bridge/
|
|
|
278
279
|
Plugin: /plugin marketplace update agentbridge (then /reload-plugins)
|
|
279
280
|
```
|
|
280
281
|
|
|
281
|
-
The check is best-effort
|
|
282
|
+
The check is best-effort: the notice is printed from a cached result, the npm check runs at most once per day in the background, and any network/registry failure is silently ignored. On an interactive TTY, a cached update prompts before launch; answering `y` runs `npm install -g @raysonmeng/agentbridge@latest`, while `N` (or no answer within 15 seconds) records that version as dismissed and continues launching. Non-interactive output and CI never prompt, and the notice can be disabled with `NO_UPDATE_NOTIFIER=1` or kept notice-only with `AGENTBRIDGE_UPDATE_PROMPT=0`.
|
|
282
283
|
|
|
283
284
|
### State Directory
|
|
284
285
|
|
package/README.zh-CN.md
CHANGED
|
@@ -253,6 +253,7 @@ agent_bridge/
|
|
|
253
253
|
| `AGENTBRIDGE_DAEMON_ENTRY` | `./daemon.ts` | 覆盖 daemon 入口(插件包使用) |
|
|
254
254
|
| `NO_UPDATE_NOTIFIER` | 未设置 | 设为任意值即关闭「有新版本」提示(生态通用 opt-out) |
|
|
255
255
|
| `AGENTBRIDGE_NO_UPDATE_NOTIFIER` | 未设置 | 命名空间化的关闭开关(效果同 `NO_UPDATE_NOTIFIER`) |
|
|
256
|
+
| `AGENTBRIDGE_UPDATE_PROMPT` | 未设置 | 设为 `0` 可关闭交互询问,恢复纯打印提示 |
|
|
256
257
|
| `AGENTBRIDGE_UPDATE_CHECK_INTERVAL_MS` | `86400000` | `abg claude`/`abg codex` 多久查一次 npm 新版本(默认每天一次)。其余时候只读缓存打印,大多数调用零网络 |
|
|
257
258
|
|
|
258
259
|
### 更新提示
|
|
@@ -265,7 +266,7 @@ agent_bridge/
|
|
|
265
266
|
Plugin: /plugin marketplace update agentbridge (then /reload-plugins)
|
|
266
267
|
```
|
|
267
268
|
|
|
268
|
-
该检查是 best-effort
|
|
269
|
+
该检查是 best-effort:提示从缓存打印,npm 检查每天最多在后台跑一次,任何网络/registry 失败都静默忽略。交互式 TTY 下,命中缓存更新会在启动前询问;输入 `y` 会运行 `npm install -g @raysonmeng/agentbridge@latest`,输入 `N`(或 15 秒内无应答)会记住本版本已拒绝并继续启动。非交互(管道)输出和 CI 下绝不询问,可用 `NO_UPDATE_NOTIFIER=1` 关闭提示,或用 `AGENTBRIDGE_UPDATE_PROMPT=0` 保持纯打印。
|
|
269
270
|
|
|
270
271
|
### 状态目录
|
|
271
272
|
|
package/dist/cli.js
CHANGED
|
@@ -176,7 +176,7 @@ function parsePositiveIntEnv(name, fallback, log = () => {}, env = process.env)
|
|
|
176
176
|
var require_package = __commonJS((exports, module) => {
|
|
177
177
|
module.exports = {
|
|
178
178
|
name: "@raysonmeng/agentbridge",
|
|
179
|
-
version: "0.1.
|
|
179
|
+
version: "0.1.16",
|
|
180
180
|
description: "Bridge between Claude Code and Codex \u2014 bidirectional agent communication via MCP Channel + JSON-RPC",
|
|
181
181
|
type: "module",
|
|
182
182
|
packageManager: "bun@1.3.11",
|
|
@@ -255,9 +255,13 @@ __export(exports_update_notifier, {
|
|
|
255
255
|
isUpdateCheckSuppressed: () => isUpdateCheckSuppressed,
|
|
256
256
|
getCurrentVersion: () => getCurrentVersion,
|
|
257
257
|
buildUpdateNotice: () => buildUpdateNotice,
|
|
258
|
-
|
|
258
|
+
buildDismissedUpdateNotice: () => buildDismissedUpdateNotice,
|
|
259
|
+
PACKAGE_NAME: () => PACKAGE_NAME,
|
|
260
|
+
DEFAULT_UPDATE_PROMPT_TIMEOUT_MS: () => DEFAULT_UPDATE_PROMPT_TIMEOUT_MS
|
|
259
261
|
});
|
|
260
262
|
import { readFileSync } from "fs";
|
|
263
|
+
import { spawnSync } from "child_process";
|
|
264
|
+
import { createInterface } from "readline";
|
|
261
265
|
function getCurrentVersion() {
|
|
262
266
|
try {
|
|
263
267
|
return require_package().version;
|
|
@@ -285,7 +289,8 @@ function readCache(stateDir) {
|
|
|
285
289
|
return null;
|
|
286
290
|
return {
|
|
287
291
|
lastCheckMs: parsed.lastCheckMs,
|
|
288
|
-
latest: typeof parsed.latest === "string" ? parsed.latest : null
|
|
292
|
+
latest: typeof parsed.latest === "string" ? parsed.latest : null,
|
|
293
|
+
dismissedVersion: typeof parsed.dismissedVersion === "string" ? parsed.dismissedVersion : undefined
|
|
289
294
|
};
|
|
290
295
|
} catch {
|
|
291
296
|
return null;
|
|
@@ -327,7 +332,11 @@ async function refreshUpdateCache(deps = {}) {
|
|
|
327
332
|
try {
|
|
328
333
|
const latest = await fetchLatest(fetchImpl);
|
|
329
334
|
const prev = readCache(stateDir);
|
|
330
|
-
writeCache(stateDir, {
|
|
335
|
+
writeCache(stateDir, {
|
|
336
|
+
lastCheckMs: now(),
|
|
337
|
+
latest: latest ?? prev?.latest ?? null,
|
|
338
|
+
dismissedVersion: prev?.dismissedVersion
|
|
339
|
+
});
|
|
331
340
|
} catch {}
|
|
332
341
|
}
|
|
333
342
|
function buildUpdateNotice(current, latest, isTTY) {
|
|
@@ -342,30 +351,109 @@ function buildUpdateNotice(current, latest, isTTY) {
|
|
|
342
351
|
].join(`
|
|
343
352
|
`);
|
|
344
353
|
}
|
|
354
|
+
function buildDismissedUpdateNotice(current, latest, isTTY) {
|
|
355
|
+
const yellow = isTTY ? "\x1B[33m" : "";
|
|
356
|
+
const bold = isTTY ? "\x1B[1m" : "";
|
|
357
|
+
const reset = isTTY ? "\x1B[0m" : "";
|
|
358
|
+
return `${yellow}\u26A0 AgentBridge update available: ${bold}${current}${reset}${yellow} \u2192 ${bold}${latest}${reset} (previously dismissed)`;
|
|
359
|
+
}
|
|
345
360
|
function checkIntervalMs(env) {
|
|
346
361
|
return parsePositiveIntEnv(CHECK_INTERVAL_ENV, DEFAULT_CHECK_INTERVAL_MS, undefined, env);
|
|
347
362
|
}
|
|
348
|
-
function
|
|
363
|
+
function updatePromptDisabled(env) {
|
|
364
|
+
return env.AGENTBRIDGE_UPDATE_PROMPT === "0";
|
|
365
|
+
}
|
|
366
|
+
function defaultInstallUpdate(cmd, args) {
|
|
367
|
+
const res = spawnSync(cmd, args, { stdio: "inherit" });
|
|
368
|
+
if (res.error)
|
|
369
|
+
return { ok: false, status: res.status, error: res.error };
|
|
370
|
+
return { ok: res.status === 0, status: res.status };
|
|
371
|
+
}
|
|
372
|
+
function defaultPromptUpdate(opts) {
|
|
373
|
+
return new Promise((resolve) => {
|
|
374
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
375
|
+
let settled = false;
|
|
376
|
+
let timer;
|
|
377
|
+
const finish = (answer) => {
|
|
378
|
+
if (settled)
|
|
379
|
+
return;
|
|
380
|
+
settled = true;
|
|
381
|
+
clearTimeout(timer);
|
|
382
|
+
rl.close();
|
|
383
|
+
resolve(answer);
|
|
384
|
+
};
|
|
385
|
+
timer = setTimeout(() => {
|
|
386
|
+
process.stderr.write(`
|
|
387
|
+
`);
|
|
388
|
+
finish(false);
|
|
389
|
+
}, opts.timeoutMs);
|
|
390
|
+
timer.unref?.();
|
|
391
|
+
rl.question(`Update AgentBridge now? [y/N] `, (answer) => {
|
|
392
|
+
finish(/^y(?:es)?$/i.test(answer.trim()));
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function recordDismissal(stateDir, cache, latest) {
|
|
397
|
+
writeCache(stateDir, {
|
|
398
|
+
...cache,
|
|
399
|
+
latest,
|
|
400
|
+
dismissedVersion: latest
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
async function maybeNotifyUpdate(deps = {}) {
|
|
349
404
|
try {
|
|
350
405
|
const env = deps.env ?? process.env;
|
|
351
406
|
const isTTY = deps.isTTY ?? Boolean(process.stderr.isTTY);
|
|
352
407
|
if (isUpdateCheckSuppressed(env, isTTY))
|
|
353
|
-
return;
|
|
408
|
+
return "continue";
|
|
354
409
|
const current = deps.current ?? getCurrentVersion();
|
|
355
410
|
const stateDir = deps.stateDir ?? new StateDirResolver;
|
|
356
411
|
const now = deps.now ?? Date.now;
|
|
357
412
|
const print = deps.print ?? ((m) => process.stderr.write(m + `
|
|
358
413
|
`));
|
|
414
|
+
const inputIsTTY = deps.inputIsTTY ?? Boolean(process.stdin.isTTY);
|
|
415
|
+
const promptTimeoutMs = deps.promptTimeoutMs ?? DEFAULT_UPDATE_PROMPT_TIMEOUT_MS;
|
|
359
416
|
const cache = readCache(stateDir);
|
|
360
417
|
if (cache?.latest && isStableUpgrade(current, cache.latest)) {
|
|
361
|
-
|
|
418
|
+
if (cache.dismissedVersion === cache.latest) {
|
|
419
|
+
print(buildDismissedUpdateNotice(current, cache.latest, isTTY));
|
|
420
|
+
} else {
|
|
421
|
+
print(buildUpdateNotice(current, cache.latest, isTTY));
|
|
422
|
+
if (!updatePromptDisabled(env) && inputIsTTY) {
|
|
423
|
+
const promptUpdate = deps.promptUpdate ?? defaultPromptUpdate;
|
|
424
|
+
let accepted = false;
|
|
425
|
+
try {
|
|
426
|
+
accepted = await promptUpdate({ current, latest: cache.latest, timeoutMs: promptTimeoutMs });
|
|
427
|
+
} catch {
|
|
428
|
+
accepted = false;
|
|
429
|
+
}
|
|
430
|
+
if (accepted) {
|
|
431
|
+
const installUpdate = deps.installUpdate ?? defaultInstallUpdate;
|
|
432
|
+
const cmd = "npm";
|
|
433
|
+
const args = ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
434
|
+
const result = installUpdate(cmd, args);
|
|
435
|
+
if (result.ok) {
|
|
436
|
+
print("AgentBridge CLI updated. \u8BF7\u91CD\u65B0\u8FD0\u884C\u547D\u4EE4\u3002");
|
|
437
|
+
print("Plugin: in Claude, run `/plugin marketplace update agentbridge` and then `/reload-plugins`.");
|
|
438
|
+
return "updated";
|
|
439
|
+
}
|
|
440
|
+
const detail = result.error?.message ? ` (${result.error.message})` : typeof result.status === "number" ? ` (exit ${result.status})` : "";
|
|
441
|
+
print(`\u26A0 AgentBridge update failed${detail}; continuing with the current command.`);
|
|
442
|
+
} else {
|
|
443
|
+
recordDismissal(stateDir, cache, cache.latest);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
362
447
|
}
|
|
363
448
|
if (deps.refresh && (!cache || now() - cache.lastCheckMs >= checkIntervalMs(env))) {
|
|
364
449
|
refreshUpdateCache({ stateDir, now, fetchImpl: deps.fetchImpl }).catch(() => {});
|
|
365
450
|
}
|
|
366
|
-
|
|
451
|
+
return "continue";
|
|
452
|
+
} catch {
|
|
453
|
+
return "continue";
|
|
454
|
+
}
|
|
367
455
|
}
|
|
368
|
-
var PACKAGE_NAME = "@raysonmeng/agentbridge", REGISTRY_URL, ABBREVIATED_ACCEPT = "application/vnd.npm.install-v1+json", DEFAULT_CHECK_INTERVAL_MS, FETCH_TIMEOUT_MS = 2500, CHECK_INTERVAL_ENV = "AGENTBRIDGE_UPDATE_CHECK_INTERVAL_MS";
|
|
456
|
+
var PACKAGE_NAME = "@raysonmeng/agentbridge", REGISTRY_URL, ABBREVIATED_ACCEPT = "application/vnd.npm.install-v1+json", DEFAULT_CHECK_INTERVAL_MS, FETCH_TIMEOUT_MS = 2500, DEFAULT_UPDATE_PROMPT_TIMEOUT_MS = 15000, CHECK_INTERVAL_ENV = "AGENTBRIDGE_UPDATE_CHECK_INTERVAL_MS";
|
|
369
457
|
var init_update_notifier = __esm(() => {
|
|
370
458
|
init_atomic_json();
|
|
371
459
|
init_state_dir();
|
|
@@ -1037,7 +1125,7 @@ var exports_dev = {};
|
|
|
1037
1125
|
__export(exports_dev, {
|
|
1038
1126
|
runDev: () => runDev
|
|
1039
1127
|
});
|
|
1040
|
-
import { execFileSync as execFileSync3, spawnSync } from "child_process";
|
|
1128
|
+
import { execFileSync as execFileSync3, spawnSync as spawnSync2 } from "child_process";
|
|
1041
1129
|
import { resolve as resolve2 } from "path";
|
|
1042
1130
|
import { existsSync as existsSync5, cpSync, rmSync } from "fs";
|
|
1043
1131
|
async function runDev(args = []) {
|
|
@@ -1063,7 +1151,7 @@ async function runDev(args = []) {
|
|
|
1063
1151
|
`);
|
|
1064
1152
|
} else {
|
|
1065
1153
|
console.log("Building CLI from source...");
|
|
1066
|
-
const cliBuild =
|
|
1154
|
+
const cliBuild = spawnSync2("bun", ["run", "build:cli"], {
|
|
1067
1155
|
cwd: projectRoot,
|
|
1068
1156
|
stdio: "inherit"
|
|
1069
1157
|
});
|
|
@@ -1074,7 +1162,7 @@ async function runDev(args = []) {
|
|
|
1074
1162
|
console.log(` \u2713 CLI built successfully
|
|
1075
1163
|
`);
|
|
1076
1164
|
console.log("Building plugin from source...");
|
|
1077
|
-
const buildResult =
|
|
1165
|
+
const buildResult = spawnSync2("bun", ["run", "build:plugin"], {
|
|
1078
1166
|
cwd: projectRoot,
|
|
1079
1167
|
stdio: "inherit"
|
|
1080
1168
|
});
|
|
@@ -1497,11 +1585,11 @@ function formatBuildInfo(build) {
|
|
|
1497
1585
|
var CODE_HASH_SENTINEL = "source", BUILD_INFO;
|
|
1498
1586
|
var init_build_info = __esm(() => {
|
|
1499
1587
|
BUILD_INFO = Object.freeze({
|
|
1500
|
-
version: defineString("0.1.
|
|
1501
|
-
commit: defineString("
|
|
1588
|
+
version: defineString("0.1.16", "0.0.0-source"),
|
|
1589
|
+
commit: defineString("1dc5e4f", "source"),
|
|
1502
1590
|
bundle: defineBundle("dist"),
|
|
1503
1591
|
contractVersion: defineNumber(1, CONTRACT_VERSION),
|
|
1504
|
-
codeHash: defineString("
|
|
1592
|
+
codeHash: defineString("1fc975838e46", "source")
|
|
1505
1593
|
});
|
|
1506
1594
|
});
|
|
1507
1595
|
|
|
@@ -6161,7 +6249,9 @@ async function main(command, restArgs) {
|
|
|
6161
6249
|
if (command && NOTIFY_COMMANDS.has(command)) {
|
|
6162
6250
|
try {
|
|
6163
6251
|
const { maybeNotifyUpdate: maybeNotifyUpdate2 } = await Promise.resolve().then(() => (init_update_notifier(), exports_update_notifier));
|
|
6164
|
-
maybeNotifyUpdate2({ refresh: REFRESH_COMMANDS.has(command) });
|
|
6252
|
+
const decision = await maybeNotifyUpdate2({ refresh: REFRESH_COMMANDS.has(command) });
|
|
6253
|
+
if (decision === "updated")
|
|
6254
|
+
process.exit(0);
|
|
6165
6255
|
} catch {}
|
|
6166
6256
|
}
|
|
6167
6257
|
switch (command) {
|
package/dist/daemon.js
CHANGED
|
@@ -26,11 +26,11 @@ function defineNumber(value, fallback) {
|
|
|
26
26
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
27
27
|
}
|
|
28
28
|
var BUILD_INFO = Object.freeze({
|
|
29
|
-
version: defineString("0.1.
|
|
30
|
-
commit: defineString("
|
|
29
|
+
version: defineString("0.1.16", "0.0.0-source"),
|
|
30
|
+
commit: defineString("1dc5e4f", "source"),
|
|
31
31
|
bundle: defineBundle("dist"),
|
|
32
32
|
contractVersion: defineNumber(1, CONTRACT_VERSION),
|
|
33
|
-
codeHash: defineString("
|
|
33
|
+
codeHash: defineString("1fc975838e46", "source")
|
|
34
34
|
});
|
|
35
35
|
function daemonStatusBuildInfo() {
|
|
36
36
|
return { ...BUILD_INFO };
|
|
@@ -4741,12 +4741,12 @@ class QuotaSource {
|
|
|
4741
4741
|
return candidates;
|
|
4742
4742
|
}
|
|
4743
4743
|
const binDir = join5(this.homeDir, ".budget-guard/bin");
|
|
4744
|
-
const installedBudgetProbe = join5(binDir, "budget-probe");
|
|
4745
|
-
if (existsSync5(installedBudgetProbe))
|
|
4746
|
-
add(installedBudgetProbe, "budget-probe");
|
|
4747
4744
|
const installedProbeMjs = join5(binDir, "probe.mjs");
|
|
4748
4745
|
if (existsSync5(installedProbeMjs))
|
|
4749
4746
|
add(installedProbeMjs, "probe-mjs");
|
|
4747
|
+
const installedBudgetProbe = join5(binDir, "budget-probe");
|
|
4748
|
+
if (existsSync5(installedBudgetProbe))
|
|
4749
|
+
add(installedBudgetProbe, "budget-probe");
|
|
4750
4750
|
return candidates;
|
|
4751
4751
|
}
|
|
4752
4752
|
async fetchAgent(candidates, agent) {
|
package/package.json
CHANGED
|
@@ -14511,11 +14511,11 @@ function defineNumber(value, fallback) {
|
|
|
14511
14511
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
14512
14512
|
}
|
|
14513
14513
|
var BUILD_INFO = Object.freeze({
|
|
14514
|
-
version: defineString("0.1.
|
|
14515
|
-
commit: defineString("
|
|
14514
|
+
version: defineString("0.1.16", "0.0.0-source"),
|
|
14515
|
+
commit: defineString("1dc5e4f", "source"),
|
|
14516
14516
|
bundle: defineBundle("plugin"),
|
|
14517
14517
|
contractVersion: defineNumber(1, CONTRACT_VERSION),
|
|
14518
|
-
codeHash: defineString("
|
|
14518
|
+
codeHash: defineString("1fc975838e46", "source")
|
|
14519
14519
|
});
|
|
14520
14520
|
function sameRuntimeContract(a, b) {
|
|
14521
14521
|
if (!a || !b)
|
|
@@ -26,11 +26,11 @@ function defineNumber(value, fallback) {
|
|
|
26
26
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
27
27
|
}
|
|
28
28
|
var BUILD_INFO = Object.freeze({
|
|
29
|
-
version: defineString("0.1.
|
|
30
|
-
commit: defineString("
|
|
29
|
+
version: defineString("0.1.16", "0.0.0-source"),
|
|
30
|
+
commit: defineString("1dc5e4f", "source"),
|
|
31
31
|
bundle: defineBundle("plugin"),
|
|
32
32
|
contractVersion: defineNumber(1, CONTRACT_VERSION),
|
|
33
|
-
codeHash: defineString("
|
|
33
|
+
codeHash: defineString("1fc975838e46", "source")
|
|
34
34
|
});
|
|
35
35
|
function daemonStatusBuildInfo() {
|
|
36
36
|
return { ...BUILD_INFO };
|
|
@@ -4741,12 +4741,12 @@ class QuotaSource {
|
|
|
4741
4741
|
return candidates;
|
|
4742
4742
|
}
|
|
4743
4743
|
const binDir = join5(this.homeDir, ".budget-guard/bin");
|
|
4744
|
-
const installedBudgetProbe = join5(binDir, "budget-probe");
|
|
4745
|
-
if (existsSync5(installedBudgetProbe))
|
|
4746
|
-
add(installedBudgetProbe, "budget-probe");
|
|
4747
4744
|
const installedProbeMjs = join5(binDir, "probe.mjs");
|
|
4748
4745
|
if (existsSync5(installedProbeMjs))
|
|
4749
4746
|
add(installedProbeMjs, "probe-mjs");
|
|
4747
|
+
const installedBudgetProbe = join5(binDir, "budget-probe");
|
|
4748
|
+
if (existsSync5(installedBudgetProbe))
|
|
4749
|
+
add(installedBudgetProbe, "budget-probe");
|
|
4750
4750
|
return candidates;
|
|
4751
4751
|
}
|
|
4752
4752
|
async fetchAgent(candidates, agent) {
|