codeam-cli 2.65.0 → 2.65.2
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/CHANGELOG.md +38 -0
- package/dist/index.js +1011 -802
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3148,11 +3148,11 @@ function quiet(fn) {
|
|
|
3148
3148
|
log.debug(TAG, "ignored sync error", err);
|
|
3149
3149
|
}
|
|
3150
3150
|
}
|
|
3151
|
-
function rmIfExistsQuiet(
|
|
3151
|
+
function rmIfExistsQuiet(path92) {
|
|
3152
3152
|
try {
|
|
3153
|
-
fs2.rmSync(
|
|
3153
|
+
fs2.rmSync(path92, { force: true });
|
|
3154
3154
|
} catch (err) {
|
|
3155
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
3155
|
+
log.debug(TAG, `rmIfExists failed for ${path92}`, err);
|
|
3156
3156
|
}
|
|
3157
3157
|
}
|
|
3158
3158
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -3321,9 +3321,9 @@ var _default = makeConfig();
|
|
|
3321
3321
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
3322
3322
|
|
|
3323
3323
|
// src/commands/pair-auto.ts
|
|
3324
|
-
var
|
|
3325
|
-
var
|
|
3326
|
-
var
|
|
3324
|
+
var fs64 = __toESM(require("fs"));
|
|
3325
|
+
var os54 = __toESM(require("os"));
|
|
3326
|
+
var path69 = __toESM(require("path"));
|
|
3327
3327
|
var import_crypto4 = require("crypto");
|
|
3328
3328
|
|
|
3329
3329
|
// src/services/telemetry.service.ts
|
|
@@ -3359,8 +3359,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
3359
3359
|
return decodedFile;
|
|
3360
3360
|
};
|
|
3361
3361
|
}
|
|
3362
|
-
function normalizeWindowsPath(
|
|
3363
|
-
return
|
|
3362
|
+
function normalizeWindowsPath(path92) {
|
|
3363
|
+
return path92.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
3364
3364
|
}
|
|
3365
3365
|
|
|
3366
3366
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -5840,9 +5840,9 @@ async function addSourceContext(frames) {
|
|
|
5840
5840
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
5841
5841
|
return frames;
|
|
5842
5842
|
}
|
|
5843
|
-
function getContextLinesFromFile(
|
|
5843
|
+
function getContextLinesFromFile(path92, ranges, output) {
|
|
5844
5844
|
return new Promise((resolve9) => {
|
|
5845
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
5845
|
+
const stream = (0, import_node_fs.createReadStream)(path92);
|
|
5846
5846
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
5847
5847
|
input: stream
|
|
5848
5848
|
});
|
|
@@ -5857,7 +5857,7 @@ function getContextLinesFromFile(path91, ranges, output) {
|
|
|
5857
5857
|
let rangeStart = range[0];
|
|
5858
5858
|
let rangeEnd = range[1];
|
|
5859
5859
|
function onStreamError() {
|
|
5860
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
5860
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path92, 1);
|
|
5861
5861
|
lineReaded.close();
|
|
5862
5862
|
lineReaded.removeAllListeners();
|
|
5863
5863
|
destroyStreamAndResolve();
|
|
@@ -5918,8 +5918,8 @@ function clearLineContext(frame) {
|
|
|
5918
5918
|
delete frame.context_line;
|
|
5919
5919
|
delete frame.post_context;
|
|
5920
5920
|
}
|
|
5921
|
-
function shouldSkipContextLinesForFile(
|
|
5922
|
-
return
|
|
5921
|
+
function shouldSkipContextLinesForFile(path92) {
|
|
5922
|
+
return path92.startsWith("node:") || path92.endsWith(".min.js") || path92.endsWith(".min.cjs") || path92.endsWith(".min.mjs") || path92.startsWith("data:");
|
|
5923
5923
|
}
|
|
5924
5924
|
function shouldSkipContextLinesForFrame(frame) {
|
|
5925
5925
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -8073,7 +8073,7 @@ function readAnonId() {
|
|
|
8073
8073
|
}
|
|
8074
8074
|
function superProperties() {
|
|
8075
8075
|
return {
|
|
8076
|
-
cliVersion: true ? "2.65.
|
|
8076
|
+
cliVersion: true ? "2.65.2" : "0.0.0-dev",
|
|
8077
8077
|
nodeVersion: process.version,
|
|
8078
8078
|
platform: process.platform,
|
|
8079
8079
|
arch: process.arch,
|
|
@@ -8254,7 +8254,7 @@ var os4 = __toESM(require("os"));
|
|
|
8254
8254
|
// package.json
|
|
8255
8255
|
var package_default = {
|
|
8256
8256
|
name: "codeam-cli",
|
|
8257
|
-
version: "2.65.
|
|
8257
|
+
version: "2.65.2",
|
|
8258
8258
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
8259
8259
|
type: "commonjs",
|
|
8260
8260
|
main: "dist/index.js",
|
|
@@ -9706,7 +9706,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9706
9706
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
9707
9707
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
9708
9708
|
// pair/reconnect). Older backends ignore the extra field.
|
|
9709
|
-
..."2.65.
|
|
9709
|
+
..."2.65.2" ? { ideVersion: "2.65.2" } : {}
|
|
9710
9710
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
9711
9711
|
}
|
|
9712
9712
|
/**
|
|
@@ -11098,11 +11098,11 @@ function closeAllTerminals() {
|
|
|
11098
11098
|
}
|
|
11099
11099
|
|
|
11100
11100
|
// src/commands/start/handlers.ts
|
|
11101
|
-
var
|
|
11102
|
-
var
|
|
11103
|
-
var
|
|
11101
|
+
var fs63 = __toESM(require("fs"));
|
|
11102
|
+
var os53 = __toESM(require("os"));
|
|
11103
|
+
var path68 = __toESM(require("path"));
|
|
11104
11104
|
var import_crypto3 = require("crypto");
|
|
11105
|
-
var
|
|
11105
|
+
var import_child_process26 = require("child_process");
|
|
11106
11106
|
|
|
11107
11107
|
// src/lib/payload.ts
|
|
11108
11108
|
var import_zod = require("zod");
|
|
@@ -11932,8 +11932,8 @@ function findGitRoot2(startDir) {
|
|
|
11932
11932
|
|
|
11933
11933
|
// src/commands/link.ts
|
|
11934
11934
|
var import_node_crypto8 = require("crypto");
|
|
11935
|
-
var
|
|
11936
|
-
var
|
|
11935
|
+
var fs32 = __toESM(require("fs"));
|
|
11936
|
+
var path37 = __toESM(require("path"));
|
|
11937
11937
|
var import_chokidar = __toESM(require("chokidar"));
|
|
11938
11938
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
11939
11939
|
|
|
@@ -14610,10 +14610,10 @@ function buildForPlatform(platform3) {
|
|
|
14610
14610
|
var import_node_crypto4 = require("crypto");
|
|
14611
14611
|
|
|
14612
14612
|
// src/agents/claude/resolver.ts
|
|
14613
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
14614
|
-
const found =
|
|
14613
|
+
function buildClaudeLaunch(extraArgs = [], os67 = createOsStrategy()) {
|
|
14614
|
+
const found = os67.findInPath("claude") ?? os67.findInPath("claude-code");
|
|
14615
14615
|
if (!found) return null;
|
|
14616
|
-
return
|
|
14616
|
+
return os67.buildLaunch(found, extraArgs);
|
|
14617
14617
|
}
|
|
14618
14618
|
|
|
14619
14619
|
// src/agents/claude/installer.ts
|
|
@@ -15203,8 +15203,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
15203
15203
|
meta = getAgent("claude");
|
|
15204
15204
|
mode = "interactive";
|
|
15205
15205
|
os;
|
|
15206
|
-
constructor(
|
|
15207
|
-
this.os =
|
|
15206
|
+
constructor(os67) {
|
|
15207
|
+
this.os = os67;
|
|
15208
15208
|
}
|
|
15209
15209
|
/**
|
|
15210
15210
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -15984,8 +15984,8 @@ function codexCredentialLocator() {
|
|
|
15984
15984
|
function codexLoginLauncher() {
|
|
15985
15985
|
return {
|
|
15986
15986
|
async ensureInstalled() {
|
|
15987
|
-
const
|
|
15988
|
-
return
|
|
15987
|
+
const os67 = createOsStrategy();
|
|
15988
|
+
return os67.findInPath("codex") !== null;
|
|
15989
15989
|
},
|
|
15990
15990
|
launch() {
|
|
15991
15991
|
return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -16008,8 +16008,8 @@ var CodexRuntimeStrategy = class {
|
|
|
16008
16008
|
meta = getAgent("codex");
|
|
16009
16009
|
mode = "interactive";
|
|
16010
16010
|
os;
|
|
16011
|
-
constructor(
|
|
16012
|
-
this.os =
|
|
16011
|
+
constructor(os67) {
|
|
16012
|
+
this.os = os67;
|
|
16013
16013
|
}
|
|
16014
16014
|
async prepareLaunch() {
|
|
16015
16015
|
let binary = this.os.findInPath("codex");
|
|
@@ -16118,12 +16118,12 @@ var CodexRuntimeStrategy = class {
|
|
|
16118
16118
|
});
|
|
16119
16119
|
}
|
|
16120
16120
|
};
|
|
16121
|
-
function resolveNpm(
|
|
16122
|
-
return
|
|
16121
|
+
function resolveNpm(os67) {
|
|
16122
|
+
return os67.id === "win32" ? "npm.cmd" : "npm";
|
|
16123
16123
|
}
|
|
16124
|
-
async function installCodexViaNpm(
|
|
16124
|
+
async function installCodexViaNpm(os67) {
|
|
16125
16125
|
return new Promise((resolve9, reject) => {
|
|
16126
|
-
const proc = (0, import_node_child_process5.spawn)(resolveNpm(
|
|
16126
|
+
const proc = (0, import_node_child_process5.spawn)(resolveNpm(os67), ["install", "-g", "@openai/codex"], {
|
|
16127
16127
|
stdio: "inherit"
|
|
16128
16128
|
});
|
|
16129
16129
|
proc.on("close", (code) => {
|
|
@@ -16140,16 +16140,16 @@ async function installCodexViaNpm(os66) {
|
|
|
16140
16140
|
});
|
|
16141
16141
|
});
|
|
16142
16142
|
}
|
|
16143
|
-
function augmentNpmGlobalBin(
|
|
16143
|
+
function augmentNpmGlobalBin(os67) {
|
|
16144
16144
|
try {
|
|
16145
|
-
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(
|
|
16145
|
+
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os67), ["prefix", "-g"], {
|
|
16146
16146
|
stdio: ["ignore", "pipe", "ignore"]
|
|
16147
16147
|
});
|
|
16148
16148
|
if (result.status !== 0) return;
|
|
16149
16149
|
const prefix = result.stdout.toString().trim();
|
|
16150
16150
|
if (!prefix) return;
|
|
16151
|
-
const binDir =
|
|
16152
|
-
|
|
16151
|
+
const binDir = os67.id === "win32" ? prefix : path25.join(prefix, "bin");
|
|
16152
|
+
os67.augmentPath([binDir]);
|
|
16153
16153
|
} catch {
|
|
16154
16154
|
}
|
|
16155
16155
|
}
|
|
@@ -16543,15 +16543,27 @@ var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
|
16543
16543
|
var INSTALL_TIMEOUT_MS = 15e4;
|
|
16544
16544
|
var PREREQ_INSTALL_TIMEOUT_MS = 12e4;
|
|
16545
16545
|
var REQUIRED_TOOLS = ["unzip", "git"];
|
|
16546
|
+
function defaultRunVersionProbe(binary, env) {
|
|
16547
|
+
const r = (0, import_node_child_process7.spawnSync)(binary, ["--version"], { stdio: "ignore", timeout: 15e3, env });
|
|
16548
|
+
return !r.error && r.status === 0;
|
|
16549
|
+
}
|
|
16550
|
+
function probeRuns(binary, env, deps) {
|
|
16551
|
+
const probe = deps.runVersionProbe ?? defaultRunVersionProbe;
|
|
16552
|
+
try {
|
|
16553
|
+
return probe(binary, env);
|
|
16554
|
+
} catch {
|
|
16555
|
+
return false;
|
|
16556
|
+
}
|
|
16557
|
+
}
|
|
16546
16558
|
function manualInstallHint(runner, tools) {
|
|
16547
16559
|
const pkgs = tools.join(" ");
|
|
16548
16560
|
const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
|
|
16549
16561
|
return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
|
|
16550
16562
|
}
|
|
16551
|
-
function writeUnzipShim(
|
|
16563
|
+
function writeUnzipShim(os67, runner) {
|
|
16552
16564
|
const python = ["python3", "python"].find((p2) => runner.which(p2));
|
|
16553
16565
|
if (!python) return null;
|
|
16554
|
-
const dir =
|
|
16566
|
+
const dir = os67.scratchPath("codeam-cr-prereq");
|
|
16555
16567
|
const shim = path27.join(dir, "unzip");
|
|
16556
16568
|
const script = `#!/bin/sh
|
|
16557
16569
|
set -e
|
|
@@ -16573,9 +16585,9 @@ exec ${python} -m zipfile -e "$archive" "$dest"
|
|
|
16573
16585
|
(0, import_node_fs5.chmodSync)(shim, 448);
|
|
16574
16586
|
return dir;
|
|
16575
16587
|
}
|
|
16576
|
-
async function ensureInstallPrerequisites(
|
|
16588
|
+
async function ensureInstallPrerequisites(os67, deps = {}) {
|
|
16577
16589
|
const runner = deps.runner ?? defaultHeadroomRunner;
|
|
16578
|
-
const missing = REQUIRED_TOOLS.filter((t2) =>
|
|
16590
|
+
const missing = REQUIRED_TOOLS.filter((t2) => os67.findInPath(t2) === null);
|
|
16579
16591
|
if (missing.length === 0) return { ok: true, extraPath: [] };
|
|
16580
16592
|
log.info(
|
|
16581
16593
|
"coderabbit",
|
|
@@ -16594,10 +16606,10 @@ async function ensureInstallPrerequisites(os66, deps = {}) {
|
|
|
16594
16606
|
);
|
|
16595
16607
|
}
|
|
16596
16608
|
}
|
|
16597
|
-
const stillMissing = REQUIRED_TOOLS.filter((t2) =>
|
|
16609
|
+
const stillMissing = REQUIRED_TOOLS.filter((t2) => os67.findInPath(t2) === null);
|
|
16598
16610
|
if (stillMissing.length === 0) return { ok: true, extraPath: [] };
|
|
16599
16611
|
if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
|
|
16600
|
-
const shimDir = writeUnzipShim(
|
|
16612
|
+
const shimDir = writeUnzipShim(os67, runner);
|
|
16601
16613
|
if (shimDir) {
|
|
16602
16614
|
log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
|
|
16603
16615
|
return { ok: true, extraPath: [shimDir] };
|
|
@@ -16660,15 +16672,15 @@ function summarizeInstallFailure(output) {
|
|
|
16660
16672
|
}
|
|
16661
16673
|
return lines.length > 0 ? lines[lines.length - 1] : null;
|
|
16662
16674
|
}
|
|
16663
|
-
async function ensureCoderabbitInstalled(
|
|
16664
|
-
if (
|
|
16665
|
-
if (
|
|
16675
|
+
async function ensureCoderabbitInstalled(os67, deps = {}) {
|
|
16676
|
+
if (os67.findInPath("coderabbit")) return { ok: true };
|
|
16677
|
+
if (os67.id === "win32") {
|
|
16666
16678
|
return {
|
|
16667
16679
|
ok: false,
|
|
16668
16680
|
error: "CodeRabbit on Windows requires WSL. Install the CLI inside your WSL distribution (curl -fsSL https://cli.coderabbit.ai/install.sh | sh), then try again."
|
|
16669
16681
|
};
|
|
16670
16682
|
}
|
|
16671
|
-
const prereq = await ensureInstallPrerequisites(
|
|
16683
|
+
const prereq = await ensureInstallPrerequisites(os67, deps);
|
|
16672
16684
|
if (!prereq.ok) return { ok: false, error: prereq.error };
|
|
16673
16685
|
const env = { ...process.env };
|
|
16674
16686
|
if (prereq.extraPath.length > 0) {
|
|
@@ -16677,22 +16689,27 @@ async function ensureCoderabbitInstalled(os66, deps = {}) {
|
|
|
16677
16689
|
log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
|
|
16678
16690
|
const run = deps.runInstallScript ?? defaultRunInstallScript;
|
|
16679
16691
|
const { code, output } = await run(env);
|
|
16680
|
-
|
|
16681
|
-
|
|
16692
|
+
os67.augmentPath([`${os67.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
16693
|
+
const binary = os67.findInPath("coderabbit");
|
|
16694
|
+
const detail = summarizeInstallFailure(output);
|
|
16695
|
+
if (binary !== null) {
|
|
16696
|
+
if (code === 0) return { ok: true };
|
|
16697
|
+
if (probeRuns(binary, env, deps)) return { ok: true };
|
|
16682
16698
|
return {
|
|
16683
16699
|
ok: false,
|
|
16684
|
-
error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress
|
|
16700
|
+
error: detail ? `CodeRabbit CLI install failed and the installed binary does not run: ${detail}` : "CodeRabbit CLI install failed \u2014 the installed `coderabbit` binary does not run. Re-run the install and check this machine's network egress."
|
|
16685
16701
|
};
|
|
16686
16702
|
}
|
|
16687
|
-
|
|
16688
|
-
if (os66.findInPath("coderabbit") === null) {
|
|
16689
|
-
const detail = summarizeInstallFailure(output);
|
|
16703
|
+
if (code !== 0) {
|
|
16690
16704
|
return {
|
|
16691
16705
|
ok: false,
|
|
16692
|
-
error: detail ? `CodeRabbit CLI install
|
|
16706
|
+
error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress and try again."
|
|
16693
16707
|
};
|
|
16694
16708
|
}
|
|
16695
|
-
return {
|
|
16709
|
+
return {
|
|
16710
|
+
ok: false,
|
|
16711
|
+
error: detail ? `CodeRabbit CLI install did not produce a binary: ${detail}` : "CodeRabbit CLI install reported success but no `coderabbit` binary was found on PATH."
|
|
16712
|
+
};
|
|
16696
16713
|
}
|
|
16697
16714
|
|
|
16698
16715
|
// src/agents/coderabbit/link.ts
|
|
@@ -16727,10 +16744,10 @@ function coderabbitCredentialLocator() {
|
|
|
16727
16744
|
validate: validateNonEmptyCredential
|
|
16728
16745
|
};
|
|
16729
16746
|
}
|
|
16730
|
-
function coderabbitLoginLauncher(
|
|
16747
|
+
function coderabbitLoginLauncher(os67) {
|
|
16731
16748
|
return {
|
|
16732
16749
|
async ensureInstalled() {
|
|
16733
|
-
const result = await ensureCoderabbitInstalled(
|
|
16750
|
+
const result = await ensureCoderabbitInstalled(os67);
|
|
16734
16751
|
if (!result.ok && result.error) console.error(`
|
|
16735
16752
|
\u2717 ${result.error}
|
|
16736
16753
|
`);
|
|
@@ -16790,8 +16807,8 @@ function pickLine(obj) {
|
|
|
16790
16807
|
function toHunk(raw, groupSeverity) {
|
|
16791
16808
|
if (!raw || typeof raw !== "object") return null;
|
|
16792
16809
|
const o = raw;
|
|
16793
|
-
const
|
|
16794
|
-
if (!
|
|
16810
|
+
const path92 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
16811
|
+
if (!path92) return null;
|
|
16795
16812
|
const message = asString(
|
|
16796
16813
|
pick(o, [
|
|
16797
16814
|
"comment",
|
|
@@ -16808,7 +16825,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
16808
16825
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
16809
16826
|
const locObj = pick(o, ["location"]) ?? o;
|
|
16810
16827
|
return {
|
|
16811
|
-
path:
|
|
16828
|
+
path: path92.trim(),
|
|
16812
16829
|
line: pickLine(o) ?? pickLine(locObj),
|
|
16813
16830
|
severity,
|
|
16814
16831
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -16891,10 +16908,10 @@ function parsePlain(stdout) {
|
|
|
16891
16908
|
for (const line of stdout.split(/\r?\n/)) {
|
|
16892
16909
|
const m = line.match(HUNK_LINE_RE);
|
|
16893
16910
|
if (!m) continue;
|
|
16894
|
-
const [,
|
|
16895
|
-
if (!
|
|
16911
|
+
const [, path92, lineNo, sevToken, message] = m;
|
|
16912
|
+
if (!path92 || !lineNo || !message) continue;
|
|
16896
16913
|
hunks.push({
|
|
16897
|
-
path:
|
|
16914
|
+
path: path92.trim(),
|
|
16898
16915
|
line: Number(lineNo),
|
|
16899
16916
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
16900
16917
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -16954,8 +16971,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
16954
16971
|
meta = getAgent("coderabbit");
|
|
16955
16972
|
mode = "batch";
|
|
16956
16973
|
os;
|
|
16957
|
-
constructor(
|
|
16958
|
-
this.os =
|
|
16974
|
+
constructor(os67) {
|
|
16975
|
+
this.os = os67;
|
|
16959
16976
|
}
|
|
16960
16977
|
getDefaultArgs() {
|
|
16961
16978
|
return ["review", "--agent"];
|
|
@@ -17226,10 +17243,10 @@ function cursorCredentialLocator() {
|
|
|
17226
17243
|
validate: validateNonEmptyCredential
|
|
17227
17244
|
};
|
|
17228
17245
|
}
|
|
17229
|
-
function cursorLoginLauncher(
|
|
17246
|
+
function cursorLoginLauncher(os67) {
|
|
17230
17247
|
return {
|
|
17231
17248
|
async ensureInstalled() {
|
|
17232
|
-
if (
|
|
17249
|
+
if (os67.findInPath("cursor-agent")) return true;
|
|
17233
17250
|
console.error(
|
|
17234
17251
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
17235
17252
|
);
|
|
@@ -17293,8 +17310,8 @@ var CursorRuntimeStrategy = class {
|
|
|
17293
17310
|
meta = getAgent("cursor");
|
|
17294
17311
|
mode = "interactive";
|
|
17295
17312
|
os;
|
|
17296
|
-
constructor(
|
|
17297
|
-
this.os =
|
|
17313
|
+
constructor(os67) {
|
|
17314
|
+
this.os = os67;
|
|
17298
17315
|
}
|
|
17299
17316
|
async prepareLaunch() {
|
|
17300
17317
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -17510,10 +17527,10 @@ function aiderCredentialLocator() {
|
|
|
17510
17527
|
validate: validateNonEmptyCredential
|
|
17511
17528
|
};
|
|
17512
17529
|
}
|
|
17513
|
-
function aiderLoginLauncher(
|
|
17530
|
+
function aiderLoginLauncher(os67) {
|
|
17514
17531
|
return {
|
|
17515
17532
|
async ensureInstalled() {
|
|
17516
|
-
if (
|
|
17533
|
+
if (os67.findInPath("aider")) return true;
|
|
17517
17534
|
console.error(
|
|
17518
17535
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
17519
17536
|
);
|
|
@@ -17523,7 +17540,7 @@ function aiderLoginLauncher(os66) {
|
|
|
17523
17540
|
console.error(
|
|
17524
17541
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
17525
17542
|
);
|
|
17526
|
-
return (0, import_node_child_process12.spawn)(
|
|
17543
|
+
return (0, import_node_child_process12.spawn)(os67.id === "win32" ? "cmd.exe" : "sh", os67.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
17527
17544
|
stdio: "ignore"
|
|
17528
17545
|
});
|
|
17529
17546
|
}
|
|
@@ -17581,6 +17598,198 @@ function detectAiderSelector(_lines) {
|
|
|
17581
17598
|
return null;
|
|
17582
17599
|
}
|
|
17583
17600
|
|
|
17601
|
+
// src/agents/acp/agent-binary.ts
|
|
17602
|
+
var import_fs = __toESM(require("fs"));
|
|
17603
|
+
var import_os4 = __toESM(require("os"));
|
|
17604
|
+
var import_path4 = __toESM(require("path"));
|
|
17605
|
+
var import_child_process13 = require("child_process");
|
|
17606
|
+
function currentPlatformKey() {
|
|
17607
|
+
return `${process.platform}-${process.arch}`;
|
|
17608
|
+
}
|
|
17609
|
+
var SDK_PKG = "@anthropic-ai/claude-agent-sdk";
|
|
17610
|
+
function resolveSdkDirViaRequire(req = require) {
|
|
17611
|
+
try {
|
|
17612
|
+
return import_path4.default.dirname(req.resolve(`${SDK_PKG}/package.json`));
|
|
17613
|
+
} catch {
|
|
17614
|
+
}
|
|
17615
|
+
try {
|
|
17616
|
+
let dir = import_path4.default.dirname(req.resolve(SDK_PKG));
|
|
17617
|
+
for (let i = 0; i < 5; i++) {
|
|
17618
|
+
if (import_path4.default.basename(dir) === "claude-agent-sdk") return dir;
|
|
17619
|
+
const parent = import_path4.default.dirname(dir);
|
|
17620
|
+
if (parent === dir) break;
|
|
17621
|
+
dir = parent;
|
|
17622
|
+
}
|
|
17623
|
+
return null;
|
|
17624
|
+
} catch {
|
|
17625
|
+
return null;
|
|
17626
|
+
}
|
|
17627
|
+
}
|
|
17628
|
+
function defaultSdkDir() {
|
|
17629
|
+
return resolveSdkDirViaRequire();
|
|
17630
|
+
}
|
|
17631
|
+
function resolveClaudeNativeBinary(deps = {}) {
|
|
17632
|
+
const existsSync29 = deps.existsSync ?? import_fs.default.existsSync;
|
|
17633
|
+
const platformKey = deps.platformKey ?? currentPlatformKey();
|
|
17634
|
+
const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
|
|
17635
|
+
if (!sdkDir) return null;
|
|
17636
|
+
const scopeDir = import_path4.default.dirname(sdkDir);
|
|
17637
|
+
const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
|
|
17638
|
+
const candidate = import_path4.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
|
|
17639
|
+
return existsSync29(candidate) ? candidate : null;
|
|
17640
|
+
}
|
|
17641
|
+
var realSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
17642
|
+
async function waitForClaudeNativeBinary(opts = {}) {
|
|
17643
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
17644
|
+
const pollMs = opts.pollMs ?? 500;
|
|
17645
|
+
const now = opts.now ?? Date.now;
|
|
17646
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
17647
|
+
const deps = {
|
|
17648
|
+
sdkDir: opts.sdkDir,
|
|
17649
|
+
platformKey: opts.platformKey,
|
|
17650
|
+
existsSync: opts.existsSync
|
|
17651
|
+
};
|
|
17652
|
+
const deadline = now() + timeoutMs;
|
|
17653
|
+
let found = resolveClaudeNativeBinary(deps);
|
|
17654
|
+
if (found) return found;
|
|
17655
|
+
while (now() < deadline) {
|
|
17656
|
+
await sleep5(pollMs);
|
|
17657
|
+
found = resolveClaudeNativeBinary(deps);
|
|
17658
|
+
if (found) return found;
|
|
17659
|
+
}
|
|
17660
|
+
return resolveClaudeNativeBinary(deps);
|
|
17661
|
+
}
|
|
17662
|
+
function isCommandOnPath(cmd, probe = defaultWhich) {
|
|
17663
|
+
return probe(cmd);
|
|
17664
|
+
}
|
|
17665
|
+
function defaultWhich(cmd) {
|
|
17666
|
+
const finder = process.platform === "win32" ? "where" : "which";
|
|
17667
|
+
try {
|
|
17668
|
+
const res = (0, import_child_process13.spawnSync)(finder, [cmd], { stdio: "ignore" });
|
|
17669
|
+
return res.status === 0;
|
|
17670
|
+
} catch {
|
|
17671
|
+
return false;
|
|
17672
|
+
}
|
|
17673
|
+
}
|
|
17674
|
+
async function waitForCommandOnPath(cmd, opts = {}) {
|
|
17675
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
17676
|
+
const pollMs = opts.pollMs ?? 500;
|
|
17677
|
+
const now = opts.now ?? Date.now;
|
|
17678
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
17679
|
+
const probe = opts.probe;
|
|
17680
|
+
const check = () => isCommandOnPath(cmd, probe);
|
|
17681
|
+
const deadline = now() + timeoutMs;
|
|
17682
|
+
if (check()) return true;
|
|
17683
|
+
while (now() < deadline) {
|
|
17684
|
+
await sleep5(pollMs);
|
|
17685
|
+
if (check()) return true;
|
|
17686
|
+
}
|
|
17687
|
+
return check();
|
|
17688
|
+
}
|
|
17689
|
+
function augmentUserLocalBinPaths() {
|
|
17690
|
+
const home = import_os4.default.homedir();
|
|
17691
|
+
const candidates = [
|
|
17692
|
+
// XDG-style per-user bin — npm's default global-prefix bin dir on most
|
|
17693
|
+
// Linux setups (`npm config set prefix ~/.local` or an nvm-less
|
|
17694
|
+
// per-user npm), and where curl-based agent installers commonly land.
|
|
17695
|
+
import_path4.default.join(home, ".local", "bin"),
|
|
17696
|
+
// Common explicit npm global-prefix conventions seen in the wild
|
|
17697
|
+
// (`npm config set prefix ~/.npm-global`, and Debian/Fedora's
|
|
17698
|
+
// `~/.local/share/npm` layout for `npm config set prefix
|
|
17699
|
+
// ~/.local/share/npm`).
|
|
17700
|
+
import_path4.default.join(home, ".npm-global", "bin"),
|
|
17701
|
+
import_path4.default.join(home, ".local", "share", "npm", "bin")
|
|
17702
|
+
];
|
|
17703
|
+
const parts = (process.env.PATH ?? "").split(import_path4.default.delimiter).filter((p2) => p2.length > 0);
|
|
17704
|
+
const existing = new Set(parts);
|
|
17705
|
+
const additions = candidates.filter((dir) => !existing.has(dir));
|
|
17706
|
+
if (additions.length === 0) return;
|
|
17707
|
+
process.env.PATH = [...additions, ...parts].join(import_path4.default.delimiter);
|
|
17708
|
+
}
|
|
17709
|
+
function resolveCursorAgentBinary(deps = {}) {
|
|
17710
|
+
const existsSync29 = deps.existsSync ?? import_fs.default.existsSync;
|
|
17711
|
+
const platform3 = deps.platform ?? process.platform;
|
|
17712
|
+
const env = deps.env ?? process.env;
|
|
17713
|
+
if (platform3 === "win32") {
|
|
17714
|
+
const localAppData = env.LOCALAPPDATA;
|
|
17715
|
+
if (!localAppData) return null;
|
|
17716
|
+
const exe = import_path4.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
|
|
17717
|
+
return existsSync29(exe) ? exe : null;
|
|
17718
|
+
}
|
|
17719
|
+
const home = deps.homedir ?? import_os4.default.homedir();
|
|
17720
|
+
const unix = import_path4.default.posix.join(home, ".local", "bin", "cursor-agent");
|
|
17721
|
+
return existsSync29(unix) ? unix : null;
|
|
17722
|
+
}
|
|
17723
|
+
async function waitForCursorAgent(opts = {}) {
|
|
17724
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
17725
|
+
const pollMs = opts.pollMs ?? 500;
|
|
17726
|
+
const now = opts.now ?? Date.now;
|
|
17727
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
17728
|
+
const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
|
|
17729
|
+
const deadline = now() + timeoutMs;
|
|
17730
|
+
if (check()) return true;
|
|
17731
|
+
while (now() < deadline) {
|
|
17732
|
+
await sleep5(pollMs);
|
|
17733
|
+
if (check()) return true;
|
|
17734
|
+
}
|
|
17735
|
+
return check();
|
|
17736
|
+
}
|
|
17737
|
+
var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|ERR_UNSUPPORTED_DIR_IMPORT|ERR_PACKAGE_PATH_NOT_EXPORTED|ERR_INVALID_PACKAGE_CONFIG|ERR_INVALID_PACKAGE_TARGET|ERR_INVALID_MODULE_SPECIFIER|node:internal\/modules\/|Directory import|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
|
|
17738
|
+
var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
|
|
17739
|
+
function probeAdapterModuleGraph(command2, args2, opts = {}) {
|
|
17740
|
+
const livenessMs = opts.livenessMs ?? 400;
|
|
17741
|
+
const spawnFn = opts.spawnFn ?? import_child_process13.spawn;
|
|
17742
|
+
return new Promise((resolve9) => {
|
|
17743
|
+
let settled = false;
|
|
17744
|
+
let stderr = "";
|
|
17745
|
+
let timer;
|
|
17746
|
+
let child;
|
|
17747
|
+
const finish = (r) => {
|
|
17748
|
+
if (settled) return;
|
|
17749
|
+
settled = true;
|
|
17750
|
+
if (timer) clearTimeout(timer);
|
|
17751
|
+
try {
|
|
17752
|
+
child?.kill("SIGKILL");
|
|
17753
|
+
} catch {
|
|
17754
|
+
}
|
|
17755
|
+
resolve9(r);
|
|
17756
|
+
};
|
|
17757
|
+
try {
|
|
17758
|
+
child = spawnFn(command2, [...args2], { stdio: ["pipe", "ignore", "pipe"] });
|
|
17759
|
+
} catch {
|
|
17760
|
+
resolve9("ok");
|
|
17761
|
+
return;
|
|
17762
|
+
}
|
|
17763
|
+
child.stderr?.on("data", (d3) => {
|
|
17764
|
+
stderr += d3.toString();
|
|
17765
|
+
if (stderr.length > 8192) stderr = stderr.slice(-8192);
|
|
17766
|
+
});
|
|
17767
|
+
child.on("error", () => finish("ok"));
|
|
17768
|
+
child.on("exit", (code) => {
|
|
17769
|
+
if (code !== 0 && code !== null && !PERMANENT_ADAPTER_STARTUP_RE.test(stderr)) {
|
|
17770
|
+
finish("transient");
|
|
17771
|
+
} else {
|
|
17772
|
+
finish("ok");
|
|
17773
|
+
}
|
|
17774
|
+
});
|
|
17775
|
+
timer = setTimeout(() => finish("ok"), livenessMs);
|
|
17776
|
+
});
|
|
17777
|
+
}
|
|
17778
|
+
async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
17779
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
17780
|
+
const pollMs = opts.pollMs ?? 500;
|
|
17781
|
+
const now = opts.now ?? Date.now;
|
|
17782
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
17783
|
+
const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
|
|
17784
|
+
const deadline = now() + timeoutMs;
|
|
17785
|
+
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
17786
|
+
while (now() < deadline) {
|
|
17787
|
+
await sleep5(pollMs);
|
|
17788
|
+
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
17789
|
+
}
|
|
17790
|
+
return false;
|
|
17791
|
+
}
|
|
17792
|
+
|
|
17584
17793
|
// src/agents/aider/runtime.ts
|
|
17585
17794
|
var AIDER_CONTEXT_WINDOW = 2e5;
|
|
17586
17795
|
var AIDER_MODELS = [
|
|
@@ -17595,10 +17804,11 @@ var AiderRuntimeStrategy = class {
|
|
|
17595
17804
|
meta = getAgent("aider");
|
|
17596
17805
|
mode = "interactive";
|
|
17597
17806
|
os;
|
|
17598
|
-
constructor(
|
|
17599
|
-
this.os =
|
|
17807
|
+
constructor(os67) {
|
|
17808
|
+
this.os = os67;
|
|
17600
17809
|
}
|
|
17601
17810
|
async prepareLaunch() {
|
|
17811
|
+
augmentUserLocalBinPaths();
|
|
17602
17812
|
const binary = this.os.findInPath("aider");
|
|
17603
17813
|
if (!binary) {
|
|
17604
17814
|
throw new Error(
|
|
@@ -17670,19 +17880,19 @@ var import_node_crypto6 = require("crypto");
|
|
|
17670
17880
|
var import_node_child_process13 = require("child_process");
|
|
17671
17881
|
|
|
17672
17882
|
// src/agents/gemini/local-token.ts
|
|
17673
|
-
var
|
|
17674
|
-
var
|
|
17675
|
-
var
|
|
17883
|
+
var fs29 = __toESM(require("fs"));
|
|
17884
|
+
var os26 = __toESM(require("os"));
|
|
17885
|
+
var path34 = __toESM(require("path"));
|
|
17676
17886
|
function geminiCredentialsPath() {
|
|
17677
|
-
return
|
|
17887
|
+
return path34.join(os26.homedir(), ".gemini", "oauth_creds.json");
|
|
17678
17888
|
}
|
|
17679
17889
|
function geminiCredentialsPaths() {
|
|
17680
17890
|
return [geminiCredentialsPath()];
|
|
17681
17891
|
}
|
|
17682
17892
|
async function extractLocalGeminiToken() {
|
|
17683
17893
|
const file = geminiCredentialsPath();
|
|
17684
|
-
if (!
|
|
17685
|
-
const credential =
|
|
17894
|
+
if (!fs29.existsSync(file)) return null;
|
|
17895
|
+
const credential = fs29.readFileSync(file, "utf8").trim();
|
|
17686
17896
|
if (credential.length === 0) return null;
|
|
17687
17897
|
return { method: "oauth", credential, source: "flat-file" };
|
|
17688
17898
|
}
|
|
@@ -17728,8 +17938,8 @@ function geminiCredentialLocator() {
|
|
|
17728
17938
|
function geminiLoginLauncher() {
|
|
17729
17939
|
return {
|
|
17730
17940
|
async ensureInstalled() {
|
|
17731
|
-
const
|
|
17732
|
-
return
|
|
17941
|
+
const os67 = createOsStrategy();
|
|
17942
|
+
return os67.findInPath("gemini") !== null;
|
|
17733
17943
|
},
|
|
17734
17944
|
launch() {
|
|
17735
17945
|
return (0, import_node_child_process13.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -17738,20 +17948,20 @@ function geminiLoginLauncher() {
|
|
|
17738
17948
|
}
|
|
17739
17949
|
|
|
17740
17950
|
// src/agents/gemini/history.ts
|
|
17741
|
-
var
|
|
17742
|
-
var
|
|
17743
|
-
var
|
|
17744
|
-
var GEMINI_ROOT =
|
|
17951
|
+
var fs30 = __toESM(require("fs"));
|
|
17952
|
+
var os27 = __toESM(require("os"));
|
|
17953
|
+
var path35 = __toESM(require("path"));
|
|
17954
|
+
var GEMINI_ROOT = path35.join(os27.homedir(), ".gemini");
|
|
17745
17955
|
function projectNameForCwd(cwd, root) {
|
|
17746
17956
|
try {
|
|
17747
17957
|
const parsed = JSON.parse(
|
|
17748
|
-
|
|
17958
|
+
fs30.readFileSync(path35.join(root, "projects.json"), "utf8")
|
|
17749
17959
|
);
|
|
17750
17960
|
const map = parsed.projects;
|
|
17751
17961
|
if (map && typeof map === "object") {
|
|
17752
17962
|
if (typeof map[cwd] === "string") return map[cwd];
|
|
17753
17963
|
try {
|
|
17754
|
-
const rp =
|
|
17964
|
+
const rp = fs30.realpathSync(cwd);
|
|
17755
17965
|
if (typeof map[rp] === "string") return map[rp];
|
|
17756
17966
|
} catch {
|
|
17757
17967
|
}
|
|
@@ -17760,7 +17970,7 @@ function projectNameForCwd(cwd, root) {
|
|
|
17760
17970
|
} catch (err) {
|
|
17761
17971
|
log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
|
|
17762
17972
|
}
|
|
17763
|
-
return
|
|
17973
|
+
return path35.basename(cwd) || null;
|
|
17764
17974
|
}
|
|
17765
17975
|
function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
17766
17976
|
const name = projectNameForCwd(cwd, root);
|
|
@@ -17768,8 +17978,8 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
|
17768
17978
|
log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
|
|
17769
17979
|
return null;
|
|
17770
17980
|
}
|
|
17771
|
-
const dir =
|
|
17772
|
-
if (!
|
|
17981
|
+
const dir = path35.join(root, "tmp", name, "chats");
|
|
17982
|
+
if (!fs30.existsSync(dir)) {
|
|
17773
17983
|
log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
|
|
17774
17984
|
return null;
|
|
17775
17985
|
}
|
|
@@ -17781,7 +17991,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
17781
17991
|
if (!dir) return null;
|
|
17782
17992
|
let files;
|
|
17783
17993
|
try {
|
|
17784
|
-
files =
|
|
17994
|
+
files = fs30.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
17785
17995
|
} catch (err) {
|
|
17786
17996
|
log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
|
|
17787
17997
|
return null;
|
|
@@ -17793,12 +18003,12 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
17793
18003
|
const byName = files.find((f) => id8.length > 0 && f.includes(id8));
|
|
17794
18004
|
if (byName) {
|
|
17795
18005
|
log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
|
|
17796
|
-
return
|
|
18006
|
+
return path35.join(dir, byName);
|
|
17797
18007
|
}
|
|
17798
18008
|
for (const f of files) {
|
|
17799
|
-
const full =
|
|
18009
|
+
const full = path35.join(dir, f);
|
|
17800
18010
|
try {
|
|
17801
|
-
const firstLine =
|
|
18011
|
+
const firstLine = fs30.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
|
|
17802
18012
|
const hdr = JSON.parse(firstLine);
|
|
17803
18013
|
if (hdr.sessionId === sessionId) {
|
|
17804
18014
|
log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
|
|
@@ -17811,7 +18021,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
17811
18021
|
let newest = null;
|
|
17812
18022
|
for (const f of files) {
|
|
17813
18023
|
try {
|
|
17814
|
-
const mtime =
|
|
18024
|
+
const mtime = fs30.statSync(path35.join(dir, f)).mtimeMs;
|
|
17815
18025
|
if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
|
|
17816
18026
|
} catch {
|
|
17817
18027
|
}
|
|
@@ -17820,7 +18030,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
17820
18030
|
"gemini",
|
|
17821
18031
|
`resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
|
|
17822
18032
|
);
|
|
17823
|
-
return newest ?
|
|
18033
|
+
return newest ? path35.join(dir, newest.file) : null;
|
|
17824
18034
|
}
|
|
17825
18035
|
function extractGeminiText(content) {
|
|
17826
18036
|
const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
|
|
@@ -17848,7 +18058,7 @@ function isSyntheticGeminiTurn(text) {
|
|
|
17848
18058
|
function parseHistoryFile5(filePath) {
|
|
17849
18059
|
let raw;
|
|
17850
18060
|
try {
|
|
17851
|
-
raw =
|
|
18061
|
+
raw = fs30.readFileSync(filePath, "utf8");
|
|
17852
18062
|
} catch (err) {
|
|
17853
18063
|
log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
|
|
17854
18064
|
return [];
|
|
@@ -17889,7 +18099,7 @@ function parseHistoryFile5(filePath) {
|
|
|
17889
18099
|
}
|
|
17890
18100
|
log.trace(
|
|
17891
18101
|
"gemini",
|
|
17892
|
-
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${
|
|
18102
|
+
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${path35.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
|
|
17893
18103
|
);
|
|
17894
18104
|
return out2;
|
|
17895
18105
|
}
|
|
@@ -17919,8 +18129,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
17919
18129
|
meta = getAgent("gemini");
|
|
17920
18130
|
mode = "interactive";
|
|
17921
18131
|
os;
|
|
17922
|
-
constructor(
|
|
17923
|
-
this.os =
|
|
18132
|
+
constructor(os67) {
|
|
18133
|
+
this.os = os67;
|
|
17924
18134
|
}
|
|
17925
18135
|
async prepareLaunch() {
|
|
17926
18136
|
const binary = this.os.findInPath("gemini");
|
|
@@ -18033,42 +18243,42 @@ var import_node_os3 = require("os");
|
|
|
18033
18243
|
var import_node_path4 = require("path");
|
|
18034
18244
|
|
|
18035
18245
|
// src/agents/kimi/history.ts
|
|
18036
|
-
var
|
|
18037
|
-
var
|
|
18038
|
-
var
|
|
18246
|
+
var fs31 = __toESM(require("fs"));
|
|
18247
|
+
var os28 = __toESM(require("os"));
|
|
18248
|
+
var path36 = __toESM(require("path"));
|
|
18039
18249
|
var import_node_crypto7 = require("crypto");
|
|
18040
18250
|
function kimiHome() {
|
|
18041
|
-
return process.env.KIMI_CODE_HOME ||
|
|
18251
|
+
return process.env.KIMI_CODE_HOME || path36.join(os28.homedir(), ".kimi-code");
|
|
18042
18252
|
}
|
|
18043
18253
|
function workDirKey(cwd) {
|
|
18044
18254
|
const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
|
|
18045
|
-
return `wd_${
|
|
18255
|
+
return `wd_${path36.basename(cwd)}_${hash}`;
|
|
18046
18256
|
}
|
|
18047
18257
|
function resolveHistoryDir6(cwd) {
|
|
18048
|
-
const dir =
|
|
18049
|
-
if (!
|
|
18258
|
+
const dir = path36.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18259
|
+
if (!fs31.existsSync(dir)) {
|
|
18050
18260
|
log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
|
|
18051
18261
|
return null;
|
|
18052
18262
|
}
|
|
18053
18263
|
return dir;
|
|
18054
18264
|
}
|
|
18055
|
-
var WIRE_REL =
|
|
18265
|
+
var WIRE_REL = path36.join("agents", "main", "wire.jsonl");
|
|
18056
18266
|
function resolveHistoryFile5(cwd, sessionId) {
|
|
18057
18267
|
const fromIndex = sessionDirFromIndex(sessionId);
|
|
18058
18268
|
if (fromIndex) {
|
|
18059
|
-
const p2 =
|
|
18060
|
-
if (
|
|
18269
|
+
const p2 = path36.join(fromIndex, WIRE_REL);
|
|
18270
|
+
if (fs31.existsSync(p2)) return p2;
|
|
18061
18271
|
}
|
|
18062
|
-
const bucket2 =
|
|
18063
|
-
const computed =
|
|
18064
|
-
if (
|
|
18272
|
+
const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18273
|
+
const computed = path36.join(bucket2, sessionId, WIRE_REL);
|
|
18274
|
+
if (fs31.existsSync(computed)) return computed;
|
|
18065
18275
|
const scanned = scanBucketsForSession(sessionId);
|
|
18066
18276
|
if (scanned) return scanned;
|
|
18067
18277
|
return null;
|
|
18068
18278
|
}
|
|
18069
18279
|
function sessionDirFromIndex(sessionId) {
|
|
18070
18280
|
try {
|
|
18071
|
-
const raw =
|
|
18281
|
+
const raw = fs31.readFileSync(path36.join(kimiHome(), "session_index.jsonl"), "utf8");
|
|
18072
18282
|
for (const line of raw.split("\n")) {
|
|
18073
18283
|
if (!line.includes(sessionId)) continue;
|
|
18074
18284
|
try {
|
|
@@ -18084,22 +18294,22 @@ function sessionDirFromIndex(sessionId) {
|
|
|
18084
18294
|
return null;
|
|
18085
18295
|
}
|
|
18086
18296
|
function scanBucketsForSession(sessionId) {
|
|
18087
|
-
const sessionsRoot =
|
|
18297
|
+
const sessionsRoot = path36.join(kimiHome(), "sessions");
|
|
18088
18298
|
let buckets;
|
|
18089
18299
|
try {
|
|
18090
|
-
buckets =
|
|
18300
|
+
buckets = fs31.readdirSync(sessionsRoot, { withFileTypes: true });
|
|
18091
18301
|
} catch {
|
|
18092
18302
|
return null;
|
|
18093
18303
|
}
|
|
18094
18304
|
for (const b of buckets) {
|
|
18095
18305
|
if (!b.isDirectory()) continue;
|
|
18096
|
-
const candidate =
|
|
18097
|
-
if (
|
|
18306
|
+
const candidate = path36.join(sessionsRoot, b.name, sessionId, WIRE_REL);
|
|
18307
|
+
if (fs31.existsSync(candidate)) return candidate;
|
|
18098
18308
|
}
|
|
18099
18309
|
return null;
|
|
18100
18310
|
}
|
|
18101
18311
|
async function discoverSessionId2(cwd, opts) {
|
|
18102
|
-
const bucket2 =
|
|
18312
|
+
const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18103
18313
|
const floor = opts.sinceMs - 2e3;
|
|
18104
18314
|
const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
|
|
18105
18315
|
for (; ; ) {
|
|
@@ -18112,7 +18322,7 @@ async function discoverSessionId2(cwd, opts) {
|
|
|
18112
18322
|
function newestSessionSince(bucket2, floorMs) {
|
|
18113
18323
|
let entries;
|
|
18114
18324
|
try {
|
|
18115
|
-
entries =
|
|
18325
|
+
entries = fs31.readdirSync(bucket2, { withFileTypes: true });
|
|
18116
18326
|
} catch {
|
|
18117
18327
|
return null;
|
|
18118
18328
|
}
|
|
@@ -18122,7 +18332,7 @@ function newestSessionSince(bucket2, floorMs) {
|
|
|
18122
18332
|
if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
|
|
18123
18333
|
let mtime;
|
|
18124
18334
|
try {
|
|
18125
|
-
mtime =
|
|
18335
|
+
mtime = fs31.statSync(path36.join(bucket2, e.name)).mtimeMs;
|
|
18126
18336
|
} catch {
|
|
18127
18337
|
continue;
|
|
18128
18338
|
}
|
|
@@ -18143,7 +18353,7 @@ function joinTextParts(parts) {
|
|
|
18143
18353
|
function parseHistoryFile6(filePath) {
|
|
18144
18354
|
let raw;
|
|
18145
18355
|
try {
|
|
18146
|
-
raw =
|
|
18356
|
+
raw = fs31.readFileSync(filePath, "utf8");
|
|
18147
18357
|
} catch {
|
|
18148
18358
|
return [];
|
|
18149
18359
|
}
|
|
@@ -18211,8 +18421,8 @@ var KimiRuntimeStrategy = class {
|
|
|
18211
18421
|
meta = getAgent("kimi");
|
|
18212
18422
|
mode = "interactive";
|
|
18213
18423
|
os;
|
|
18214
|
-
constructor(
|
|
18215
|
-
this.os =
|
|
18424
|
+
constructor(os67) {
|
|
18425
|
+
this.os = os67;
|
|
18216
18426
|
}
|
|
18217
18427
|
async prepareLaunch() {
|
|
18218
18428
|
const binary = this.os.findInPath("kimi");
|
|
@@ -18354,8 +18564,8 @@ var OpencodeRuntimeStrategy = class {
|
|
|
18354
18564
|
meta = getAgent("opencode");
|
|
18355
18565
|
mode = "interactive";
|
|
18356
18566
|
os;
|
|
18357
|
-
constructor(
|
|
18358
|
-
this.os =
|
|
18567
|
+
constructor(os67) {
|
|
18568
|
+
this.os = os67;
|
|
18359
18569
|
}
|
|
18360
18570
|
async prepareLaunch() {
|
|
18361
18571
|
const binary = this.os.findInPath("opencode");
|
|
@@ -18439,20 +18649,20 @@ var OpencodeRuntimeStrategy = class {
|
|
|
18439
18649
|
|
|
18440
18650
|
// src/agents/registry.ts
|
|
18441
18651
|
var runtimeBuilders = {
|
|
18442
|
-
claude: (
|
|
18443
|
-
codex: (
|
|
18444
|
-
coderabbit: (
|
|
18445
|
-
cursor: (
|
|
18446
|
-
aider: (
|
|
18447
|
-
gemini: (
|
|
18448
|
-
kimi: (
|
|
18449
|
-
opencode: (
|
|
18652
|
+
claude: (os67) => new ClaudeRuntimeStrategy(os67),
|
|
18653
|
+
codex: (os67) => new CodexRuntimeStrategy(os67),
|
|
18654
|
+
coderabbit: (os67) => new CoderabbitRuntimeStrategy(os67),
|
|
18655
|
+
cursor: (os67) => new CursorRuntimeStrategy(os67),
|
|
18656
|
+
aider: (os67) => new AiderRuntimeStrategy(os67),
|
|
18657
|
+
gemini: (os67) => new GeminiRuntimeStrategy(os67),
|
|
18658
|
+
kimi: (os67) => new KimiRuntimeStrategy(os67),
|
|
18659
|
+
opencode: (os67) => new OpencodeRuntimeStrategy(os67)
|
|
18450
18660
|
};
|
|
18451
18661
|
var deployBuilders = {
|
|
18452
18662
|
claude: () => new ClaudeDeployStrategy(),
|
|
18453
18663
|
codex: () => new CodexDeployStrategy()
|
|
18454
18664
|
};
|
|
18455
|
-
function createAgentStrategy(agent,
|
|
18665
|
+
function createAgentStrategy(agent, os67 = createOsStrategy()) {
|
|
18456
18666
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
18457
18667
|
throw new Error(
|
|
18458
18668
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -18462,10 +18672,10 @@ function createAgentStrategy(agent, os66 = createOsStrategy()) {
|
|
|
18462
18672
|
if (!build) {
|
|
18463
18673
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
18464
18674
|
}
|
|
18465
|
-
return build(
|
|
18675
|
+
return build(os67);
|
|
18466
18676
|
}
|
|
18467
|
-
function createInteractiveAgentStrategy(agent,
|
|
18468
|
-
const s = createAgentStrategy(agent,
|
|
18677
|
+
function createInteractiveAgentStrategy(agent, os67 = createOsStrategy()) {
|
|
18678
|
+
const s = createAgentStrategy(agent, os67);
|
|
18469
18679
|
if (s.mode !== "interactive") {
|
|
18470
18680
|
throw new Error(
|
|
18471
18681
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -18521,7 +18731,7 @@ function parseLinkArgs(args2) {
|
|
|
18521
18731
|
if (apiKeyFileArg) {
|
|
18522
18732
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
18523
18733
|
try {
|
|
18524
|
-
apiKey =
|
|
18734
|
+
apiKey = fs32.readFileSync(path37.resolve(filePath), "utf8").trim();
|
|
18525
18735
|
} catch (err) {
|
|
18526
18736
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
18527
18737
|
}
|
|
@@ -18648,7 +18858,7 @@ async function link(args2 = []) {
|
|
|
18648
18858
|
return;
|
|
18649
18859
|
}
|
|
18650
18860
|
if (parsed.tokenFile) {
|
|
18651
|
-
const credential =
|
|
18861
|
+
const credential = fs32.readFileSync(path37.resolve(parsed.tokenFile), "utf8").trim();
|
|
18652
18862
|
if (!credential) {
|
|
18653
18863
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
18654
18864
|
process.exit(1);
|
|
@@ -18867,13 +19077,13 @@ async function linkDryRunPreflight(ctx) {
|
|
|
18867
19077
|
// src/agents/coderabbit/configure.ts
|
|
18868
19078
|
var import_node_child_process17 = require("child_process");
|
|
18869
19079
|
var import_node_fs6 = require("fs");
|
|
18870
|
-
var
|
|
19080
|
+
var path39 = __toESM(require("path"));
|
|
18871
19081
|
|
|
18872
19082
|
// src/agents/coderabbit/oauth.ts
|
|
18873
19083
|
var import_node_child_process16 = require("child_process");
|
|
18874
|
-
var
|
|
18875
|
-
var
|
|
18876
|
-
var
|
|
19084
|
+
var fs33 = __toESM(require("fs"));
|
|
19085
|
+
var os29 = __toESM(require("os"));
|
|
19086
|
+
var path38 = __toESM(require("path"));
|
|
18877
19087
|
function parseCoderabbitAuthEvent(line) {
|
|
18878
19088
|
const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
|
|
18879
19089
|
if (!l || l[0] !== "{") return null;
|
|
@@ -18922,8 +19132,8 @@ function resolvePython() {
|
|
|
18922
19132
|
function spawnCoderabbitLoginProc(cmd, args2) {
|
|
18923
19133
|
const python = resolvePython();
|
|
18924
19134
|
if (python) {
|
|
18925
|
-
const helper =
|
|
18926
|
-
|
|
19135
|
+
const helper = path38.join(os29.tmpdir(), "codeam-cr-pty.py");
|
|
19136
|
+
fs33.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
|
|
18927
19137
|
return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
|
|
18928
19138
|
stdio: ["pipe", "pipe", "pipe"],
|
|
18929
19139
|
env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
|
|
@@ -19034,7 +19244,7 @@ function runCoderabbitOAuthLogin(deps) {
|
|
|
19034
19244
|
});
|
|
19035
19245
|
}
|
|
19036
19246
|
function coderabbitDir(home) {
|
|
19037
|
-
return
|
|
19247
|
+
return path38.join(home ?? os29.homedir(), ".coderabbit");
|
|
19038
19248
|
}
|
|
19039
19249
|
var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
|
|
19040
19250
|
function snapshotCredentialDir(home) {
|
|
@@ -19042,14 +19252,14 @@ function snapshotCredentialDir(home) {
|
|
|
19042
19252
|
const snap = {};
|
|
19043
19253
|
let entries;
|
|
19044
19254
|
try {
|
|
19045
|
-
entries =
|
|
19255
|
+
entries = fs33.readdirSync(dir, { withFileTypes: true });
|
|
19046
19256
|
} catch {
|
|
19047
19257
|
return snap;
|
|
19048
19258
|
}
|
|
19049
19259
|
for (const e of entries) {
|
|
19050
19260
|
if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
|
|
19051
19261
|
try {
|
|
19052
|
-
const st3 =
|
|
19262
|
+
const st3 = fs33.statSync(path38.join(dir, e.name));
|
|
19053
19263
|
snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
|
|
19054
19264
|
} catch {
|
|
19055
19265
|
}
|
|
@@ -19067,7 +19277,7 @@ function diffCapturedCredential(before, home) {
|
|
|
19067
19277
|
}
|
|
19068
19278
|
if (!best) return null;
|
|
19069
19279
|
try {
|
|
19070
|
-
return { file: best.file, contents:
|
|
19280
|
+
return { file: best.file, contents: fs33.readFileSync(path38.join(dir, best.file), "utf8") };
|
|
19071
19281
|
} catch {
|
|
19072
19282
|
return null;
|
|
19073
19283
|
}
|
|
@@ -19143,8 +19353,8 @@ function collectChangedFiles(cwd) {
|
|
|
19143
19353
|
}
|
|
19144
19354
|
return [...byPath.values()];
|
|
19145
19355
|
}
|
|
19146
|
-
function restoreCoderabbitOauthBlob(
|
|
19147
|
-
const dir =
|
|
19356
|
+
function restoreCoderabbitOauthBlob(os67, value) {
|
|
19357
|
+
const dir = path39.join(os67.homeDir(), ".coderabbit");
|
|
19148
19358
|
(0, import_node_fs6.mkdirSync)(dir, { recursive: true });
|
|
19149
19359
|
let file = "auth.json";
|
|
19150
19360
|
let contents = value.trim();
|
|
@@ -19152,38 +19362,38 @@ function restoreCoderabbitOauthBlob(os66, value) {
|
|
|
19152
19362
|
try {
|
|
19153
19363
|
const parsed = JSON.parse(contents);
|
|
19154
19364
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
19155
|
-
file =
|
|
19365
|
+
file = path39.basename(parsed.file);
|
|
19156
19366
|
contents = parsed.contents;
|
|
19157
19367
|
}
|
|
19158
19368
|
} catch {
|
|
19159
19369
|
}
|
|
19160
19370
|
}
|
|
19161
|
-
(0, import_node_fs6.writeFileSync)(
|
|
19371
|
+
(0, import_node_fs6.writeFileSync)(path39.join(dir, file), contents, { mode: 384 });
|
|
19162
19372
|
}
|
|
19163
19373
|
function installFailureMessage(result) {
|
|
19164
19374
|
return result.error ?? "CodeRabbit CLI could not be installed";
|
|
19165
19375
|
}
|
|
19166
19376
|
async function configureCoderabbit(input, deps = {}) {
|
|
19167
|
-
const
|
|
19377
|
+
const os67 = deps.os ?? createOsStrategy();
|
|
19168
19378
|
const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
|
|
19169
19379
|
const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
|
|
19170
19380
|
const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
|
|
19171
19381
|
const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
|
|
19172
19382
|
const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
|
|
19173
19383
|
const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
|
|
19174
|
-
const home =
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
] : [
|
|
19384
|
+
const home = os67.homeDir();
|
|
19385
|
+
os67.augmentPath(
|
|
19386
|
+
os67.id === "win32" ? [
|
|
19387
|
+
path39.join(home, ".local", "bin"),
|
|
19388
|
+
path39.join(process.env.APPDATA ?? path39.join(home, "AppData", "Roaming"), "npm"),
|
|
19389
|
+
path39.join(home, "scoop", "shims")
|
|
19390
|
+
] : [path39.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
19181
19391
|
);
|
|
19182
|
-
const installed2 =
|
|
19392
|
+
const installed2 = os67.findInPath("coderabbit") !== null;
|
|
19183
19393
|
const base = () => ({
|
|
19184
19394
|
action: input.action,
|
|
19185
19395
|
supported: true,
|
|
19186
|
-
installed:
|
|
19396
|
+
installed: os67.findInPath("coderabbit") !== null,
|
|
19187
19397
|
loggedIn: false
|
|
19188
19398
|
});
|
|
19189
19399
|
if (input.action === "status") {
|
|
@@ -19197,7 +19407,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19197
19407
|
const key = (input.apiKey ?? "").trim();
|
|
19198
19408
|
if (!key) return { ...res2, error: "No API key provided" };
|
|
19199
19409
|
if (!res2.installed) {
|
|
19200
|
-
const inst = await ensureInstalled(
|
|
19410
|
+
const inst = await ensureInstalled(os67);
|
|
19201
19411
|
res2.installed = inst.ok;
|
|
19202
19412
|
if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
|
|
19203
19413
|
}
|
|
@@ -19221,7 +19431,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19221
19431
|
}
|
|
19222
19432
|
if (!res2.installed) {
|
|
19223
19433
|
deps.onEvent?.({ kind: "installing" });
|
|
19224
|
-
const inst = await ensureInstalled(
|
|
19434
|
+
const inst = await ensureInstalled(os67);
|
|
19225
19435
|
res2.installed = inst.ok;
|
|
19226
19436
|
if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
|
|
19227
19437
|
}
|
|
@@ -19238,7 +19448,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19238
19448
|
return { ...res2, loggedIn: true, linked: true };
|
|
19239
19449
|
}
|
|
19240
19450
|
try {
|
|
19241
|
-
restoreCoderabbitOauthBlob(
|
|
19451
|
+
restoreCoderabbitOauthBlob(os67, cred.credential);
|
|
19242
19452
|
} catch (err) {
|
|
19243
19453
|
return {
|
|
19244
19454
|
...res2,
|
|
@@ -19262,7 +19472,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19262
19472
|
const res2 = base();
|
|
19263
19473
|
if (!installed2) {
|
|
19264
19474
|
deps.onEvent?.({ kind: "installing" });
|
|
19265
|
-
const inst = await ensureInstalled(
|
|
19475
|
+
const inst = await ensureInstalled(os67);
|
|
19266
19476
|
res2.installed = inst.ok;
|
|
19267
19477
|
if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
|
|
19268
19478
|
}
|
|
@@ -19302,7 +19512,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19302
19512
|
}
|
|
19303
19513
|
const res = base();
|
|
19304
19514
|
if (!res.installed) {
|
|
19305
|
-
const inst = await ensureInstalled(
|
|
19515
|
+
const inst = await ensureInstalled(os67);
|
|
19306
19516
|
res.installed = inst.ok;
|
|
19307
19517
|
if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
|
|
19308
19518
|
}
|
|
@@ -19486,9 +19696,9 @@ function defaultRunGh(args2) {
|
|
|
19486
19696
|
|
|
19487
19697
|
// src/commands/host-agent.ts
|
|
19488
19698
|
var import_node_child_process25 = require("child_process");
|
|
19489
|
-
var
|
|
19490
|
-
var
|
|
19491
|
-
var
|
|
19699
|
+
var os42 = __toESM(require("os"));
|
|
19700
|
+
var fs46 = __toESM(require("fs"));
|
|
19701
|
+
var path50 = __toESM(require("path"));
|
|
19492
19702
|
|
|
19493
19703
|
// src/integrations/manifest.ts
|
|
19494
19704
|
var import_node_fs8 = __toESM(require("fs"));
|
|
@@ -19611,14 +19821,14 @@ function persistOrClearSkillsFromPayload(skills) {
|
|
|
19611
19821
|
}
|
|
19612
19822
|
|
|
19613
19823
|
// src/commands/host/agent-install.ts
|
|
19614
|
-
var
|
|
19615
|
-
var
|
|
19824
|
+
var import_child_process14 = require("child_process");
|
|
19825
|
+
var os33 = __toESM(require("os"));
|
|
19616
19826
|
function runAgentInstallScript(script, opts = {}) {
|
|
19617
19827
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
19618
19828
|
const scope = opts.logScope ?? "agent-install";
|
|
19619
19829
|
return new Promise((resolve9) => {
|
|
19620
|
-
const home = process.env.HOME ||
|
|
19621
|
-
const child = (0,
|
|
19830
|
+
const home = process.env.HOME || os33.homedir();
|
|
19831
|
+
const child = (0, import_child_process14.spawn)("sh", ["-c", script], {
|
|
19622
19832
|
env: { ...process.env, HOME: home },
|
|
19623
19833
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19624
19834
|
});
|
|
@@ -19683,14 +19893,14 @@ function describeReason(reason) {
|
|
|
19683
19893
|
}
|
|
19684
19894
|
|
|
19685
19895
|
// src/commands/host/host-client.ts
|
|
19686
|
-
var
|
|
19687
|
-
var
|
|
19688
|
-
var
|
|
19896
|
+
var fs37 = __toESM(require("fs"));
|
|
19897
|
+
var os34 = __toESM(require("os"));
|
|
19898
|
+
var path42 = __toESM(require("path"));
|
|
19689
19899
|
var import_node_crypto9 = require("crypto");
|
|
19690
19900
|
function sampleCpuTimes() {
|
|
19691
19901
|
let idle = 0;
|
|
19692
19902
|
let total = 0;
|
|
19693
|
-
for (const cpu of
|
|
19903
|
+
for (const cpu of os34.cpus()) {
|
|
19694
19904
|
const t2 = cpu.times;
|
|
19695
19905
|
idle += t2.idle;
|
|
19696
19906
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -19709,8 +19919,8 @@ var MetricsCollector = class {
|
|
|
19709
19919
|
const prev = this.prevCpu;
|
|
19710
19920
|
this.prevCpu = current2;
|
|
19711
19921
|
if (!prev) {
|
|
19712
|
-
const cores =
|
|
19713
|
-
const proxy =
|
|
19922
|
+
const cores = os34.cpus().length || 1;
|
|
19923
|
+
const proxy = os34.loadavg()[0] / cores * 100;
|
|
19714
19924
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
19715
19925
|
}
|
|
19716
19926
|
const idleDelta = current2.idle - prev.idle;
|
|
@@ -19723,8 +19933,8 @@ var MetricsCollector = class {
|
|
|
19723
19933
|
collect() {
|
|
19724
19934
|
return {
|
|
19725
19935
|
cpuPct: this.cpuPct(),
|
|
19726
|
-
ramUsedMb: Math.round((
|
|
19727
|
-
ramTotalMb: Math.round(
|
|
19936
|
+
ramUsedMb: Math.round((os34.totalmem() - os34.freemem()) / 1048576),
|
|
19937
|
+
ramTotalMb: Math.round(os34.totalmem() / 1048576),
|
|
19728
19938
|
latencyMs: this.lastLatencyMs
|
|
19729
19939
|
};
|
|
19730
19940
|
}
|
|
@@ -19733,19 +19943,19 @@ function apiBase() {
|
|
|
19733
19943
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
19734
19944
|
}
|
|
19735
19945
|
function hostIdentityPath() {
|
|
19736
|
-
return
|
|
19946
|
+
return path42.join(os34.homedir(), ".codeam", "host-agent.json");
|
|
19737
19947
|
}
|
|
19738
19948
|
function collectOsInfo() {
|
|
19739
19949
|
return {
|
|
19740
|
-
distro:
|
|
19741
|
-
arch:
|
|
19742
|
-
kernel:
|
|
19950
|
+
distro: os34.platform(),
|
|
19951
|
+
arch: os34.arch(),
|
|
19952
|
+
kernel: os34.release(),
|
|
19743
19953
|
nodeVersion: process.versions.node
|
|
19744
19954
|
};
|
|
19745
19955
|
}
|
|
19746
19956
|
function loadHostIdentity() {
|
|
19747
19957
|
try {
|
|
19748
|
-
const raw =
|
|
19958
|
+
const raw = fs37.readFileSync(hostIdentityPath(), "utf8");
|
|
19749
19959
|
const parsed = JSON.parse(raw);
|
|
19750
19960
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
19751
19961
|
const p2 = parsed;
|
|
@@ -19764,8 +19974,8 @@ function loadHostIdentity() {
|
|
|
19764
19974
|
}
|
|
19765
19975
|
function saveHostIdentity(identity) {
|
|
19766
19976
|
const file = hostIdentityPath();
|
|
19767
|
-
|
|
19768
|
-
|
|
19977
|
+
fs37.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
|
|
19978
|
+
fs37.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
19769
19979
|
encoding: "utf8",
|
|
19770
19980
|
mode: 384
|
|
19771
19981
|
});
|
|
@@ -19810,7 +20020,7 @@ function isTerminalEnrollError(err) {
|
|
|
19810
20020
|
}
|
|
19811
20021
|
function deleteHostIdentity() {
|
|
19812
20022
|
try {
|
|
19813
|
-
|
|
20023
|
+
fs37.rmSync(hostIdentityPath(), { force: true });
|
|
19814
20024
|
} catch {
|
|
19815
20025
|
}
|
|
19816
20026
|
}
|
|
@@ -19834,7 +20044,7 @@ async function postJson(pathname, body) {
|
|
|
19834
20044
|
function resolveHostLabel(label) {
|
|
19835
20045
|
const explicit = label?.trim();
|
|
19836
20046
|
const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
|
|
19837
|
-
const resolved = explicit || envLabel ||
|
|
20047
|
+
const resolved = explicit || envLabel || os34.hostname();
|
|
19838
20048
|
return resolved.slice(0, 80);
|
|
19839
20049
|
}
|
|
19840
20050
|
async function redeemEnrollToken(token, label) {
|
|
@@ -19945,17 +20155,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
19945
20155
|
}
|
|
19946
20156
|
|
|
19947
20157
|
// src/commands/host/workspace.ts
|
|
19948
|
-
var
|
|
19949
|
-
var
|
|
19950
|
-
var
|
|
20158
|
+
var fs38 = __toESM(require("fs"));
|
|
20159
|
+
var os35 = __toESM(require("os"));
|
|
20160
|
+
var path43 = __toESM(require("path"));
|
|
19951
20161
|
var import_node_child_process20 = require("child_process");
|
|
19952
20162
|
var import_node_util4 = require("util");
|
|
19953
20163
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process20.execFile);
|
|
19954
20164
|
function isAbsolutePathTarget(target) {
|
|
19955
|
-
return
|
|
20165
|
+
return path43.isAbsolute(target);
|
|
19956
20166
|
}
|
|
19957
20167
|
function selfHostedWorkspaceRoot() {
|
|
19958
|
-
return
|
|
20168
|
+
return path43.join(os35.homedir(), ".codeam", "self-hosted");
|
|
19959
20169
|
}
|
|
19960
20170
|
function nonInteractiveGitEnv() {
|
|
19961
20171
|
return {
|
|
@@ -20025,15 +20235,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
|
|
|
20025
20235
|
const isGitlab = provider === "gitlab";
|
|
20026
20236
|
if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
|
|
20027
20237
|
if (!cloneToken) return;
|
|
20028
|
-
const credFile =
|
|
20238
|
+
const credFile = path43.join(dest, ".git", "codeam-credentials");
|
|
20029
20239
|
const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
|
|
20030
20240
|
` : `https://x-access-token:${cloneToken}@github.com
|
|
20031
20241
|
`;
|
|
20032
|
-
|
|
20242
|
+
fs38.writeFileSync(credFile, credLine, { mode: 384 });
|
|
20033
20243
|
restrictToOwner(credFile);
|
|
20034
20244
|
const env = nonInteractiveGitEnv();
|
|
20035
20245
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
20036
|
-
const credFilePosix = credFile.split(
|
|
20246
|
+
const credFilePosix = credFile.split(path43.sep).join("/");
|
|
20037
20247
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
20038
20248
|
});
|
|
20039
20249
|
await git2([
|
|
@@ -20066,17 +20276,17 @@ function maskToken(text, cloneToken) {
|
|
|
20066
20276
|
}
|
|
20067
20277
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
|
|
20068
20278
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
20069
|
-
if (!
|
|
20279
|
+
if (!fs38.existsSync(repoOrPath)) {
|
|
20070
20280
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
20071
20281
|
}
|
|
20072
20282
|
return repoOrPath;
|
|
20073
20283
|
}
|
|
20074
|
-
const dest =
|
|
20075
|
-
if (
|
|
20284
|
+
const dest = path43.join(selfHostedWorkspaceRoot(), deployId);
|
|
20285
|
+
if (fs38.existsSync(path43.join(dest, ".git"))) {
|
|
20076
20286
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
|
|
20077
20287
|
return dest;
|
|
20078
20288
|
}
|
|
20079
|
-
|
|
20289
|
+
fs38.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
20080
20290
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
|
|
20081
20291
|
const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
|
|
20082
20292
|
try {
|
|
@@ -20094,9 +20304,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
|
|
|
20094
20304
|
}
|
|
20095
20305
|
|
|
20096
20306
|
// src/commands/host/agent-provisioning.ts
|
|
20097
|
-
var
|
|
20098
|
-
var
|
|
20099
|
-
var
|
|
20307
|
+
var fs39 = __toESM(require("fs"));
|
|
20308
|
+
var os36 = __toESM(require("os"));
|
|
20309
|
+
var path44 = __toESM(require("path"));
|
|
20100
20310
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
20101
20311
|
claude_code: "claude",
|
|
20102
20312
|
claude: "claude",
|
|
@@ -20113,22 +20323,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
20113
20323
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
20114
20324
|
}
|
|
20115
20325
|
function ensureDir(dir) {
|
|
20116
|
-
|
|
20326
|
+
fs39.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
20117
20327
|
}
|
|
20118
20328
|
function writeFile0600(filePath, contents) {
|
|
20119
|
-
ensureDir(
|
|
20120
|
-
|
|
20329
|
+
ensureDir(path44.dirname(filePath));
|
|
20330
|
+
fs39.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
20121
20331
|
restrictToOwner(filePath);
|
|
20122
20332
|
}
|
|
20123
20333
|
function rmIfExists(filePath) {
|
|
20124
20334
|
try {
|
|
20125
|
-
|
|
20335
|
+
fs39.rmSync(filePath, { force: true });
|
|
20126
20336
|
} catch {
|
|
20127
20337
|
}
|
|
20128
20338
|
}
|
|
20129
20339
|
var claudeProvisioner = {
|
|
20130
20340
|
write(auth, home) {
|
|
20131
|
-
const credentialsJson =
|
|
20341
|
+
const credentialsJson = path44.join(home, ".claude", ".credentials.json");
|
|
20132
20342
|
if (auth.kind === "api_key") {
|
|
20133
20343
|
rmIfExists(credentialsJson);
|
|
20134
20344
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -20140,8 +20350,8 @@ var claudeProvisioner = {
|
|
|
20140
20350
|
} else {
|
|
20141
20351
|
rmIfExists(credentialsJson);
|
|
20142
20352
|
}
|
|
20143
|
-
const claudeJson =
|
|
20144
|
-
if (!
|
|
20353
|
+
const claudeJson = path44.join(home, ".claude.json");
|
|
20354
|
+
if (!fs39.existsSync(claudeJson)) {
|
|
20145
20355
|
writeFile0600(
|
|
20146
20356
|
claudeJson,
|
|
20147
20357
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -20152,7 +20362,7 @@ var claudeProvisioner = {
|
|
|
20152
20362
|
};
|
|
20153
20363
|
var codexProvisioner = {
|
|
20154
20364
|
write(auth, home) {
|
|
20155
|
-
const authJson =
|
|
20365
|
+
const authJson = path44.join(home, ".codex", "auth.json");
|
|
20156
20366
|
if (auth.kind === "api_key") {
|
|
20157
20367
|
rmIfExists(authJson);
|
|
20158
20368
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -20163,8 +20373,8 @@ var codexProvisioner = {
|
|
|
20163
20373
|
};
|
|
20164
20374
|
var geminiProvisioner = {
|
|
20165
20375
|
write(auth, home) {
|
|
20166
|
-
const settingsJson =
|
|
20167
|
-
const oauthCreds =
|
|
20376
|
+
const settingsJson = path44.join(home, ".gemini", "settings.json");
|
|
20377
|
+
const oauthCreds = path44.join(home, ".gemini", "oauth_creds.json");
|
|
20168
20378
|
if (auth.kind === "api_key") {
|
|
20169
20379
|
rmIfExists(oauthCreds);
|
|
20170
20380
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -20177,7 +20387,7 @@ var geminiProvisioner = {
|
|
|
20177
20387
|
};
|
|
20178
20388
|
var cursorProvisioner = {
|
|
20179
20389
|
write(auth, home) {
|
|
20180
|
-
const authJson =
|
|
20390
|
+
const authJson = path44.join(home, ".config", "cursor", "auth.json");
|
|
20181
20391
|
if (auth.kind === "api_key") {
|
|
20182
20392
|
rmIfExists(authJson);
|
|
20183
20393
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -20219,22 +20429,22 @@ max_context_size = 262144
|
|
|
20219
20429
|
var kimiProvisioner = {
|
|
20220
20430
|
write(auth, home) {
|
|
20221
20431
|
const credentialsFiles = [
|
|
20222
|
-
|
|
20223
|
-
|
|
20432
|
+
path44.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
20433
|
+
path44.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
20224
20434
|
];
|
|
20225
20435
|
if (auth.kind === "api_key") {
|
|
20226
20436
|
credentialsFiles.forEach(rmIfExists);
|
|
20227
20437
|
return { KIMI_API_KEY: auth.value };
|
|
20228
20438
|
}
|
|
20229
20439
|
credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
|
|
20230
|
-
writeFile0600(
|
|
20440
|
+
writeFile0600(path44.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
|
|
20231
20441
|
return {};
|
|
20232
20442
|
}
|
|
20233
20443
|
};
|
|
20234
20444
|
var coderabbitProvisioner = {
|
|
20235
20445
|
write(auth, home) {
|
|
20236
|
-
const dir =
|
|
20237
|
-
const authJson =
|
|
20446
|
+
const dir = path44.join(home, ".coderabbit");
|
|
20447
|
+
const authJson = path44.join(dir, "auth.json");
|
|
20238
20448
|
if (auth.kind === "api_key") {
|
|
20239
20449
|
rmIfExists(authJson);
|
|
20240
20450
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -20246,13 +20456,13 @@ var coderabbitProvisioner = {
|
|
|
20246
20456
|
try {
|
|
20247
20457
|
const parsed = JSON.parse(value);
|
|
20248
20458
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
20249
|
-
file =
|
|
20459
|
+
file = path44.basename(parsed.file);
|
|
20250
20460
|
contents = parsed.contents;
|
|
20251
20461
|
}
|
|
20252
20462
|
} catch {
|
|
20253
20463
|
}
|
|
20254
20464
|
}
|
|
20255
|
-
writeFile0600(
|
|
20465
|
+
writeFile0600(path44.join(dir, file), contents);
|
|
20256
20466
|
return {};
|
|
20257
20467
|
}
|
|
20258
20468
|
};
|
|
@@ -20280,7 +20490,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
20280
20490
|
this.agentId = agentId;
|
|
20281
20491
|
}
|
|
20282
20492
|
};
|
|
20283
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
20493
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os36.homedir()) {
|
|
20284
20494
|
const internal = toInternalAgentId(publicAgentId);
|
|
20285
20495
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
20286
20496
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -20290,11 +20500,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os35.homedir(
|
|
|
20290
20500
|
|
|
20291
20501
|
// src/commands/host/git-tooling.ts
|
|
20292
20502
|
var import_node_child_process21 = require("child_process");
|
|
20293
|
-
var
|
|
20294
|
-
var
|
|
20295
|
-
var
|
|
20503
|
+
var fs40 = __toESM(require("fs"));
|
|
20504
|
+
var os37 = __toESM(require("os"));
|
|
20505
|
+
var path45 = __toESM(require("path"));
|
|
20296
20506
|
function codeamBinDir() {
|
|
20297
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
20507
|
+
return process.env.CODEAM_BIN_DIR ?? path45.join(os37.homedir(), ".codeam", "bin");
|
|
20298
20508
|
}
|
|
20299
20509
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
20300
20510
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -20326,7 +20536,7 @@ async function download(url2, dest) {
|
|
|
20326
20536
|
const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
|
|
20327
20537
|
if (!res.ok || !res.body) return false;
|
|
20328
20538
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
20329
|
-
|
|
20539
|
+
fs40.writeFileSync(dest, buf);
|
|
20330
20540
|
return true;
|
|
20331
20541
|
} catch {
|
|
20332
20542
|
return false;
|
|
@@ -20349,8 +20559,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
20349
20559
|
const version3 = await resolveVersionFn(token);
|
|
20350
20560
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
20351
20561
|
const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
20352
|
-
const tmpRoot =
|
|
20353
|
-
const archive =
|
|
20562
|
+
const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-gh-"));
|
|
20563
|
+
const archive = path45.join(tmpRoot, `${asset}.${ext}`);
|
|
20354
20564
|
if (!await downloadFn(url2, archive)) {
|
|
20355
20565
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
20356
20566
|
return null;
|
|
@@ -20360,16 +20570,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
20360
20570
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
20361
20571
|
return null;
|
|
20362
20572
|
}
|
|
20363
|
-
const extractedBin =
|
|
20364
|
-
if (!
|
|
20573
|
+
const extractedBin = path45.join(tmpRoot, asset, "bin", binaryName);
|
|
20574
|
+
if (!fs40.existsSync(extractedBin)) {
|
|
20365
20575
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
20366
20576
|
return null;
|
|
20367
20577
|
}
|
|
20368
20578
|
const binDir = codeamBinDir();
|
|
20369
|
-
|
|
20370
|
-
const target =
|
|
20371
|
-
|
|
20372
|
-
|
|
20579
|
+
fs40.mkdirSync(binDir, { recursive: true });
|
|
20580
|
+
const target = path45.join(binDir, binaryName);
|
|
20581
|
+
fs40.copyFileSync(extractedBin, target);
|
|
20582
|
+
fs40.chmodSync(target, 493);
|
|
20373
20583
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
20374
20584
|
return target;
|
|
20375
20585
|
} catch (e) {
|
|
@@ -20429,8 +20639,8 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
20429
20639
|
const version3 = await resolveLatestGlabVersion();
|
|
20430
20640
|
const asset = `glab_${version3}_${osToken}_${arch2}`;
|
|
20431
20641
|
const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
|
|
20432
|
-
const tmpRoot =
|
|
20433
|
-
const archive =
|
|
20642
|
+
const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-glab-"));
|
|
20643
|
+
const archive = path45.join(tmpRoot, `${asset}.${ext}`);
|
|
20434
20644
|
if (!await downloadFn(url2, archive)) {
|
|
20435
20645
|
log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
|
|
20436
20646
|
return null;
|
|
@@ -20441,20 +20651,20 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
20441
20651
|
return null;
|
|
20442
20652
|
}
|
|
20443
20653
|
const candidates = [
|
|
20444
|
-
|
|
20445
|
-
|
|
20446
|
-
|
|
20654
|
+
path45.join(tmpRoot, "bin", binaryName),
|
|
20655
|
+
path45.join(tmpRoot, asset, "bin", binaryName),
|
|
20656
|
+
path45.join(tmpRoot, binaryName)
|
|
20447
20657
|
];
|
|
20448
|
-
const extractedBin = candidates.find((c2) =>
|
|
20658
|
+
const extractedBin = candidates.find((c2) => fs40.existsSync(c2));
|
|
20449
20659
|
if (!extractedBin) {
|
|
20450
20660
|
log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
|
|
20451
20661
|
return null;
|
|
20452
20662
|
}
|
|
20453
20663
|
const binDir = codeamBinDir();
|
|
20454
|
-
|
|
20455
|
-
const target =
|
|
20456
|
-
|
|
20457
|
-
|
|
20664
|
+
fs40.mkdirSync(binDir, { recursive: true });
|
|
20665
|
+
const target = path45.join(binDir, binaryName);
|
|
20666
|
+
fs40.copyFileSync(extractedBin, target);
|
|
20667
|
+
fs40.chmodSync(target, 493);
|
|
20458
20668
|
log.info("host-agent", `glab installed to ${target} (v${version3})`);
|
|
20459
20669
|
return target;
|
|
20460
20670
|
} catch (e) {
|
|
@@ -20651,24 +20861,24 @@ var HeadroomStatsReporter = class {
|
|
|
20651
20861
|
};
|
|
20652
20862
|
|
|
20653
20863
|
// src/commands/host/headroom-bootstrap.ts
|
|
20654
|
-
var
|
|
20655
|
-
var
|
|
20656
|
-
var
|
|
20864
|
+
var fs42 = __toESM(require("fs"));
|
|
20865
|
+
var path47 = __toESM(require("path"));
|
|
20866
|
+
var os39 = __toESM(require("os"));
|
|
20657
20867
|
|
|
20658
20868
|
// src/commands/host/headroom-config.ts
|
|
20659
|
-
var
|
|
20660
|
-
var
|
|
20661
|
-
var
|
|
20869
|
+
var fs41 = __toESM(require("fs"));
|
|
20870
|
+
var os38 = __toESM(require("os"));
|
|
20871
|
+
var path46 = __toESM(require("path"));
|
|
20662
20872
|
function headroomConfigPath() {
|
|
20663
|
-
return
|
|
20873
|
+
return path46.join(os38.homedir(), ".codeam", "headroom-config.json");
|
|
20664
20874
|
}
|
|
20665
20875
|
function persistHeadroomConfig(config) {
|
|
20666
20876
|
try {
|
|
20667
20877
|
const file = headroomConfigPath();
|
|
20668
|
-
|
|
20878
|
+
fs41.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
|
|
20669
20879
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
20670
|
-
|
|
20671
|
-
|
|
20880
|
+
fs41.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
20881
|
+
fs41.renameSync(tmp, file);
|
|
20672
20882
|
restrictToOwner(file);
|
|
20673
20883
|
} catch (err) {
|
|
20674
20884
|
log.warn(
|
|
@@ -20678,21 +20888,21 @@ function persistHeadroomConfig(config) {
|
|
|
20678
20888
|
}
|
|
20679
20889
|
}
|
|
20680
20890
|
function agentSettingsPath(kind) {
|
|
20681
|
-
const home =
|
|
20682
|
-
if (kind === "claude") return
|
|
20683
|
-
if (kind === "codex") return
|
|
20684
|
-
if (kind === "copilot") return
|
|
20891
|
+
const home = os38.homedir();
|
|
20892
|
+
if (kind === "claude") return path46.join(home, ".claude", "settings.json");
|
|
20893
|
+
if (kind === "codex") return path46.join(home, ".codex", "auth.json");
|
|
20894
|
+
if (kind === "copilot") return path46.join(home, ".config", "github-copilot", "hosts.json");
|
|
20685
20895
|
return null;
|
|
20686
20896
|
}
|
|
20687
20897
|
function backupAgentHeadroomConfig(kind) {
|
|
20688
20898
|
const src = agentSettingsPath(kind);
|
|
20689
20899
|
if (!src) return;
|
|
20690
20900
|
try {
|
|
20691
|
-
if (!
|
|
20692
|
-
const dest =
|
|
20693
|
-
|
|
20694
|
-
|
|
20695
|
-
|
|
20901
|
+
if (!fs41.existsSync(src)) return;
|
|
20902
|
+
const dest = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
20903
|
+
fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
|
|
20904
|
+
fs41.copyFileSync(src, dest);
|
|
20905
|
+
fs41.chmodSync(dest, 384);
|
|
20696
20906
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
20697
20907
|
} catch (err) {
|
|
20698
20908
|
log.warn(
|
|
@@ -20704,12 +20914,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
20704
20914
|
function restoreAgentHeadroomConfig(kind) {
|
|
20705
20915
|
const dest = agentSettingsPath(kind);
|
|
20706
20916
|
if (!dest) return false;
|
|
20707
|
-
const src =
|
|
20708
|
-
if (!
|
|
20917
|
+
const src = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
20918
|
+
if (!fs41.existsSync(src)) return false;
|
|
20709
20919
|
try {
|
|
20710
|
-
|
|
20711
|
-
|
|
20712
|
-
|
|
20920
|
+
fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
|
|
20921
|
+
fs41.copyFileSync(src, dest);
|
|
20922
|
+
fs41.chmodSync(dest, 384);
|
|
20713
20923
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
20714
20924
|
return true;
|
|
20715
20925
|
} catch (err) {
|
|
@@ -20722,7 +20932,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
20722
20932
|
}
|
|
20723
20933
|
function readHeadroomChildEnv() {
|
|
20724
20934
|
try {
|
|
20725
|
-
const raw =
|
|
20935
|
+
const raw = fs41.readFileSync(headroomConfigPath(), "utf8");
|
|
20726
20936
|
const parsed = JSON.parse(raw);
|
|
20727
20937
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
20728
20938
|
const o = parsed;
|
|
@@ -20758,49 +20968,49 @@ function bundledClaudeBinDir() {
|
|
|
20758
20968
|
const roots = /* @__PURE__ */ new Set();
|
|
20759
20969
|
let dir = __dirname;
|
|
20760
20970
|
for (let i = 0; i < 6; i++) {
|
|
20761
|
-
roots.add(
|
|
20762
|
-
const parent =
|
|
20971
|
+
roots.add(path47.join(dir, "node_modules"));
|
|
20972
|
+
const parent = path47.dirname(dir);
|
|
20763
20973
|
if (parent === dir) break;
|
|
20764
20974
|
dir = parent;
|
|
20765
20975
|
}
|
|
20766
20976
|
try {
|
|
20767
20977
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
20768
|
-
const marker = `${
|
|
20978
|
+
const marker = `${path47.sep}@anthropic-ai${path47.sep}`;
|
|
20769
20979
|
const idx = main2.lastIndexOf(marker);
|
|
20770
20980
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
20771
20981
|
} catch {
|
|
20772
20982
|
}
|
|
20773
20983
|
for (const nm of roots) {
|
|
20774
|
-
const atAnthropic =
|
|
20984
|
+
const atAnthropic = path47.join(nm, "@anthropic-ai");
|
|
20775
20985
|
let entries;
|
|
20776
20986
|
try {
|
|
20777
|
-
entries =
|
|
20987
|
+
entries = fs42.readdirSync(atAnthropic);
|
|
20778
20988
|
} catch {
|
|
20779
20989
|
continue;
|
|
20780
20990
|
}
|
|
20781
20991
|
for (const entry of entries) {
|
|
20782
20992
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
20783
|
-
const bin =
|
|
20784
|
-
if (
|
|
20993
|
+
const bin = path47.join(atAnthropic, entry, "claude");
|
|
20994
|
+
if (fs42.existsSync(bin)) return path47.dirname(bin);
|
|
20785
20995
|
}
|
|
20786
20996
|
}
|
|
20787
20997
|
return null;
|
|
20788
20998
|
}
|
|
20789
20999
|
async function getFreeDiskBytes(dir) {
|
|
20790
21000
|
try {
|
|
20791
|
-
const s = await
|
|
21001
|
+
const s = await fs42.promises.statfs(dir);
|
|
20792
21002
|
return s.bsize * s.bavail;
|
|
20793
21003
|
} catch {
|
|
20794
21004
|
return null;
|
|
20795
21005
|
}
|
|
20796
21006
|
}
|
|
20797
21007
|
function headroomModelsCached() {
|
|
20798
|
-
const hubDir = process.env.HUGGINGFACE_HUB_CACHE ||
|
|
20799
|
-
process.env.HF_HOME ||
|
|
21008
|
+
const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path47.join(
|
|
21009
|
+
process.env.HF_HOME || path47.join(os39.homedir(), ".cache", "huggingface"),
|
|
20800
21010
|
"hub"
|
|
20801
21011
|
);
|
|
20802
21012
|
return HEADROOM_MODELS.every(
|
|
20803
|
-
(m) =>
|
|
21013
|
+
(m) => fs42.existsSync(path47.join(hubDir, `models--${m.repo.replace("/", "--")}`))
|
|
20804
21014
|
);
|
|
20805
21015
|
}
|
|
20806
21016
|
async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
|
|
@@ -20869,7 +21079,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
20869
21079
|
if (initKind === "claude") {
|
|
20870
21080
|
const claudeDir = bundledClaudeBinDir();
|
|
20871
21081
|
if (claudeDir) {
|
|
20872
|
-
initEnv.PATH = `${claudeDir}${
|
|
21082
|
+
initEnv.PATH = `${claudeDir}${path47.delimiter}${process.env["PATH"] ?? ""}`;
|
|
20873
21083
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
20874
21084
|
} else {
|
|
20875
21085
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -20906,19 +21116,19 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
20906
21116
|
}
|
|
20907
21117
|
|
|
20908
21118
|
// src/commands/host/house-proxy-config.ts
|
|
20909
|
-
var
|
|
20910
|
-
var
|
|
20911
|
-
var
|
|
21119
|
+
var fs43 = __toESM(require("fs"));
|
|
21120
|
+
var os40 = __toESM(require("os"));
|
|
21121
|
+
var path48 = __toESM(require("path"));
|
|
20912
21122
|
function houseProxyConfigPath() {
|
|
20913
|
-
return
|
|
21123
|
+
return path48.join(os40.homedir(), ".codeam", "house-proxy.json");
|
|
20914
21124
|
}
|
|
20915
21125
|
function persistHouseProxyConfig(config) {
|
|
20916
21126
|
try {
|
|
20917
21127
|
const file = houseProxyConfigPath();
|
|
20918
|
-
|
|
21128
|
+
fs43.mkdirSync(path48.dirname(file), { recursive: true, mode: 448 });
|
|
20919
21129
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
20920
|
-
|
|
20921
|
-
|
|
21130
|
+
fs43.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
21131
|
+
fs43.renameSync(tmp, file);
|
|
20922
21132
|
restrictToOwner(file);
|
|
20923
21133
|
} catch (err) {
|
|
20924
21134
|
log.warn(
|
|
@@ -20929,13 +21139,13 @@ function persistHouseProxyConfig(config) {
|
|
|
20929
21139
|
}
|
|
20930
21140
|
function clearHouseProxyConfig() {
|
|
20931
21141
|
try {
|
|
20932
|
-
|
|
21142
|
+
fs43.rmSync(houseProxyConfigPath(), { force: true });
|
|
20933
21143
|
} catch {
|
|
20934
21144
|
}
|
|
20935
21145
|
}
|
|
20936
21146
|
function readHouseProxyChildEnv() {
|
|
20937
21147
|
try {
|
|
20938
|
-
const raw =
|
|
21148
|
+
const raw = fs43.readFileSync(houseProxyConfigPath(), "utf8");
|
|
20939
21149
|
const parsed = JSON.parse(raw);
|
|
20940
21150
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
20941
21151
|
const o = parsed;
|
|
@@ -20968,9 +21178,9 @@ function readHouseProxyChildEnv() {
|
|
|
20968
21178
|
var import_node_child_process23 = require("child_process");
|
|
20969
21179
|
|
|
20970
21180
|
// src/lib/updateNotifier.ts
|
|
20971
|
-
var
|
|
20972
|
-
var
|
|
20973
|
-
var
|
|
21181
|
+
var fs44 = __toESM(require("fs"));
|
|
21182
|
+
var os41 = __toESM(require("os"));
|
|
21183
|
+
var path49 = __toESM(require("path"));
|
|
20974
21184
|
var https6 = __toESM(require("https"));
|
|
20975
21185
|
var import_node_child_process22 = require("child_process");
|
|
20976
21186
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -20979,12 +21189,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
20979
21189
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
20980
21190
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
20981
21191
|
function cachePath() {
|
|
20982
|
-
const dir =
|
|
20983
|
-
return
|
|
21192
|
+
const dir = path49.join(os41.homedir(), ".codeam");
|
|
21193
|
+
return path49.join(dir, "update-check.json");
|
|
20984
21194
|
}
|
|
20985
21195
|
function readCache() {
|
|
20986
21196
|
try {
|
|
20987
|
-
const raw =
|
|
21197
|
+
const raw = fs44.readFileSync(cachePath(), "utf8");
|
|
20988
21198
|
const parsed = JSON.parse(raw);
|
|
20989
21199
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
20990
21200
|
return parsed;
|
|
@@ -20995,10 +21205,10 @@ function readCache() {
|
|
|
20995
21205
|
function writeCache(cache) {
|
|
20996
21206
|
try {
|
|
20997
21207
|
const file = cachePath();
|
|
20998
|
-
|
|
21208
|
+
fs44.mkdirSync(path49.dirname(file), { recursive: true });
|
|
20999
21209
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
21000
|
-
|
|
21001
|
-
|
|
21210
|
+
fs44.writeFileSync(tmp, JSON.stringify(cache));
|
|
21211
|
+
fs44.renameSync(tmp, file);
|
|
21002
21212
|
} catch {
|
|
21003
21213
|
}
|
|
21004
21214
|
}
|
|
@@ -21072,8 +21282,8 @@ function isLinkedInstall() {
|
|
|
21072
21282
|
timeout: 2e3
|
|
21073
21283
|
}).trim();
|
|
21074
21284
|
if (!root) return false;
|
|
21075
|
-
const pkgPath =
|
|
21076
|
-
return
|
|
21285
|
+
const pkgPath = path49.join(root, PKG_NAME);
|
|
21286
|
+
return fs44.lstatSync(pkgPath).isSymbolicLink();
|
|
21077
21287
|
} catch {
|
|
21078
21288
|
return false;
|
|
21079
21289
|
}
|
|
@@ -21109,7 +21319,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
21109
21319
|
return;
|
|
21110
21320
|
}
|
|
21111
21321
|
try {
|
|
21112
|
-
|
|
21322
|
+
fs44.unlinkSync(cachePath());
|
|
21113
21323
|
} catch {
|
|
21114
21324
|
}
|
|
21115
21325
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -21125,7 +21335,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
21125
21335
|
if (process.env.NODE_ENV === "test") return;
|
|
21126
21336
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21127
21337
|
if (process.env.CI) return;
|
|
21128
|
-
const current2 = true ? "2.65.
|
|
21338
|
+
const current2 = true ? "2.65.2" : null;
|
|
21129
21339
|
if (!current2) return;
|
|
21130
21340
|
const cache = readCache();
|
|
21131
21341
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21142,7 +21352,7 @@ function checkForUpdates() {
|
|
|
21142
21352
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21143
21353
|
if (process.env.CI) return;
|
|
21144
21354
|
if (!process.stdout.isTTY) return;
|
|
21145
|
-
const current2 = true ? "2.65.
|
|
21355
|
+
const current2 = true ? "2.65.2" : null;
|
|
21146
21356
|
if (!current2) return;
|
|
21147
21357
|
const cache = readCache();
|
|
21148
21358
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21162,7 +21372,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
21162
21372
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
21163
21373
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
21164
21374
|
function currentCliVersion() {
|
|
21165
|
-
return true ? "2.65.
|
|
21375
|
+
return true ? "2.65.2" : null;
|
|
21166
21376
|
}
|
|
21167
21377
|
function runCmd(cmd, args2, timeoutMs) {
|
|
21168
21378
|
return new Promise((resolve9) => {
|
|
@@ -21229,7 +21439,7 @@ async function runSelfUpdate() {
|
|
|
21229
21439
|
|
|
21230
21440
|
// src/commands/host/teardown.ts
|
|
21231
21441
|
var import_node_child_process24 = require("child_process");
|
|
21232
|
-
var
|
|
21442
|
+
var fs45 = __toESM(require("fs"));
|
|
21233
21443
|
var defaultDisableService = () => {
|
|
21234
21444
|
try {
|
|
21235
21445
|
(0, import_node_child_process24.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
@@ -21238,7 +21448,7 @@ var defaultDisableService = () => {
|
|
|
21238
21448
|
};
|
|
21239
21449
|
var defaultTeardownHeadroom = () => {
|
|
21240
21450
|
try {
|
|
21241
|
-
const kind = JSON.parse(
|
|
21451
|
+
const kind = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
21242
21452
|
if (kind) {
|
|
21243
21453
|
(0, import_node_child_process24.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
21244
21454
|
}
|
|
@@ -21306,8 +21516,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
21306
21516
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
21307
21517
|
try {
|
|
21308
21518
|
const file = headroomConfigPath();
|
|
21309
|
-
if (!
|
|
21310
|
-
const cfg = JSON.parse(
|
|
21519
|
+
if (!fs46.existsSync(file)) return null;
|
|
21520
|
+
const cfg = JSON.parse(fs46.readFileSync(file, "utf8"));
|
|
21311
21521
|
if (!cfg?.enabled) return null;
|
|
21312
21522
|
const agent = cfg.agent ?? "claude";
|
|
21313
21523
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -21894,13 +22104,13 @@ var HostAgentSupervisor = class {
|
|
|
21894
22104
|
const relay = this.relay;
|
|
21895
22105
|
if (!relay) return;
|
|
21896
22106
|
const raw = cmd.payload?.path;
|
|
21897
|
-
const target = typeof raw === "string" && raw.trim() ?
|
|
22107
|
+
const target = typeof raw === "string" && raw.trim() ? path50.resolve(raw.trim()) : os42.homedir();
|
|
21898
22108
|
try {
|
|
21899
|
-
const dirents = await
|
|
22109
|
+
const dirents = await fs46.promises.readdir(target, { withFileTypes: true });
|
|
21900
22110
|
const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
|
|
21901
22111
|
(a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
|
|
21902
22112
|
);
|
|
21903
|
-
const parent =
|
|
22113
|
+
const parent = path50.dirname(target);
|
|
21904
22114
|
await relay.sendResult(cmd.id, "completed", {
|
|
21905
22115
|
path: target,
|
|
21906
22116
|
// null at the filesystem root so the UI can hide the ".." affordance.
|
|
@@ -22133,14 +22343,14 @@ var HostAgentSupervisor = class {
|
|
|
22133
22343
|
API_TIMEOUT_MS: "3000000",
|
|
22134
22344
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
22135
22345
|
};
|
|
22136
|
-
const houseConfigDir =
|
|
22137
|
-
|
|
22346
|
+
const houseConfigDir = path50.join(
|
|
22347
|
+
os42.homedir(),
|
|
22138
22348
|
".codeam",
|
|
22139
22349
|
"house-claude",
|
|
22140
22350
|
payload.deployId
|
|
22141
22351
|
);
|
|
22142
22352
|
try {
|
|
22143
|
-
|
|
22353
|
+
fs46.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
22144
22354
|
} catch {
|
|
22145
22355
|
}
|
|
22146
22356
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -22166,7 +22376,7 @@ var HostAgentSupervisor = class {
|
|
|
22166
22376
|
report("installing", "installing agent CLI");
|
|
22167
22377
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
22168
22378
|
}
|
|
22169
|
-
const home = process.env.HOME ||
|
|
22379
|
+
const home = process.env.HOME || os42.homedir();
|
|
22170
22380
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
22171
22381
|
if (payload.cloneToken) {
|
|
22172
22382
|
try {
|
|
@@ -22174,13 +22384,13 @@ var HostAgentSupervisor = class {
|
|
|
22174
22384
|
if ((payload.repoProvider ?? "github") === "gitlab") {
|
|
22175
22385
|
const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
|
|
22176
22386
|
if (glabCmd) {
|
|
22177
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
22387
|
+
childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
|
|
22178
22388
|
await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
|
|
22179
22389
|
}
|
|
22180
22390
|
} else {
|
|
22181
22391
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
22182
22392
|
if (ghCmd) {
|
|
22183
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
22393
|
+
childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
|
|
22184
22394
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
22185
22395
|
}
|
|
22186
22396
|
}
|
|
@@ -22200,7 +22410,7 @@ var HostAgentSupervisor = class {
|
|
|
22200
22410
|
}
|
|
22201
22411
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
22202
22412
|
report("headroom", "setting up Headroom proxy");
|
|
22203
|
-
const freeBytes = await this.getFreeDisk(
|
|
22413
|
+
const freeBytes = await this.getFreeDisk(os42.homedir());
|
|
22204
22414
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
22205
22415
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
22206
22416
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -22259,9 +22469,9 @@ var HostAgentSupervisor = class {
|
|
|
22259
22469
|
);
|
|
22260
22470
|
if (!payload.suppressOnboardingWelcome) {
|
|
22261
22471
|
try {
|
|
22262
|
-
const cfgDir = childEnv.CLAUDE_CONFIG_DIR ||
|
|
22263
|
-
const projectDir =
|
|
22264
|
-
const hasPriorConversation =
|
|
22472
|
+
const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path50.join(os42.homedir(), ".claude");
|
|
22473
|
+
const projectDir = path50.join(cfgDir, "projects", encodeCwd(cwd));
|
|
22474
|
+
const hasPriorConversation = fs46.existsSync(projectDir) && fs46.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
|
|
22265
22475
|
if (hasPriorConversation) {
|
|
22266
22476
|
childEnv.CODEAM_RESUME_LATEST = "1";
|
|
22267
22477
|
log.info(
|
|
@@ -22360,7 +22570,7 @@ var HostAgentSupervisor = class {
|
|
|
22360
22570
|
if (this.children.size > 0) return;
|
|
22361
22571
|
const session = getActiveSession();
|
|
22362
22572
|
if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
|
|
22363
|
-
const cwd = session.cwd &&
|
|
22573
|
+
const cwd = session.cwd && fs46.existsSync(session.cwd) ? session.cwd : process.cwd();
|
|
22364
22574
|
const proc = this.resumeSpawner(
|
|
22365
22575
|
{ ...readHeadroomChildEnv(), ...readHouseProxyChildEnv() },
|
|
22366
22576
|
cwd
|
|
@@ -22457,12 +22667,12 @@ var HostAgentSupervisor = class {
|
|
|
22457
22667
|
this.children.delete(deployId);
|
|
22458
22668
|
}
|
|
22459
22669
|
const dirs = [
|
|
22460
|
-
|
|
22461
|
-
|
|
22670
|
+
path50.join(selfHostedWorkspaceRoot(), deployId),
|
|
22671
|
+
path50.join(os42.homedir(), ".codeam", "house-claude", deployId)
|
|
22462
22672
|
];
|
|
22463
22673
|
for (const dir of dirs) {
|
|
22464
22674
|
try {
|
|
22465
|
-
|
|
22675
|
+
fs46.rmSync(dir, { recursive: true, force: true });
|
|
22466
22676
|
} catch (err) {
|
|
22467
22677
|
log.warn(
|
|
22468
22678
|
"host-agent",
|
|
@@ -22599,10 +22809,10 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
22599
22809
|
}
|
|
22600
22810
|
|
|
22601
22811
|
// src/services/headroom/budget-relaunch.ts
|
|
22602
|
-
var
|
|
22603
|
-
var
|
|
22604
|
-
var
|
|
22605
|
-
var
|
|
22812
|
+
var fs47 = __toESM(require("fs"));
|
|
22813
|
+
var os43 = __toESM(require("os"));
|
|
22814
|
+
var path51 = __toESM(require("path"));
|
|
22815
|
+
var import_child_process15 = require("child_process");
|
|
22606
22816
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
22607
22817
|
const rawArgs = manifest.proxy_args ?? [];
|
|
22608
22818
|
const strippedArgs = [];
|
|
@@ -22635,7 +22845,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
22635
22845
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
22636
22846
|
}
|
|
22637
22847
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
22638
|
-
const deployDir =
|
|
22848
|
+
const deployDir = path51.join(homeDir2, ".headroom", "deploy");
|
|
22639
22849
|
let profiles;
|
|
22640
22850
|
try {
|
|
22641
22851
|
profiles = deps.readDir(deployDir);
|
|
@@ -22644,7 +22854,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
22644
22854
|
}
|
|
22645
22855
|
const results = [];
|
|
22646
22856
|
for (const profile of profiles) {
|
|
22647
|
-
const manifestPath =
|
|
22857
|
+
const manifestPath = path51.join(deployDir, profile, "manifest.json");
|
|
22648
22858
|
let raw;
|
|
22649
22859
|
try {
|
|
22650
22860
|
raw = deps.readJson(manifestPath);
|
|
@@ -22676,12 +22886,12 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
22676
22886
|
}
|
|
22677
22887
|
function writeManifestReal(manifestPath, manifest) {
|
|
22678
22888
|
const tmp = manifestPath + ".codeam.tmp";
|
|
22679
|
-
|
|
22680
|
-
|
|
22889
|
+
fs47.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
22890
|
+
fs47.renameSync(tmp, manifestPath);
|
|
22681
22891
|
}
|
|
22682
22892
|
function restartDeploymentReal(profile) {
|
|
22683
22893
|
try {
|
|
22684
|
-
const proc = (0,
|
|
22894
|
+
const proc = (0, import_child_process15.spawn)("headroom", ["install", "restart", "--profile", profile], {
|
|
22685
22895
|
detached: true,
|
|
22686
22896
|
stdio: "ignore"
|
|
22687
22897
|
});
|
|
@@ -22712,11 +22922,11 @@ function spawnProxyReal2(_budget) {
|
|
|
22712
22922
|
);
|
|
22713
22923
|
}
|
|
22714
22924
|
function makeRealApplyBudgetDeps() {
|
|
22715
|
-
const homeDir2 =
|
|
22925
|
+
const homeDir2 = os43.homedir();
|
|
22716
22926
|
return {
|
|
22717
22927
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
22718
|
-
readDir: (dir) =>
|
|
22719
|
-
readJson: (filePath) => JSON.parse(
|
|
22928
|
+
readDir: (dir) => fs47.readdirSync(dir),
|
|
22929
|
+
readJson: (filePath) => JSON.parse(fs47.readFileSync(filePath, "utf8"))
|
|
22720
22930
|
}),
|
|
22721
22931
|
writeManifest: writeManifestReal,
|
|
22722
22932
|
restartDeployment: restartDeploymentReal,
|
|
@@ -22831,7 +23041,7 @@ async function defaultFetchJson(url2) {
|
|
|
22831
23041
|
async function readUsageReport(deps = {}) {
|
|
22832
23042
|
const port = deps.port ?? HEADROOM_PROXY_PORT;
|
|
22833
23043
|
const base = `http://127.0.0.1:${port}`;
|
|
22834
|
-
const get2 = deps.fetchJson ?? ((
|
|
23044
|
+
const get2 = deps.fetchJson ?? ((path92) => defaultFetchJson(`${base}${path92}`));
|
|
22835
23045
|
let history;
|
|
22836
23046
|
try {
|
|
22837
23047
|
history = await get2("/stats-history");
|
|
@@ -22849,47 +23059,47 @@ async function readUsageReport(deps = {}) {
|
|
|
22849
23059
|
}
|
|
22850
23060
|
|
|
22851
23061
|
// src/agents/acp/guardrail-config.ts
|
|
22852
|
-
var
|
|
22853
|
-
var
|
|
22854
|
-
var
|
|
23062
|
+
var fs48 = __toESM(require("fs"));
|
|
23063
|
+
var path52 = __toESM(require("path"));
|
|
23064
|
+
var os44 = __toESM(require("os"));
|
|
22855
23065
|
var current = null;
|
|
22856
|
-
function guardrailConfigPath(homeDir2 =
|
|
22857
|
-
return
|
|
23066
|
+
function guardrailConfigPath(homeDir2 = os44.homedir()) {
|
|
23067
|
+
return path52.join(homeDir2, ".codeam", "guardrails.json");
|
|
22858
23068
|
}
|
|
22859
|
-
function loadGuardrailPolicy(homeDir2 =
|
|
23069
|
+
function loadGuardrailPolicy(homeDir2 = os44.homedir()) {
|
|
22860
23070
|
try {
|
|
22861
|
-
current = normalizeGuardrailPolicy(JSON.parse(
|
|
23071
|
+
current = normalizeGuardrailPolicy(JSON.parse(fs48.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
|
|
22862
23072
|
} catch {
|
|
22863
23073
|
current = { ...DEFAULT_GUARDRAIL_POLICY };
|
|
22864
23074
|
}
|
|
22865
23075
|
return current;
|
|
22866
23076
|
}
|
|
22867
|
-
function getGuardrailPolicy(homeDir2 =
|
|
23077
|
+
function getGuardrailPolicy(homeDir2 = os44.homedir()) {
|
|
22868
23078
|
return current ?? loadGuardrailPolicy(homeDir2);
|
|
22869
23079
|
}
|
|
22870
|
-
function setGuardrailPolicy(raw, homeDir2 =
|
|
23080
|
+
function setGuardrailPolicy(raw, homeDir2 = os44.homedir()) {
|
|
22871
23081
|
const next = normalizeGuardrailPolicy(raw);
|
|
22872
23082
|
current = next;
|
|
22873
23083
|
try {
|
|
22874
23084
|
const p2 = guardrailConfigPath(homeDir2);
|
|
22875
|
-
|
|
22876
|
-
|
|
23085
|
+
fs48.mkdirSync(path52.dirname(p2), { recursive: true });
|
|
23086
|
+
fs48.writeFileSync(p2, JSON.stringify(next, null, 2));
|
|
22877
23087
|
} catch {
|
|
22878
23088
|
}
|
|
22879
23089
|
return next;
|
|
22880
23090
|
}
|
|
22881
23091
|
|
|
22882
23092
|
// src/services/preview/port-registry.ts
|
|
22883
|
-
var
|
|
22884
|
-
var
|
|
22885
|
-
var
|
|
22886
|
-
var
|
|
23093
|
+
var fs49 = __toESM(require("fs"));
|
|
23094
|
+
var os45 = __toESM(require("os"));
|
|
23095
|
+
var path53 = __toESM(require("path"));
|
|
23096
|
+
var import_child_process16 = require("child_process");
|
|
22887
23097
|
function registryPath() {
|
|
22888
|
-
return
|
|
23098
|
+
return path53.join(os45.homedir(), ".codeam", "preview-ports.json");
|
|
22889
23099
|
}
|
|
22890
23100
|
function readRegistry() {
|
|
22891
23101
|
try {
|
|
22892
|
-
const raw =
|
|
23102
|
+
const raw = fs49.readFileSync(registryPath(), "utf8");
|
|
22893
23103
|
const parsed = JSON.parse(raw);
|
|
22894
23104
|
if (parsed && typeof parsed === "object") return parsed;
|
|
22895
23105
|
} catch {
|
|
@@ -22899,10 +23109,10 @@ function readRegistry() {
|
|
|
22899
23109
|
function writeRegistry(reg) {
|
|
22900
23110
|
try {
|
|
22901
23111
|
const file = registryPath();
|
|
22902
|
-
|
|
23112
|
+
fs49.mkdirSync(path53.dirname(file), { recursive: true });
|
|
22903
23113
|
const tmp = `${file}.tmp`;
|
|
22904
|
-
|
|
22905
|
-
|
|
23114
|
+
fs49.writeFileSync(tmp, JSON.stringify(reg), "utf8");
|
|
23115
|
+
fs49.renameSync(tmp, file);
|
|
22906
23116
|
} catch (err) {
|
|
22907
23117
|
log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
22908
23118
|
}
|
|
@@ -22930,7 +23140,7 @@ function groupAlive(pgid) {
|
|
|
22930
23140
|
}
|
|
22931
23141
|
function killGroup(pgid) {
|
|
22932
23142
|
if (process.platform === "win32") {
|
|
22933
|
-
(0,
|
|
23143
|
+
(0, import_child_process16.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
|
|
22934
23144
|
return;
|
|
22935
23145
|
}
|
|
22936
23146
|
try {
|
|
@@ -22967,8 +23177,8 @@ function reclaimOwnOrphanPort(port) {
|
|
|
22967
23177
|
}
|
|
22968
23178
|
|
|
22969
23179
|
// src/services/preview/host-allow.ts
|
|
22970
|
-
var
|
|
22971
|
-
var
|
|
23180
|
+
var import_fs2 = require("fs");
|
|
23181
|
+
var path54 = __toESM(require("path"));
|
|
22972
23182
|
var NEXT_ALLOWED_ORIGINS = [
|
|
22973
23183
|
"*.trycloudflare.com",
|
|
22974
23184
|
"*.preview.codeagent-mobile.com",
|
|
@@ -22988,11 +23198,11 @@ var MARKER_DIR = ".codeam";
|
|
|
22988
23198
|
var MARKER_FILE = "preview-host-allow.json";
|
|
22989
23199
|
var ORIG_INFIX = ".codeam-orig";
|
|
22990
23200
|
function markerPath(cwd) {
|
|
22991
|
-
return
|
|
23201
|
+
return path54.join(cwd, MARKER_DIR, MARKER_FILE);
|
|
22992
23202
|
}
|
|
22993
23203
|
async function fileExists(p2) {
|
|
22994
23204
|
try {
|
|
22995
|
-
await
|
|
23205
|
+
await import_fs2.promises.access(p2);
|
|
22996
23206
|
return true;
|
|
22997
23207
|
} catch {
|
|
22998
23208
|
return false;
|
|
@@ -23001,13 +23211,13 @@ async function fileExists(p2) {
|
|
|
23001
23211
|
async function findConfigFile(cwd, framework) {
|
|
23002
23212
|
const base = CONFIG_BASENAMES[framework];
|
|
23003
23213
|
for (const ext of CONFIG_EXTS) {
|
|
23004
|
-
if (await fileExists(
|
|
23214
|
+
if (await fileExists(path54.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
|
|
23005
23215
|
}
|
|
23006
23216
|
return null;
|
|
23007
23217
|
}
|
|
23008
23218
|
async function dependsOn(cwd, pkgName) {
|
|
23009
23219
|
try {
|
|
23010
|
-
const raw = await
|
|
23220
|
+
const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
|
|
23011
23221
|
const pkg = JSON.parse(raw);
|
|
23012
23222
|
return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
|
|
23013
23223
|
} catch {
|
|
@@ -23015,11 +23225,11 @@ async function dependsOn(cwd, pkgName) {
|
|
|
23015
23225
|
}
|
|
23016
23226
|
}
|
|
23017
23227
|
async function isEsmConfig(cwd, configFile) {
|
|
23018
|
-
const ext =
|
|
23228
|
+
const ext = path54.extname(configFile);
|
|
23019
23229
|
if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
|
|
23020
23230
|
if (ext === ".cjs") return false;
|
|
23021
23231
|
try {
|
|
23022
|
-
const raw = await
|
|
23232
|
+
const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
|
|
23023
23233
|
return JSON.parse(raw).type === "module";
|
|
23024
23234
|
} catch {
|
|
23025
23235
|
return false;
|
|
@@ -23102,12 +23312,12 @@ function shimFor(framework, origBasename, esm) {
|
|
|
23102
23312
|
return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
|
|
23103
23313
|
}
|
|
23104
23314
|
async function writeMarker(cwd, marker) {
|
|
23105
|
-
await
|
|
23106
|
-
await
|
|
23315
|
+
await import_fs2.promises.mkdir(path54.join(cwd, MARKER_DIR), { recursive: true });
|
|
23316
|
+
await import_fs2.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
|
|
23107
23317
|
}
|
|
23108
23318
|
async function readMarker(cwd) {
|
|
23109
23319
|
try {
|
|
23110
|
-
const parsed = JSON.parse(await
|
|
23320
|
+
const parsed = JSON.parse(await import_fs2.promises.readFile(markerPath(cwd), "utf8"));
|
|
23111
23321
|
return parsed && parsed.configFile ? parsed : null;
|
|
23112
23322
|
} catch {
|
|
23113
23323
|
return null;
|
|
@@ -23117,20 +23327,20 @@ async function restorePreviewHostAllow(cwd) {
|
|
|
23117
23327
|
const marker = await readMarker(cwd);
|
|
23118
23328
|
if (!marker) return;
|
|
23119
23329
|
try {
|
|
23120
|
-
const configAbs =
|
|
23330
|
+
const configAbs = path54.join(cwd, marker.configFile);
|
|
23121
23331
|
if (marker.backupFile) {
|
|
23122
|
-
const backupAbs =
|
|
23332
|
+
const backupAbs = path54.join(cwd, marker.backupFile);
|
|
23123
23333
|
if (await fileExists(backupAbs)) {
|
|
23124
|
-
await
|
|
23125
|
-
await
|
|
23334
|
+
await import_fs2.promises.rm(configAbs, { force: true });
|
|
23335
|
+
await import_fs2.promises.rename(backupAbs, configAbs);
|
|
23126
23336
|
}
|
|
23127
23337
|
} else {
|
|
23128
|
-
await
|
|
23338
|
+
await import_fs2.promises.rm(configAbs, { force: true });
|
|
23129
23339
|
}
|
|
23130
23340
|
} catch (err) {
|
|
23131
23341
|
log.warn("preview", `host-allow restore failed: ${err instanceof Error ? err.message : err}`);
|
|
23132
23342
|
} finally {
|
|
23133
|
-
await
|
|
23343
|
+
await import_fs2.promises.rm(markerPath(cwd), { force: true }).catch(() => void 0);
|
|
23134
23344
|
}
|
|
23135
23345
|
}
|
|
23136
23346
|
async function applyPreviewHostAllow(cwd) {
|
|
@@ -23152,16 +23362,16 @@ async function applyPreviewHostAllow(cwd) {
|
|
|
23152
23362
|
}
|
|
23153
23363
|
if (!framework) return;
|
|
23154
23364
|
if (existing) {
|
|
23155
|
-
const ext =
|
|
23365
|
+
const ext = path54.extname(existing);
|
|
23156
23366
|
const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
|
|
23157
23367
|
const esm = await isEsmConfig(cwd, existing);
|
|
23158
|
-
await
|
|
23159
|
-
await
|
|
23368
|
+
await import_fs2.promises.rename(path54.join(cwd, existing), path54.join(cwd, origBasename));
|
|
23369
|
+
await import_fs2.promises.writeFile(path54.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
|
|
23160
23370
|
await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
|
|
23161
23371
|
log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
|
|
23162
23372
|
} else {
|
|
23163
23373
|
const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
|
|
23164
|
-
await
|
|
23374
|
+
await import_fs2.promises.writeFile(path54.join(cwd, configFile), shimFor(framework, null, true), "utf8");
|
|
23165
23375
|
await writeMarker(cwd, { framework, configFile, backupFile: null });
|
|
23166
23376
|
log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
|
|
23167
23377
|
}
|
|
@@ -23171,14 +23381,14 @@ async function applyPreviewHostAllow(cwd) {
|
|
|
23171
23381
|
}
|
|
23172
23382
|
|
|
23173
23383
|
// src/services/preview/cloudflared.ts
|
|
23174
|
-
var
|
|
23175
|
-
var
|
|
23384
|
+
var import_child_process17 = require("child_process");
|
|
23385
|
+
var import_fs3 = require("fs");
|
|
23176
23386
|
var import_promises = __toESM(require("fs/promises"));
|
|
23177
|
-
var
|
|
23178
|
-
var
|
|
23387
|
+
var import_os10 = __toESM(require("os"));
|
|
23388
|
+
var import_path5 = __toESM(require("path"));
|
|
23179
23389
|
var import_promises2 = require("stream/promises");
|
|
23180
23390
|
var import_which = __toESM(require("which"));
|
|
23181
|
-
var CACHED_BINARY =
|
|
23391
|
+
var CACHED_BINARY = import_path5.default.join(import_os10.default.homedir(), ".codeam", "bin", "cloudflared");
|
|
23182
23392
|
async function resolveCloudflared(opts = {}) {
|
|
23183
23393
|
try {
|
|
23184
23394
|
return await (0, import_which.default)("cloudflared");
|
|
@@ -23202,7 +23412,7 @@ async function resolveCloudflared(opts = {}) {
|
|
|
23202
23412
|
}
|
|
23203
23413
|
async function downloadCloudflared(target) {
|
|
23204
23414
|
const url2 = downloadUrlForPlatform();
|
|
23205
|
-
await import_promises.default.mkdir(
|
|
23415
|
+
await import_promises.default.mkdir(import_path5.default.dirname(target), { recursive: true });
|
|
23206
23416
|
const response = await fetch(url2);
|
|
23207
23417
|
if (!response.ok || !response.body) {
|
|
23208
23418
|
throw new Error(
|
|
@@ -23213,10 +23423,10 @@ async function downloadCloudflared(target) {
|
|
|
23213
23423
|
const tmp = `${target}.download.tgz`;
|
|
23214
23424
|
await (0, import_promises2.pipeline)(
|
|
23215
23425
|
response.body,
|
|
23216
|
-
(0,
|
|
23426
|
+
(0, import_fs3.createWriteStream)(tmp)
|
|
23217
23427
|
);
|
|
23218
23428
|
try {
|
|
23219
|
-
await extractTgz(tmp,
|
|
23429
|
+
await extractTgz(tmp, import_path5.default.dirname(target));
|
|
23220
23430
|
await import_promises.default.access(target);
|
|
23221
23431
|
await import_promises.default.chmod(target, 493);
|
|
23222
23432
|
} catch (err) {
|
|
@@ -23230,7 +23440,7 @@ async function downloadCloudflared(target) {
|
|
|
23230
23440
|
}
|
|
23231
23441
|
await (0, import_promises2.pipeline)(
|
|
23232
23442
|
response.body,
|
|
23233
|
-
(0,
|
|
23443
|
+
(0, import_fs3.createWriteStream)(target, { mode: 493 })
|
|
23234
23444
|
);
|
|
23235
23445
|
}
|
|
23236
23446
|
async function isExecutableBinary(p2) {
|
|
@@ -23248,7 +23458,7 @@ async function isExecutableBinary(p2) {
|
|
|
23248
23458
|
}
|
|
23249
23459
|
function extractTgz(tgzPath, destDir) {
|
|
23250
23460
|
return new Promise((resolve9, reject) => {
|
|
23251
|
-
const child = (0,
|
|
23461
|
+
const child = (0, import_child_process17.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
|
|
23252
23462
|
child.on("error", (err) => reject(err));
|
|
23253
23463
|
child.on(
|
|
23254
23464
|
"exit",
|
|
@@ -23278,11 +23488,11 @@ function decodeTunnelToken(token) {
|
|
|
23278
23488
|
}
|
|
23279
23489
|
async function spawnNamedTunnel(bin, token, port) {
|
|
23280
23490
|
const creds = decodeTunnelToken(token);
|
|
23281
|
-
const credDir =
|
|
23491
|
+
const credDir = import_path5.default.join(import_os10.default.homedir(), ".codeam");
|
|
23282
23492
|
await import_promises.default.mkdir(credDir, { recursive: true });
|
|
23283
|
-
const credFile =
|
|
23493
|
+
const credFile = import_path5.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
|
|
23284
23494
|
await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
|
|
23285
|
-
return (0,
|
|
23495
|
+
return (0, import_child_process17.spawn)(
|
|
23286
23496
|
bin,
|
|
23287
23497
|
[
|
|
23288
23498
|
"tunnel",
|
|
@@ -23298,17 +23508,17 @@ async function spawnNamedTunnel(bin, token, port) {
|
|
|
23298
23508
|
}
|
|
23299
23509
|
|
|
23300
23510
|
// src/services/preview/codespace.ts
|
|
23301
|
-
var
|
|
23511
|
+
var import_child_process18 = require("child_process");
|
|
23302
23512
|
var import_util3 = require("util");
|
|
23303
|
-
var execFileP5 = (0, import_util3.promisify)(
|
|
23513
|
+
var execFileP5 = (0, import_util3.promisify)(import_child_process18.execFile);
|
|
23304
23514
|
|
|
23305
23515
|
// src/services/preview/config-file.ts
|
|
23306
23516
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
23307
|
-
var
|
|
23517
|
+
var import_path6 = __toESM(require("path"));
|
|
23308
23518
|
var CONFIG_DIR = ".codeam";
|
|
23309
23519
|
var CONFIG_FILE = "preview.json";
|
|
23310
23520
|
function configPath(cwd) {
|
|
23311
|
-
return
|
|
23521
|
+
return import_path6.default.join(cwd, CONFIG_DIR, CONFIG_FILE);
|
|
23312
23522
|
}
|
|
23313
23523
|
var REQUIRED_FIELDS = [
|
|
23314
23524
|
"framework",
|
|
@@ -23339,7 +23549,7 @@ async function readPreviewConfig(cwd) {
|
|
|
23339
23549
|
}
|
|
23340
23550
|
async function writePreviewConfig(cwd, detection) {
|
|
23341
23551
|
const filePath = configPath(cwd);
|
|
23342
|
-
await import_promises3.default.mkdir(
|
|
23552
|
+
await import_promises3.default.mkdir(import_path6.default.dirname(filePath), { recursive: true });
|
|
23343
23553
|
await import_promises3.default.writeFile(filePath, JSON.stringify(detection, null, 2) + "\n", "utf-8");
|
|
23344
23554
|
}
|
|
23345
23555
|
|
|
@@ -23491,14 +23701,14 @@ async function waitForPortListening(port, opts) {
|
|
|
23491
23701
|
}
|
|
23492
23702
|
|
|
23493
23703
|
// src/services/preview/provision-deps.ts
|
|
23494
|
-
var
|
|
23495
|
-
var
|
|
23704
|
+
var import_fs4 = require("fs");
|
|
23705
|
+
var import_path7 = __toESM(require("path"));
|
|
23496
23706
|
|
|
23497
23707
|
// src/services/preview/run-setup.ts
|
|
23498
|
-
var
|
|
23708
|
+
var import_child_process19 = require("child_process");
|
|
23499
23709
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
23500
23710
|
return new Promise((resolve9) => {
|
|
23501
|
-
const child = (0,
|
|
23711
|
+
const child = (0, import_child_process19.spawn)(cmd, args2, {
|
|
23502
23712
|
cwd,
|
|
23503
23713
|
env: { ...process.env, ...env ?? {} },
|
|
23504
23714
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -23639,37 +23849,37 @@ function pickMigrationScript(scripts) {
|
|
|
23639
23849
|
}
|
|
23640
23850
|
async function exists(p2) {
|
|
23641
23851
|
try {
|
|
23642
|
-
await
|
|
23852
|
+
await import_fs4.promises.access(p2);
|
|
23643
23853
|
return true;
|
|
23644
23854
|
} catch {
|
|
23645
23855
|
return false;
|
|
23646
23856
|
}
|
|
23647
23857
|
}
|
|
23648
23858
|
async function firstExisting(cwd, names) {
|
|
23649
|
-
for (const n of names) if (await exists(
|
|
23859
|
+
for (const n of names) if (await exists(import_path7.default.join(cwd, n))) return n;
|
|
23650
23860
|
return null;
|
|
23651
23861
|
}
|
|
23652
23862
|
async function ensureEnvFile(cwd, generated) {
|
|
23653
|
-
if (await exists(
|
|
23863
|
+
if (await exists(import_path7.default.join(cwd, ".env"))) {
|
|
23654
23864
|
log.info("provision", ".env already present \u2014 leaving it untouched");
|
|
23655
23865
|
return;
|
|
23656
23866
|
}
|
|
23657
23867
|
const sample = await firstExisting(cwd, ENV_SAMPLES);
|
|
23658
23868
|
if (sample) {
|
|
23659
|
-
const body = await
|
|
23660
|
-
await
|
|
23869
|
+
const body = await import_fs4.promises.readFile(import_path7.default.join(cwd, sample), "utf8");
|
|
23870
|
+
await import_fs4.promises.writeFile(import_path7.default.join(cwd, ".env"), body);
|
|
23661
23871
|
log.info("provision", `wrote .env from ${sample}`);
|
|
23662
23872
|
return;
|
|
23663
23873
|
}
|
|
23664
23874
|
if (generated.length > 0) {
|
|
23665
23875
|
const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
|
|
23666
|
-
await
|
|
23876
|
+
await import_fs4.promises.writeFile(import_path7.default.join(cwd, ".env"), body);
|
|
23667
23877
|
log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
|
|
23668
23878
|
}
|
|
23669
23879
|
}
|
|
23670
23880
|
async function readPackageJson(cwd) {
|
|
23671
23881
|
try {
|
|
23672
|
-
return JSON.parse(await
|
|
23882
|
+
return JSON.parse(await import_fs4.promises.readFile(import_path7.default.join(cwd, "package.json"), "utf8"));
|
|
23673
23883
|
} catch {
|
|
23674
23884
|
return null;
|
|
23675
23885
|
}
|
|
@@ -23709,10 +23919,10 @@ async function provisionProjectDependencies(cwd) {
|
|
|
23709
23919
|
} else if (pkg) {
|
|
23710
23920
|
generated = detectServicesFromDeps(pkg);
|
|
23711
23921
|
if (generated.length > 0) {
|
|
23712
|
-
const dir =
|
|
23713
|
-
await
|
|
23714
|
-
const file =
|
|
23715
|
-
await
|
|
23922
|
+
const dir = import_path7.default.join(cwd, ".codeam", "provision");
|
|
23923
|
+
await import_fs4.promises.mkdir(dir, { recursive: true });
|
|
23924
|
+
const file = import_path7.default.join(dir, "compose.generated.yaml");
|
|
23925
|
+
await import_fs4.promises.writeFile(file, renderComposeYaml(generated));
|
|
23716
23926
|
log.info(
|
|
23717
23927
|
"provision",
|
|
23718
23928
|
`no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
|
|
@@ -23733,12 +23943,12 @@ async function provisionProjectDependencies(cwd) {
|
|
|
23733
23943
|
}
|
|
23734
23944
|
|
|
23735
23945
|
// src/services/preview/setup-deps.ts
|
|
23736
|
-
var
|
|
23737
|
-
var
|
|
23946
|
+
var import_fs5 = __toESM(require("fs"));
|
|
23947
|
+
var import_path8 = __toESM(require("path"));
|
|
23738
23948
|
function detectMissingNodeDeps(cwd) {
|
|
23739
|
-
if (!
|
|
23740
|
-
if (
|
|
23741
|
-
if (
|
|
23949
|
+
if (!import_fs5.default.existsSync(import_path8.default.join(cwd, "package.json"))) return null;
|
|
23950
|
+
if (import_fs5.default.existsSync(import_path8.default.join(cwd, "node_modules"))) return null;
|
|
23951
|
+
if (import_fs5.default.existsSync(import_path8.default.join(cwd, "yarn.lock"))) {
|
|
23742
23952
|
return { cmd: "yarn", args: ["install"] };
|
|
23743
23953
|
}
|
|
23744
23954
|
return { cmd: "npm", args: ["install", "--legacy-peer-deps"] };
|
|
@@ -23842,20 +24052,20 @@ function activePreviewSessionIds() {
|
|
|
23842
24052
|
}
|
|
23843
24053
|
|
|
23844
24054
|
// src/services/preview/start-orchestrator.ts
|
|
23845
|
-
var
|
|
23846
|
-
var
|
|
23847
|
-
var
|
|
24055
|
+
var import_child_process21 = require("child_process");
|
|
24056
|
+
var fs57 = __toESM(require("fs"));
|
|
24057
|
+
var path61 = __toESM(require("path"));
|
|
23848
24058
|
var import_which2 = __toESM(require("which"));
|
|
23849
24059
|
|
|
23850
24060
|
// src/services/project-env/index.ts
|
|
23851
|
-
var
|
|
23852
|
-
var
|
|
24061
|
+
var import_fs6 = require("fs");
|
|
24062
|
+
var path60 = __toESM(require("path"));
|
|
23853
24063
|
|
|
23854
24064
|
// src/beads/project-key.ts
|
|
23855
|
-
var
|
|
24065
|
+
var import_child_process20 = require("child_process");
|
|
23856
24066
|
var crypto2 = __toESM(require("crypto"));
|
|
23857
|
-
var
|
|
23858
|
-
var
|
|
24067
|
+
var fs55 = __toESM(require("fs"));
|
|
24068
|
+
var path59 = __toESM(require("path"));
|
|
23859
24069
|
function normalizeOrigin(raw) {
|
|
23860
24070
|
const trimmed = raw.trim();
|
|
23861
24071
|
if (!trimmed) return null;
|
|
@@ -23881,17 +24091,17 @@ function normalizeOrigin(raw) {
|
|
|
23881
24091
|
return `${host2}/${pathPart}`;
|
|
23882
24092
|
}
|
|
23883
24093
|
function findRepoRoot(cwd) {
|
|
23884
|
-
let dir =
|
|
24094
|
+
let dir = path59.resolve(cwd);
|
|
23885
24095
|
const seen = /* @__PURE__ */ new Set();
|
|
23886
24096
|
for (let i = 0; i < 256; i++) {
|
|
23887
24097
|
if (seen.has(dir)) return null;
|
|
23888
24098
|
seen.add(dir);
|
|
23889
24099
|
try {
|
|
23890
|
-
const stat3 =
|
|
24100
|
+
const stat3 = fs55.statSync(path59.join(dir, ".git"), { throwIfNoEntry: false });
|
|
23891
24101
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
23892
24102
|
} catch {
|
|
23893
24103
|
}
|
|
23894
|
-
const parent =
|
|
24104
|
+
const parent = path59.dirname(dir);
|
|
23895
24105
|
if (parent === dir) return null;
|
|
23896
24106
|
dir = parent;
|
|
23897
24107
|
}
|
|
@@ -23899,10 +24109,10 @@ function findRepoRoot(cwd) {
|
|
|
23899
24109
|
}
|
|
23900
24110
|
var _execSeam2 = {
|
|
23901
24111
|
exec: (file, args2, opts) => {
|
|
23902
|
-
const out2 = (0,
|
|
24112
|
+
const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
|
|
23903
24113
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
23904
24114
|
},
|
|
23905
|
-
realpath: (p2) =>
|
|
24115
|
+
realpath: (p2) => fs55.realpathSync(p2)
|
|
23906
24116
|
};
|
|
23907
24117
|
function readOrigin(cwd) {
|
|
23908
24118
|
try {
|
|
@@ -23931,20 +24141,20 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
23931
24141
|
} catch {
|
|
23932
24142
|
}
|
|
23933
24143
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
23934
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
24144
|
+
return { projectKey: `path:${hash}`, projectLabel: path59.basename(real) || "project" };
|
|
23935
24145
|
}
|
|
23936
24146
|
|
|
23937
24147
|
// src/services/project-env/index.ts
|
|
23938
24148
|
async function readIfExists(p2) {
|
|
23939
24149
|
try {
|
|
23940
|
-
return await
|
|
24150
|
+
return await import_fs6.promises.readFile(p2, "utf8");
|
|
23941
24151
|
} catch {
|
|
23942
24152
|
return null;
|
|
23943
24153
|
}
|
|
23944
24154
|
}
|
|
23945
24155
|
async function syncProjectEnvUp(cwd, ctx) {
|
|
23946
24156
|
if (!ctx.pluginAuthToken) return;
|
|
23947
|
-
const content = await readIfExists(
|
|
24157
|
+
const content = await readIfExists(path60.join(cwd, ".env"));
|
|
23948
24158
|
if (content == null) return;
|
|
23949
24159
|
try {
|
|
23950
24160
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -23966,7 +24176,7 @@ async function syncProjectEnvUp(cwd, ctx) {
|
|
|
23966
24176
|
}
|
|
23967
24177
|
async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
23968
24178
|
if (!ctx.pluginAuthToken) return false;
|
|
23969
|
-
const envPath =
|
|
24179
|
+
const envPath = path60.join(cwd, ".env");
|
|
23970
24180
|
if (await readIfExists(envPath) != null) return false;
|
|
23971
24181
|
try {
|
|
23972
24182
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -23977,9 +24187,9 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
|
23977
24187
|
projectKey
|
|
23978
24188
|
});
|
|
23979
24189
|
if (!stored) return false;
|
|
23980
|
-
const tmp =
|
|
23981
|
-
await
|
|
23982
|
-
await
|
|
24190
|
+
const tmp = path60.join(cwd, ".env.codeam-restore.tmp");
|
|
24191
|
+
await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
|
|
24192
|
+
await import_fs6.promises.rename(tmp, envPath);
|
|
23983
24193
|
log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
|
|
23984
24194
|
return true;
|
|
23985
24195
|
} catch (err) {
|
|
@@ -24054,8 +24264,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
24054
24264
|
if (args2.length === 0) return detection;
|
|
24055
24265
|
const binName = args2[0];
|
|
24056
24266
|
if (binName.startsWith("-")) return detection;
|
|
24057
|
-
const binPath =
|
|
24058
|
-
if (!
|
|
24267
|
+
const binPath = path61.join(cwd, "node_modules", ".bin", binName);
|
|
24268
|
+
if (!fs57.existsSync(binPath)) return detection;
|
|
24059
24269
|
return {
|
|
24060
24270
|
...detection,
|
|
24061
24271
|
command: binPath,
|
|
@@ -24271,7 +24481,7 @@ async function startDevServer(ctx) {
|
|
|
24271
24481
|
await applyPreviewHostAllow(cwd);
|
|
24272
24482
|
const spawnable = normalizeDetectionForSpawn(detection, cwd);
|
|
24273
24483
|
emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
|
|
24274
|
-
const devServer = (0,
|
|
24484
|
+
const devServer = (0, import_child_process21.spawn)(spawnable.command, spawnable.args, {
|
|
24275
24485
|
cwd,
|
|
24276
24486
|
env: { ...process.env, ...spawnable.env ?? {} },
|
|
24277
24487
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -24396,7 +24606,7 @@ async function establishTunnel(ctx, dev) {
|
|
|
24396
24606
|
`cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
|
|
24397
24607
|
);
|
|
24398
24608
|
}
|
|
24399
|
-
const candidate = (0,
|
|
24609
|
+
const candidate = (0, import_child_process21.spawn)(
|
|
24400
24610
|
bin,
|
|
24401
24611
|
["tunnel", "--url", `http://localhost:${detection.port}`],
|
|
24402
24612
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -24427,10 +24637,10 @@ async function establishTunnel(ctx, dev) {
|
|
|
24427
24637
|
}
|
|
24428
24638
|
|
|
24429
24639
|
// src/beads/bd-adapter.ts
|
|
24430
|
-
var
|
|
24431
|
-
var
|
|
24432
|
-
var
|
|
24433
|
-
var
|
|
24640
|
+
var import_child_process22 = require("child_process");
|
|
24641
|
+
var fs58 = __toESM(require("fs"));
|
|
24642
|
+
var os47 = __toESM(require("os"));
|
|
24643
|
+
var path62 = __toESM(require("path"));
|
|
24434
24644
|
var BD_PACKAGE = "@beads/bd";
|
|
24435
24645
|
function resolveBundledBdBinary() {
|
|
24436
24646
|
return _resolveSeam.resolveBundled();
|
|
@@ -24442,11 +24652,11 @@ function _defaultResolveBundled() {
|
|
|
24442
24652
|
} catch {
|
|
24443
24653
|
return null;
|
|
24444
24654
|
}
|
|
24445
|
-
const binDir =
|
|
24655
|
+
const binDir = path62.join(path62.dirname(pkgJsonPath), "bin");
|
|
24446
24656
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
24447
|
-
const binaryPath =
|
|
24657
|
+
const binaryPath = path62.join(binDir, binaryName);
|
|
24448
24658
|
try {
|
|
24449
|
-
|
|
24659
|
+
fs58.accessSync(binaryPath, fs58.constants.F_OK);
|
|
24450
24660
|
return binaryPath;
|
|
24451
24661
|
} catch {
|
|
24452
24662
|
return null;
|
|
@@ -24456,13 +24666,13 @@ function resolveBdOnPath() {
|
|
|
24456
24666
|
return _resolveSeam.resolveOnPath();
|
|
24457
24667
|
}
|
|
24458
24668
|
function _defaultResolveOnPath() {
|
|
24459
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
24669
|
+
const dirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
|
|
24460
24670
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
24461
24671
|
for (const dir of dirs) {
|
|
24462
24672
|
for (const candidate of candidates) {
|
|
24463
|
-
const full =
|
|
24673
|
+
const full = path62.join(dir, candidate);
|
|
24464
24674
|
try {
|
|
24465
|
-
|
|
24675
|
+
fs58.accessSync(full, fs58.constants.F_OK);
|
|
24466
24676
|
return full;
|
|
24467
24677
|
} catch {
|
|
24468
24678
|
}
|
|
@@ -24481,7 +24691,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
|
|
|
24481
24691
|
return new Promise((resolve9) => {
|
|
24482
24692
|
let proc;
|
|
24483
24693
|
try {
|
|
24484
|
-
proc = (0,
|
|
24694
|
+
proc = (0, import_child_process22.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
|
|
24485
24695
|
} catch (err) {
|
|
24486
24696
|
resolve9({ code: -1, stdout: "", stderr: err.message });
|
|
24487
24697
|
return;
|
|
@@ -24547,7 +24757,7 @@ var BdAdapter = class {
|
|
|
24547
24757
|
const env = { ...process.env };
|
|
24548
24758
|
if (!env.HOME) {
|
|
24549
24759
|
try {
|
|
24550
|
-
const home =
|
|
24760
|
+
const home = os47.homedir();
|
|
24551
24761
|
if (home) env.HOME = home;
|
|
24552
24762
|
} catch {
|
|
24553
24763
|
}
|
|
@@ -24638,13 +24848,13 @@ function coerceIssue(row, projectKey) {
|
|
|
24638
24848
|
}
|
|
24639
24849
|
|
|
24640
24850
|
// src/beads/provisioner.ts
|
|
24641
|
-
var
|
|
24642
|
-
var
|
|
24643
|
-
var
|
|
24644
|
-
var
|
|
24851
|
+
var import_child_process25 = require("child_process");
|
|
24852
|
+
var fs60 = __toESM(require("fs"));
|
|
24853
|
+
var os49 = __toESM(require("os"));
|
|
24854
|
+
var path64 = __toESM(require("path"));
|
|
24645
24855
|
|
|
24646
24856
|
// src/beads/install-bd.ts
|
|
24647
|
-
var
|
|
24857
|
+
var import_child_process23 = require("child_process");
|
|
24648
24858
|
var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
|
|
24649
24859
|
var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
|
|
24650
24860
|
function resolveInstallStrategy(platform3) {
|
|
@@ -24675,7 +24885,7 @@ function _defaultInstallSpawn(strategy) {
|
|
|
24675
24885
|
return new Promise((resolve9) => {
|
|
24676
24886
|
let proc;
|
|
24677
24887
|
try {
|
|
24678
|
-
proc = (0,
|
|
24888
|
+
proc = (0, import_child_process23.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
24679
24889
|
} catch (err) {
|
|
24680
24890
|
resolve9({ ok: false, code: -1, stderr: err.message });
|
|
24681
24891
|
return;
|
|
@@ -24705,10 +24915,10 @@ async function installBd(platform3 = process.platform) {
|
|
|
24705
24915
|
}
|
|
24706
24916
|
|
|
24707
24917
|
// src/beads/install-dolt.ts
|
|
24708
|
-
var
|
|
24709
|
-
var
|
|
24710
|
-
var
|
|
24711
|
-
var
|
|
24918
|
+
var import_child_process24 = require("child_process");
|
|
24919
|
+
var fs59 = __toESM(require("fs"));
|
|
24920
|
+
var os48 = __toESM(require("os"));
|
|
24921
|
+
var path63 = __toESM(require("path"));
|
|
24712
24922
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
24713
24923
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
24714
24924
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -24748,11 +24958,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
24748
24958
|
}
|
|
24749
24959
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
24750
24960
|
function doltPlatformTuple(platform3, arch2) {
|
|
24751
|
-
const
|
|
24961
|
+
const os67 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
24752
24962
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
24753
24963
|
if (!a) return null;
|
|
24754
|
-
if (
|
|
24755
|
-
return `${
|
|
24964
|
+
if (os67 === "windows" && a !== "amd64") return null;
|
|
24965
|
+
return `${os67}-${a}`;
|
|
24756
24966
|
}
|
|
24757
24967
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
24758
24968
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -24797,14 +25007,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
24797
25007
|
return result;
|
|
24798
25008
|
}
|
|
24799
25009
|
var _doltPathSeam = {
|
|
24800
|
-
homedir: () =>
|
|
25010
|
+
homedir: () => os48.homedir(),
|
|
24801
25011
|
getPath: () => process.env.PATH ?? "",
|
|
24802
25012
|
setPath: (p2) => {
|
|
24803
25013
|
process.env.PATH = p2;
|
|
24804
25014
|
},
|
|
24805
25015
|
exists: (p2) => {
|
|
24806
25016
|
try {
|
|
24807
|
-
|
|
25017
|
+
fs59.accessSync(p2, fs59.constants.F_OK);
|
|
24808
25018
|
return true;
|
|
24809
25019
|
} catch {
|
|
24810
25020
|
return false;
|
|
@@ -24815,7 +25025,7 @@ function doltBinaryNames(platform3) {
|
|
|
24815
25025
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
24816
25026
|
}
|
|
24817
25027
|
function knownDoltDirs(platform3) {
|
|
24818
|
-
const P3 = platform3 === "win32" ?
|
|
25028
|
+
const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
|
|
24819
25029
|
const home = _doltPathSeam.homedir();
|
|
24820
25030
|
if (platform3 === "win32") {
|
|
24821
25031
|
return [
|
|
@@ -24831,7 +25041,7 @@ function knownDoltDirs(platform3) {
|
|
|
24831
25041
|
].filter(Boolean);
|
|
24832
25042
|
}
|
|
24833
25043
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
24834
|
-
const P3 = platform3 === "win32" ?
|
|
25044
|
+
const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
|
|
24835
25045
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
24836
25046
|
const names = doltBinaryNames(platform3);
|
|
24837
25047
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -24867,7 +25077,7 @@ function _defaultDoltInstallSpawn(strategy) {
|
|
|
24867
25077
|
};
|
|
24868
25078
|
let proc;
|
|
24869
25079
|
try {
|
|
24870
|
-
proc = (0,
|
|
25080
|
+
proc = (0, import_child_process24.spawn)(strategy.command, strategy.args, {
|
|
24871
25081
|
env: process.env,
|
|
24872
25082
|
stdio: ["ignore", "pipe", "pipe"]
|
|
24873
25083
|
});
|
|
@@ -25008,17 +25218,17 @@ var _provisionSeam = {
|
|
|
25008
25218
|
};
|
|
25009
25219
|
var _linkSeam = {
|
|
25010
25220
|
platform: () => process.platform,
|
|
25011
|
-
homedir: () =>
|
|
25221
|
+
homedir: () => os49.homedir(),
|
|
25012
25222
|
isWritableDir: (dir) => {
|
|
25013
25223
|
try {
|
|
25014
|
-
|
|
25224
|
+
fs60.accessSync(dir, fs60.constants.W_OK);
|
|
25015
25225
|
return true;
|
|
25016
25226
|
} catch {
|
|
25017
25227
|
return false;
|
|
25018
25228
|
}
|
|
25019
25229
|
},
|
|
25020
25230
|
ensureDir: (dir) => {
|
|
25021
|
-
|
|
25231
|
+
fs60.mkdirSync(dir, { recursive: true });
|
|
25022
25232
|
},
|
|
25023
25233
|
/**
|
|
25024
25234
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -25039,9 +25249,9 @@ var _linkSeam = {
|
|
|
25039
25249
|
* which `linkBdOntoPath` creates if missing.
|
|
25040
25250
|
*/
|
|
25041
25251
|
cliBinDir: () => {
|
|
25042
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
25252
|
+
const pathDirs = (process.env.PATH ?? "").split(path64.delimiter).filter(Boolean);
|
|
25043
25253
|
const home = _linkSeam.homedir();
|
|
25044
|
-
const localBin = home ?
|
|
25254
|
+
const localBin = home ? path64.join(home, ".local", "bin") : null;
|
|
25045
25255
|
if (localBin) {
|
|
25046
25256
|
try {
|
|
25047
25257
|
_linkSeam.ensureDir(localBin);
|
|
@@ -25051,16 +25261,16 @@ var _linkSeam = {
|
|
|
25051
25261
|
const candidates = [];
|
|
25052
25262
|
if (localBin) candidates.push(localBin);
|
|
25053
25263
|
try {
|
|
25054
|
-
candidates.push(
|
|
25264
|
+
candidates.push(path64.dirname(process.execPath));
|
|
25055
25265
|
} catch {
|
|
25056
25266
|
}
|
|
25057
25267
|
candidates.push("/usr/local/bin");
|
|
25058
25268
|
const entry = process.argv[1];
|
|
25059
25269
|
if (entry) {
|
|
25060
25270
|
try {
|
|
25061
|
-
candidates.push(
|
|
25271
|
+
candidates.push(path64.dirname(fs60.realpathSync(entry)));
|
|
25062
25272
|
} catch {
|
|
25063
|
-
candidates.push(
|
|
25273
|
+
candidates.push(path64.dirname(entry));
|
|
25064
25274
|
}
|
|
25065
25275
|
}
|
|
25066
25276
|
const onPathWritable = candidates.find(
|
|
@@ -25072,20 +25282,20 @@ var _linkSeam = {
|
|
|
25072
25282
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
25073
25283
|
readlink: (linkPath) => {
|
|
25074
25284
|
try {
|
|
25075
|
-
return
|
|
25285
|
+
return fs60.readlinkSync(linkPath);
|
|
25076
25286
|
} catch {
|
|
25077
25287
|
return null;
|
|
25078
25288
|
}
|
|
25079
25289
|
},
|
|
25080
|
-
unlink: (linkPath) =>
|
|
25081
|
-
symlink: (target, linkPath) =>
|
|
25290
|
+
unlink: (linkPath) => fs60.unlinkSync(linkPath),
|
|
25291
|
+
symlink: (target, linkPath) => fs60.symlinkSync(target, linkPath)
|
|
25082
25292
|
};
|
|
25083
25293
|
function linkBdOntoPath(binaryPath) {
|
|
25084
25294
|
if (_linkSeam.platform() === "win32") return;
|
|
25085
25295
|
const binDir = _linkSeam.cliBinDir();
|
|
25086
25296
|
if (!binDir) return;
|
|
25087
25297
|
_linkSeam.ensureDir(binDir);
|
|
25088
|
-
const linkPath =
|
|
25298
|
+
const linkPath = path64.join(binDir, "bd");
|
|
25089
25299
|
if (linkPath === binaryPath) return;
|
|
25090
25300
|
const current2 = _linkSeam.readlink(linkPath);
|
|
25091
25301
|
if (current2 === binaryPath) return;
|
|
@@ -25094,7 +25304,7 @@ function linkBdOntoPath(binaryPath) {
|
|
|
25094
25304
|
log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
|
|
25095
25305
|
}
|
|
25096
25306
|
function setGitBeadsRole() {
|
|
25097
|
-
(0,
|
|
25307
|
+
(0, import_child_process25.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
|
|
25098
25308
|
stdio: "ignore"
|
|
25099
25309
|
});
|
|
25100
25310
|
}
|
|
@@ -25280,7 +25490,7 @@ function dedupeRecipes(agents) {
|
|
|
25280
25490
|
|
|
25281
25491
|
// src/beads/watcher.ts
|
|
25282
25492
|
var crypto4 = __toESM(require("crypto"));
|
|
25283
|
-
var
|
|
25493
|
+
var path65 = __toESM(require("path"));
|
|
25284
25494
|
var API_BASE6 = resolveApiBaseUrl();
|
|
25285
25495
|
var DEBOUNCE_MS2 = 400;
|
|
25286
25496
|
var ZERO_SUMMARY = {
|
|
@@ -25304,7 +25514,7 @@ var BeadsWatcher = class {
|
|
|
25304
25514
|
constructor(opts) {
|
|
25305
25515
|
this.opts = opts;
|
|
25306
25516
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
25307
|
-
this.feedPath = opts.feedPath ??
|
|
25517
|
+
this.feedPath = opts.feedPath ?? path65.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
25308
25518
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
25309
25519
|
}
|
|
25310
25520
|
opts;
|
|
@@ -25803,8 +26013,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
25803
26013
|
function saveFilesTemp(files) {
|
|
25804
26014
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
25805
26015
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
25806
|
-
const tmpPath =
|
|
25807
|
-
|
|
26016
|
+
const tmpPath = path68.join(os53.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
26017
|
+
fs63.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
25808
26018
|
pendingAttachmentFiles.add(tmpPath);
|
|
25809
26019
|
return tmpPath;
|
|
25810
26020
|
});
|
|
@@ -25949,7 +26159,7 @@ var sessionTerminated = async (ctx, cmd) => {
|
|
|
25949
26159
|
}
|
|
25950
26160
|
quiet(() => ctx.agent.kill());
|
|
25951
26161
|
try {
|
|
25952
|
-
const proc = (0,
|
|
26162
|
+
const proc = (0, import_child_process26.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
25953
26163
|
detached: true,
|
|
25954
26164
|
stdio: "ignore"
|
|
25955
26165
|
});
|
|
@@ -25968,7 +26178,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
25968
26178
|
quiet(() => ctx.agent.kill());
|
|
25969
26179
|
if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
|
|
25970
26180
|
try {
|
|
25971
|
-
const stopProc = (0,
|
|
26181
|
+
const stopProc = (0, import_child_process26.spawn)(
|
|
25972
26182
|
"bash",
|
|
25973
26183
|
["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
|
|
25974
26184
|
{ detached: true, stdio: "ignore" }
|
|
@@ -25978,7 +26188,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
25978
26188
|
}
|
|
25979
26189
|
}
|
|
25980
26190
|
try {
|
|
25981
|
-
const proc = (0,
|
|
26191
|
+
const proc = (0, import_child_process26.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
25982
26192
|
detached: true,
|
|
25983
26193
|
stdio: "ignore"
|
|
25984
26194
|
});
|
|
@@ -26022,10 +26232,10 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
26022
26232
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
26023
26233
|
};
|
|
26024
26234
|
var envReadH = async (ctx, cmd) => {
|
|
26025
|
-
const envPath =
|
|
26235
|
+
const envPath = path68.join(process.cwd(), ".env");
|
|
26026
26236
|
await restoreProjectEnvIfMissing(process.cwd(), ctx);
|
|
26027
26237
|
try {
|
|
26028
|
-
const raw = await
|
|
26238
|
+
const raw = await fs63.promises.readFile(envPath, "utf8");
|
|
26029
26239
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
26030
26240
|
exists: true,
|
|
26031
26241
|
vars: parseDotenv(raw)
|
|
@@ -26056,15 +26266,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
26056
26266
|
}
|
|
26057
26267
|
seen.add(v.key);
|
|
26058
26268
|
}
|
|
26059
|
-
const envPath =
|
|
26060
|
-
const tmpPath =
|
|
26269
|
+
const envPath = path68.join(process.cwd(), ".env");
|
|
26270
|
+
const tmpPath = path68.join(process.cwd(), ".env.codeam.tmp");
|
|
26061
26271
|
try {
|
|
26062
|
-
await
|
|
26063
|
-
await
|
|
26272
|
+
await fs63.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
26273
|
+
await fs63.promises.rename(tmpPath, envPath);
|
|
26064
26274
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
26065
26275
|
void syncProjectEnvUp(process.cwd(), ctx);
|
|
26066
26276
|
} catch (err) {
|
|
26067
|
-
await
|
|
26277
|
+
await fs63.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
26068
26278
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
26069
26279
|
}
|
|
26070
26280
|
};
|
|
@@ -26113,7 +26323,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
26113
26323
|
let configuredAgent = rawAgentId;
|
|
26114
26324
|
if (!configuredAgent) {
|
|
26115
26325
|
try {
|
|
26116
|
-
const raw = JSON.parse(
|
|
26326
|
+
const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
|
|
26117
26327
|
configuredAgent = raw.agent ?? "";
|
|
26118
26328
|
} catch {
|
|
26119
26329
|
}
|
|
@@ -26147,7 +26357,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
26147
26357
|
persist: persistHeadroomConfig,
|
|
26148
26358
|
readEnabled: () => {
|
|
26149
26359
|
try {
|
|
26150
|
-
const raw = JSON.parse(
|
|
26360
|
+
const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
|
|
26151
26361
|
return raw.enabled === true;
|
|
26152
26362
|
} catch {
|
|
26153
26363
|
return false;
|
|
@@ -26404,7 +26614,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
|
|
|
26404
26614
|
});
|
|
26405
26615
|
const token = ctx.pluginAuthToken;
|
|
26406
26616
|
void (async () => {
|
|
26407
|
-
const
|
|
26617
|
+
const os67 = createOsStrategy();
|
|
26408
26618
|
try {
|
|
26409
26619
|
const report = await reviewPullRequest(
|
|
26410
26620
|
{
|
|
@@ -26413,7 +26623,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
|
|
|
26413
26623
|
baseBranch: parsed.baseBranch
|
|
26414
26624
|
},
|
|
26415
26625
|
{
|
|
26416
|
-
runReview: (input) => new CoderabbitRuntimeStrategy(
|
|
26626
|
+
runReview: (input) => new CoderabbitRuntimeStrategy(os67).runOneShot(input),
|
|
26417
26627
|
runGh: (args2) => defaultRunGh(args2),
|
|
26418
26628
|
postReport: async (r) => {
|
|
26419
26629
|
if (!token) return;
|
|
@@ -26469,7 +26679,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
26469
26679
|
}
|
|
26470
26680
|
let headroomActive = false;
|
|
26471
26681
|
try {
|
|
26472
|
-
const raw = JSON.parse(
|
|
26682
|
+
const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
|
|
26473
26683
|
headroomActive = raw.enabled === true;
|
|
26474
26684
|
} catch {
|
|
26475
26685
|
}
|
|
@@ -26479,7 +26689,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
26479
26689
|
}
|
|
26480
26690
|
let existingConfig = { enabled: true };
|
|
26481
26691
|
try {
|
|
26482
|
-
existingConfig = JSON.parse(
|
|
26692
|
+
existingConfig = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
|
|
26483
26693
|
} catch {
|
|
26484
26694
|
}
|
|
26485
26695
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -26583,7 +26793,7 @@ var defaultCliUpdateDeps = {
|
|
|
26583
26793
|
// Only a truly local `codeam start` (neither marker) re-execs in place below.
|
|
26584
26794
|
isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
|
|
26585
26795
|
relaunch: (args2) => {
|
|
26586
|
-
const child = (0,
|
|
26796
|
+
const child = (0, import_child_process26.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
|
|
26587
26797
|
process.exit(child.status ?? 0);
|
|
26588
26798
|
}
|
|
26589
26799
|
};
|
|
@@ -26592,9 +26802,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
26592
26802
|
function buildNpmInstallInvocation(opts) {
|
|
26593
26803
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
26594
26804
|
const execPath = opts?.execPath ?? process.execPath;
|
|
26595
|
-
const exists2 = opts?.existsSync ??
|
|
26805
|
+
const exists2 = opts?.existsSync ?? fs63.existsSync;
|
|
26596
26806
|
const platform3 = opts?.platform ?? process.platform;
|
|
26597
|
-
const p2 = platform3 === "win32" ?
|
|
26807
|
+
const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
|
|
26598
26808
|
const normalized = entryScript.split(/[\\/]/).join("/");
|
|
26599
26809
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
26600
26810
|
const markerIdx = normalized.indexOf(marker);
|
|
@@ -26616,7 +26826,7 @@ function isPermissionError(stderr) {
|
|
|
26616
26826
|
function resolveGlobalNodeModulesDir(opts) {
|
|
26617
26827
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
26618
26828
|
const platform3 = opts?.platform ?? process.platform;
|
|
26619
|
-
const p2 = platform3 === "win32" ?
|
|
26829
|
+
const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
|
|
26620
26830
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
26621
26831
|
const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
|
|
26622
26832
|
if (markerIdx <= 0) return null;
|
|
@@ -26626,9 +26836,9 @@ function resolveGlobalNodeModulesDir(opts) {
|
|
|
26626
26836
|
var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
|
|
26627
26837
|
function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
26628
26838
|
if (!nodeModulesDir) return 0;
|
|
26629
|
-
const readdirSync15 = deps?.readdirSync ??
|
|
26630
|
-
const statSync17 = deps?.statSync ??
|
|
26631
|
-
const rmSync9 = deps?.rmSync ??
|
|
26839
|
+
const readdirSync15 = deps?.readdirSync ?? fs63.readdirSync;
|
|
26840
|
+
const statSync17 = deps?.statSync ?? fs63.statSync;
|
|
26841
|
+
const rmSync9 = deps?.rmSync ?? fs63.rmSync;
|
|
26632
26842
|
let removed = 0;
|
|
26633
26843
|
let entries;
|
|
26634
26844
|
try {
|
|
@@ -26638,7 +26848,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
|
26638
26848
|
}
|
|
26639
26849
|
for (const name of entries) {
|
|
26640
26850
|
if (!/^\.codeam-cli-/.test(name)) continue;
|
|
26641
|
-
const full =
|
|
26851
|
+
const full = path68.join(nodeModulesDir, name);
|
|
26642
26852
|
try {
|
|
26643
26853
|
const st3 = statSync17(full);
|
|
26644
26854
|
if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
|
|
@@ -26664,7 +26874,7 @@ async function runNpmInstallLatest() {
|
|
|
26664
26874
|
const useShell = process.platform === "win32";
|
|
26665
26875
|
const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
|
|
26666
26876
|
const result = await new Promise((resolve9) => {
|
|
26667
|
-
(0,
|
|
26877
|
+
(0, import_child_process26.execFile)(
|
|
26668
26878
|
command2,
|
|
26669
26879
|
invocation.args,
|
|
26670
26880
|
{ timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS, shell: useShell },
|
|
@@ -27278,13 +27488,13 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
27278
27488
|
}
|
|
27279
27489
|
|
|
27280
27490
|
// src/commands/start/keep-alive.ts
|
|
27281
|
-
var
|
|
27491
|
+
var import_child_process27 = require("child_process");
|
|
27282
27492
|
function buildKeepAlive(ctx) {
|
|
27283
27493
|
let timer = null;
|
|
27284
27494
|
async function setIdleTimeout(minutes) {
|
|
27285
27495
|
if (!ctx.inCodespace || !ctx.codespaceName) return;
|
|
27286
27496
|
await new Promise((resolve9) => {
|
|
27287
|
-
const proc = (0,
|
|
27497
|
+
const proc = (0, import_child_process27.spawn)(
|
|
27288
27498
|
"gh",
|
|
27289
27499
|
[
|
|
27290
27500
|
"api",
|
|
@@ -27516,11 +27726,11 @@ function resolveTokenValue(args2) {
|
|
|
27516
27726
|
}
|
|
27517
27727
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
27518
27728
|
if (fileFlag) {
|
|
27519
|
-
const
|
|
27729
|
+
const path92 = fileFlag.slice("--token-file=".length);
|
|
27520
27730
|
try {
|
|
27521
|
-
const content =
|
|
27522
|
-
if (content.length === 0) fail(`--token-file ${
|
|
27523
|
-
rmIfExistsQuiet(
|
|
27731
|
+
const content = fs64.readFileSync(path92, "utf8").trim();
|
|
27732
|
+
if (content.length === 0) fail(`--token-file ${path92} is empty`);
|
|
27733
|
+
rmIfExistsQuiet(path92);
|
|
27524
27734
|
return content;
|
|
27525
27735
|
} catch (err) {
|
|
27526
27736
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -27549,7 +27759,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
27549
27759
|
pluginId,
|
|
27550
27760
|
ideName: "codeam-cli (codespace)",
|
|
27551
27761
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
27552
|
-
hostname:
|
|
27762
|
+
hostname: os54.hostname(),
|
|
27553
27763
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
27554
27764
|
// Current git branch of the codespace's working directory, so the
|
|
27555
27765
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -27610,7 +27820,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
27610
27820
|
}
|
|
27611
27821
|
}
|
|
27612
27822
|
function pairAutoLockPath() {
|
|
27613
|
-
return
|
|
27823
|
+
return path69.join(os54.homedir(), ".codeam", "pair-auto.lock");
|
|
27614
27824
|
}
|
|
27615
27825
|
function isLivePairAuto(pid) {
|
|
27616
27826
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -27620,7 +27830,7 @@ function isLivePairAuto(pid) {
|
|
|
27620
27830
|
if (e.code !== "EPERM") return false;
|
|
27621
27831
|
}
|
|
27622
27832
|
try {
|
|
27623
|
-
return
|
|
27833
|
+
return fs64.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
27624
27834
|
} catch {
|
|
27625
27835
|
return true;
|
|
27626
27836
|
}
|
|
@@ -27630,24 +27840,24 @@ function isLiveCodeam(pid) {
|
|
|
27630
27840
|
}
|
|
27631
27841
|
function daemonLockPath(sessionId) {
|
|
27632
27842
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
27633
|
-
return
|
|
27843
|
+
return path69.join(os54.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
27634
27844
|
}
|
|
27635
27845
|
function acquireDaemonLock(sessionId) {
|
|
27636
27846
|
const lockPath = daemonLockPath(sessionId);
|
|
27637
27847
|
try {
|
|
27638
|
-
|
|
27848
|
+
fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
|
|
27639
27849
|
try {
|
|
27640
|
-
|
|
27850
|
+
fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
27641
27851
|
} catch (e) {
|
|
27642
27852
|
if (e.code !== "EEXIST") throw e;
|
|
27643
|
-
const holder = Number(
|
|
27853
|
+
const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
|
|
27644
27854
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
27645
|
-
|
|
27855
|
+
fs64.writeFileSync(lockPath, String(process.pid));
|
|
27646
27856
|
}
|
|
27647
27857
|
const release3 = () => {
|
|
27648
27858
|
try {
|
|
27649
|
-
if (
|
|
27650
|
-
|
|
27859
|
+
if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
27860
|
+
fs64.unlinkSync(lockPath);
|
|
27651
27861
|
}
|
|
27652
27862
|
} catch {
|
|
27653
27863
|
}
|
|
@@ -27669,19 +27879,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
27669
27879
|
function acquireSingletonLock() {
|
|
27670
27880
|
const lockPath = pairAutoLockPath();
|
|
27671
27881
|
try {
|
|
27672
|
-
|
|
27882
|
+
fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
|
|
27673
27883
|
try {
|
|
27674
|
-
|
|
27884
|
+
fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
27675
27885
|
} catch (e) {
|
|
27676
27886
|
if (e.code !== "EEXIST") throw e;
|
|
27677
|
-
const holder = Number(
|
|
27887
|
+
const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
|
|
27678
27888
|
if (isLivePairAuto(holder)) return false;
|
|
27679
|
-
|
|
27889
|
+
fs64.writeFileSync(lockPath, String(process.pid));
|
|
27680
27890
|
}
|
|
27681
27891
|
process.once("exit", () => {
|
|
27682
27892
|
try {
|
|
27683
|
-
if (
|
|
27684
|
-
|
|
27893
|
+
if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
27894
|
+
fs64.unlinkSync(lockPath);
|
|
27685
27895
|
}
|
|
27686
27896
|
} catch {
|
|
27687
27897
|
}
|
|
@@ -28135,178 +28345,6 @@ var AgentService = class _AgentService {
|
|
|
28135
28345
|
// src/agents/acp/adapters.ts
|
|
28136
28346
|
var path70 = __toESM(require("path"));
|
|
28137
28347
|
|
|
28138
|
-
// src/agents/acp/agent-binary.ts
|
|
28139
|
-
var import_fs6 = __toESM(require("fs"));
|
|
28140
|
-
var import_os11 = __toESM(require("os"));
|
|
28141
|
-
var import_path8 = __toESM(require("path"));
|
|
28142
|
-
var import_child_process27 = require("child_process");
|
|
28143
|
-
function currentPlatformKey() {
|
|
28144
|
-
return `${process.platform}-${process.arch}`;
|
|
28145
|
-
}
|
|
28146
|
-
var SDK_PKG = "@anthropic-ai/claude-agent-sdk";
|
|
28147
|
-
function resolveSdkDirViaRequire(req = require) {
|
|
28148
|
-
try {
|
|
28149
|
-
return import_path8.default.dirname(req.resolve(`${SDK_PKG}/package.json`));
|
|
28150
|
-
} catch {
|
|
28151
|
-
}
|
|
28152
|
-
try {
|
|
28153
|
-
let dir = import_path8.default.dirname(req.resolve(SDK_PKG));
|
|
28154
|
-
for (let i = 0; i < 5; i++) {
|
|
28155
|
-
if (import_path8.default.basename(dir) === "claude-agent-sdk") return dir;
|
|
28156
|
-
const parent = import_path8.default.dirname(dir);
|
|
28157
|
-
if (parent === dir) break;
|
|
28158
|
-
dir = parent;
|
|
28159
|
-
}
|
|
28160
|
-
return null;
|
|
28161
|
-
} catch {
|
|
28162
|
-
return null;
|
|
28163
|
-
}
|
|
28164
|
-
}
|
|
28165
|
-
function defaultSdkDir() {
|
|
28166
|
-
return resolveSdkDirViaRequire();
|
|
28167
|
-
}
|
|
28168
|
-
function resolveClaudeNativeBinary(deps = {}) {
|
|
28169
|
-
const existsSync29 = deps.existsSync ?? import_fs6.default.existsSync;
|
|
28170
|
-
const platformKey = deps.platformKey ?? currentPlatformKey();
|
|
28171
|
-
const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
|
|
28172
|
-
if (!sdkDir) return null;
|
|
28173
|
-
const scopeDir = import_path8.default.dirname(sdkDir);
|
|
28174
|
-
const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
|
|
28175
|
-
const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
|
|
28176
|
-
return existsSync29(candidate) ? candidate : null;
|
|
28177
|
-
}
|
|
28178
|
-
var realSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
28179
|
-
async function waitForClaudeNativeBinary(opts = {}) {
|
|
28180
|
-
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
28181
|
-
const pollMs = opts.pollMs ?? 500;
|
|
28182
|
-
const now = opts.now ?? Date.now;
|
|
28183
|
-
const sleep5 = opts.sleep ?? realSleep;
|
|
28184
|
-
const deps = {
|
|
28185
|
-
sdkDir: opts.sdkDir,
|
|
28186
|
-
platformKey: opts.platformKey,
|
|
28187
|
-
existsSync: opts.existsSync
|
|
28188
|
-
};
|
|
28189
|
-
const deadline = now() + timeoutMs;
|
|
28190
|
-
let found = resolveClaudeNativeBinary(deps);
|
|
28191
|
-
if (found) return found;
|
|
28192
|
-
while (now() < deadline) {
|
|
28193
|
-
await sleep5(pollMs);
|
|
28194
|
-
found = resolveClaudeNativeBinary(deps);
|
|
28195
|
-
if (found) return found;
|
|
28196
|
-
}
|
|
28197
|
-
return resolveClaudeNativeBinary(deps);
|
|
28198
|
-
}
|
|
28199
|
-
function isCommandOnPath(cmd, probe = defaultWhich) {
|
|
28200
|
-
return probe(cmd);
|
|
28201
|
-
}
|
|
28202
|
-
function defaultWhich(cmd) {
|
|
28203
|
-
const finder = process.platform === "win32" ? "where" : "which";
|
|
28204
|
-
try {
|
|
28205
|
-
const res = (0, import_child_process27.spawnSync)(finder, [cmd], { stdio: "ignore" });
|
|
28206
|
-
return res.status === 0;
|
|
28207
|
-
} catch {
|
|
28208
|
-
return false;
|
|
28209
|
-
}
|
|
28210
|
-
}
|
|
28211
|
-
async function waitForCommandOnPath(cmd, opts = {}) {
|
|
28212
|
-
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
28213
|
-
const pollMs = opts.pollMs ?? 500;
|
|
28214
|
-
const now = opts.now ?? Date.now;
|
|
28215
|
-
const sleep5 = opts.sleep ?? realSleep;
|
|
28216
|
-
const probe = opts.probe;
|
|
28217
|
-
const check = () => isCommandOnPath(cmd, probe);
|
|
28218
|
-
const deadline = now() + timeoutMs;
|
|
28219
|
-
if (check()) return true;
|
|
28220
|
-
while (now() < deadline) {
|
|
28221
|
-
await sleep5(pollMs);
|
|
28222
|
-
if (check()) return true;
|
|
28223
|
-
}
|
|
28224
|
-
return check();
|
|
28225
|
-
}
|
|
28226
|
-
function resolveCursorAgentBinary(deps = {}) {
|
|
28227
|
-
const existsSync29 = deps.existsSync ?? import_fs6.default.existsSync;
|
|
28228
|
-
const platform3 = deps.platform ?? process.platform;
|
|
28229
|
-
const env = deps.env ?? process.env;
|
|
28230
|
-
if (platform3 === "win32") {
|
|
28231
|
-
const localAppData = env.LOCALAPPDATA;
|
|
28232
|
-
if (!localAppData) return null;
|
|
28233
|
-
const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
|
|
28234
|
-
return existsSync29(exe) ? exe : null;
|
|
28235
|
-
}
|
|
28236
|
-
const home = deps.homedir ?? import_os11.default.homedir();
|
|
28237
|
-
const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
|
|
28238
|
-
return existsSync29(unix) ? unix : null;
|
|
28239
|
-
}
|
|
28240
|
-
async function waitForCursorAgent(opts = {}) {
|
|
28241
|
-
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
28242
|
-
const pollMs = opts.pollMs ?? 500;
|
|
28243
|
-
const now = opts.now ?? Date.now;
|
|
28244
|
-
const sleep5 = opts.sleep ?? realSleep;
|
|
28245
|
-
const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
|
|
28246
|
-
const deadline = now() + timeoutMs;
|
|
28247
|
-
if (check()) return true;
|
|
28248
|
-
while (now() < deadline) {
|
|
28249
|
-
await sleep5(pollMs);
|
|
28250
|
-
if (check()) return true;
|
|
28251
|
-
}
|
|
28252
|
-
return check();
|
|
28253
|
-
}
|
|
28254
|
-
var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|ERR_UNSUPPORTED_DIR_IMPORT|ERR_PACKAGE_PATH_NOT_EXPORTED|ERR_INVALID_PACKAGE_CONFIG|ERR_INVALID_PACKAGE_TARGET|ERR_INVALID_MODULE_SPECIFIER|node:internal\/modules\/|Directory import|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
|
|
28255
|
-
var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
|
|
28256
|
-
function probeAdapterModuleGraph(command2, args2, opts = {}) {
|
|
28257
|
-
const livenessMs = opts.livenessMs ?? 400;
|
|
28258
|
-
const spawnFn = opts.spawnFn ?? import_child_process27.spawn;
|
|
28259
|
-
return new Promise((resolve9) => {
|
|
28260
|
-
let settled = false;
|
|
28261
|
-
let stderr = "";
|
|
28262
|
-
let timer;
|
|
28263
|
-
let child;
|
|
28264
|
-
const finish = (r) => {
|
|
28265
|
-
if (settled) return;
|
|
28266
|
-
settled = true;
|
|
28267
|
-
if (timer) clearTimeout(timer);
|
|
28268
|
-
try {
|
|
28269
|
-
child?.kill("SIGKILL");
|
|
28270
|
-
} catch {
|
|
28271
|
-
}
|
|
28272
|
-
resolve9(r);
|
|
28273
|
-
};
|
|
28274
|
-
try {
|
|
28275
|
-
child = spawnFn(command2, [...args2], { stdio: ["pipe", "ignore", "pipe"] });
|
|
28276
|
-
} catch {
|
|
28277
|
-
resolve9("ok");
|
|
28278
|
-
return;
|
|
28279
|
-
}
|
|
28280
|
-
child.stderr?.on("data", (d3) => {
|
|
28281
|
-
stderr += d3.toString();
|
|
28282
|
-
if (stderr.length > 8192) stderr = stderr.slice(-8192);
|
|
28283
|
-
});
|
|
28284
|
-
child.on("error", () => finish("ok"));
|
|
28285
|
-
child.on("exit", (code) => {
|
|
28286
|
-
if (code !== 0 && code !== null && !PERMANENT_ADAPTER_STARTUP_RE.test(stderr)) {
|
|
28287
|
-
finish("transient");
|
|
28288
|
-
} else {
|
|
28289
|
-
finish("ok");
|
|
28290
|
-
}
|
|
28291
|
-
});
|
|
28292
|
-
timer = setTimeout(() => finish("ok"), livenessMs);
|
|
28293
|
-
});
|
|
28294
|
-
}
|
|
28295
|
-
async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
28296
|
-
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
28297
|
-
const pollMs = opts.pollMs ?? 500;
|
|
28298
|
-
const now = opts.now ?? Date.now;
|
|
28299
|
-
const sleep5 = opts.sleep ?? realSleep;
|
|
28300
|
-
const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
|
|
28301
|
-
const deadline = now() + timeoutMs;
|
|
28302
|
-
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
28303
|
-
while (now() < deadline) {
|
|
28304
|
-
await sleep5(pollMs);
|
|
28305
|
-
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
28306
|
-
}
|
|
28307
|
-
return false;
|
|
28308
|
-
}
|
|
28309
|
-
|
|
28310
28348
|
// src/agents/kimi/installer.ts
|
|
28311
28349
|
var import_node_child_process27 = require("child_process");
|
|
28312
28350
|
var import_node_os10 = require("os");
|
|
@@ -28455,7 +28493,10 @@ var REGISTRY = {
|
|
|
28455
28493
|
args: [bin],
|
|
28456
28494
|
requiresAgentBinary: "codex",
|
|
28457
28495
|
// codex ships via `npm install -g @openai/codex` → PATH binary.
|
|
28458
|
-
waitForBinary: (o) =>
|
|
28496
|
+
waitForBinary: (o) => {
|
|
28497
|
+
augmentUserLocalBinPaths();
|
|
28498
|
+
return waitForCommandOnPath("codex", o);
|
|
28499
|
+
}
|
|
28459
28500
|
};
|
|
28460
28501
|
},
|
|
28461
28502
|
// Cursor speaks ACP NATIVELY via `cursor-agent acp` ("Start the Cursor
|
|
@@ -28481,7 +28522,30 @@ var REGISTRY = {
|
|
|
28481
28522
|
command: resolveCursorAgentBinary() ?? "cursor-agent",
|
|
28482
28523
|
args: ["acp"],
|
|
28483
28524
|
requiresAgentBinary: "cursor-agent",
|
|
28484
|
-
|
|
28525
|
+
// Stale-PATH guard — same class as codex/gemini above, kept here so the
|
|
28526
|
+
// PROBE and the SPAWN agree about what "ready" means.
|
|
28527
|
+
//
|
|
28528
|
+
// On an in-session switch the adapter spec is resolved BEFORE the install
|
|
28529
|
+
// (`ensureAgentBinaryForSwitch`'s first step), so with no cursor-agent on
|
|
28530
|
+
// disk yet `resolveCursorAgentBinary()` returns null and the spec is
|
|
28531
|
+
// PERMANENTLY CACHED with the bare name `cursor-agent`. The installer then
|
|
28532
|
+
// drops the binary in ~/.local/bin, which a systemd-minimal PATH lacks,
|
|
28533
|
+
// yet `waitForCursorAgent` still reports READY (it probes the absolute
|
|
28534
|
+
// install location).
|
|
28535
|
+
//
|
|
28536
|
+
// ⚠️ Scope, honestly: this is defence in depth, NOT a live outage fix.
|
|
28537
|
+
// `AcpClient.start` already spawns with `expandPathForAgentBinaries(...)`
|
|
28538
|
+
// (client.ts), which folds the same dirs in, so the production ACP spawn
|
|
28539
|
+
// very likely resolved anyway. What was genuinely wrong is that a probe
|
|
28540
|
+
// could report ready while a *plain* spawn from the same process could not
|
|
28541
|
+
// find the binary — the real-install gate
|
|
28542
|
+
// (`__tests__/integration/agent-install.int.test.ts`) spawns without that
|
|
28543
|
+
// expansion and caught the divergence. Aligning the probe with codex/gemini
|
|
28544
|
+
// costs one idempotent call and removes the discrepancy.
|
|
28545
|
+
waitForBinary: (o) => {
|
|
28546
|
+
augmentUserLocalBinPaths();
|
|
28547
|
+
return waitForCursorAgent(o);
|
|
28548
|
+
}
|
|
28485
28549
|
}),
|
|
28486
28550
|
// Gemini speaks ACP natively via `gemini --acp` — no npm adapter
|
|
28487
28551
|
// package, just the user-installed `gemini` binary on PATH. Same
|
|
@@ -28499,7 +28563,12 @@ var REGISTRY = {
|
|
|
28499
28563
|
// codeam was launched from.
|
|
28500
28564
|
args: ["--skip-trust", "--acp"],
|
|
28501
28565
|
requiresAgentBinary: "gemini",
|
|
28502
|
-
|
|
28566
|
+
// gemini ships via `npm install -g @google/gemini-cli` → PATH binary,
|
|
28567
|
+
// same stale-PATH exposure as codex above.
|
|
28568
|
+
waitForBinary: (o) => {
|
|
28569
|
+
augmentUserLocalBinPaths();
|
|
28570
|
+
return waitForCommandOnPath("gemini", o);
|
|
28571
|
+
}
|
|
28503
28572
|
}),
|
|
28504
28573
|
// Kimi Code (Moonshot) speaks ACP natively via `kimi acp` — a stdio
|
|
28505
28574
|
// JSON-RPC server that answers `initialize` (agentInfo `Kimi Code CLI`,
|
|
@@ -34688,7 +34757,7 @@ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
|
|
|
34688
34757
|
};
|
|
34689
34758
|
}
|
|
34690
34759
|
log.info("switchAgent", `installing ${agentId} binary (missing on PATH)`);
|
|
34691
|
-
const res = await runInstall(installScript, { logScope: "switchAgent" });
|
|
34760
|
+
const res = await runInstall(installScript, { logScope: "switchAgent", timeoutMs: 3e5 });
|
|
34692
34761
|
if (!res.ok) {
|
|
34693
34762
|
return {
|
|
34694
34763
|
ok: false,
|
|
@@ -34696,6 +34765,22 @@ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
|
|
|
34696
34765
|
};
|
|
34697
34766
|
}
|
|
34698
34767
|
if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
|
|
34768
|
+
log.info(
|
|
34769
|
+
"switchAgent",
|
|
34770
|
+
"install probe failed \u2014 retrying install once (half-finished bin link class)"
|
|
34771
|
+
);
|
|
34772
|
+
deps.onRetry?.();
|
|
34773
|
+
const retryRes = await runInstall(installScript, {
|
|
34774
|
+
logScope: "switchAgent",
|
|
34775
|
+
timeoutMs: 3e5
|
|
34776
|
+
});
|
|
34777
|
+
if (!retryRes.ok) {
|
|
34778
|
+
return {
|
|
34779
|
+
ok: false,
|
|
34780
|
+
error: retryRes.timedOut ? `${displayName(agentId)} install timed out.` : `${displayName(agentId)} install failed.`
|
|
34781
|
+
};
|
|
34782
|
+
}
|
|
34783
|
+
if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
|
|
34699
34784
|
return {
|
|
34700
34785
|
ok: false,
|
|
34701
34786
|
error: `${displayName(agentId)} installed but its binary never appeared on PATH.`
|
|
@@ -34729,7 +34814,11 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
|
|
|
34729
34814
|
const from = deps.currentAgent();
|
|
34730
34815
|
const target = resolveSwitchTarget(rawAgentId, from);
|
|
34731
34816
|
if (!target.ok) {
|
|
34732
|
-
return {
|
|
34817
|
+
return {
|
|
34818
|
+
ok: false,
|
|
34819
|
+
agentId: typeof rawAgentId === "string" ? rawAgentId : "",
|
|
34820
|
+
error: target.error
|
|
34821
|
+
};
|
|
34733
34822
|
}
|
|
34734
34823
|
const agentId = target.agentId;
|
|
34735
34824
|
const emitStatus = (status2) => deps.postEvent("switch_agent_status", { ...status2 });
|
|
@@ -34760,7 +34849,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
|
|
|
34760
34849
|
}
|
|
34761
34850
|
if (!fastPath.skipInstall) {
|
|
34762
34851
|
void emitStep("install");
|
|
34763
|
-
const bin = await deps.ensureBinary(agentId, installScript)
|
|
34852
|
+
const bin = await deps.ensureBinary(agentId, installScript, () => {
|
|
34853
|
+
void emitStep("install");
|
|
34854
|
+
});
|
|
34764
34855
|
if (!bin.ok) return fail2(bin.error);
|
|
34765
34856
|
}
|
|
34766
34857
|
void emitStep("restart");
|
|
@@ -34776,7 +34867,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
|
|
|
34776
34867
|
`Switching to ${displayName(agentId)} failed and ${displayName(from)} couldn't be restored \u2014 restart the session.`
|
|
34777
34868
|
);
|
|
34778
34869
|
}
|
|
34779
|
-
return fail2(
|
|
34870
|
+
return fail2(
|
|
34871
|
+
`Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`
|
|
34872
|
+
);
|
|
34780
34873
|
}
|
|
34781
34874
|
try {
|
|
34782
34875
|
deps.persistAgent(agentId);
|
|
@@ -35848,7 +35941,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
35848
35941
|
});
|
|
35849
35942
|
}
|
|
35850
35943
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
35851
|
-
const
|
|
35944
|
+
const fs81 = await import("fs/promises");
|
|
35852
35945
|
const out2 = [];
|
|
35853
35946
|
await walk(workingDir, 0);
|
|
35854
35947
|
return out2;
|
|
@@ -35856,7 +35949,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
35856
35949
|
if (depth > maxDepth) return;
|
|
35857
35950
|
let entries = [];
|
|
35858
35951
|
try {
|
|
35859
|
-
const dirents = await
|
|
35952
|
+
const dirents = await fs81.readdir(dir, { withFileTypes: true });
|
|
35860
35953
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
35861
35954
|
} catch {
|
|
35862
35955
|
return;
|
|
@@ -37091,12 +37184,124 @@ function buildMcpServersForStart(ctx) {
|
|
|
37091
37184
|
return servers;
|
|
37092
37185
|
}
|
|
37093
37186
|
|
|
37094
|
-
// src/
|
|
37187
|
+
// src/services/local-mcp-servers.ts
|
|
37095
37188
|
var import_node_fs12 = __toESM(require("fs"));
|
|
37189
|
+
var import_node_os12 = __toESM(require("os"));
|
|
37096
37190
|
var import_node_path11 = __toESM(require("path"));
|
|
37191
|
+
var MAX_LOCAL_MCP_SERVERS = 10;
|
|
37192
|
+
function localMcpServersPath() {
|
|
37193
|
+
return import_node_path11.default.join(import_node_os12.default.homedir(), ".codeam", "mcp-servers.json");
|
|
37194
|
+
}
|
|
37195
|
+
function isStringArray(v) {
|
|
37196
|
+
return Array.isArray(v) && v.every((item) => typeof item === "string");
|
|
37197
|
+
}
|
|
37198
|
+
function toEnvVariables(v) {
|
|
37199
|
+
if (v === void 0) return [];
|
|
37200
|
+
if (v === null || typeof v !== "object" || Array.isArray(v)) return null;
|
|
37201
|
+
const entries = Object.entries(v);
|
|
37202
|
+
if (entries.some(([, value]) => typeof value !== "string")) return null;
|
|
37203
|
+
return entries.map(([name, value]) => ({ name, value }));
|
|
37204
|
+
}
|
|
37205
|
+
function isValidEntry(entry) {
|
|
37206
|
+
return typeof entry.name === "string" && entry.name.length > 0 && typeof entry.command === "string" && entry.command.length > 0 && isStringArray(entry.args);
|
|
37207
|
+
}
|
|
37208
|
+
function readLocalMcpServers() {
|
|
37209
|
+
let raw;
|
|
37210
|
+
try {
|
|
37211
|
+
raw = import_node_fs12.default.readFileSync(localMcpServersPath(), "utf8");
|
|
37212
|
+
} catch {
|
|
37213
|
+
return [];
|
|
37214
|
+
}
|
|
37215
|
+
let parsed;
|
|
37216
|
+
try {
|
|
37217
|
+
parsed = JSON.parse(raw);
|
|
37218
|
+
} catch (err) {
|
|
37219
|
+
log.warn(
|
|
37220
|
+
"localMcp",
|
|
37221
|
+
`~/.codeam/mcp-servers.json is not valid JSON \u2014 ignoring (${err instanceof Error ? err.message : String(err)})`
|
|
37222
|
+
);
|
|
37223
|
+
return [];
|
|
37224
|
+
}
|
|
37225
|
+
if (!Array.isArray(parsed)) {
|
|
37226
|
+
log.warn("localMcp", "~/.codeam/mcp-servers.json must be a JSON array \u2014 ignoring");
|
|
37227
|
+
return [];
|
|
37228
|
+
}
|
|
37229
|
+
const servers = [];
|
|
37230
|
+
let sawInvalid = false;
|
|
37231
|
+
let sawTruncated = false;
|
|
37232
|
+
let sawDuplicate = false;
|
|
37233
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
37234
|
+
for (const entry of parsed) {
|
|
37235
|
+
if (servers.length >= MAX_LOCAL_MCP_SERVERS) {
|
|
37236
|
+
sawTruncated = true;
|
|
37237
|
+
continue;
|
|
37238
|
+
}
|
|
37239
|
+
if (entry === null || typeof entry !== "object" || !isValidEntry(entry)) {
|
|
37240
|
+
sawInvalid = true;
|
|
37241
|
+
continue;
|
|
37242
|
+
}
|
|
37243
|
+
const env = toEnvVariables(entry.env);
|
|
37244
|
+
if (env === null) {
|
|
37245
|
+
sawInvalid = true;
|
|
37246
|
+
continue;
|
|
37247
|
+
}
|
|
37248
|
+
if (seenNames.has(entry.name)) {
|
|
37249
|
+
sawDuplicate = true;
|
|
37250
|
+
continue;
|
|
37251
|
+
}
|
|
37252
|
+
seenNames.add(entry.name);
|
|
37253
|
+
servers.push({ name: entry.name, command: entry.command, args: entry.args, env });
|
|
37254
|
+
}
|
|
37255
|
+
if (sawDuplicate) {
|
|
37256
|
+
log.warn(
|
|
37257
|
+
"localMcp",
|
|
37258
|
+
"~/.codeam/mcp-servers.json has duplicate server names \u2014 kept the first of each"
|
|
37259
|
+
);
|
|
37260
|
+
}
|
|
37261
|
+
if (sawInvalid) {
|
|
37262
|
+
log.warn(
|
|
37263
|
+
"localMcp",
|
|
37264
|
+
'~/.codeam/mcp-servers.json contains one or more invalid entries \u2014 skipped (each needs a non-empty "name", non-empty "command", "args" as a string array, and "env" as an object of string values)'
|
|
37265
|
+
);
|
|
37266
|
+
}
|
|
37267
|
+
if (sawTruncated) {
|
|
37268
|
+
log.warn(
|
|
37269
|
+
"localMcp",
|
|
37270
|
+
`~/.codeam/mcp-servers.json has more than ${MAX_LOCAL_MCP_SERVERS} entries \u2014 only the first ${MAX_LOCAL_MCP_SERVERS} were loaded`
|
|
37271
|
+
);
|
|
37272
|
+
}
|
|
37273
|
+
if (servers.length) {
|
|
37274
|
+
log.info(
|
|
37275
|
+
"localMcp",
|
|
37276
|
+
`loaded ${servers.length} local MCP server(s): ${servers.map((s) => s.name).join(", ")}`
|
|
37277
|
+
);
|
|
37278
|
+
}
|
|
37279
|
+
return servers;
|
|
37280
|
+
}
|
|
37281
|
+
function mergeWithLocalMcpServers(integrationServers) {
|
|
37282
|
+
const localServers = readLocalMcpServers();
|
|
37283
|
+
if (localServers.length === 0) return integrationServers;
|
|
37284
|
+
const integrationNames = new Set(integrationServers.map((s) => s.name));
|
|
37285
|
+
const merged = [...integrationServers];
|
|
37286
|
+
for (const local of localServers) {
|
|
37287
|
+
if (integrationNames.has(local.name)) {
|
|
37288
|
+
log.warn(
|
|
37289
|
+
"localMcp",
|
|
37290
|
+
`local MCP server "${local.name}" collides with an Agent Toolkit integration of the same name \u2014 the integration wins, skipping the local entry`
|
|
37291
|
+
);
|
|
37292
|
+
continue;
|
|
37293
|
+
}
|
|
37294
|
+
merged.push(local);
|
|
37295
|
+
}
|
|
37296
|
+
return merged;
|
|
37297
|
+
}
|
|
37298
|
+
|
|
37299
|
+
// src/integrations/detect-stack.ts
|
|
37300
|
+
var import_node_fs13 = __toESM(require("fs"));
|
|
37301
|
+
var import_node_path12 = __toESM(require("path"));
|
|
37097
37302
|
function readSafe(cwd, rel) {
|
|
37098
37303
|
try {
|
|
37099
|
-
return
|
|
37304
|
+
return import_node_fs13.default.readFileSync(import_node_path12.default.join(cwd, rel), "utf8");
|
|
37100
37305
|
} catch {
|
|
37101
37306
|
return "";
|
|
37102
37307
|
}
|
|
@@ -37279,35 +37484,35 @@ function buildAcpPromptBlocks(payload) {
|
|
|
37279
37484
|
}
|
|
37280
37485
|
|
|
37281
37486
|
// src/agents/agent-standard.ts
|
|
37282
|
-
var
|
|
37283
|
-
var
|
|
37284
|
-
var
|
|
37285
|
-
function ensureAgentStandard(homeDir2 =
|
|
37487
|
+
var fs76 = __toESM(require("fs"));
|
|
37488
|
+
var path83 = __toESM(require("path"));
|
|
37489
|
+
var os61 = __toESM(require("os"));
|
|
37490
|
+
function ensureAgentStandard(homeDir2 = os61.homedir()) {
|
|
37286
37491
|
try {
|
|
37287
|
-
const file =
|
|
37492
|
+
const file = path83.join(homeDir2, ".claude", "CLAUDE.md");
|
|
37288
37493
|
let existing = "";
|
|
37289
37494
|
try {
|
|
37290
|
-
existing =
|
|
37495
|
+
existing = fs76.readFileSync(file, "utf8");
|
|
37291
37496
|
} catch {
|
|
37292
37497
|
}
|
|
37293
37498
|
if (existing.includes(AGENT_STANDARD_MARKER)) return;
|
|
37294
|
-
|
|
37499
|
+
fs76.mkdirSync(path83.dirname(file), { recursive: true });
|
|
37295
37500
|
const next = existing.trim() ? `${existing.trimEnd()}
|
|
37296
37501
|
|
|
37297
37502
|
${AGENT_STANDARD_BLOCK}
|
|
37298
37503
|
` : `${AGENT_STANDARD_BLOCK}
|
|
37299
37504
|
`;
|
|
37300
|
-
|
|
37505
|
+
fs76.writeFileSync(file, next);
|
|
37301
37506
|
} catch {
|
|
37302
37507
|
}
|
|
37303
37508
|
}
|
|
37304
37509
|
var _agentStandardSeam = {
|
|
37305
37510
|
isLocalSession: () => isLocalSession(),
|
|
37306
|
-
markerPath: (sessionId) =>
|
|
37307
|
-
exists: (p2) =>
|
|
37511
|
+
markerPath: (sessionId) => path83.join(os61.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
|
|
37512
|
+
exists: (p2) => fs76.existsSync(p2),
|
|
37308
37513
|
write: (p2) => {
|
|
37309
|
-
|
|
37310
|
-
|
|
37514
|
+
fs76.mkdirSync(path83.dirname(p2), { recursive: true });
|
|
37515
|
+
fs76.writeFileSync(p2, "");
|
|
37311
37516
|
}
|
|
37312
37517
|
};
|
|
37313
37518
|
function isClaude(agent) {
|
|
@@ -38245,12 +38450,14 @@ async function integrationsSyncH(ctx) {
|
|
|
38245
38450
|
const previousIds = new Set((readIntegrationsManifest()?.integrations ?? []).map((e) => e.id));
|
|
38246
38451
|
persistIntegrationsManifest(manifest);
|
|
38247
38452
|
await prewarmNewMcpEntries(manifest, previousIds);
|
|
38248
|
-
const servers =
|
|
38249
|
-
|
|
38250
|
-
|
|
38251
|
-
|
|
38252
|
-
|
|
38253
|
-
|
|
38453
|
+
const servers = mergeWithLocalMcpServers(
|
|
38454
|
+
buildMcpServersForStart({
|
|
38455
|
+
sessionId: opts.sessionId,
|
|
38456
|
+
pluginId: opts.pluginId,
|
|
38457
|
+
pluginAuthToken: opts.pluginAuthToken,
|
|
38458
|
+
pollSecret: opts.pollSecret
|
|
38459
|
+
})
|
|
38460
|
+
);
|
|
38254
38461
|
const applied = await client3.reprovisionMcp(servers);
|
|
38255
38462
|
await relay.sendResult(cmd.id, "completed", {
|
|
38256
38463
|
synced: true,
|
|
@@ -39348,7 +39555,7 @@ async function runAcpSession(opts) {
|
|
|
39348
39555
|
provisionCredential: (agentId, auth) => {
|
|
39349
39556
|
switchCredentialEnv = provisionAgentCredentials(agentId, auth);
|
|
39350
39557
|
},
|
|
39351
|
-
ensureBinary: (agentId, installScript) => ensureAgentBinaryForSwitch(agentId, installScript),
|
|
39558
|
+
ensureBinary: (agentId, installScript, onRetry) => ensureAgentBinaryForSwitch(agentId, installScript, { onRetry }),
|
|
39352
39559
|
swapRuntime: relaunchWith,
|
|
39353
39560
|
revertRuntime: relaunchWith,
|
|
39354
39561
|
persistAgent: (agentId) => setSessionAgent(opts.pluginId, agentId),
|
|
@@ -40515,9 +40722,9 @@ function startClaudeCredentialSync(opts) {
|
|
|
40515
40722
|
}
|
|
40516
40723
|
|
|
40517
40724
|
// src/beads/workflow-hint.ts
|
|
40518
|
-
var
|
|
40519
|
-
var
|
|
40520
|
-
var
|
|
40725
|
+
var fs77 = __toESM(require("fs"));
|
|
40726
|
+
var path84 = __toESM(require("path"));
|
|
40727
|
+
var os62 = __toESM(require("os"));
|
|
40521
40728
|
var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
|
|
40522
40729
|
var BEADS_HINT = `${BEADS_HINT_MARKER}
|
|
40523
40730
|
# Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
|
|
@@ -40531,29 +40738,29 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
|
|
|
40531
40738
|
- \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
|
|
40532
40739
|
- Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
|
|
40533
40740
|
${BEADS_HINT_MARKER}`;
|
|
40534
|
-
function ensureBeadsWorkflowHint(homeDir2 =
|
|
40741
|
+
function ensureBeadsWorkflowHint(homeDir2 = os62.homedir()) {
|
|
40535
40742
|
try {
|
|
40536
|
-
const file =
|
|
40743
|
+
const file = path84.join(homeDir2, ".claude", "CLAUDE.md");
|
|
40537
40744
|
let existing = "";
|
|
40538
40745
|
try {
|
|
40539
|
-
existing =
|
|
40746
|
+
existing = fs77.readFileSync(file, "utf8");
|
|
40540
40747
|
} catch {
|
|
40541
40748
|
}
|
|
40542
40749
|
if (existing.includes(BEADS_HINT_MARKER)) return;
|
|
40543
|
-
|
|
40750
|
+
fs77.mkdirSync(path84.dirname(file), { recursive: true });
|
|
40544
40751
|
const next = existing.trim() ? `${existing.trimEnd()}
|
|
40545
40752
|
|
|
40546
40753
|
${BEADS_HINT}
|
|
40547
40754
|
` : `${BEADS_HINT}
|
|
40548
40755
|
`;
|
|
40549
|
-
|
|
40756
|
+
fs77.writeFileSync(file, next);
|
|
40550
40757
|
} catch {
|
|
40551
40758
|
}
|
|
40552
40759
|
}
|
|
40553
40760
|
|
|
40554
40761
|
// src/skills/provision.ts
|
|
40555
|
-
var
|
|
40556
|
-
function provisionSkillsForStart(home =
|
|
40762
|
+
var import_node_os13 = __toESM(require("os"));
|
|
40763
|
+
function provisionSkillsForStart(home = import_node_os13.default.homedir()) {
|
|
40557
40764
|
const materialized = [];
|
|
40558
40765
|
try {
|
|
40559
40766
|
const manifest = readSkillsManifest();
|
|
@@ -40918,7 +41125,7 @@ var AcpDriver = class {
|
|
|
40918
41125
|
};
|
|
40919
41126
|
|
|
40920
41127
|
// src/baton/transcript-mirror.ts
|
|
40921
|
-
var
|
|
41128
|
+
var fs78 = __toESM(require("fs"));
|
|
40922
41129
|
var TranscriptMirror = class {
|
|
40923
41130
|
constructor(deps) {
|
|
40924
41131
|
this.deps = deps;
|
|
@@ -40985,7 +41192,7 @@ var TranscriptMirror = class {
|
|
|
40985
41192
|
}
|
|
40986
41193
|
};
|
|
40987
41194
|
function defaultWatch(file, onChange) {
|
|
40988
|
-
const w3 =
|
|
41195
|
+
const w3 = fs78.watch(file, { persistent: false }, () => onChange());
|
|
40989
41196
|
return () => w3.close();
|
|
40990
41197
|
}
|
|
40991
41198
|
|
|
@@ -41283,16 +41490,16 @@ function keepDeviceAwake(deps = {}) {
|
|
|
41283
41490
|
}
|
|
41284
41491
|
|
|
41285
41492
|
// src/agents/claude/onboarding.ts
|
|
41286
|
-
var
|
|
41287
|
-
var
|
|
41288
|
-
var
|
|
41493
|
+
var fs79 = __toESM(require("fs"));
|
|
41494
|
+
var os64 = __toESM(require("os"));
|
|
41495
|
+
var path85 = __toESM(require("path"));
|
|
41289
41496
|
var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
|
|
41290
41497
|
function ensureClaudeOnboarded(cwd) {
|
|
41291
41498
|
try {
|
|
41292
|
-
const file =
|
|
41499
|
+
const file = path85.join(os64.homedir(), ".claude.json");
|
|
41293
41500
|
let config = {};
|
|
41294
41501
|
try {
|
|
41295
|
-
config = JSON.parse(
|
|
41502
|
+
config = JSON.parse(fs79.readFileSync(file, "utf8"));
|
|
41296
41503
|
} catch {
|
|
41297
41504
|
}
|
|
41298
41505
|
let changed = false;
|
|
@@ -41317,8 +41524,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
41317
41524
|
}
|
|
41318
41525
|
}
|
|
41319
41526
|
if (!changed) return;
|
|
41320
|
-
|
|
41321
|
-
|
|
41527
|
+
fs79.mkdirSync(path85.dirname(file), { recursive: true });
|
|
41528
|
+
fs79.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
41322
41529
|
log.info(
|
|
41323
41530
|
"claude",
|
|
41324
41531
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -41436,12 +41643,14 @@ async function start(requestedAgent, presetSession) {
|
|
|
41436
41643
|
beads = started;
|
|
41437
41644
|
return started;
|
|
41438
41645
|
});
|
|
41439
|
-
const mcpServers =
|
|
41440
|
-
|
|
41441
|
-
|
|
41442
|
-
|
|
41443
|
-
|
|
41444
|
-
|
|
41646
|
+
const mcpServers = mergeWithLocalMcpServers(
|
|
41647
|
+
buildMcpServersForStart({
|
|
41648
|
+
sessionId: session.id,
|
|
41649
|
+
pluginId,
|
|
41650
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
41651
|
+
pollSecret: session.pollSecret
|
|
41652
|
+
})
|
|
41653
|
+
);
|
|
41445
41654
|
provisionSkillsForStart();
|
|
41446
41655
|
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
41447
41656
|
if (process.env.CODESPACES === "true") {
|
|
@@ -42050,7 +42259,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
42050
42259
|
var import_child_process30 = require("child_process");
|
|
42051
42260
|
var import_util4 = require("util");
|
|
42052
42261
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
42053
|
-
var
|
|
42262
|
+
var path86 = __toESM(require("path"));
|
|
42054
42263
|
var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
|
|
42055
42264
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
42056
42265
|
function resetStdinForChild() {
|
|
@@ -42539,7 +42748,7 @@ var GitHubCodespacesProvider = class {
|
|
|
42539
42748
|
});
|
|
42540
42749
|
}
|
|
42541
42750
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
42542
|
-
const remoteDir =
|
|
42751
|
+
const remoteDir = path86.posix.dirname(remotePath);
|
|
42543
42752
|
const parts = [
|
|
42544
42753
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
42545
42754
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -42609,7 +42818,7 @@ function shellQuote(s) {
|
|
|
42609
42818
|
// src/services/providers/gitpod.ts
|
|
42610
42819
|
var import_child_process31 = require("child_process");
|
|
42611
42820
|
var import_util5 = require("util");
|
|
42612
|
-
var
|
|
42821
|
+
var path87 = __toESM(require("path"));
|
|
42613
42822
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
42614
42823
|
var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
|
|
42615
42824
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -42849,7 +43058,7 @@ var GitpodProvider = class {
|
|
|
42849
43058
|
});
|
|
42850
43059
|
}
|
|
42851
43060
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
42852
|
-
const remoteDir =
|
|
43061
|
+
const remoteDir = path87.posix.dirname(remotePath);
|
|
42853
43062
|
const parts = [
|
|
42854
43063
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
42855
43064
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -42885,7 +43094,7 @@ function shellQuote2(s) {
|
|
|
42885
43094
|
// src/services/providers/gitlab-workspaces.ts
|
|
42886
43095
|
var import_child_process32 = require("child_process");
|
|
42887
43096
|
var import_util6 = require("util");
|
|
42888
|
-
var
|
|
43097
|
+
var path88 = __toESM(require("path"));
|
|
42889
43098
|
var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
|
|
42890
43099
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
42891
43100
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -43145,7 +43354,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
43145
43354
|
}
|
|
43146
43355
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
43147
43356
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
43148
|
-
const remoteDir =
|
|
43357
|
+
const remoteDir = path88.posix.dirname(remotePath);
|
|
43149
43358
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
43150
43359
|
if (options.mode != null) {
|
|
43151
43360
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -43213,7 +43422,7 @@ function shellQuote3(s) {
|
|
|
43213
43422
|
// src/services/providers/railway.ts
|
|
43214
43423
|
var import_child_process33 = require("child_process");
|
|
43215
43424
|
var import_util7 = require("util");
|
|
43216
|
-
var
|
|
43425
|
+
var path89 = __toESM(require("path"));
|
|
43217
43426
|
var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
|
|
43218
43427
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
43219
43428
|
function resetStdinForChild4() {
|
|
@@ -43449,7 +43658,7 @@ var RailwayProvider = class {
|
|
|
43449
43658
|
if (!projectId || !serviceId) {
|
|
43450
43659
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
43451
43660
|
}
|
|
43452
|
-
const remoteDir =
|
|
43661
|
+
const remoteDir = path89.posix.dirname(remotePath);
|
|
43453
43662
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
43454
43663
|
if (options.mode != null) {
|
|
43455
43664
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -44095,8 +44304,8 @@ async function invite() {
|
|
|
44095
44304
|
var import_node_dns = require("dns");
|
|
44096
44305
|
var import_node_util5 = require("util");
|
|
44097
44306
|
var import_node_crypto13 = require("crypto");
|
|
44098
|
-
var
|
|
44099
|
-
var
|
|
44307
|
+
var fs80 = __toESM(require("fs"));
|
|
44308
|
+
var path90 = __toESM(require("path"));
|
|
44100
44309
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
44101
44310
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
44102
44311
|
async function checkDns(apiBase2) {
|
|
@@ -44152,13 +44361,13 @@ async function checkHealth(apiBase2) {
|
|
|
44152
44361
|
}
|
|
44153
44362
|
}
|
|
44154
44363
|
function checkConfigDir() {
|
|
44155
|
-
const dir =
|
|
44364
|
+
const dir = path90.join(require("os").homedir(), ".codeam");
|
|
44156
44365
|
try {
|
|
44157
|
-
|
|
44158
|
-
const probe =
|
|
44159
|
-
|
|
44160
|
-
const read2 =
|
|
44161
|
-
|
|
44366
|
+
fs80.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
44367
|
+
const probe = path90.join(dir, ".doctor-probe");
|
|
44368
|
+
fs80.writeFileSync(probe, "ok", { mode: 384 });
|
|
44369
|
+
const read2 = fs80.readFileSync(probe, "utf8");
|
|
44370
|
+
fs80.unlinkSync(probe);
|
|
44162
44371
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
44163
44372
|
return {
|
|
44164
44373
|
id: "config-dir",
|
|
@@ -44198,9 +44407,9 @@ function checkSessions() {
|
|
|
44198
44407
|
}
|
|
44199
44408
|
}
|
|
44200
44409
|
function checkAgentBinaries() {
|
|
44201
|
-
const
|
|
44410
|
+
const os67 = createOsStrategy();
|
|
44202
44411
|
return getEnabledAgents().map((meta) => {
|
|
44203
|
-
const found =
|
|
44412
|
+
const found = os67.findInPath(meta.binaryName);
|
|
44204
44413
|
return {
|
|
44205
44414
|
id: `agent-${meta.id}`,
|
|
44206
44415
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -44222,7 +44431,7 @@ function checkNodePty() {
|
|
|
44222
44431
|
detail: "not required on this platform"
|
|
44223
44432
|
};
|
|
44224
44433
|
}
|
|
44225
|
-
const vendoredPath =
|
|
44434
|
+
const vendoredPath = path90.join(__dirname, "vendor", "node-pty");
|
|
44226
44435
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
44227
44436
|
try {
|
|
44228
44437
|
require(target);
|
|
@@ -44264,7 +44473,7 @@ function checkChokidar() {
|
|
|
44264
44473
|
}
|
|
44265
44474
|
async function doctor(args2 = []) {
|
|
44266
44475
|
const json = args2.includes("--json");
|
|
44267
|
-
const cliVersion = true ? "2.65.
|
|
44476
|
+
const cliVersion = true ? "2.65.2" : "0.0.0-dev";
|
|
44268
44477
|
const apiBase2 = resolveApiBaseUrl();
|
|
44269
44478
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
44270
44479
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -44462,9 +44671,9 @@ async function completion(args2) {
|
|
|
44462
44671
|
|
|
44463
44672
|
// src/integrations/mcp-run.ts
|
|
44464
44673
|
var import_node_child_process34 = require("child_process");
|
|
44465
|
-
var
|
|
44466
|
-
var
|
|
44467
|
-
var
|
|
44674
|
+
var import_node_fs14 = require("fs");
|
|
44675
|
+
var import_node_os14 = __toESM(require("os"));
|
|
44676
|
+
var import_node_path13 = __toESM(require("path"));
|
|
44468
44677
|
|
|
44469
44678
|
// src/integrations/token-client.ts
|
|
44470
44679
|
var REFRESH_AHEAD_MS = 5 * 60 * 1e3;
|
|
@@ -44544,13 +44753,13 @@ function commandExists(command2) {
|
|
|
44544
44753
|
}
|
|
44545
44754
|
function localBinCandidates(command2) {
|
|
44546
44755
|
return [
|
|
44547
|
-
|
|
44548
|
-
|
|
44756
|
+
import_node_path13.default.join(import_node_os14.default.homedir(), ".local", "bin", command2),
|
|
44757
|
+
import_node_path13.default.join(import_node_os14.default.homedir(), ".cargo", "bin", command2)
|
|
44549
44758
|
];
|
|
44550
44759
|
}
|
|
44551
44760
|
function resolveLauncherPath(command2, deps = {
|
|
44552
44761
|
commandExists,
|
|
44553
|
-
existsSync:
|
|
44762
|
+
existsSync: import_node_fs14.existsSync
|
|
44554
44763
|
}) {
|
|
44555
44764
|
if (deps.commandExists(command2)) return command2;
|
|
44556
44765
|
for (const candidate of localBinCandidates(command2)) {
|
|
@@ -44655,7 +44864,7 @@ async function mcpRun(args2) {
|
|
|
44655
44864
|
// src/commands/version.ts
|
|
44656
44865
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
44657
44866
|
function version2() {
|
|
44658
|
-
const v = true ? "2.65.
|
|
44867
|
+
const v = true ? "2.65.2" : "unknown";
|
|
44659
44868
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
44660
44869
|
}
|
|
44661
44870
|
|
|
@@ -44804,10 +45013,10 @@ var EXIT_CODE_NAMES = {
|
|
|
44804
45013
|
};
|
|
44805
45014
|
|
|
44806
45015
|
// src/index.ts
|
|
44807
|
-
var
|
|
45016
|
+
var os66 = __toESM(require("os"));
|
|
44808
45017
|
if (!process.env.HOME) {
|
|
44809
45018
|
try {
|
|
44810
|
-
const home =
|
|
45019
|
+
const home = os66.homedir();
|
|
44811
45020
|
if (home) process.env.HOME = home;
|
|
44812
45021
|
} catch {
|
|
44813
45022
|
}
|