@buildautomaton/cli 0.1.69 → 0.1.71
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 +784 -511
- package/dist/cli.js.map +4 -4
- package/dist/index.js +872 -599
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22367,14 +22367,14 @@ var init_access = __esm({
|
|
|
22367
22367
|
|
|
22368
22368
|
// src/sqlite/read-migration-sql.ts
|
|
22369
22369
|
import { existsSync, readFileSync as readFileSync2 } from "node:fs";
|
|
22370
|
-
import { dirname as dirname2, join } from "node:path";
|
|
22370
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
22371
22371
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
22372
22372
|
function readMigrationSql(filename, ...searchSubdirs) {
|
|
22373
22373
|
const moduleDir = dirname2(fileURLToPath2(import.meta.url));
|
|
22374
22374
|
const candidates = searchSubdirs.flatMap((sub) => [
|
|
22375
|
-
|
|
22376
|
-
|
|
22377
|
-
|
|
22375
|
+
join2(moduleDir, sub, filename),
|
|
22376
|
+
join2(moduleDir, "..", sub, filename),
|
|
22377
|
+
join2(moduleDir, "..", "..", "dist", sub, filename)
|
|
22378
22378
|
]);
|
|
22379
22379
|
const resolved = candidates.find((path82) => existsSync(path82));
|
|
22380
22380
|
if (!resolved) {
|
|
@@ -25255,26 +25255,26 @@ var init_member_access = __esm({
|
|
|
25255
25255
|
|
|
25256
25256
|
// src/code-nav/tree-sitter-assets-dir.ts
|
|
25257
25257
|
import { existsSync as existsSync2 } from "node:fs";
|
|
25258
|
-
import { dirname as dirname3, join as
|
|
25258
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
25259
25259
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
25260
25260
|
function repoNodeModulesDir(fromDir) {
|
|
25261
|
-
return
|
|
25261
|
+
return join3(fromDir, "..", "..", "..", "node_modules");
|
|
25262
25262
|
}
|
|
25263
25263
|
function firstDirWithWebTreeSitterWasm(candidates) {
|
|
25264
25264
|
for (const dir of candidates) {
|
|
25265
|
-
if (existsSync2(
|
|
25265
|
+
if (existsSync2(join3(dir, "web-tree-sitter.wasm"))) return dir;
|
|
25266
25266
|
}
|
|
25267
25267
|
return null;
|
|
25268
25268
|
}
|
|
25269
25269
|
function getTreeSitterAssetsDir() {
|
|
25270
25270
|
const moduleDir = dirname3(fileURLToPath3(import.meta.url));
|
|
25271
25271
|
const fromModule = firstDirWithWebTreeSitterWasm([
|
|
25272
|
-
|
|
25273
|
-
|
|
25274
|
-
|
|
25272
|
+
join3(moduleDir, "tree-sitter"),
|
|
25273
|
+
join3(moduleDir, "..", "tree-sitter"),
|
|
25274
|
+
join3(moduleDir, "..", "..", "dist", "tree-sitter")
|
|
25275
25275
|
]);
|
|
25276
25276
|
if (fromModule) return fromModule;
|
|
25277
|
-
const fromNodeModules = firstDirWithWebTreeSitterWasm([
|
|
25277
|
+
const fromNodeModules = firstDirWithWebTreeSitterWasm([join3(repoNodeModulesDir(moduleDir), "web-tree-sitter")]);
|
|
25278
25278
|
if (fromNodeModules) return fromNodeModules;
|
|
25279
25279
|
throw new Error(
|
|
25280
25280
|
"Missing web-tree-sitter.wasm. Run `pnpm build` in packages/cli to copy tree-sitter assets into dist/tree-sitter."
|
|
@@ -25288,7 +25288,7 @@ var init_tree_sitter_assets_dir = __esm({
|
|
|
25288
25288
|
|
|
25289
25289
|
// src/code-nav/parser/tree-sitter-runtime.ts
|
|
25290
25290
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
25291
|
-
import { dirname as dirname4, join as
|
|
25291
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
25292
25292
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
25293
25293
|
import { Parser, Language, Query, LANGUAGE_VERSION, MIN_COMPATIBLE_VERSION } from "web-tree-sitter";
|
|
25294
25294
|
function withTreeSitterRuntimeLock(fn) {
|
|
@@ -25303,7 +25303,7 @@ async function ensureParserInit() {
|
|
|
25303
25303
|
if (!initPromise2) {
|
|
25304
25304
|
const assetsDir = getTreeSitterAssetsDir();
|
|
25305
25305
|
initPromise2 = Parser.init({
|
|
25306
|
-
locateFile: (scriptName) =>
|
|
25306
|
+
locateFile: (scriptName) => join4(assetsDir, scriptName)
|
|
25307
25307
|
}).catch((e) => {
|
|
25308
25308
|
initPromise2 = null;
|
|
25309
25309
|
throw e;
|
|
@@ -25313,9 +25313,9 @@ async function ensureParserInit() {
|
|
|
25313
25313
|
}
|
|
25314
25314
|
function resolveWasmPath(assetsDir, wasmFile) {
|
|
25315
25315
|
const candidates = [
|
|
25316
|
-
|
|
25317
|
-
|
|
25318
|
-
|
|
25316
|
+
join4(assetsDir, wasmFile),
|
|
25317
|
+
join4(assetsDir, "..", "..", "dist", "tree-sitter", wasmFile),
|
|
25318
|
+
join4(assetsDir, "..", "..", "..", "node_modules", wasmFile.replace(".wasm", ""), wasmFile)
|
|
25319
25319
|
];
|
|
25320
25320
|
const hit = candidates.find((p) => existsSync3(p));
|
|
25321
25321
|
if (!hit) throw new Error(`Missing tree-sitter wasm: ${wasmFile}`);
|
|
@@ -25324,10 +25324,10 @@ function resolveWasmPath(assetsDir, wasmFile) {
|
|
|
25324
25324
|
function resolveTagsPath(assetsDir, tagsQueryFile) {
|
|
25325
25325
|
const pkgName = tagsQueryFile.split("/")[0] ?? "";
|
|
25326
25326
|
const candidates = [
|
|
25327
|
-
|
|
25328
|
-
|
|
25329
|
-
|
|
25330
|
-
|
|
25327
|
+
join4(CODE_NAV_QUERIES_ROOT, tagsQueryFile),
|
|
25328
|
+
join4(assetsDir, tagsQueryFile),
|
|
25329
|
+
join4(assetsDir, "..", "..", "dist", "tree-sitter", tagsQueryFile),
|
|
25330
|
+
join4(assetsDir, "..", "..", "..", "node_modules", pkgName, "queries", "tags.scm")
|
|
25331
25331
|
];
|
|
25332
25332
|
const hit = candidates.find((p) => existsSync3(p));
|
|
25333
25333
|
if (!hit) throw new Error(`Missing tags query: ${tagsQueryFile}`);
|
|
@@ -25365,7 +25365,7 @@ var init_tree_sitter_runtime = __esm({
|
|
|
25365
25365
|
loadedByKey = /* @__PURE__ */ new Map();
|
|
25366
25366
|
failedLanguageKeys = /* @__PURE__ */ new Set();
|
|
25367
25367
|
runtimeChain = Promise.resolve();
|
|
25368
|
-
CODE_NAV_QUERIES_ROOT =
|
|
25368
|
+
CODE_NAV_QUERIES_ROOT = join4(dirname4(fileURLToPath4(import.meta.url)), "..", "queries");
|
|
25369
25369
|
}
|
|
25370
25370
|
});
|
|
25371
25371
|
|
|
@@ -26936,7 +26936,7 @@ var init_in_process_bridge = __esm({
|
|
|
26936
26936
|
});
|
|
26937
26937
|
|
|
26938
26938
|
// src/code-nav/symbol-index/worker/lifecycle/state.ts
|
|
26939
|
-
import { dirname as dirname5, join as
|
|
26939
|
+
import { dirname as dirname5, join as join5 } from "node:path";
|
|
26940
26940
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
26941
26941
|
function getWorker() {
|
|
26942
26942
|
return worker;
|
|
@@ -26955,7 +26955,7 @@ function shouldUseInProcessWorker() {
|
|
|
26955
26955
|
}
|
|
26956
26956
|
function resolveWorkerScriptPath() {
|
|
26957
26957
|
const moduleDir = dirname5(fileURLToPath5(import.meta.url));
|
|
26958
|
-
return
|
|
26958
|
+
return join5(moduleDir, "..", "worker.js");
|
|
26959
26959
|
}
|
|
26960
26960
|
function resetLifecycleStateForTests() {
|
|
26961
26961
|
terminatePromise = null;
|
|
@@ -29341,6 +29341,18 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
29341
29341
|
return t !== "" ? t : null;
|
|
29342
29342
|
}
|
|
29343
29343
|
|
|
29344
|
+
// ../types/src/overview/heatmap/constants.ts
|
|
29345
|
+
var HOUR_MS = 36e5;
|
|
29346
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
29347
|
+
|
|
29348
|
+
// ../types/src/bridges/agents/types.ts
|
|
29349
|
+
var INSTALLABLE_BRIDGE_AGENTS = [
|
|
29350
|
+
{ value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
|
|
29351
|
+
{ value: "codex-acp", label: "Codex", tokenLabel: "OpenAI API key", tokenEnvVar: "OPENAI_API_KEY" },
|
|
29352
|
+
{ value: "cursor-cli", label: "Cursor CLI agent", tokenLabel: "Cursor API key", tokenEnvVar: "CURSOR_API_KEY" },
|
|
29353
|
+
{ value: "opencode", label: "OpenCode agent", tokenLabel: "Provider API key", tokenEnvVar: "OPENCODE_API_KEY" }
|
|
29354
|
+
];
|
|
29355
|
+
|
|
29344
29356
|
// src/agents/acp/safe-fs-path.ts
|
|
29345
29357
|
import * as path2 from "node:path";
|
|
29346
29358
|
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
@@ -30574,7 +30586,7 @@ function installBridgeProcessResilience() {
|
|
|
30574
30586
|
}
|
|
30575
30587
|
|
|
30576
30588
|
// src/cli-version.ts
|
|
30577
|
-
var CLI_VERSION = "0.1.
|
|
30589
|
+
var CLI_VERSION = "0.1.71".length > 0 ? "0.1.71" : "0.0.0-dev";
|
|
30578
30590
|
|
|
30579
30591
|
// src/connection/heartbeat/constants.ts
|
|
30580
30592
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -31696,6 +31708,46 @@ function runPendingAuth(options) {
|
|
|
31696
31708
|
// src/run-bridge-connected.ts
|
|
31697
31709
|
init_log();
|
|
31698
31710
|
|
|
31711
|
+
// src/agents/acp/clients/bridge-agent-path.ts
|
|
31712
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
31713
|
+
import { homedir } from "node:os";
|
|
31714
|
+
import { join } from "node:path";
|
|
31715
|
+
function getBridgeAgentPathEntries(home = process.env.HOME ?? homedir()) {
|
|
31716
|
+
const entries = [
|
|
31717
|
+
join(home, ".local", "bin"),
|
|
31718
|
+
join(home, ".npm-global", "bin"),
|
|
31719
|
+
"/usr/local/bin"
|
|
31720
|
+
];
|
|
31721
|
+
const prefix = process.env.NPM_CONFIG_PREFIX;
|
|
31722
|
+
if (prefix) entries.push(join(prefix, "bin"));
|
|
31723
|
+
try {
|
|
31724
|
+
const npmBin = execFileSync2("npm", ["bin", "-g"], { encoding: "utf8", timeout: 2e3 }).trim();
|
|
31725
|
+
if (npmBin) entries.push(npmBin);
|
|
31726
|
+
} catch {
|
|
31727
|
+
}
|
|
31728
|
+
return entries;
|
|
31729
|
+
}
|
|
31730
|
+
function augmentPath(pathValue, extra) {
|
|
31731
|
+
const current = pathValue ?? "";
|
|
31732
|
+
const parts = current.split(":").filter(Boolean);
|
|
31733
|
+
const seen = new Set(parts);
|
|
31734
|
+
const prefix = [];
|
|
31735
|
+
for (const entry of extra) {
|
|
31736
|
+
if (!entry || seen.has(entry)) continue;
|
|
31737
|
+
seen.add(entry);
|
|
31738
|
+
prefix.push(entry);
|
|
31739
|
+
}
|
|
31740
|
+
if (prefix.length === 0) return current;
|
|
31741
|
+
return current ? `${prefix.join(":")}:${current}` : prefix.join(":");
|
|
31742
|
+
}
|
|
31743
|
+
function ensureBridgeAgentPathInProcessEnv() {
|
|
31744
|
+
const extra = getBridgeAgentPathEntries();
|
|
31745
|
+
process.env.PATH = augmentPath(process.env.PATH, extra);
|
|
31746
|
+
}
|
|
31747
|
+
function bridgeAgentPathEnv(base = process.env) {
|
|
31748
|
+
return { ...base, PATH: augmentPath(base.PATH, getBridgeAgentPathEntries()) };
|
|
31749
|
+
}
|
|
31750
|
+
|
|
31699
31751
|
// src/files/watch-file-index.ts
|
|
31700
31752
|
import path25 from "node:path";
|
|
31701
31753
|
|
|
@@ -33000,7 +33052,10 @@ async function execFileShutdownAware(file2, args, timeoutMs) {
|
|
|
33000
33052
|
async function isCommandOnPath(command, timeoutMs = COMMAND_ON_PATH_PROBE_TIMEOUT_MS) {
|
|
33001
33053
|
if (isCliImmediateShutdownRequested()) return false;
|
|
33002
33054
|
try {
|
|
33003
|
-
await
|
|
33055
|
+
await execFileAsync5("which", [command], {
|
|
33056
|
+
timeout: timeoutMs,
|
|
33057
|
+
env: bridgeAgentPathEnv()
|
|
33058
|
+
});
|
|
33004
33059
|
return true;
|
|
33005
33060
|
} catch {
|
|
33006
33061
|
return false;
|
|
@@ -33692,15 +33747,15 @@ function resolveAgentCommand(preferredAgentType) {
|
|
|
33692
33747
|
}
|
|
33693
33748
|
|
|
33694
33749
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
33695
|
-
import { execFileSync as
|
|
33750
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
33696
33751
|
import { existsSync as existsSync4, statSync } from "node:fs";
|
|
33697
33752
|
|
|
33698
33753
|
// src/git/get-git-repo-root-sync.ts
|
|
33699
|
-
import { execFileSync as
|
|
33754
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
33700
33755
|
import * as path27 from "node:path";
|
|
33701
33756
|
function getGitRepoRootSync(startDir) {
|
|
33702
33757
|
try {
|
|
33703
|
-
const out =
|
|
33758
|
+
const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
|
|
33704
33759
|
cwd: path27.resolve(startDir),
|
|
33705
33760
|
encoding: "utf8",
|
|
33706
33761
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -33713,7 +33768,7 @@ function getGitRepoRootSync(startDir) {
|
|
|
33713
33768
|
}
|
|
33714
33769
|
|
|
33715
33770
|
// src/agents/acp/workspace-files.ts
|
|
33716
|
-
import { execFileSync as
|
|
33771
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
33717
33772
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
33718
33773
|
import * as path28 from "node:path";
|
|
33719
33774
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
@@ -33774,7 +33829,7 @@ function readGitHeadBlob(sessionParentPath, displayPath) {
|
|
|
33774
33829
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
33775
33830
|
const execCwd = gitRoot ?? sessionParentPath;
|
|
33776
33831
|
try {
|
|
33777
|
-
return
|
|
33832
|
+
return execFileSync4("git", ["show", `HEAD:${displayPath}`], {
|
|
33778
33833
|
cwd: execCwd,
|
|
33779
33834
|
encoding: "utf8",
|
|
33780
33835
|
maxBuffer: 50 * 1024 * 1024
|
|
@@ -33790,7 +33845,7 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
|
33790
33845
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
33791
33846
|
if (!gitRoot) return null;
|
|
33792
33847
|
try {
|
|
33793
|
-
return
|
|
33848
|
+
return execFileSync5("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
33794
33849
|
cwd: gitRoot,
|
|
33795
33850
|
encoding: "utf8"
|
|
33796
33851
|
}).trim();
|
|
@@ -34645,11 +34700,11 @@ init_cli_process_interrupt();
|
|
|
34645
34700
|
var BRIDGE_MCP_SERVER_NAME2 = "buildautomaton-bridge";
|
|
34646
34701
|
|
|
34647
34702
|
// src/mcp/resolve-bridge-mcp-server-path.ts
|
|
34648
|
-
import { dirname as dirname7, join as
|
|
34703
|
+
import { dirname as dirname7, join as join6 } from "node:path";
|
|
34649
34704
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
34650
34705
|
function resolveBridgeMcpServerScriptPath() {
|
|
34651
34706
|
const cliDir = dirname7(fileURLToPath7(import.meta.url));
|
|
34652
|
-
return
|
|
34707
|
+
return join6(cliDir, "bridge-mcp-server.js");
|
|
34653
34708
|
}
|
|
34654
34709
|
|
|
34655
34710
|
// src/mcp/build-acp-mcp-servers.ts
|
|
@@ -48443,6 +48498,7 @@ var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
|
48443
48498
|
"code_nav",
|
|
48444
48499
|
"skill_layout_request",
|
|
48445
48500
|
"install_skills",
|
|
48501
|
+
"install_agent",
|
|
48446
48502
|
"refresh_local_skills",
|
|
48447
48503
|
"bridge_git_context_request",
|
|
48448
48504
|
"list_repo_branches_request"
|
|
@@ -48518,6 +48574,100 @@ var handleBridgeHeartbeatAck = (msg, deps) => {
|
|
|
48518
48574
|
deps.onBridgeHeartbeatAck?.(Math.trunc(raw));
|
|
48519
48575
|
};
|
|
48520
48576
|
|
|
48577
|
+
// src/routing/dispatch/connection.ts
|
|
48578
|
+
function dispatchBridgeConnectionMessage(msg, deps) {
|
|
48579
|
+
switch (msg.type) {
|
|
48580
|
+
case "auth_token":
|
|
48581
|
+
handleAuthToken(msg, deps);
|
|
48582
|
+
break;
|
|
48583
|
+
case "bridge_identified":
|
|
48584
|
+
handleBridgeIdentified(msg, deps);
|
|
48585
|
+
break;
|
|
48586
|
+
case "ha":
|
|
48587
|
+
handleBridgeHeartbeatAck(msg, deps);
|
|
48588
|
+
break;
|
|
48589
|
+
}
|
|
48590
|
+
}
|
|
48591
|
+
|
|
48592
|
+
// src/routing/handlers/preview-environment-control.ts
|
|
48593
|
+
var handlePreviewEnvironmentControl = (msg, deps) => {
|
|
48594
|
+
let wire;
|
|
48595
|
+
try {
|
|
48596
|
+
wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
|
|
48597
|
+
} catch (e) {
|
|
48598
|
+
deps.log(`[E2EE] Could not decrypt preview environment command: ${e instanceof Error ? e.message : String(e)}`);
|
|
48599
|
+
return;
|
|
48600
|
+
}
|
|
48601
|
+
const environmentId = typeof wire.environmentId === "string" ? wire.environmentId : "";
|
|
48602
|
+
const action = wire.action === "start" || wire.action === "stop" ? wire.action : null;
|
|
48603
|
+
if (!environmentId || !action) return;
|
|
48604
|
+
deps.previewEnvironmentManager?.handleControl(environmentId, action);
|
|
48605
|
+
};
|
|
48606
|
+
|
|
48607
|
+
// src/routing/handlers/preview-environments-config.ts
|
|
48608
|
+
var VALID_PORT = (p) => typeof p === "number" && Number.isInteger(p) && p > 0 && p < 65536;
|
|
48609
|
+
var handlePreviewEnvironmentsConfig = (msg, deps) => {
|
|
48610
|
+
const previewEnvironments = msg.previewEnvironments;
|
|
48611
|
+
const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts.filter(VALID_PORT) : void 0;
|
|
48612
|
+
setImmediate(() => {
|
|
48613
|
+
deps.previewEnvironmentManager?.applyConfig(previewEnvironments ?? []);
|
|
48614
|
+
const environmentIds = parsePreviewEnvironmentDefs(previewEnvironments ?? []).map((d) => d.environmentId);
|
|
48615
|
+
void deps.previewWorktreeManager?.syncConfiguredEnvironments(environmentIds);
|
|
48616
|
+
if (proxyPorts !== void 0) {
|
|
48617
|
+
deps.updateFirehoseProxyPorts?.(proxyPorts);
|
|
48618
|
+
}
|
|
48619
|
+
});
|
|
48620
|
+
};
|
|
48621
|
+
|
|
48622
|
+
// src/routing/handlers/send-deploy-session-to-preview-result.ts
|
|
48623
|
+
function sendDeploySessionToPreviewResult(ws, id, payload) {
|
|
48624
|
+
if (!ws) return;
|
|
48625
|
+
sendWsMessage(ws, { type: "deploy_session_to_preview_result", id, ...payload });
|
|
48626
|
+
}
|
|
48627
|
+
|
|
48628
|
+
// src/routing/handlers/deploy-session-to-preview.ts
|
|
48629
|
+
var handleDeploySessionToPreviewMessage = (msg, deps) => {
|
|
48630
|
+
if (typeof msg.id !== "string") return;
|
|
48631
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
48632
|
+
const environmentId = typeof msg.environmentId === "string" ? msg.environmentId : "";
|
|
48633
|
+
if (!sessionId || !environmentId) return;
|
|
48634
|
+
void (async () => {
|
|
48635
|
+
const ws = deps.getWs();
|
|
48636
|
+
const reply = (payload) => sendDeploySessionToPreviewResult(ws, msg.id, payload);
|
|
48637
|
+
try {
|
|
48638
|
+
if (!deps.previewWorktreeManager) {
|
|
48639
|
+
reply({ ok: false, error: "Preview worktree manager unavailable" });
|
|
48640
|
+
return;
|
|
48641
|
+
}
|
|
48642
|
+
const result = await deploySessionToPreviewEnvironment({
|
|
48643
|
+
sessionWorktreeManager: deps.sessionWorktreeManager,
|
|
48644
|
+
previewWorktreeManager: deps.previewWorktreeManager,
|
|
48645
|
+
sessionId,
|
|
48646
|
+
environmentId,
|
|
48647
|
+
log: deps.log
|
|
48648
|
+
});
|
|
48649
|
+
reply(result);
|
|
48650
|
+
} catch (e) {
|
|
48651
|
+
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
48652
|
+
}
|
|
48653
|
+
})();
|
|
48654
|
+
};
|
|
48655
|
+
|
|
48656
|
+
// src/routing/dispatch/preview.ts
|
|
48657
|
+
function dispatchBridgePreviewMessage(msg, deps) {
|
|
48658
|
+
switch (msg.type) {
|
|
48659
|
+
case "preview_environments_config":
|
|
48660
|
+
handlePreviewEnvironmentsConfig(msg, deps);
|
|
48661
|
+
break;
|
|
48662
|
+
case "preview_environment_control":
|
|
48663
|
+
handlePreviewEnvironmentControl(msg, deps);
|
|
48664
|
+
break;
|
|
48665
|
+
case "deploy_session_to_preview":
|
|
48666
|
+
handleDeploySessionToPreviewMessage(msg, deps);
|
|
48667
|
+
break;
|
|
48668
|
+
}
|
|
48669
|
+
}
|
|
48670
|
+
|
|
48521
48671
|
// src/agents/acp/from-bridge/handle-bridge-agent-config.ts
|
|
48522
48672
|
function handleBridgeAgentConfig(msg, { acpManager }) {
|
|
48523
48673
|
if (!Array.isArray(msg.agents) || msg.agents.length === 0) return;
|
|
@@ -49156,193 +49306,331 @@ var handleSessionRequestResponseMessage = (msg, deps) => {
|
|
|
49156
49306
|
handleBridgeSessionRequestResponse(msg, deps);
|
|
49157
49307
|
};
|
|
49158
49308
|
|
|
49159
|
-
// src/
|
|
49160
|
-
function
|
|
49161
|
-
|
|
49162
|
-
|
|
49163
|
-
|
|
49164
|
-
|
|
49165
|
-
|
|
49309
|
+
// src/routing/handlers/git/handle-session-git-commit.ts
|
|
49310
|
+
async function handleSessionGitCommitAction(deps, sessionId, msg, reply) {
|
|
49311
|
+
const branch = typeof msg.branch === "string" ? msg.branch : "";
|
|
49312
|
+
const message = typeof msg.message === "string" ? msg.message : "";
|
|
49313
|
+
const pushAfterCommit = msg.pushAfterCommit === true;
|
|
49314
|
+
if (!branch.trim() || !message.trim()) {
|
|
49315
|
+
reply({ ok: false, error: "branch and message are required for commit" });
|
|
49316
|
+
return;
|
|
49317
|
+
}
|
|
49318
|
+
const commitRes = await deps.sessionWorktreeManager.commitSession({
|
|
49319
|
+
sessionId,
|
|
49320
|
+
branch: branch.trim(),
|
|
49321
|
+
message: message.trim(),
|
|
49322
|
+
push: pushAfterCommit
|
|
49323
|
+
});
|
|
49324
|
+
if (!commitRes.ok) {
|
|
49325
|
+
reply({ ok: false, error: commitRes.error ?? "Commit failed" });
|
|
49326
|
+
return;
|
|
49327
|
+
}
|
|
49328
|
+
const st = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
|
|
49329
|
+
reply({
|
|
49330
|
+
ok: true,
|
|
49331
|
+
hasUncommittedChanges: st.hasUncommittedChanges,
|
|
49332
|
+
hasUnpushedCommits: st.hasUnpushedCommits,
|
|
49333
|
+
uncommittedFileCount: st.uncommittedFileCount
|
|
49166
49334
|
});
|
|
49167
49335
|
}
|
|
49168
49336
|
|
|
49169
|
-
// src/routing/handlers/
|
|
49170
|
-
|
|
49171
|
-
|
|
49172
|
-
|
|
49173
|
-
|
|
49174
|
-
const
|
|
49175
|
-
if (!
|
|
49176
|
-
|
|
49177
|
-
|
|
49178
|
-
|
|
49179
|
-
|
|
49180
|
-
);
|
|
49181
|
-
|
|
49182
|
-
|
|
49183
|
-
|
|
49184
|
-
|
|
49185
|
-
|
|
49337
|
+
// src/routing/handlers/git/session-git-changes-params.ts
|
|
49338
|
+
function readString(value) {
|
|
49339
|
+
return typeof value === "string" ? value.trim() : "";
|
|
49340
|
+
}
|
|
49341
|
+
function readChangesObject(msg) {
|
|
49342
|
+
const changes = msg.changes;
|
|
49343
|
+
if (!changes || typeof changes !== "object" || Array.isArray(changes)) return null;
|
|
49344
|
+
return changes;
|
|
49345
|
+
}
|
|
49346
|
+
function parseSessionGitChangesParams(msg) {
|
|
49347
|
+
const nested = readChangesObject(msg);
|
|
49348
|
+
const file2 = nested?.file && typeof nested.file === "object" && !Array.isArray(nested.file) ? nested.file : null;
|
|
49349
|
+
const repoRelPath = readString(nested?.repoRelPath) || readString(msg.changesRepoRelPath);
|
|
49350
|
+
const viewRaw = nested?.view ?? msg.changesView;
|
|
49351
|
+
const view = viewRaw === "commit" ? "commit" : "working";
|
|
49352
|
+
const commitSha = readString(nested?.commitSha) || readString(msg.changesCommitSha);
|
|
49353
|
+
const recentCommitsLimit = nested?.recentCommitsLimit ?? msg.changesRecentCommitsLimit;
|
|
49354
|
+
return {
|
|
49355
|
+
repoRelPath,
|
|
49356
|
+
view,
|
|
49357
|
+
commitSha,
|
|
49358
|
+
recentCommitsLimit: typeof recentCommitsLimit === "number" || typeof recentCommitsLimit === "string" ? recentCommitsLimit : void 0,
|
|
49359
|
+
fileWorkspaceRelPath: readString(file2?.workspaceRelPath),
|
|
49360
|
+
fileChange: readString(file2?.change),
|
|
49361
|
+
fileMovedFromWorkspaceRelPath: readString(file2?.movedFromWorkspaceRelPath)
|
|
49362
|
+
};
|
|
49186
49363
|
}
|
|
49187
49364
|
|
|
49188
|
-
// src/
|
|
49189
|
-
async function
|
|
49190
|
-
const
|
|
49191
|
-
|
|
49192
|
-
|
|
49365
|
+
// src/routing/handlers/git/handle-session-git-get-change-file-patch.ts
|
|
49366
|
+
async function handleSessionGitGetChangeFilePatchAction(deps, msg, reply) {
|
|
49367
|
+
const changes = parseSessionGitChangesParams(msg);
|
|
49368
|
+
const { repoRelPath: repoRel, view, commitSha, fileWorkspaceRelPath, fileChange, fileMovedFromWorkspaceRelPath } = changes;
|
|
49369
|
+
const change = parseWorkingTreeChangeKind(fileChange);
|
|
49370
|
+
if (!repoRel || !fileWorkspaceRelPath || !change) {
|
|
49371
|
+
reply({
|
|
49372
|
+
ok: false,
|
|
49373
|
+
error: "changes.repoRelPath, changes.file.workspaceRelPath, and changes.file.change are required"
|
|
49374
|
+
});
|
|
49193
49375
|
return;
|
|
49194
49376
|
}
|
|
49195
|
-
|
|
49196
|
-
}
|
|
49197
|
-
|
|
49198
|
-
// src/files/browser/handle-file-browser-read.ts
|
|
49199
|
-
async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
|
|
49200
|
-
const result = await executeFileBrowserRead({ msg, reqPath, sessionParentPath, gitScope });
|
|
49201
|
-
if ("error" in result) {
|
|
49202
|
-
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
49377
|
+
if (view === "commit" && !commitSha) {
|
|
49378
|
+
reply({ ok: false, error: "changes.commitSha is required for commit file patch" });
|
|
49203
49379
|
return;
|
|
49204
49380
|
}
|
|
49205
|
-
const
|
|
49206
|
-
|
|
49207
|
-
|
|
49208
|
-
|
|
49209
|
-
|
|
49210
|
-
|
|
49211
|
-
};
|
|
49212
|
-
|
|
49213
|
-
|
|
49214
|
-
|
|
49215
|
-
|
|
49381
|
+
const patch = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeFilePatch(msg.sessionId, {
|
|
49382
|
+
repoRelPath: repoRel,
|
|
49383
|
+
workspaceRelPath: fileWorkspaceRelPath,
|
|
49384
|
+
change,
|
|
49385
|
+
movedFromWorkspaceRelPath: fileMovedFromWorkspaceRelPath || null,
|
|
49386
|
+
basis: view === "commit" ? { kind: "commit", sha: commitSha } : { kind: "working" }
|
|
49387
|
+
});
|
|
49388
|
+
reply(
|
|
49389
|
+
{
|
|
49390
|
+
ok: true,
|
|
49391
|
+
patchContent: patch.patchContent ?? null,
|
|
49392
|
+
totalLines: patch.totalLines
|
|
49393
|
+
},
|
|
49394
|
+
["patchContent"]
|
|
49395
|
+
);
|
|
49216
49396
|
}
|
|
49217
49397
|
|
|
49218
|
-
// src/
|
|
49219
|
-
|
|
49220
|
-
function
|
|
49221
|
-
|
|
49222
|
-
|
|
49223
|
-
|
|
49224
|
-
|
|
49225
|
-
|
|
49226
|
-
|
|
49227
|
-
|
|
49228
|
-
|
|
49229
|
-
|
|
49230
|
-
|
|
49231
|
-
|
|
49232
|
-
|
|
49233
|
-
|
|
49234
|
-
|
|
49235
|
-
|
|
49236
|
-
|
|
49237
|
-
|
|
49238
|
-
|
|
49239
|
-
})
|
|
49398
|
+
// src/routing/handlers/git/coalesce-list-changes.ts
|
|
49399
|
+
var listChangesInflight = /* @__PURE__ */ new Map();
|
|
49400
|
+
function normalizeListChangesRepoPathRelativeToWorkspaceRoot(repoRelPath) {
|
|
49401
|
+
if (!repoRelPath?.trim()) return "";
|
|
49402
|
+
return normalizeRepoPathRelativeToWorkspaceRoot(repoRelPath.trim());
|
|
49403
|
+
}
|
|
49404
|
+
function listChangesInflightKey(sessionId, opts) {
|
|
49405
|
+
const basis = opts?.basis;
|
|
49406
|
+
return [
|
|
49407
|
+
sessionId,
|
|
49408
|
+
normalizeListChangesRepoPathRelativeToWorkspaceRoot(opts?.repoRelPath),
|
|
49409
|
+
basis?.kind === "commit" ? `commit:${basis.sha}` : "working",
|
|
49410
|
+
String(opts?.recentCommitsLimit ?? "")
|
|
49411
|
+
].join("|");
|
|
49412
|
+
}
|
|
49413
|
+
function getSessionWorkingTreeChangeDetailsCoalesced(sessionWorktreeManager, sessionId, opts) {
|
|
49414
|
+
const key = listChangesInflightKey(sessionId, opts);
|
|
49415
|
+
const existing = listChangesInflight.get(key);
|
|
49416
|
+
if (existing) return existing;
|
|
49417
|
+
const promise2 = sessionWorktreeManager.getSessionWorkingTreeChangeDetails(sessionId, opts).finally(() => {
|
|
49418
|
+
if (listChangesInflight.get(key) === promise2) listChangesInflight.delete(key);
|
|
49419
|
+
});
|
|
49420
|
+
listChangesInflight.set(key, promise2);
|
|
49421
|
+
return promise2;
|
|
49240
49422
|
}
|
|
49241
49423
|
|
|
49242
|
-
// src/
|
|
49243
|
-
|
|
49244
|
-
|
|
49245
|
-
|
|
49246
|
-
|
|
49247
|
-
|
|
49248
|
-
|
|
49249
|
-
|
|
49250
|
-
|
|
49251
|
-
|
|
49252
|
-
);
|
|
49253
|
-
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
49254
|
-
triggerFileIndexBuild(sessionParentPath);
|
|
49255
|
-
const payload2 = {
|
|
49256
|
-
type: "file_browser_search_response",
|
|
49257
|
-
id: msg.id,
|
|
49258
|
-
paths: [],
|
|
49259
|
-
indexReady: false
|
|
49260
|
-
};
|
|
49261
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
49424
|
+
// src/routing/handlers/git/handle-session-git-list-changes.ts
|
|
49425
|
+
async function handleSessionGitListChangesAction(deps, msg, reply) {
|
|
49426
|
+
const changes = parseSessionGitChangesParams(msg);
|
|
49427
|
+
const { repoRelPath: repoRel, view, commitSha, recentCommitsLimit } = changes;
|
|
49428
|
+
if (view === "commit") {
|
|
49429
|
+
if (!repoRel || !commitSha) {
|
|
49430
|
+
reply({
|
|
49431
|
+
ok: false,
|
|
49432
|
+
error: "changes.repoRelPath and changes.commitSha are required for commit view"
|
|
49433
|
+
});
|
|
49262
49434
|
return;
|
|
49263
49435
|
}
|
|
49264
|
-
|
|
49265
|
-
|
|
49266
|
-
|
|
49267
|
-
|
|
49268
|
-
|
|
49269
|
-
|
|
49270
|
-
|
|
49271
|
-
|
|
49272
|
-
|
|
49436
|
+
}
|
|
49437
|
+
const opts = repoRel && view === "commit" && commitSha ? {
|
|
49438
|
+
repoRelPath: repoRel,
|
|
49439
|
+
basis: { kind: "commit", sha: commitSha },
|
|
49440
|
+
recentCommitsLimit
|
|
49441
|
+
} : repoRel ? { repoRelPath: repoRel, basis: { kind: "working" }, recentCommitsLimit } : recentCommitsLimit !== void 0 ? { recentCommitsLimit } : void 0;
|
|
49442
|
+
const repos = await getSessionWorkingTreeChangeDetailsCoalesced(
|
|
49443
|
+
deps.sessionWorktreeManager,
|
|
49444
|
+
msg.sessionId,
|
|
49445
|
+
opts
|
|
49446
|
+
);
|
|
49447
|
+
reply({ ok: true, repos }, ["repos"]);
|
|
49273
49448
|
}
|
|
49274
|
-
|
|
49275
|
-
|
|
49276
|
-
|
|
49277
|
-
|
|
49278
|
-
|
|
49449
|
+
|
|
49450
|
+
// src/routing/handlers/git/handle-session-git-push.ts
|
|
49451
|
+
async function handleSessionGitPushAction(deps, sessionId, reply) {
|
|
49452
|
+
const pushRes = await deps.sessionWorktreeManager.pushSessionUpstream(sessionId);
|
|
49453
|
+
if (!pushRes.ok) {
|
|
49454
|
+
reply({ ok: false, error: pushRes.error ?? "Push failed" });
|
|
49455
|
+
return;
|
|
49456
|
+
}
|
|
49457
|
+
const st = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
|
|
49458
|
+
reply({
|
|
49459
|
+
ok: true,
|
|
49460
|
+
hasUncommittedChanges: st.hasUncommittedChanges,
|
|
49461
|
+
hasUnpushedCommits: st.hasUnpushedCommits,
|
|
49462
|
+
uncommittedFileCount: st.uncommittedFileCount
|
|
49279
49463
|
});
|
|
49280
49464
|
}
|
|
49281
49465
|
|
|
49282
|
-
// src/routing/handlers/
|
|
49283
|
-
function
|
|
49284
|
-
|
|
49285
|
-
|
|
49286
|
-
|
|
49287
|
-
|
|
49288
|
-
|
|
49289
|
-
|
|
49290
|
-
|
|
49291
|
-
const socket = getWs();
|
|
49292
|
-
if (!socket) return;
|
|
49293
|
-
handleFileBrowserSearch(
|
|
49294
|
-
msg,
|
|
49295
|
-
socket,
|
|
49296
|
-
e2ee,
|
|
49297
|
-
sessionWorktreeManager
|
|
49298
|
-
);
|
|
49466
|
+
// src/routing/handlers/git/handle-session-git-status.ts
|
|
49467
|
+
async function handleSessionGitStatusAction(deps, sessionId, reply) {
|
|
49468
|
+
const r = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
|
|
49469
|
+
reply({
|
|
49470
|
+
ok: true,
|
|
49471
|
+
hasUncommittedChanges: r.hasUncommittedChanges,
|
|
49472
|
+
hasUnpushedCommits: r.hasUnpushedCommits,
|
|
49473
|
+
uncommittedFileCount: r.uncommittedFileCount
|
|
49474
|
+
});
|
|
49299
49475
|
}
|
|
49300
49476
|
|
|
49301
|
-
// src/
|
|
49302
|
-
|
|
49303
|
-
|
|
49304
|
-
const
|
|
49305
|
-
|
|
49306
|
-
|
|
49307
|
-
|
|
49308
|
-
|
|
49477
|
+
// src/routing/handlers/git/send-session-git-result.ts
|
|
49478
|
+
function sendSessionGitResult(ws, id, payload, e2ee, encryptedFields = []) {
|
|
49479
|
+
if (!ws) return;
|
|
49480
|
+
const message = { type: "session_git_result", id, ...payload };
|
|
49481
|
+
let wire = message;
|
|
49482
|
+
if (e2ee && encryptedFields.length > 0) {
|
|
49483
|
+
wire = e2ee.encryptFields(message, encryptedFields);
|
|
49484
|
+
}
|
|
49485
|
+
sendWsMessage(ws, wire);
|
|
49309
49486
|
}
|
|
49310
49487
|
|
|
49311
|
-
// src/
|
|
49312
|
-
|
|
49488
|
+
// src/routing/handlers/git/session-git-request.ts
|
|
49489
|
+
var handleSessionGitRequestMessage = (msg, deps) => {
|
|
49490
|
+
if (typeof msg.id !== "string") return;
|
|
49491
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
49492
|
+
const action = msg.action;
|
|
49493
|
+
if (!sessionId || action !== "status" && action !== "push" && action !== "commit" && action !== "list_changes" && action !== "file_diff")
|
|
49494
|
+
return;
|
|
49313
49495
|
void (async () => {
|
|
49314
|
-
const
|
|
49315
|
-
|
|
49316
|
-
|
|
49317
|
-
|
|
49318
|
-
|
|
49496
|
+
const ws = deps.getWs();
|
|
49497
|
+
const reply = (payload, encryptedFields = []) => sendSessionGitResult(ws, msg.id, payload, deps.e2ee, encryptedFields);
|
|
49498
|
+
try {
|
|
49499
|
+
if (action === "status") {
|
|
49500
|
+
await handleSessionGitStatusAction(deps, sessionId, reply);
|
|
49501
|
+
return;
|
|
49502
|
+
}
|
|
49503
|
+
if (action === "list_changes") {
|
|
49504
|
+
await handleSessionGitListChangesAction(deps, { ...msg, sessionId }, reply);
|
|
49505
|
+
return;
|
|
49506
|
+
}
|
|
49507
|
+
if (action === "file_diff") {
|
|
49508
|
+
await handleSessionGitGetChangeFilePatchAction(deps, { ...msg, sessionId }, reply);
|
|
49509
|
+
return;
|
|
49510
|
+
}
|
|
49511
|
+
if (action === "push") {
|
|
49512
|
+
await handleSessionGitPushAction(deps, sessionId, reply);
|
|
49513
|
+
return;
|
|
49514
|
+
}
|
|
49515
|
+
await handleSessionGitCommitAction(deps, sessionId, msg, reply);
|
|
49516
|
+
} catch (e) {
|
|
49517
|
+
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
49518
|
+
}
|
|
49519
|
+
})();
|
|
49520
|
+
};
|
|
49521
|
+
|
|
49522
|
+
// src/routing/handlers/rename-session-branch.ts
|
|
49523
|
+
var handleRenameSessionBranchMessage = (msg, deps) => {
|
|
49524
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
49525
|
+
const newBranch = typeof msg.newBranch === "string" ? msg.newBranch : "";
|
|
49526
|
+
if (!sessionId || !newBranch) return;
|
|
49527
|
+
void deps.sessionWorktreeManager.renameSessionBranch(sessionId, newBranch);
|
|
49528
|
+
};
|
|
49529
|
+
|
|
49530
|
+
// src/routing/handlers/session-archived.ts
|
|
49531
|
+
var handleSessionArchivedMessage = (msg, deps) => {
|
|
49532
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
49533
|
+
if (!sessionId) return;
|
|
49534
|
+
void deps.sessionWorktreeManager.removeSessionWorktrees(sessionId);
|
|
49535
|
+
};
|
|
49536
|
+
|
|
49537
|
+
// src/routing/handlers/session-discarded.ts
|
|
49538
|
+
var handleSessionDiscardedMessage = (msg, deps) => {
|
|
49539
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
49540
|
+
if (!sessionId) return;
|
|
49541
|
+
void deps.sessionWorktreeManager.removeSessionWorktrees(sessionId);
|
|
49542
|
+
};
|
|
49543
|
+
|
|
49544
|
+
// src/routing/handlers/revert-turn-snapshot.ts
|
|
49545
|
+
import * as fs59 from "node:fs";
|
|
49546
|
+
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
49547
|
+
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49548
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
49549
|
+
const turnId = typeof msg.turnId === "string" ? msg.turnId : "";
|
|
49550
|
+
if (!id || !sessionId || !turnId) return;
|
|
49551
|
+
const { getWs, log: log2, sessionWorktreeManager } = deps;
|
|
49552
|
+
void (async () => {
|
|
49553
|
+
const s = getWs();
|
|
49554
|
+
if (!s) return;
|
|
49555
|
+
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
49556
|
+
const file2 = snapshotFilePath(agentBase, turnId);
|
|
49557
|
+
try {
|
|
49558
|
+
await fs59.promises.access(file2, fs59.constants.F_OK);
|
|
49559
|
+
} catch {
|
|
49560
|
+
sendWsMessage(s, {
|
|
49561
|
+
type: "revert_turn_snapshot_result",
|
|
49562
|
+
id,
|
|
49563
|
+
ok: false,
|
|
49564
|
+
error: "No snapshot found for this turn (git state may be unavailable)."
|
|
49565
|
+
});
|
|
49566
|
+
return;
|
|
49567
|
+
}
|
|
49568
|
+
const res = await applyPreTurnSnapshot(file2, log2);
|
|
49569
|
+
sendWsMessage(s, {
|
|
49570
|
+
type: "revert_turn_snapshot_result",
|
|
49571
|
+
id,
|
|
49572
|
+
ok: res.ok,
|
|
49573
|
+
...res.error ? { error: res.error } : {}
|
|
49319
49574
|
});
|
|
49320
49575
|
})();
|
|
49576
|
+
};
|
|
49577
|
+
|
|
49578
|
+
// src/routing/dispatch/session.ts
|
|
49579
|
+
function dispatchBridgeSessionMessage(msg, deps) {
|
|
49580
|
+
switch (msg.type) {
|
|
49581
|
+
case "agent_config":
|
|
49582
|
+
handleAgentConfigMessage(msg, deps);
|
|
49583
|
+
break;
|
|
49584
|
+
case "prompt_queue_state":
|
|
49585
|
+
handlePromptQueueStateMessage(msg, deps);
|
|
49586
|
+
break;
|
|
49587
|
+
case "prompt":
|
|
49588
|
+
handlePromptMessage(msg, deps);
|
|
49589
|
+
break;
|
|
49590
|
+
case "session_git_request":
|
|
49591
|
+
handleSessionGitRequestMessage(msg, deps);
|
|
49592
|
+
break;
|
|
49593
|
+
case "rename_session_branch":
|
|
49594
|
+
handleRenameSessionBranchMessage(msg, deps);
|
|
49595
|
+
break;
|
|
49596
|
+
case "session_archived":
|
|
49597
|
+
handleSessionArchivedMessage(msg, deps);
|
|
49598
|
+
break;
|
|
49599
|
+
case "session_discarded":
|
|
49600
|
+
handleSessionDiscardedMessage(msg, deps);
|
|
49601
|
+
break;
|
|
49602
|
+
case "revert_turn_snapshot":
|
|
49603
|
+
handleRevertTurnSnapshotMessage(msg, deps);
|
|
49604
|
+
break;
|
|
49605
|
+
case "cursor_request_response":
|
|
49606
|
+
handleSessionRequestResponseMessage(msg, deps);
|
|
49607
|
+
break;
|
|
49608
|
+
}
|
|
49321
49609
|
}
|
|
49322
49610
|
|
|
49323
|
-
// src/
|
|
49324
|
-
|
|
49611
|
+
// src/skills/handle-skill-call.ts
|
|
49612
|
+
function handleSkillCall(msg, socket, log2) {
|
|
49613
|
+
callSkill(msg.skillId, msg.operationId, msg.params ?? {}).then((result) => {
|
|
49614
|
+
sendWsMessage(socket, { type: "skill_result", id: msg.id, result });
|
|
49615
|
+
}).catch((err) => {
|
|
49616
|
+
sendWsMessage(socket, { type: "skill_result", id: msg.id, error: String(err) });
|
|
49617
|
+
log2(`[Bridge service] Skill invocation failed (${msg.skillId}/${msg.operationId}): ${err}`);
|
|
49618
|
+
});
|
|
49619
|
+
}
|
|
49325
49620
|
|
|
49326
|
-
// src/routing/handlers/
|
|
49327
|
-
|
|
49328
|
-
|
|
49621
|
+
// src/routing/handlers/skill-call.ts
|
|
49622
|
+
var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
49623
|
+
const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
|
|
49624
|
+
const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
|
|
49625
|
+
if (!skillId || !operationId) return;
|
|
49329
49626
|
const socket = getWs();
|
|
49330
49627
|
if (!socket) return;
|
|
49331
|
-
|
|
49332
|
-
{
|
|
49333
|
-
id: msg.id,
|
|
49334
|
-
type: "code_nav",
|
|
49335
|
-
op: msg.op === "references" ? "references" : msg.op === "symbols" ? "symbols" : msg.op === "definitions" ? "definitions" : "definition",
|
|
49336
|
-
path: msg.path,
|
|
49337
|
-
line: typeof msg.line === "number" ? msg.line : 1,
|
|
49338
|
-
column: typeof msg.column === "number" ? msg.column : 0,
|
|
49339
|
-
sessionId: msg.sessionId
|
|
49340
|
-
},
|
|
49628
|
+
handleSkillCall(
|
|
49629
|
+
{ id: msg.id, skillId, operationId, params: msg.params },
|
|
49341
49630
|
socket,
|
|
49342
|
-
|
|
49343
|
-
sessionWorktreeManager
|
|
49631
|
+
log2
|
|
49344
49632
|
);
|
|
49345
|
-
}
|
|
49633
|
+
};
|
|
49346
49634
|
|
|
49347
49635
|
// src/routing/handlers/skill-layout-request.ts
|
|
49348
49636
|
function handleSkillLayoutRequest(msg, deps) {
|
|
@@ -49365,8 +49653,8 @@ function isValidRemoteSkillInstallItem(item) {
|
|
|
49365
49653
|
|
|
49366
49654
|
// src/skills/install/install-remote-skills-async.ts
|
|
49367
49655
|
init_yield_to_event_loop();
|
|
49368
|
-
import
|
|
49369
|
-
import
|
|
49656
|
+
import fs60 from "node:fs";
|
|
49657
|
+
import path79 from "node:path";
|
|
49370
49658
|
|
|
49371
49659
|
// src/skills/install/constants.ts
|
|
49372
49660
|
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
@@ -49374,404 +49662,404 @@ var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
|
49374
49662
|
// src/skills/install/install-remote-skills-async.ts
|
|
49375
49663
|
async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
49376
49664
|
if (typeof f.path !== "string" || !f.text && !f.base64) return;
|
|
49377
|
-
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
49378
|
-
await yieldToEventLoop();
|
|
49379
|
-
}
|
|
49380
|
-
const dest =
|
|
49381
|
-
await
|
|
49382
|
-
if (f.text !== void 0) {
|
|
49383
|
-
await
|
|
49384
|
-
} else if (f.base64) {
|
|
49385
|
-
await
|
|
49386
|
-
}
|
|
49387
|
-
}
|
|
49388
|
-
async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
49389
|
-
const installed2 = [];
|
|
49390
|
-
if (!Array.isArray(items)) {
|
|
49391
|
-
return { success: false, error: "Invalid items" };
|
|
49392
|
-
}
|
|
49393
|
-
const filesWritten = { count: 0 };
|
|
49394
|
-
try {
|
|
49395
|
-
for (const item of items) {
|
|
49396
|
-
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
49397
|
-
const skillDir = path80.join(cwd, targetDir, item.skillName);
|
|
49398
|
-
for (const f of item.files) {
|
|
49399
|
-
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
49400
|
-
}
|
|
49401
|
-
installed2.push({
|
|
49402
|
-
sourceId: item.sourceId,
|
|
49403
|
-
skillName: item.skillName,
|
|
49404
|
-
versionHash: item.versionHash
|
|
49405
|
-
});
|
|
49406
|
-
}
|
|
49407
|
-
return { success: true, installed: installed2 };
|
|
49408
|
-
} catch (e) {
|
|
49409
|
-
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
49410
|
-
}
|
|
49411
|
-
}
|
|
49412
|
-
|
|
49413
|
-
// src/routing/handlers/install-skills.ts
|
|
49414
|
-
var handleInstallSkillsMessage = (msg, deps) => {
|
|
49415
|
-
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49416
|
-
const targetDir = typeof msg.targetDir === "string" && msg.targetDir.trim() ? msg.targetDir.trim() : ".agents/skills";
|
|
49417
|
-
const rawItems = msg.items;
|
|
49418
|
-
const cwd = getBridgeRoot();
|
|
49419
|
-
void (async () => {
|
|
49420
|
-
const socket = deps.getWs();
|
|
49421
|
-
const result = await installRemoteSkillsAsync(cwd, targetDir, rawItems);
|
|
49422
|
-
if (!result.success) {
|
|
49423
|
-
const err = result.error ?? "Invalid items";
|
|
49424
|
-
deps.log(`[Bridge service] Install skills failed: ${err}`);
|
|
49425
|
-
if (socket) {
|
|
49426
|
-
sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
|
|
49427
|
-
}
|
|
49428
|
-
return;
|
|
49429
|
-
}
|
|
49430
|
-
if (socket) {
|
|
49431
|
-
sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
|
|
49432
|
-
}
|
|
49433
|
-
})();
|
|
49434
|
-
};
|
|
49435
|
-
|
|
49436
|
-
// src/routing/handlers/refresh-local-skills.ts
|
|
49437
|
-
var handleRefreshLocalSkills = (_msg, deps) => {
|
|
49438
|
-
setImmediate(() => {
|
|
49439
|
-
deps.sendLocalSkillsReport?.();
|
|
49440
|
-
});
|
|
49441
|
-
};
|
|
49442
|
-
|
|
49443
|
-
// src/routing/handlers/git/handle-session-git-commit.ts
|
|
49444
|
-
async function handleSessionGitCommitAction(deps, sessionId, msg, reply) {
|
|
49445
|
-
const branch = typeof msg.branch === "string" ? msg.branch : "";
|
|
49446
|
-
const message = typeof msg.message === "string" ? msg.message : "";
|
|
49447
|
-
const pushAfterCommit = msg.pushAfterCommit === true;
|
|
49448
|
-
if (!branch.trim() || !message.trim()) {
|
|
49449
|
-
reply({ ok: false, error: "branch and message are required for commit" });
|
|
49450
|
-
return;
|
|
49451
|
-
}
|
|
49452
|
-
const commitRes = await deps.sessionWorktreeManager.commitSession({
|
|
49453
|
-
sessionId,
|
|
49454
|
-
branch: branch.trim(),
|
|
49455
|
-
message: message.trim(),
|
|
49456
|
-
push: pushAfterCommit
|
|
49457
|
-
});
|
|
49458
|
-
if (!commitRes.ok) {
|
|
49459
|
-
reply({ ok: false, error: commitRes.error ?? "Commit failed" });
|
|
49460
|
-
return;
|
|
49461
|
-
}
|
|
49462
|
-
const st = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
|
|
49463
|
-
reply({
|
|
49464
|
-
ok: true,
|
|
49465
|
-
hasUncommittedChanges: st.hasUncommittedChanges,
|
|
49466
|
-
hasUnpushedCommits: st.hasUnpushedCommits,
|
|
49467
|
-
uncommittedFileCount: st.uncommittedFileCount
|
|
49468
|
-
});
|
|
49469
|
-
}
|
|
49470
|
-
|
|
49471
|
-
// src/routing/handlers/git/session-git-changes-params.ts
|
|
49472
|
-
function readString(value) {
|
|
49473
|
-
return typeof value === "string" ? value.trim() : "";
|
|
49474
|
-
}
|
|
49475
|
-
function readChangesObject(msg) {
|
|
49476
|
-
const changes = msg.changes;
|
|
49477
|
-
if (!changes || typeof changes !== "object" || Array.isArray(changes)) return null;
|
|
49478
|
-
return changes;
|
|
49479
|
-
}
|
|
49480
|
-
function parseSessionGitChangesParams(msg) {
|
|
49481
|
-
const nested = readChangesObject(msg);
|
|
49482
|
-
const file2 = nested?.file && typeof nested.file === "object" && !Array.isArray(nested.file) ? nested.file : null;
|
|
49483
|
-
const repoRelPath = readString(nested?.repoRelPath) || readString(msg.changesRepoRelPath);
|
|
49484
|
-
const viewRaw = nested?.view ?? msg.changesView;
|
|
49485
|
-
const view = viewRaw === "commit" ? "commit" : "working";
|
|
49486
|
-
const commitSha = readString(nested?.commitSha) || readString(msg.changesCommitSha);
|
|
49487
|
-
const recentCommitsLimit = nested?.recentCommitsLimit ?? msg.changesRecentCommitsLimit;
|
|
49488
|
-
return {
|
|
49489
|
-
repoRelPath,
|
|
49490
|
-
view,
|
|
49491
|
-
commitSha,
|
|
49492
|
-
recentCommitsLimit: typeof recentCommitsLimit === "number" || typeof recentCommitsLimit === "string" ? recentCommitsLimit : void 0,
|
|
49493
|
-
fileWorkspaceRelPath: readString(file2?.workspaceRelPath),
|
|
49494
|
-
fileChange: readString(file2?.change),
|
|
49495
|
-
fileMovedFromWorkspaceRelPath: readString(file2?.movedFromWorkspaceRelPath)
|
|
49496
|
-
};
|
|
49497
|
-
}
|
|
49498
|
-
|
|
49499
|
-
// src/routing/handlers/git/handle-session-git-get-change-file-patch.ts
|
|
49500
|
-
async function handleSessionGitGetChangeFilePatchAction(deps, msg, reply) {
|
|
49501
|
-
const changes = parseSessionGitChangesParams(msg);
|
|
49502
|
-
const { repoRelPath: repoRel, view, commitSha, fileWorkspaceRelPath, fileChange, fileMovedFromWorkspaceRelPath } = changes;
|
|
49503
|
-
const change = parseWorkingTreeChangeKind(fileChange);
|
|
49504
|
-
if (!repoRel || !fileWorkspaceRelPath || !change) {
|
|
49505
|
-
reply({
|
|
49506
|
-
ok: false,
|
|
49507
|
-
error: "changes.repoRelPath, changes.file.workspaceRelPath, and changes.file.change are required"
|
|
49508
|
-
});
|
|
49509
|
-
return;
|
|
49510
|
-
}
|
|
49511
|
-
if (view === "commit" && !commitSha) {
|
|
49512
|
-
reply({ ok: false, error: "changes.commitSha is required for commit file patch" });
|
|
49513
|
-
return;
|
|
49514
|
-
}
|
|
49515
|
-
const patch = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeFilePatch(msg.sessionId, {
|
|
49516
|
-
repoRelPath: repoRel,
|
|
49517
|
-
workspaceRelPath: fileWorkspaceRelPath,
|
|
49518
|
-
change,
|
|
49519
|
-
movedFromWorkspaceRelPath: fileMovedFromWorkspaceRelPath || null,
|
|
49520
|
-
basis: view === "commit" ? { kind: "commit", sha: commitSha } : { kind: "working" }
|
|
49521
|
-
});
|
|
49522
|
-
reply(
|
|
49523
|
-
{
|
|
49524
|
-
ok: true,
|
|
49525
|
-
patchContent: patch.patchContent ?? null,
|
|
49526
|
-
totalLines: patch.totalLines
|
|
49527
|
-
},
|
|
49528
|
-
["patchContent"]
|
|
49529
|
-
);
|
|
49530
|
-
}
|
|
49531
|
-
|
|
49532
|
-
// src/routing/handlers/git/coalesce-list-changes.ts
|
|
49533
|
-
var listChangesInflight = /* @__PURE__ */ new Map();
|
|
49534
|
-
function normalizeListChangesRepoPathRelativeToWorkspaceRoot(repoRelPath) {
|
|
49535
|
-
if (!repoRelPath?.trim()) return "";
|
|
49536
|
-
return normalizeRepoPathRelativeToWorkspaceRoot(repoRelPath.trim());
|
|
49537
|
-
}
|
|
49538
|
-
function listChangesInflightKey(sessionId, opts) {
|
|
49539
|
-
const basis = opts?.basis;
|
|
49540
|
-
return [
|
|
49541
|
-
sessionId,
|
|
49542
|
-
normalizeListChangesRepoPathRelativeToWorkspaceRoot(opts?.repoRelPath),
|
|
49543
|
-
basis?.kind === "commit" ? `commit:${basis.sha}` : "working",
|
|
49544
|
-
String(opts?.recentCommitsLimit ?? "")
|
|
49545
|
-
].join("|");
|
|
49665
|
+
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
49666
|
+
await yieldToEventLoop();
|
|
49667
|
+
}
|
|
49668
|
+
const dest = path79.join(skillDir, f.path);
|
|
49669
|
+
await fs60.promises.mkdir(path79.dirname(dest), { recursive: true });
|
|
49670
|
+
if (f.text !== void 0) {
|
|
49671
|
+
await fs60.promises.writeFile(dest, f.text, "utf8");
|
|
49672
|
+
} else if (f.base64) {
|
|
49673
|
+
await fs60.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
|
|
49674
|
+
}
|
|
49546
49675
|
}
|
|
49547
|
-
function
|
|
49548
|
-
const
|
|
49549
|
-
|
|
49550
|
-
|
|
49551
|
-
|
|
49552
|
-
|
|
49553
|
-
|
|
49554
|
-
|
|
49555
|
-
|
|
49676
|
+
async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
49677
|
+
const installed2 = [];
|
|
49678
|
+
if (!Array.isArray(items)) {
|
|
49679
|
+
return { success: false, error: "Invalid items" };
|
|
49680
|
+
}
|
|
49681
|
+
const filesWritten = { count: 0 };
|
|
49682
|
+
try {
|
|
49683
|
+
for (const item of items) {
|
|
49684
|
+
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
49685
|
+
const skillDir = path79.join(cwd, targetDir, item.skillName);
|
|
49686
|
+
for (const f of item.files) {
|
|
49687
|
+
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
49688
|
+
}
|
|
49689
|
+
installed2.push({
|
|
49690
|
+
sourceId: item.sourceId,
|
|
49691
|
+
skillName: item.skillName,
|
|
49692
|
+
versionHash: item.versionHash
|
|
49693
|
+
});
|
|
49694
|
+
}
|
|
49695
|
+
return { success: true, installed: installed2 };
|
|
49696
|
+
} catch (e) {
|
|
49697
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
49698
|
+
}
|
|
49556
49699
|
}
|
|
49557
49700
|
|
|
49558
|
-
// src/routing/handlers/
|
|
49559
|
-
|
|
49560
|
-
const
|
|
49561
|
-
const
|
|
49562
|
-
|
|
49563
|
-
|
|
49564
|
-
|
|
49565
|
-
|
|
49566
|
-
|
|
49567
|
-
|
|
49701
|
+
// src/routing/handlers/install-skills.ts
|
|
49702
|
+
var handleInstallSkillsMessage = (msg, deps) => {
|
|
49703
|
+
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49704
|
+
const targetDir = typeof msg.targetDir === "string" && msg.targetDir.trim() ? msg.targetDir.trim() : ".agents/skills";
|
|
49705
|
+
const rawItems = msg.items;
|
|
49706
|
+
const cwd = getBridgeRoot();
|
|
49707
|
+
void (async () => {
|
|
49708
|
+
const socket = deps.getWs();
|
|
49709
|
+
const result = await installRemoteSkillsAsync(cwd, targetDir, rawItems);
|
|
49710
|
+
if (!result.success) {
|
|
49711
|
+
const err = result.error ?? "Invalid items";
|
|
49712
|
+
deps.log(`[Bridge service] Install skills failed: ${err}`);
|
|
49713
|
+
if (socket) {
|
|
49714
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
|
|
49715
|
+
}
|
|
49568
49716
|
return;
|
|
49569
49717
|
}
|
|
49570
|
-
|
|
49571
|
-
|
|
49572
|
-
|
|
49573
|
-
|
|
49574
|
-
|
|
49575
|
-
|
|
49576
|
-
|
|
49577
|
-
|
|
49578
|
-
|
|
49579
|
-
|
|
49580
|
-
|
|
49581
|
-
|
|
49718
|
+
if (socket) {
|
|
49719
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
|
|
49720
|
+
}
|
|
49721
|
+
})();
|
|
49722
|
+
};
|
|
49723
|
+
|
|
49724
|
+
// src/agents/install/commands/run-npm-global-install.ts
|
|
49725
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
49726
|
+
import { promisify as promisify10 } from "node:util";
|
|
49727
|
+
var execFileAsync8 = promisify10(execFile9);
|
|
49728
|
+
async function runNpmGlobalInstall(packageName, env, timeoutMs = 3e5) {
|
|
49729
|
+
await execFileAsync8("npm", ["install", "-g", packageName], { timeout: timeoutMs, env: bridgeAgentPathEnv(env) });
|
|
49582
49730
|
}
|
|
49583
49731
|
|
|
49584
|
-
// src/
|
|
49585
|
-
|
|
49586
|
-
|
|
49587
|
-
|
|
49588
|
-
|
|
49589
|
-
|
|
49732
|
+
// src/agents/install/commands/claude-code.ts
|
|
49733
|
+
var claudeCodeInstallCommand = {
|
|
49734
|
+
agentType: "claude-code",
|
|
49735
|
+
detectCommand: "claude",
|
|
49736
|
+
async install(ctx) {
|
|
49737
|
+
ctx.onProgress?.("Installing Anthropic Claude Code");
|
|
49738
|
+
await runNpmGlobalInstall("@anthropic-ai/claude-code", {
|
|
49739
|
+
...ctx.env,
|
|
49740
|
+
ANTHROPIC_API_KEY: ctx.authToken
|
|
49741
|
+
});
|
|
49590
49742
|
}
|
|
49591
|
-
|
|
49592
|
-
reply({
|
|
49593
|
-
ok: true,
|
|
49594
|
-
hasUncommittedChanges: st.hasUncommittedChanges,
|
|
49595
|
-
hasUnpushedCommits: st.hasUnpushedCommits,
|
|
49596
|
-
uncommittedFileCount: st.uncommittedFileCount
|
|
49597
|
-
});
|
|
49598
|
-
}
|
|
49743
|
+
};
|
|
49599
49744
|
|
|
49600
|
-
// src/
|
|
49601
|
-
|
|
49602
|
-
|
|
49603
|
-
|
|
49604
|
-
|
|
49605
|
-
|
|
49606
|
-
|
|
49607
|
-
|
|
49608
|
-
|
|
49609
|
-
}
|
|
49745
|
+
// src/agents/install/commands/codex-acp.ts
|
|
49746
|
+
var codexAcpInstallCommand = {
|
|
49747
|
+
agentType: "codex-acp",
|
|
49748
|
+
detectCommand: "codex",
|
|
49749
|
+
async install(ctx) {
|
|
49750
|
+
ctx.onProgress?.("Installing Codex");
|
|
49751
|
+
await runNpmGlobalInstall("@openai/codex", {
|
|
49752
|
+
...ctx.env,
|
|
49753
|
+
OPENAI_API_KEY: ctx.authToken
|
|
49754
|
+
});
|
|
49755
|
+
}
|
|
49756
|
+
};
|
|
49610
49757
|
|
|
49611
|
-
// src/
|
|
49612
|
-
|
|
49613
|
-
|
|
49614
|
-
|
|
49615
|
-
|
|
49616
|
-
|
|
49617
|
-
|
|
49758
|
+
// src/agents/install/commands/cursor-cli.ts
|
|
49759
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
49760
|
+
import { promisify as promisify11 } from "node:util";
|
|
49761
|
+
var execFileAsync9 = promisify11(execFile10);
|
|
49762
|
+
var cursorCliInstallCommand = {
|
|
49763
|
+
agentType: "cursor-cli",
|
|
49764
|
+
detectCommand: "agent",
|
|
49765
|
+
async install(ctx) {
|
|
49766
|
+
ctx.onProgress?.("Installing Cursor CLI");
|
|
49767
|
+
await execFileAsync9("bash", ["-lc", "curl -fsSL https://cursor.com/install | bash"], {
|
|
49768
|
+
timeout: 3e5,
|
|
49769
|
+
env: { ...bridgeAgentPathEnv(ctx.env), CURSOR_API_KEY: ctx.authToken }
|
|
49770
|
+
});
|
|
49618
49771
|
}
|
|
49619
|
-
|
|
49772
|
+
};
|
|
49773
|
+
|
|
49774
|
+
// src/agents/install/commands/opencode.ts
|
|
49775
|
+
var opencodeInstallCommand = {
|
|
49776
|
+
agentType: "opencode",
|
|
49777
|
+
detectCommand: "opencode",
|
|
49778
|
+
async install(ctx) {
|
|
49779
|
+
ctx.onProgress?.("Installing OpenCode");
|
|
49780
|
+
await runNpmGlobalInstall("opencode-ai", {
|
|
49781
|
+
...ctx.env,
|
|
49782
|
+
OPENCODE_API_KEY: ctx.authToken
|
|
49783
|
+
});
|
|
49784
|
+
}
|
|
49785
|
+
};
|
|
49786
|
+
|
|
49787
|
+
// src/agents/install/commands/index.ts
|
|
49788
|
+
var COMMANDS = [
|
|
49789
|
+
claudeCodeInstallCommand,
|
|
49790
|
+
codexAcpInstallCommand,
|
|
49791
|
+
cursorCliInstallCommand,
|
|
49792
|
+
opencodeInstallCommand
|
|
49793
|
+
];
|
|
49794
|
+
var byType = new Map(COMMANDS.map((c) => [c.agentType, c]));
|
|
49795
|
+
function getAgentInstallCommand(agentType) {
|
|
49796
|
+
return byType.get(agentType);
|
|
49797
|
+
}
|
|
49798
|
+
|
|
49799
|
+
// src/agents/install/install-local-agent.ts
|
|
49800
|
+
async function installLocalAgentOnBridge(params) {
|
|
49801
|
+
const spec = INSTALLABLE_BRIDGE_AGENTS.find((a) => a.value === params.agentType);
|
|
49802
|
+
if (!spec) return { success: false, error: `Unsupported agent type: ${params.agentType}` };
|
|
49803
|
+
const command = getAgentInstallCommand(params.agentType);
|
|
49804
|
+
if (!command) return { success: false, error: `No install command for ${params.agentType}` };
|
|
49805
|
+
params.onProgress?.(`Configuring ${spec.label} credentials`);
|
|
49806
|
+
try {
|
|
49807
|
+
await command.install({
|
|
49808
|
+
authToken: params.authToken,
|
|
49809
|
+
onProgress: params.onProgress,
|
|
49810
|
+
env: { ...process.env, [spec.tokenEnvVar]: params.authToken }
|
|
49811
|
+
});
|
|
49812
|
+
} catch (e) {
|
|
49813
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
49814
|
+
return { success: false, error: msg };
|
|
49815
|
+
}
|
|
49816
|
+
ensureBridgeAgentPathInProcessEnv();
|
|
49817
|
+
const found = await isCommandOnPath(command.detectCommand);
|
|
49818
|
+
if (!found) {
|
|
49819
|
+
return { success: false, error: `${command.detectCommand} not found on PATH after install` };
|
|
49820
|
+
}
|
|
49821
|
+
return { success: true };
|
|
49620
49822
|
}
|
|
49621
49823
|
|
|
49622
|
-
// src/routing/handlers/
|
|
49623
|
-
var
|
|
49624
|
-
|
|
49625
|
-
const
|
|
49626
|
-
const
|
|
49627
|
-
|
|
49628
|
-
|
|
49824
|
+
// src/routing/handlers/install-agent.ts
|
|
49825
|
+
var handleInstallAgentMessage = (msg, deps) => {
|
|
49826
|
+
const processId = typeof msg.processId === "string" ? msg.processId : "";
|
|
49827
|
+
const agentId = typeof msg.agentId === "string" ? msg.agentId : "";
|
|
49828
|
+
const tokenId = typeof msg.tokenId === "string" ? msg.tokenId : "";
|
|
49829
|
+
const agentType = typeof msg.agentType === "string" ? msg.agentType : "";
|
|
49830
|
+
const authToken = typeof msg.authToken === "string" ? msg.authToken : "";
|
|
49831
|
+
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
49629
49832
|
void (async () => {
|
|
49630
|
-
const
|
|
49631
|
-
const
|
|
49632
|
-
|
|
49633
|
-
|
|
49634
|
-
|
|
49635
|
-
|
|
49636
|
-
|
|
49637
|
-
|
|
49638
|
-
|
|
49639
|
-
|
|
49640
|
-
|
|
49641
|
-
|
|
49642
|
-
await handleSessionGitGetChangeFilePatchAction(deps, { ...msg, sessionId }, reply);
|
|
49643
|
-
return;
|
|
49644
|
-
}
|
|
49645
|
-
if (action === "push") {
|
|
49646
|
-
await handleSessionGitPushAction(deps, sessionId, reply);
|
|
49647
|
-
return;
|
|
49833
|
+
const socket = deps.getWs();
|
|
49834
|
+
const report = (step, message) => {
|
|
49835
|
+
if (socket) {
|
|
49836
|
+
sendWsMessage(socket, {
|
|
49837
|
+
type: "install_agent_progress",
|
|
49838
|
+
processId,
|
|
49839
|
+
agentId,
|
|
49840
|
+
tokenId,
|
|
49841
|
+
agentType,
|
|
49842
|
+
step,
|
|
49843
|
+
message
|
|
49844
|
+
});
|
|
49648
49845
|
}
|
|
49649
|
-
|
|
49650
|
-
|
|
49651
|
-
|
|
49846
|
+
};
|
|
49847
|
+
const result = await installLocalAgentOnBridge({
|
|
49848
|
+
agentType,
|
|
49849
|
+
authToken,
|
|
49850
|
+
onProgress: (message) => report("agent_install_package", message)
|
|
49851
|
+
});
|
|
49852
|
+
if (socket) {
|
|
49853
|
+
sendWsMessage(socket, {
|
|
49854
|
+
type: "install_agent_result",
|
|
49855
|
+
processId,
|
|
49856
|
+
agentId,
|
|
49857
|
+
tokenId,
|
|
49858
|
+
agentType,
|
|
49859
|
+
success: result.success,
|
|
49860
|
+
error: result.error
|
|
49861
|
+
});
|
|
49862
|
+
}
|
|
49863
|
+
if (result.success) {
|
|
49864
|
+
await deps.reportAutoDetectedAgents?.();
|
|
49865
|
+
}
|
|
49866
|
+
if (!result.success) {
|
|
49867
|
+
deps.log(`[Bridge service] Install agent failed: ${result.error ?? "unknown"}`);
|
|
49652
49868
|
}
|
|
49653
49869
|
})();
|
|
49654
49870
|
};
|
|
49655
49871
|
|
|
49656
|
-
// src/routing/handlers/
|
|
49657
|
-
var
|
|
49658
|
-
|
|
49659
|
-
|
|
49660
|
-
|
|
49661
|
-
void deps.sessionWorktreeManager.renameSessionBranch(sessionId, newBranch);
|
|
49872
|
+
// src/routing/handlers/refresh-local-skills.ts
|
|
49873
|
+
var handleRefreshLocalSkills = (_msg, deps) => {
|
|
49874
|
+
setImmediate(() => {
|
|
49875
|
+
deps.sendLocalSkillsReport?.();
|
|
49876
|
+
});
|
|
49662
49877
|
};
|
|
49663
49878
|
|
|
49664
|
-
// src/routing/
|
|
49665
|
-
|
|
49666
|
-
|
|
49667
|
-
|
|
49668
|
-
|
|
49669
|
-
|
|
49879
|
+
// src/routing/dispatch/skills.ts
|
|
49880
|
+
function dispatchBridgeSkillsMessage(msg, deps) {
|
|
49881
|
+
switch (msg.type) {
|
|
49882
|
+
case "skill_call":
|
|
49883
|
+
handleSkillCallMessage(msg, deps);
|
|
49884
|
+
break;
|
|
49885
|
+
case "skill_layout_request":
|
|
49886
|
+
handleSkillLayoutRequest(msg, deps);
|
|
49887
|
+
break;
|
|
49888
|
+
case "install_skills":
|
|
49889
|
+
handleInstallSkillsMessage(msg, deps);
|
|
49890
|
+
break;
|
|
49891
|
+
case "install_agent":
|
|
49892
|
+
handleInstallAgentMessage(msg, deps);
|
|
49893
|
+
break;
|
|
49894
|
+
case "refresh_local_skills":
|
|
49895
|
+
handleRefreshLocalSkills(msg, deps);
|
|
49896
|
+
break;
|
|
49897
|
+
}
|
|
49898
|
+
}
|
|
49670
49899
|
|
|
49671
|
-
// src/
|
|
49672
|
-
|
|
49673
|
-
|
|
49674
|
-
|
|
49675
|
-
void deps.sessionWorktreeManager.removeSessionWorktrees(sessionId);
|
|
49676
|
-
};
|
|
49900
|
+
// src/files/browser/send-file-browser-message.ts
|
|
49901
|
+
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
49902
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
49903
|
+
}
|
|
49677
49904
|
|
|
49678
|
-
// src/
|
|
49679
|
-
|
|
49680
|
-
|
|
49681
|
-
|
|
49682
|
-
|
|
49683
|
-
|
|
49684
|
-
|
|
49685
|
-
|
|
49905
|
+
// src/files/browser/handle-file-browser-list.ts
|
|
49906
|
+
async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
|
|
49907
|
+
const result = await executeFileBrowserList({ reqPath, sessionParentPath, gitScope });
|
|
49908
|
+
if ("error" in result) {
|
|
49909
|
+
sendWsMessage(socket, { type: "file_browser_response", id, error: result.error });
|
|
49910
|
+
return;
|
|
49911
|
+
}
|
|
49912
|
+
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
|
|
49913
|
+
}
|
|
49914
|
+
|
|
49915
|
+
// src/files/browser/handle-file-browser-read.ts
|
|
49916
|
+
async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
|
|
49917
|
+
const result = await executeFileBrowserRead({ msg, reqPath, sessionParentPath, gitScope });
|
|
49918
|
+
if ("error" in result) {
|
|
49919
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
49920
|
+
return;
|
|
49921
|
+
}
|
|
49922
|
+
const payload = {
|
|
49923
|
+
type: "file_browser_response",
|
|
49924
|
+
id: msg.id,
|
|
49925
|
+
content: result.content,
|
|
49926
|
+
totalLines: result.totalLines,
|
|
49927
|
+
size: result.size
|
|
49928
|
+
};
|
|
49929
|
+
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
49930
|
+
if (result.mimeType != null) payload.mimeType = result.mimeType;
|
|
49931
|
+
if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
|
|
49932
|
+
sendFileBrowserMessage(socket, e2ee, payload);
|
|
49933
|
+
}
|
|
49934
|
+
|
|
49935
|
+
// src/files/browser/index.ts
|
|
49936
|
+
init_in_flight();
|
|
49937
|
+
function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49938
|
+
beginFileBrowserRequest();
|
|
49686
49939
|
void (async () => {
|
|
49687
|
-
const s = getWs();
|
|
49688
|
-
if (!s) return;
|
|
49689
|
-
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
49690
|
-
const file2 = snapshotFilePath(agentBase, turnId);
|
|
49691
49940
|
try {
|
|
49692
|
-
|
|
49693
|
-
|
|
49694
|
-
|
|
49695
|
-
|
|
49696
|
-
id,
|
|
49697
|
-
|
|
49698
|
-
|
|
49699
|
-
|
|
49700
|
-
|
|
49941
|
+
const reqPath = msg.path.replace(/^\/+/, "") || ".";
|
|
49942
|
+
const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
|
|
49943
|
+
const gitScope = resolveGitBranchScope(msg);
|
|
49944
|
+
if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
|
|
49945
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
|
|
49946
|
+
return;
|
|
49947
|
+
}
|
|
49948
|
+
if (msg.op === "read") {
|
|
49949
|
+
await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
|
|
49950
|
+
} else {
|
|
49951
|
+
await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
|
|
49952
|
+
}
|
|
49953
|
+
} finally {
|
|
49954
|
+
endFileBrowserRequest();
|
|
49701
49955
|
}
|
|
49702
|
-
const res = await applyPreTurnSnapshot(file2, log2);
|
|
49703
|
-
sendWsMessage(s, {
|
|
49704
|
-
type: "revert_turn_snapshot_result",
|
|
49705
|
-
id,
|
|
49706
|
-
ok: res.ok,
|
|
49707
|
-
...res.error ? { error: res.error } : {}
|
|
49708
|
-
});
|
|
49709
49956
|
})();
|
|
49710
|
-
}
|
|
49711
|
-
|
|
49712
|
-
// src/routing/handlers/preview-environment-control.ts
|
|
49713
|
-
var handlePreviewEnvironmentControl = (msg, deps) => {
|
|
49714
|
-
let wire;
|
|
49715
|
-
try {
|
|
49716
|
-
wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
|
|
49717
|
-
} catch (e) {
|
|
49718
|
-
deps.log(`[E2EE] Could not decrypt preview environment command: ${e instanceof Error ? e.message : String(e)}`);
|
|
49719
|
-
return;
|
|
49720
|
-
}
|
|
49721
|
-
const environmentId = typeof wire.environmentId === "string" ? wire.environmentId : "";
|
|
49722
|
-
const action = wire.action === "start" || wire.action === "stop" ? wire.action : null;
|
|
49723
|
-
if (!environmentId || !action) return;
|
|
49724
|
-
deps.previewEnvironmentManager?.handleControl(environmentId, action);
|
|
49725
|
-
};
|
|
49957
|
+
}
|
|
49726
49958
|
|
|
49727
|
-
// src/
|
|
49728
|
-
|
|
49729
|
-
|
|
49730
|
-
|
|
49731
|
-
|
|
49732
|
-
|
|
49733
|
-
|
|
49734
|
-
const
|
|
49735
|
-
|
|
49736
|
-
|
|
49737
|
-
|
|
49959
|
+
// src/files/handle-file-browser-search.ts
|
|
49960
|
+
init_yield_to_event_loop();
|
|
49961
|
+
import path80 from "node:path";
|
|
49962
|
+
var SEARCH_LIMIT = 100;
|
|
49963
|
+
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49964
|
+
void (async () => {
|
|
49965
|
+
await yieldToEventLoop();
|
|
49966
|
+
const q = typeof msg.q === "string" ? msg.q : "";
|
|
49967
|
+
const sessionParentPath = path80.resolve(
|
|
49968
|
+
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
49969
|
+
);
|
|
49970
|
+
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
49971
|
+
triggerFileIndexBuild(sessionParentPath);
|
|
49972
|
+
const payload2 = {
|
|
49973
|
+
type: "file_browser_search_response",
|
|
49974
|
+
id: msg.id,
|
|
49975
|
+
paths: [],
|
|
49976
|
+
indexReady: false
|
|
49977
|
+
};
|
|
49978
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
49979
|
+
return;
|
|
49738
49980
|
}
|
|
49981
|
+
const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
|
|
49982
|
+
const payload = {
|
|
49983
|
+
type: "file_browser_search_response",
|
|
49984
|
+
id: msg.id,
|
|
49985
|
+
paths: results,
|
|
49986
|
+
indexReady: true
|
|
49987
|
+
};
|
|
49988
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
49989
|
+
})();
|
|
49990
|
+
}
|
|
49991
|
+
function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
|
|
49992
|
+
setImmediate(() => {
|
|
49993
|
+
void ensureFileIndexAsync(sessionParentPath).catch((e) => {
|
|
49994
|
+
console.error("[file-index] Background build failed:", e);
|
|
49995
|
+
});
|
|
49739
49996
|
});
|
|
49740
|
-
};
|
|
49741
|
-
|
|
49742
|
-
// src/routing/handlers/send-deploy-session-to-preview-result.ts
|
|
49743
|
-
function sendDeploySessionToPreviewResult(ws, id, payload) {
|
|
49744
|
-
if (!ws) return;
|
|
49745
|
-
sendWsMessage(ws, { type: "deploy_session_to_preview_result", id, ...payload });
|
|
49746
49997
|
}
|
|
49747
49998
|
|
|
49748
|
-
// src/routing/handlers/
|
|
49749
|
-
|
|
49999
|
+
// src/routing/handlers/file-browser-messages.ts
|
|
50000
|
+
function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
50001
|
+
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
50002
|
+
const socket = getWs();
|
|
50003
|
+
if (!socket) return;
|
|
50004
|
+
handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager);
|
|
50005
|
+
}
|
|
50006
|
+
function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49750
50007
|
if (typeof msg.id !== "string") return;
|
|
49751
|
-
const
|
|
49752
|
-
|
|
49753
|
-
|
|
50008
|
+
const socket = getWs();
|
|
50009
|
+
if (!socket) return;
|
|
50010
|
+
handleFileBrowserSearch(
|
|
50011
|
+
msg,
|
|
50012
|
+
socket,
|
|
50013
|
+
e2ee,
|
|
50014
|
+
sessionWorktreeManager
|
|
50015
|
+
);
|
|
50016
|
+
}
|
|
50017
|
+
|
|
50018
|
+
// src/code-nav/handlers/send-code-nav-response.ts
|
|
50019
|
+
var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
|
|
50020
|
+
function sendCodeNavResponse(socket, e2ee, payload) {
|
|
50021
|
+
const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
|
|
50022
|
+
sendWsMessage(
|
|
50023
|
+
socket,
|
|
50024
|
+
e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
|
|
50025
|
+
);
|
|
50026
|
+
}
|
|
50027
|
+
|
|
50028
|
+
// src/code-nav/handlers/handle-code-nav-request.ts
|
|
50029
|
+
function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49754
50030
|
void (async () => {
|
|
49755
|
-
const
|
|
49756
|
-
|
|
49757
|
-
|
|
49758
|
-
|
|
49759
|
-
|
|
49760
|
-
|
|
49761
|
-
}
|
|
49762
|
-
const result = await deploySessionToPreviewEnvironment({
|
|
49763
|
-
sessionWorktreeManager: deps.sessionWorktreeManager,
|
|
49764
|
-
previewWorktreeManager: deps.previewWorktreeManager,
|
|
49765
|
-
sessionId,
|
|
49766
|
-
environmentId,
|
|
49767
|
-
log: deps.log
|
|
49768
|
-
});
|
|
49769
|
-
reply(result);
|
|
49770
|
-
} catch (e) {
|
|
49771
|
-
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
49772
|
-
}
|
|
50031
|
+
const body = await executeCodeNavRequest(msg, sessionWorktreeManager);
|
|
50032
|
+
sendCodeNavResponse(socket, e2ee, {
|
|
50033
|
+
type: "code_nav_response",
|
|
50034
|
+
id: msg.id,
|
|
50035
|
+
...body
|
|
50036
|
+
});
|
|
49773
50037
|
})();
|
|
49774
|
-
}
|
|
50038
|
+
}
|
|
50039
|
+
|
|
50040
|
+
// src/code-nav/handlers/trigger-symbol-index-build.ts
|
|
50041
|
+
init_normalize_resolved_path();
|
|
50042
|
+
|
|
50043
|
+
// src/routing/handlers/code-nav-messages.ts
|
|
50044
|
+
function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
50045
|
+
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
50046
|
+
const socket = getWs();
|
|
50047
|
+
if (!socket) return;
|
|
50048
|
+
handleCodeNavRequest(
|
|
50049
|
+
{
|
|
50050
|
+
id: msg.id,
|
|
50051
|
+
type: "code_nav",
|
|
50052
|
+
op: msg.op === "references" ? "references" : msg.op === "symbols" ? "symbols" : msg.op === "definitions" ? "definitions" : "definition",
|
|
50053
|
+
path: msg.path,
|
|
50054
|
+
line: typeof msg.line === "number" ? msg.line : 1,
|
|
50055
|
+
column: typeof msg.column === "number" ? msg.column : 0,
|
|
50056
|
+
sessionId: msg.sessionId
|
|
50057
|
+
},
|
|
50058
|
+
socket,
|
|
50059
|
+
e2ee,
|
|
50060
|
+
sessionWorktreeManager
|
|
50061
|
+
);
|
|
50062
|
+
}
|
|
49775
50063
|
|
|
49776
50064
|
// src/git/bridge-git-context.ts
|
|
49777
50065
|
import * as path81 from "node:path";
|
|
@@ -49918,80 +50206,64 @@ function handleListRepoBranchesRequestMessage(msg, getWs) {
|
|
|
49918
50206
|
})();
|
|
49919
50207
|
}
|
|
49920
50208
|
|
|
49921
|
-
// src/routing/dispatch-
|
|
50209
|
+
// src/routing/dispatch/file-browser.ts
|
|
50210
|
+
function dispatchBridgeFileBrowserMessage(msg, deps) {
|
|
50211
|
+
switch (msg.type) {
|
|
50212
|
+
case "file_browser_request":
|
|
50213
|
+
handleFileBrowserRequestMessage(msg, deps);
|
|
50214
|
+
break;
|
|
50215
|
+
case "file_browser_search":
|
|
50216
|
+
handleFileBrowserSearchMessage(msg, deps);
|
|
50217
|
+
break;
|
|
50218
|
+
case "code_nav":
|
|
50219
|
+
handleFileBrowserCodeNavMessage(msg, deps);
|
|
50220
|
+
break;
|
|
50221
|
+
case "bridge_git_context_request":
|
|
50222
|
+
handleBridgeGitContextRequestMessage(msg, deps.getWs);
|
|
50223
|
+
break;
|
|
50224
|
+
case "list_repo_branches_request":
|
|
50225
|
+
handleListRepoBranchesRequestMessage(msg, deps.getWs);
|
|
50226
|
+
break;
|
|
50227
|
+
}
|
|
50228
|
+
}
|
|
50229
|
+
|
|
50230
|
+
// src/routing/dispatch/index.ts
|
|
49922
50231
|
function dispatchBridgeMessage(msg, deps) {
|
|
49923
50232
|
switch (msg.type) {
|
|
49924
50233
|
case "auth_token":
|
|
49925
|
-
handleAuthToken(msg, deps);
|
|
49926
|
-
break;
|
|
49927
50234
|
case "bridge_identified":
|
|
49928
|
-
handleBridgeIdentified(msg, deps);
|
|
49929
|
-
break;
|
|
49930
50235
|
case "ha":
|
|
49931
|
-
|
|
50236
|
+
dispatchBridgeConnectionMessage(msg, deps);
|
|
49932
50237
|
break;
|
|
49933
50238
|
case "preview_environments_config":
|
|
49934
|
-
handlePreviewEnvironmentsConfig(msg, deps);
|
|
49935
|
-
break;
|
|
49936
50239
|
case "preview_environment_control":
|
|
49937
|
-
handlePreviewEnvironmentControl(msg, deps);
|
|
49938
|
-
break;
|
|
49939
50240
|
case "deploy_session_to_preview":
|
|
49940
|
-
|
|
50241
|
+
dispatchBridgePreviewMessage(msg, deps);
|
|
49941
50242
|
break;
|
|
49942
50243
|
case "agent_config":
|
|
49943
|
-
handleAgentConfigMessage(msg, deps);
|
|
49944
|
-
break;
|
|
49945
50244
|
case "prompt_queue_state":
|
|
49946
|
-
handlePromptQueueStateMessage(msg, deps);
|
|
49947
|
-
break;
|
|
49948
50245
|
case "prompt":
|
|
49949
|
-
handlePromptMessage(msg, deps);
|
|
49950
|
-
break;
|
|
49951
50246
|
case "session_git_request":
|
|
49952
|
-
handleSessionGitRequestMessage(msg, deps);
|
|
49953
|
-
break;
|
|
49954
50247
|
case "rename_session_branch":
|
|
49955
|
-
handleRenameSessionBranchMessage(msg, deps);
|
|
49956
|
-
break;
|
|
49957
50248
|
case "session_archived":
|
|
49958
|
-
handleSessionArchivedMessage(msg, deps);
|
|
49959
|
-
break;
|
|
49960
50249
|
case "session_discarded":
|
|
49961
|
-
handleSessionDiscardedMessage(msg, deps);
|
|
49962
|
-
break;
|
|
49963
50250
|
case "revert_turn_snapshot":
|
|
49964
|
-
handleRevertTurnSnapshotMessage(msg, deps);
|
|
49965
|
-
break;
|
|
49966
50251
|
case "cursor_request_response":
|
|
49967
|
-
|
|
50252
|
+
dispatchBridgeSessionMessage(msg, deps);
|
|
49968
50253
|
break;
|
|
49969
50254
|
case "skill_call":
|
|
49970
|
-
handleSkillCallMessage(msg, deps);
|
|
49971
|
-
break;
|
|
49972
|
-
case "file_browser_request":
|
|
49973
|
-
handleFileBrowserRequestMessage(msg, deps);
|
|
49974
|
-
break;
|
|
49975
|
-
case "file_browser_search":
|
|
49976
|
-
handleFileBrowserSearchMessage(msg, deps);
|
|
49977
|
-
break;
|
|
49978
|
-
case "code_nav":
|
|
49979
|
-
handleFileBrowserCodeNavMessage(msg, deps);
|
|
49980
|
-
break;
|
|
49981
50255
|
case "skill_layout_request":
|
|
49982
|
-
handleSkillLayoutRequest(msg, deps);
|
|
49983
|
-
break;
|
|
49984
50256
|
case "install_skills":
|
|
49985
|
-
|
|
49986
|
-
break;
|
|
50257
|
+
case "install_agent":
|
|
49987
50258
|
case "refresh_local_skills":
|
|
49988
|
-
|
|
50259
|
+
dispatchBridgeSkillsMessage(msg, deps);
|
|
49989
50260
|
break;
|
|
50261
|
+
case "file_browser_request":
|
|
50262
|
+
case "file_browser_search":
|
|
50263
|
+
case "code_nav":
|
|
49990
50264
|
case "bridge_git_context_request":
|
|
49991
|
-
handleBridgeGitContextRequestMessage(msg, deps.getWs);
|
|
49992
|
-
break;
|
|
49993
50265
|
case "list_repo_branches_request":
|
|
49994
|
-
|
|
50266
|
+
dispatchBridgeFileBrowserMessage(msg, deps);
|
|
49995
50267
|
break;
|
|
49996
50268
|
}
|
|
49997
50269
|
}
|
|
@@ -50276,6 +50548,7 @@ init_log();
|
|
|
50276
50548
|
async function createBridgeConnection(options) {
|
|
50277
50549
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
50278
50550
|
const logFn = options.log ?? log;
|
|
50551
|
+
ensureBridgeAgentPathInProcessEnv();
|
|
50279
50552
|
await ensureBridgeConnectionDatabases(logFn);
|
|
50280
50553
|
const { state, getWs } = createMainBridgeReconnectState();
|
|
50281
50554
|
const runtime = await createBridgeConnectionRuntime(options, { state, getWs, logFn });
|