@buildautomaton/cli 0.1.71 → 0.1.73
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 +124 -24
- package/dist/cli.js.map +4 -4
- package/dist/index.js +124 -24
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29997,12 +29997,32 @@ function attachSdkStdioStderrAuthWatch(options) {
|
|
|
29997
29997
|
|
|
29998
29998
|
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
29999
29999
|
import { spawn } from "node:child_process";
|
|
30000
|
+
|
|
30001
|
+
// src/agents/acp/clients/bridge-installed-agent-auth-env.ts
|
|
30002
|
+
var authEnv = /* @__PURE__ */ new Map();
|
|
30003
|
+
function setBridgeInstalledAgentAuthEnv(entries) {
|
|
30004
|
+
authEnv.clear();
|
|
30005
|
+
for (const entry of entries) {
|
|
30006
|
+
const envVar = typeof entry.envVar === "string" ? entry.envVar.trim() : "";
|
|
30007
|
+
const token = typeof entry.token === "string" ? entry.token.trim() : "";
|
|
30008
|
+
if (envVar && token) authEnv.set(envVar, token);
|
|
30009
|
+
}
|
|
30010
|
+
}
|
|
30011
|
+
function bridgeInstalledAgentAuthProcessEnv(base = process.env) {
|
|
30012
|
+
if (authEnv.size === 0) return base;
|
|
30013
|
+
return { ...base, ...Object.fromEntries(authEnv) };
|
|
30014
|
+
}
|
|
30015
|
+
function cursorAgentUsesApiKeyAuth(env = process.env) {
|
|
30016
|
+
return Boolean(env.CURSOR_API_KEY?.trim() || env.CURSOR_AUTH_TOKEN?.trim());
|
|
30017
|
+
}
|
|
30018
|
+
|
|
30019
|
+
// src/agents/acp/clients/sdk/spawn-sdk-stdio-process.ts
|
|
30000
30020
|
function spawnSdkStdioProcess(options) {
|
|
30001
30021
|
const isWindows = process.platform === "win32";
|
|
30002
30022
|
const child = spawn(options.command[0], options.command.slice(1), {
|
|
30003
30023
|
cwd: options.cwd,
|
|
30004
30024
|
stdio: ["pipe", "pipe", "pipe"],
|
|
30005
|
-
env: process.env,
|
|
30025
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
30006
30026
|
shell: isWindows
|
|
30007
30027
|
});
|
|
30008
30028
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -30586,7 +30606,7 @@ function installBridgeProcessResilience() {
|
|
|
30586
30606
|
}
|
|
30587
30607
|
|
|
30588
30608
|
// src/cli-version.ts
|
|
30589
|
-
var CLI_VERSION = "0.1.
|
|
30609
|
+
var CLI_VERSION = "0.1.73".length > 0 ? "0.1.73" : "0.0.0-dev";
|
|
30590
30610
|
|
|
30591
30611
|
// src/connection/heartbeat/constants.ts
|
|
30592
30612
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -33032,7 +33052,11 @@ __export(claude_code_acp_client_exports, {
|
|
|
33032
33052
|
|
|
33033
33053
|
// src/agents/acp/clients/detect-command-on-path.ts
|
|
33034
33054
|
init_cli_process_interrupt();
|
|
33055
|
+
import { constants } from "node:fs";
|
|
33056
|
+
import { access } from "node:fs/promises";
|
|
33035
33057
|
import { execFile as execFile6 } from "node:child_process";
|
|
33058
|
+
import { homedir as homedir2 } from "node:os";
|
|
33059
|
+
import { join as join6 } from "node:path";
|
|
33036
33060
|
import { promisify as promisify7 } from "node:util";
|
|
33037
33061
|
var execFileAsync5 = promisify7(execFile6);
|
|
33038
33062
|
var COMMAND_ON_PATH_PROBE_TIMEOUT_MS = 750;
|
|
@@ -33049,6 +33073,21 @@ async function execFileShutdownAware(file2, args, timeoutMs) {
|
|
|
33049
33073
|
clearInterval(shutdownPoll);
|
|
33050
33074
|
}
|
|
33051
33075
|
}
|
|
33076
|
+
async function isExecutableFile(filePath) {
|
|
33077
|
+
try {
|
|
33078
|
+
await access(filePath, constants.X_OK);
|
|
33079
|
+
return true;
|
|
33080
|
+
} catch {
|
|
33081
|
+
return false;
|
|
33082
|
+
}
|
|
33083
|
+
}
|
|
33084
|
+
async function isCommandInBridgeAgentDirs(command) {
|
|
33085
|
+
const home = process.env.HOME ?? homedir2();
|
|
33086
|
+
for (const dir of getBridgeAgentPathEntries(home)) {
|
|
33087
|
+
if (await isExecutableFile(join6(dir, command))) return true;
|
|
33088
|
+
}
|
|
33089
|
+
return false;
|
|
33090
|
+
}
|
|
33052
33091
|
async function isCommandOnPath(command, timeoutMs = COMMAND_ON_PATH_PROBE_TIMEOUT_MS) {
|
|
33053
33092
|
if (isCliImmediateShutdownRequested()) return false;
|
|
33054
33093
|
try {
|
|
@@ -33058,8 +33097,18 @@ async function isCommandOnPath(command, timeoutMs = COMMAND_ON_PATH_PROBE_TIMEOU
|
|
|
33058
33097
|
});
|
|
33059
33098
|
return true;
|
|
33060
33099
|
} catch {
|
|
33061
|
-
return
|
|
33100
|
+
return isCommandInBridgeAgentDirs(command);
|
|
33101
|
+
}
|
|
33102
|
+
}
|
|
33103
|
+
async function waitForCommandOnPath(command, opts = {}) {
|
|
33104
|
+
const maxAttempts = opts.maxAttempts ?? 8;
|
|
33105
|
+
const delayMs = opts.delayMs ?? 400;
|
|
33106
|
+
const timeoutMs = opts.timeoutMs ?? COMMAND_ON_PATH_PROBE_TIMEOUT_MS;
|
|
33107
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
33108
|
+
if (await isCommandOnPath(command, timeoutMs)) return true;
|
|
33109
|
+
if (attempt < maxAttempts - 1) await new Promise((r) => setTimeout(r, delayMs));
|
|
33062
33110
|
}
|
|
33111
|
+
return false;
|
|
33063
33112
|
}
|
|
33064
33113
|
async function execProbeShutdownAware(file2, args, timeoutMs) {
|
|
33065
33114
|
if (isCliImmediateShutdownRequested()) return false;
|
|
@@ -33440,10 +33489,11 @@ function createCursorAcpIncomingLineHandler(deps) {
|
|
|
33440
33489
|
|
|
33441
33490
|
// src/agents/acp/clients/cursor/cursor-json-rpc-acp-transport.ts
|
|
33442
33491
|
function createCursorJsonRpcAcpTransport(deps) {
|
|
33443
|
-
const { send, cancelSessionNotification } = deps;
|
|
33492
|
+
const { send, cancelSessionNotification, skipBrowserAuthenticate } = deps;
|
|
33444
33493
|
return {
|
|
33445
33494
|
initialize: (request) => send("initialize", request),
|
|
33446
33495
|
afterInitialize: async () => {
|
|
33496
|
+
if (skipBrowserAuthenticate) return;
|
|
33447
33497
|
await send("authenticate", { methodId: "cursor_login" });
|
|
33448
33498
|
},
|
|
33449
33499
|
resumeSession: (p) => send("session/resume", p),
|
|
@@ -33552,7 +33602,8 @@ async function initCursorAcpWire(options) {
|
|
|
33552
33602
|
rl.on("line", (line) => incoming.handleLine(line));
|
|
33553
33603
|
const transport = createCursorJsonRpcAcpTransport({
|
|
33554
33604
|
send: wire.send,
|
|
33555
|
-
cancelSessionNotification: wire.cancelSessionNotification
|
|
33605
|
+
cancelSessionNotification: wire.cancelSessionNotification,
|
|
33606
|
+
skipBrowserAuthenticate: options.skipBrowserAuthenticate
|
|
33556
33607
|
});
|
|
33557
33608
|
const established = await bootstrapAcpWireSession(transport, options.sessionCtx, CURSOR_ACP_CLIENT_INFO);
|
|
33558
33609
|
return { wire, transport, established, incoming, pendingRequests: pendingRequests2 };
|
|
@@ -33565,7 +33616,7 @@ function spawnCursorAcpProcess(options) {
|
|
|
33565
33616
|
const child = spawn3(options.command[0], options.command.slice(1), {
|
|
33566
33617
|
cwd: options.cwd,
|
|
33567
33618
|
stdio: ["pipe", "pipe", "pipe"],
|
|
33568
|
-
env: process.env,
|
|
33619
|
+
env: bridgeInstalledAgentAuthProcessEnv(process.env),
|
|
33569
33620
|
shell: isWindows
|
|
33570
33621
|
});
|
|
33571
33622
|
const stderrCapture = createStderrCapture(child);
|
|
@@ -33597,11 +33648,13 @@ async function createCursorAcpClient(options) {
|
|
|
33597
33648
|
onAgentSubprocessExit
|
|
33598
33649
|
} = options;
|
|
33599
33650
|
const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
|
|
33651
|
+
const spawnEnv = bridgeInstalledAgentAuthProcessEnv(process.env);
|
|
33600
33652
|
const { child, stderrCapture } = spawnCursorAcpProcess({
|
|
33601
33653
|
command,
|
|
33602
33654
|
cwd,
|
|
33603
33655
|
onAgentSubprocessExit
|
|
33604
33656
|
});
|
|
33657
|
+
const skipBrowserAuthenticate = cursorAgentUsesApiKeyAuth(spawnEnv);
|
|
33605
33658
|
const sessionCtx = createCursorAcpSessionContext({
|
|
33606
33659
|
cwd,
|
|
33607
33660
|
mcpServers: options.mcpServers,
|
|
@@ -33624,6 +33677,7 @@ async function createCursorAcpClient(options) {
|
|
|
33624
33677
|
const { wire, transport, established, incoming, pendingRequests: pendingRequests2 } = await initCursorAcpWire({
|
|
33625
33678
|
child,
|
|
33626
33679
|
sessionCtx,
|
|
33680
|
+
skipBrowserAuthenticate,
|
|
33627
33681
|
incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
|
|
33628
33682
|
});
|
|
33629
33683
|
resolve35(
|
|
@@ -34700,11 +34754,11 @@ init_cli_process_interrupt();
|
|
|
34700
34754
|
var BRIDGE_MCP_SERVER_NAME2 = "buildautomaton-bridge";
|
|
34701
34755
|
|
|
34702
34756
|
// src/mcp/resolve-bridge-mcp-server-path.ts
|
|
34703
|
-
import { dirname as dirname7, join as
|
|
34757
|
+
import { dirname as dirname7, join as join7 } from "node:path";
|
|
34704
34758
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
34705
34759
|
function resolveBridgeMcpServerScriptPath() {
|
|
34706
34760
|
const cliDir = dirname7(fileURLToPath7(import.meta.url));
|
|
34707
|
-
return
|
|
34761
|
+
return join7(cliDir, "bridge-mcp-server.js");
|
|
34708
34762
|
}
|
|
34709
34763
|
|
|
34710
34764
|
// src/mcp/build-acp-mcp-servers.ts
|
|
@@ -48479,6 +48533,7 @@ function buildBridgeUrl(apiUrl, workspaceId, authToken) {
|
|
|
48479
48533
|
var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
48480
48534
|
"auth_token",
|
|
48481
48535
|
"bridge_identified",
|
|
48536
|
+
"installed_agent_auth_sync",
|
|
48482
48537
|
"ha",
|
|
48483
48538
|
"preview_environments_config",
|
|
48484
48539
|
"preview_environment_control",
|
|
@@ -48567,6 +48622,16 @@ var handleBridgeIdentified = (msg, deps) => {
|
|
|
48567
48622
|
});
|
|
48568
48623
|
};
|
|
48569
48624
|
|
|
48625
|
+
// src/routing/handlers/installed-agent-auth-sync.ts
|
|
48626
|
+
var handleInstalledAgentAuthSync = (msg) => {
|
|
48627
|
+
const entries = Array.isArray(msg.entries) ? msg.entries : [];
|
|
48628
|
+
setBridgeInstalledAgentAuthEnv(
|
|
48629
|
+
entries.filter(
|
|
48630
|
+
(e) => e != null && typeof e === "object" && typeof e.envVar === "string" && typeof e.token === "string"
|
|
48631
|
+
)
|
|
48632
|
+
);
|
|
48633
|
+
};
|
|
48634
|
+
|
|
48570
48635
|
// src/connection/heartbeat/ack.ts
|
|
48571
48636
|
var handleBridgeHeartbeatAck = (msg, deps) => {
|
|
48572
48637
|
const raw = msg.s;
|
|
@@ -48583,6 +48648,9 @@ function dispatchBridgeConnectionMessage(msg, deps) {
|
|
|
48583
48648
|
case "bridge_identified":
|
|
48584
48649
|
handleBridgeIdentified(msg, deps);
|
|
48585
48650
|
break;
|
|
48651
|
+
case "installed_agent_auth_sync":
|
|
48652
|
+
handleInstalledAgentAuthSync(msg, deps);
|
|
48653
|
+
break;
|
|
48586
48654
|
case "ha":
|
|
48587
48655
|
handleBridgeHeartbeatAck(msg, deps);
|
|
48588
48656
|
break;
|
|
@@ -49724,9 +49792,22 @@ var handleInstallSkillsMessage = (msg, deps) => {
|
|
|
49724
49792
|
// src/agents/install/commands/run-npm-global-install.ts
|
|
49725
49793
|
import { execFile as execFile9 } from "node:child_process";
|
|
49726
49794
|
import { promisify as promisify10 } from "node:util";
|
|
49795
|
+
|
|
49796
|
+
// src/agents/install/format-command-output.ts
|
|
49797
|
+
function formatCommandOutput(stdout, stderr) {
|
|
49798
|
+
const parts = [String(stdout ?? "").trimEnd(), String(stderr ?? "").trimEnd()].filter(Boolean);
|
|
49799
|
+
return parts.join("\n");
|
|
49800
|
+
}
|
|
49801
|
+
|
|
49802
|
+
// src/agents/install/commands/run-npm-global-install.ts
|
|
49727
49803
|
var execFileAsync8 = promisify10(execFile9);
|
|
49728
49804
|
async function runNpmGlobalInstall(packageName, env, timeoutMs = 3e5) {
|
|
49729
|
-
await execFileAsync8("npm", ["install", "-g", packageName], {
|
|
49805
|
+
const { stdout, stderr } = await execFileAsync8("npm", ["install", "-g", packageName], {
|
|
49806
|
+
timeout: timeoutMs,
|
|
49807
|
+
env: bridgeAgentPathEnv(env),
|
|
49808
|
+
maxBuffer: 10 * 1024 * 1024
|
|
49809
|
+
});
|
|
49810
|
+
return formatCommandOutput(stdout, stderr);
|
|
49730
49811
|
}
|
|
49731
49812
|
|
|
49732
49813
|
// src/agents/install/commands/claude-code.ts
|
|
@@ -49734,11 +49815,11 @@ var claudeCodeInstallCommand = {
|
|
|
49734
49815
|
agentType: "claude-code",
|
|
49735
49816
|
detectCommand: "claude",
|
|
49736
49817
|
async install(ctx) {
|
|
49737
|
-
|
|
49738
|
-
await runNpmGlobalInstall("@anthropic-ai/claude-code", {
|
|
49818
|
+
const logOutput = await runNpmGlobalInstall("@anthropic-ai/claude-code", {
|
|
49739
49819
|
...ctx.env,
|
|
49740
49820
|
ANTHROPIC_API_KEY: ctx.authToken
|
|
49741
49821
|
});
|
|
49822
|
+
ctx.onProgress?.("Installing Anthropic Claude Code", logOutput || void 0);
|
|
49742
49823
|
}
|
|
49743
49824
|
};
|
|
49744
49825
|
|
|
@@ -49747,11 +49828,11 @@ var codexAcpInstallCommand = {
|
|
|
49747
49828
|
agentType: "codex-acp",
|
|
49748
49829
|
detectCommand: "codex",
|
|
49749
49830
|
async install(ctx) {
|
|
49750
|
-
|
|
49751
|
-
await runNpmGlobalInstall("@openai/codex", {
|
|
49831
|
+
const logOutput = await runNpmGlobalInstall("@openai/codex", {
|
|
49752
49832
|
...ctx.env,
|
|
49753
49833
|
OPENAI_API_KEY: ctx.authToken
|
|
49754
49834
|
});
|
|
49835
|
+
ctx.onProgress?.("Installing Codex", logOutput || void 0);
|
|
49755
49836
|
}
|
|
49756
49837
|
};
|
|
49757
49838
|
|
|
@@ -49762,12 +49843,19 @@ var execFileAsync9 = promisify11(execFile10);
|
|
|
49762
49843
|
var cursorCliInstallCommand = {
|
|
49763
49844
|
agentType: "cursor-cli",
|
|
49764
49845
|
detectCommand: "agent",
|
|
49846
|
+
alternateDetectCommands: ["cursor-agent"],
|
|
49765
49847
|
async install(ctx) {
|
|
49766
|
-
|
|
49767
|
-
|
|
49768
|
-
|
|
49769
|
-
|
|
49770
|
-
|
|
49848
|
+
const { stdout, stderr } = await execFileAsync9(
|
|
49849
|
+
"bash",
|
|
49850
|
+
["-lc", "curl -fsSL https://cursor.com/install | bash"],
|
|
49851
|
+
{
|
|
49852
|
+
timeout: 3e5,
|
|
49853
|
+
env: { ...bridgeAgentPathEnv(ctx.env), CURSOR_API_KEY: ctx.authToken },
|
|
49854
|
+
maxBuffer: 10 * 1024 * 1024
|
|
49855
|
+
}
|
|
49856
|
+
);
|
|
49857
|
+
const logOutput = formatCommandOutput(stdout, stderr);
|
|
49858
|
+
ctx.onProgress?.("Installing Cursor CLI", logOutput || void 0);
|
|
49771
49859
|
}
|
|
49772
49860
|
};
|
|
49773
49861
|
|
|
@@ -49776,11 +49864,11 @@ var opencodeInstallCommand = {
|
|
|
49776
49864
|
agentType: "opencode",
|
|
49777
49865
|
detectCommand: "opencode",
|
|
49778
49866
|
async install(ctx) {
|
|
49779
|
-
|
|
49780
|
-
await runNpmGlobalInstall("opencode-ai", {
|
|
49867
|
+
const logOutput = await runNpmGlobalInstall("opencode-ai", {
|
|
49781
49868
|
...ctx.env,
|
|
49782
49869
|
OPENCODE_API_KEY: ctx.authToken
|
|
49783
49870
|
});
|
|
49871
|
+
ctx.onProgress?.("Installing OpenCode", logOutput || void 0);
|
|
49784
49872
|
}
|
|
49785
49873
|
};
|
|
49786
49874
|
|
|
@@ -49814,7 +49902,17 @@ async function installLocalAgentOnBridge(params) {
|
|
|
49814
49902
|
return { success: false, error: msg };
|
|
49815
49903
|
}
|
|
49816
49904
|
ensureBridgeAgentPathInProcessEnv();
|
|
49817
|
-
const
|
|
49905
|
+
const detectNames = [
|
|
49906
|
+
command.detectCommand,
|
|
49907
|
+
...command.alternateDetectCommands ?? []
|
|
49908
|
+
];
|
|
49909
|
+
let found = false;
|
|
49910
|
+
for (const name of detectNames) {
|
|
49911
|
+
if (await waitForCommandOnPath(name)) {
|
|
49912
|
+
found = true;
|
|
49913
|
+
break;
|
|
49914
|
+
}
|
|
49915
|
+
}
|
|
49818
49916
|
if (!found) {
|
|
49819
49917
|
return { success: false, error: `${command.detectCommand} not found on PATH after install` };
|
|
49820
49918
|
}
|
|
@@ -49831,7 +49929,7 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
49831
49929
|
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
49832
49930
|
void (async () => {
|
|
49833
49931
|
const socket = deps.getWs();
|
|
49834
|
-
const report = (step, message) => {
|
|
49932
|
+
const report = (step, message, logOutput) => {
|
|
49835
49933
|
if (socket) {
|
|
49836
49934
|
sendWsMessage(socket, {
|
|
49837
49935
|
type: "install_agent_progress",
|
|
@@ -49840,14 +49938,15 @@ var handleInstallAgentMessage = (msg, deps) => {
|
|
|
49840
49938
|
tokenId,
|
|
49841
49939
|
agentType,
|
|
49842
49940
|
step,
|
|
49843
|
-
message
|
|
49941
|
+
message,
|
|
49942
|
+
...logOutput ? { logOutput } : {}
|
|
49844
49943
|
});
|
|
49845
49944
|
}
|
|
49846
49945
|
};
|
|
49847
49946
|
const result = await installLocalAgentOnBridge({
|
|
49848
49947
|
agentType,
|
|
49849
49948
|
authToken,
|
|
49850
|
-
onProgress: (message) => report("agent_install_package", message)
|
|
49949
|
+
onProgress: (message, logOutput) => report("agent_install_package", message, logOutput)
|
|
49851
49950
|
});
|
|
49852
49951
|
if (socket) {
|
|
49853
49952
|
sendWsMessage(socket, {
|
|
@@ -50232,6 +50331,7 @@ function dispatchBridgeMessage(msg, deps) {
|
|
|
50232
50331
|
switch (msg.type) {
|
|
50233
50332
|
case "auth_token":
|
|
50234
50333
|
case "bridge_identified":
|
|
50334
|
+
case "installed_agent_auth_sync":
|
|
50235
50335
|
case "ha":
|
|
50236
50336
|
dispatchBridgeConnectionMessage(msg, deps);
|
|
50237
50337
|
break;
|