codeam-cli 2.65.0 → 2.65.1
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 +17 -0
- package/dist/index.js +724 -631
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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
|
|
@@ -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.1" : "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.1",
|
|
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.1" ? { ideVersion: "2.65.1" } : {}
|
|
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
|
|
|
@@ -16543,6 +16543,18 @@ 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]);
|
|
@@ -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
|
+
os66.augmentPath([`${os66.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
16693
|
+
const binary = os66.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
|
|
@@ -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 = [
|
|
@@ -17599,6 +17808,7 @@ var AiderRuntimeStrategy = class {
|
|
|
17599
17808
|
this.os = os66;
|
|
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
|
}
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|
|
@@ -19144,7 +19354,7 @@ function collectChangedFiles(cwd) {
|
|
|
19144
19354
|
return [...byPath.values()];
|
|
19145
19355
|
}
|
|
19146
19356
|
function restoreCoderabbitOauthBlob(os66, value) {
|
|
19147
|
-
const dir =
|
|
19357
|
+
const dir = path39.join(os66.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,13 +19362,13 @@ 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";
|
|
@@ -19174,10 +19384,10 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19174
19384
|
const home = os66.homeDir();
|
|
19175
19385
|
os66.augmentPath(
|
|
19176
19386
|
os66.id === "win32" ? [
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
] : [
|
|
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
19392
|
const installed2 = os66.findInPath("coderabbit") !== null;
|
|
19183
19393
|
const base = () => ({
|
|
@@ -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.1" : 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.1" : 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.1" : 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,
|
|
@@ -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) {
|
|
@@ -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;
|
|
@@ -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",
|
|
@@ -27518,7 +27728,7 @@ function resolveTokenValue(args2) {
|
|
|
27518
27728
|
if (fileFlag) {
|
|
27519
27729
|
const path91 = fileFlag.slice("--token-file=".length);
|
|
27520
27730
|
try {
|
|
27521
|
-
const content =
|
|
27731
|
+
const content = fs64.readFileSync(path91, "utf8").trim();
|
|
27522
27732
|
if (content.length === 0) fail(`--token-file ${path91} is empty`);
|
|
27523
27733
|
rmIfExistsQuiet(path91);
|
|
27524
27734
|
return content;
|
|
@@ -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);
|
|
@@ -39348,7 +39441,7 @@ async function runAcpSession(opts) {
|
|
|
39348
39441
|
provisionCredential: (agentId, auth) => {
|
|
39349
39442
|
switchCredentialEnv = provisionAgentCredentials(agentId, auth);
|
|
39350
39443
|
},
|
|
39351
|
-
ensureBinary: (agentId, installScript) => ensureAgentBinaryForSwitch(agentId, installScript),
|
|
39444
|
+
ensureBinary: (agentId, installScript, onRetry) => ensureAgentBinaryForSwitch(agentId, installScript, { onRetry }),
|
|
39352
39445
|
swapRuntime: relaunchWith,
|
|
39353
39446
|
revertRuntime: relaunchWith,
|
|
39354
39447
|
persistAgent: (agentId) => setSessionAgent(opts.pluginId, agentId),
|
|
@@ -44264,7 +44357,7 @@ function checkChokidar() {
|
|
|
44264
44357
|
}
|
|
44265
44358
|
async function doctor(args2 = []) {
|
|
44266
44359
|
const json = args2.includes("--json");
|
|
44267
|
-
const cliVersion = true ? "2.65.
|
|
44360
|
+
const cliVersion = true ? "2.65.1" : "0.0.0-dev";
|
|
44268
44361
|
const apiBase2 = resolveApiBaseUrl();
|
|
44269
44362
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
44270
44363
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -44655,7 +44748,7 @@ async function mcpRun(args2) {
|
|
|
44655
44748
|
// src/commands/version.ts
|
|
44656
44749
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
44657
44750
|
function version2() {
|
|
44658
|
-
const v = true ? "2.65.
|
|
44751
|
+
const v = true ? "2.65.1" : "unknown";
|
|
44659
44752
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
44660
44753
|
}
|
|
44661
44754
|
|