codeam-cli 2.60.46 → 2.60.48
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 +25 -0
- package/dist/index.js +835 -419
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -475,6 +475,47 @@ function headroomKindFor(agentId) {
|
|
|
475
475
|
return null;
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
// ../../packages/shared/src/integrations/registry.ts
|
|
479
|
+
var INTEGRATION_REGISTRY = {
|
|
480
|
+
jira: {
|
|
481
|
+
id: "jira",
|
|
482
|
+
name: "Jira",
|
|
483
|
+
icon: "jira",
|
|
484
|
+
enabled: true,
|
|
485
|
+
auth: {
|
|
486
|
+
kind: "oauth_redirect",
|
|
487
|
+
scopes: ["read:jira-work", "write:jira-work", "offline_access"]
|
|
488
|
+
},
|
|
489
|
+
delivery: {
|
|
490
|
+
mcp: {
|
|
491
|
+
// mcp-atlassian in BYO-token mode (headless; credentials via env only).
|
|
492
|
+
// Version PINNED to the exact release verified headless by Plan 2's
|
|
493
|
+
// Docker integration test (apps/cli mcp-shim.int.test.ts).
|
|
494
|
+
command: "uvx",
|
|
495
|
+
args: ["mcp-atlassian==0.22.1"],
|
|
496
|
+
envMapping: {
|
|
497
|
+
ATLASSIAN_OAUTH_ACCESS_TOKEN: "accessToken",
|
|
498
|
+
ATLASSIAN_OAUTH_CLOUD_ID: "cloudId"
|
|
499
|
+
},
|
|
500
|
+
// Without ATLASSIAN_OAUTH_ENABLE=true, JiraConfig.from_env() raises
|
|
501
|
+
// "Missing required JIRA_URL" (swallowed at server startup) and the
|
|
502
|
+
// server silently registers ZERO Jira tools. The flag activates
|
|
503
|
+
// mcp-atlassian's "minimal OAuth config for user-provided tokens"
|
|
504
|
+
// mode — the BYO-token path the broker feeds. Static + non-secret.
|
|
505
|
+
staticEnv: { ATLASSIAN_OAUTH_ENABLE: "true" }
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
function getIntegration(id) {
|
|
511
|
+
const meta = INTEGRATION_REGISTRY[id];
|
|
512
|
+
if (!meta) throw new Error(`Unknown integration id: ${id}`);
|
|
513
|
+
return meta;
|
|
514
|
+
}
|
|
515
|
+
function isKnownIntegrationId(id) {
|
|
516
|
+
return id in INTEGRATION_REGISTRY;
|
|
517
|
+
}
|
|
518
|
+
|
|
478
519
|
// ../../packages/shared/src/api-url.ts
|
|
479
520
|
var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
|
|
480
521
|
var DEV_API_BASE_URL = "https://dev-api.codeagent-mobile.com";
|
|
@@ -790,11 +831,11 @@ function quiet(fn) {
|
|
|
790
831
|
log.debug(TAG, "ignored sync error", err);
|
|
791
832
|
}
|
|
792
833
|
}
|
|
793
|
-
function rmIfExistsQuiet(
|
|
834
|
+
function rmIfExistsQuiet(path73) {
|
|
794
835
|
try {
|
|
795
|
-
fs2.rmSync(
|
|
836
|
+
fs2.rmSync(path73, { force: true });
|
|
796
837
|
} catch (err) {
|
|
797
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
838
|
+
log.debug(TAG, `rmIfExists failed for ${path73}`, err);
|
|
798
839
|
}
|
|
799
840
|
}
|
|
800
841
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -940,9 +981,9 @@ var _default = makeConfig();
|
|
|
940
981
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
941
982
|
|
|
942
983
|
// src/commands/pair-auto.ts
|
|
943
|
-
var
|
|
944
|
-
var
|
|
945
|
-
var
|
|
984
|
+
var fs55 = __toESM(require("fs"));
|
|
985
|
+
var os44 = __toESM(require("os"));
|
|
986
|
+
var path59 = __toESM(require("path"));
|
|
946
987
|
var import_crypto4 = require("crypto");
|
|
947
988
|
|
|
948
989
|
// src/services/telemetry.service.ts
|
|
@@ -978,8 +1019,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
978
1019
|
return decodedFile;
|
|
979
1020
|
};
|
|
980
1021
|
}
|
|
981
|
-
function normalizeWindowsPath(
|
|
982
|
-
return
|
|
1022
|
+
function normalizeWindowsPath(path73) {
|
|
1023
|
+
return path73.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
983
1024
|
}
|
|
984
1025
|
|
|
985
1026
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3459,9 +3500,9 @@ async function addSourceContext(frames) {
|
|
|
3459
3500
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3460
3501
|
return frames;
|
|
3461
3502
|
}
|
|
3462
|
-
function getContextLinesFromFile(
|
|
3503
|
+
function getContextLinesFromFile(path73, ranges, output) {
|
|
3463
3504
|
return new Promise((resolve7) => {
|
|
3464
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3505
|
+
const stream = (0, import_node_fs.createReadStream)(path73);
|
|
3465
3506
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3466
3507
|
input: stream
|
|
3467
3508
|
});
|
|
@@ -3476,7 +3517,7 @@ function getContextLinesFromFile(path72, ranges, output) {
|
|
|
3476
3517
|
let rangeStart = range[0];
|
|
3477
3518
|
let rangeEnd = range[1];
|
|
3478
3519
|
function onStreamError() {
|
|
3479
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3520
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path73, 1);
|
|
3480
3521
|
lineReaded.close();
|
|
3481
3522
|
lineReaded.removeAllListeners();
|
|
3482
3523
|
destroyStreamAndResolve();
|
|
@@ -3537,8 +3578,8 @@ function clearLineContext(frame) {
|
|
|
3537
3578
|
delete frame.context_line;
|
|
3538
3579
|
delete frame.post_context;
|
|
3539
3580
|
}
|
|
3540
|
-
function shouldSkipContextLinesForFile(
|
|
3541
|
-
return
|
|
3581
|
+
function shouldSkipContextLinesForFile(path73) {
|
|
3582
|
+
return path73.startsWith("node:") || path73.endsWith(".min.js") || path73.endsWith(".min.cjs") || path73.endsWith(".min.mjs") || path73.startsWith("data:");
|
|
3542
3583
|
}
|
|
3543
3584
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3544
3585
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5692,7 +5733,7 @@ function readAnonId() {
|
|
|
5692
5733
|
}
|
|
5693
5734
|
function superProperties() {
|
|
5694
5735
|
return {
|
|
5695
|
-
cliVersion: true ? "2.60.
|
|
5736
|
+
cliVersion: true ? "2.60.48" : "0.0.0-dev",
|
|
5696
5737
|
nodeVersion: process.version,
|
|
5697
5738
|
platform: process.platform,
|
|
5698
5739
|
arch: process.arch,
|
|
@@ -5873,7 +5914,7 @@ var os4 = __toESM(require("os"));
|
|
|
5873
5914
|
// package.json
|
|
5874
5915
|
var package_default = {
|
|
5875
5916
|
name: "codeam-cli",
|
|
5876
|
-
version: "2.60.
|
|
5917
|
+
version: "2.60.48",
|
|
5877
5918
|
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.",
|
|
5878
5919
|
type: "commonjs",
|
|
5879
5920
|
main: "dist/index.js",
|
|
@@ -6982,7 +7023,7 @@ var CommandRelayService = class {
|
|
|
6982
7023
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6983
7024
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6984
7025
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6985
|
-
..."2.60.
|
|
7026
|
+
..."2.60.48" ? { ideVersion: "2.60.48" } : {}
|
|
6986
7027
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6987
7028
|
}
|
|
6988
7029
|
/**
|
|
@@ -8356,9 +8397,9 @@ function closeAllTerminals() {
|
|
|
8356
8397
|
}
|
|
8357
8398
|
|
|
8358
8399
|
// src/commands/start/handlers.ts
|
|
8359
|
-
var
|
|
8360
|
-
var
|
|
8361
|
-
var
|
|
8400
|
+
var fs54 = __toESM(require("fs"));
|
|
8401
|
+
var os43 = __toESM(require("os"));
|
|
8402
|
+
var path58 = __toESM(require("path"));
|
|
8362
8403
|
var import_crypto3 = require("crypto");
|
|
8363
8404
|
var import_child_process23 = require("child_process");
|
|
8364
8405
|
|
|
@@ -11815,10 +11856,10 @@ function buildForPlatform(platform3) {
|
|
|
11815
11856
|
var import_node_crypto4 = require("crypto");
|
|
11816
11857
|
|
|
11817
11858
|
// src/agents/claude/resolver.ts
|
|
11818
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11819
|
-
const found =
|
|
11859
|
+
function buildClaudeLaunch(extraArgs = [], os51 = createOsStrategy()) {
|
|
11860
|
+
const found = os51.findInPath("claude") ?? os51.findInPath("claude-code");
|
|
11820
11861
|
if (!found) return null;
|
|
11821
|
-
return
|
|
11862
|
+
return os51.buildLaunch(found, extraArgs);
|
|
11822
11863
|
}
|
|
11823
11864
|
|
|
11824
11865
|
// src/agents/claude/installer.ts
|
|
@@ -12408,8 +12449,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
12408
12449
|
meta = getAgent("claude");
|
|
12409
12450
|
mode = "interactive";
|
|
12410
12451
|
os;
|
|
12411
|
-
constructor(
|
|
12412
|
-
this.os =
|
|
12452
|
+
constructor(os51) {
|
|
12453
|
+
this.os = os51;
|
|
12413
12454
|
}
|
|
12414
12455
|
/**
|
|
12415
12456
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -13189,8 +13230,8 @@ function codexCredentialLocator() {
|
|
|
13189
13230
|
function codexLoginLauncher() {
|
|
13190
13231
|
return {
|
|
13191
13232
|
async ensureInstalled() {
|
|
13192
|
-
const
|
|
13193
|
-
return
|
|
13233
|
+
const os51 = createOsStrategy();
|
|
13234
|
+
return os51.findInPath("codex") !== null;
|
|
13194
13235
|
},
|
|
13195
13236
|
launch() {
|
|
13196
13237
|
return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -13213,8 +13254,8 @@ var CodexRuntimeStrategy = class {
|
|
|
13213
13254
|
meta = getAgent("codex");
|
|
13214
13255
|
mode = "interactive";
|
|
13215
13256
|
os;
|
|
13216
|
-
constructor(
|
|
13217
|
-
this.os =
|
|
13257
|
+
constructor(os51) {
|
|
13258
|
+
this.os = os51;
|
|
13218
13259
|
}
|
|
13219
13260
|
async prepareLaunch() {
|
|
13220
13261
|
let binary = this.os.findInPath("codex");
|
|
@@ -13323,12 +13364,12 @@ var CodexRuntimeStrategy = class {
|
|
|
13323
13364
|
});
|
|
13324
13365
|
}
|
|
13325
13366
|
};
|
|
13326
|
-
function resolveNpm(
|
|
13327
|
-
return
|
|
13367
|
+
function resolveNpm(os51) {
|
|
13368
|
+
return os51.id === "win32" ? "npm.cmd" : "npm";
|
|
13328
13369
|
}
|
|
13329
|
-
async function installCodexViaNpm(
|
|
13370
|
+
async function installCodexViaNpm(os51) {
|
|
13330
13371
|
return new Promise((resolve7, reject) => {
|
|
13331
|
-
const proc = (0, import_node_child_process5.spawn)(resolveNpm(
|
|
13372
|
+
const proc = (0, import_node_child_process5.spawn)(resolveNpm(os51), ["install", "-g", "@openai/codex"], {
|
|
13332
13373
|
stdio: "inherit"
|
|
13333
13374
|
});
|
|
13334
13375
|
proc.on("close", (code) => {
|
|
@@ -13345,16 +13386,16 @@ async function installCodexViaNpm(os50) {
|
|
|
13345
13386
|
});
|
|
13346
13387
|
});
|
|
13347
13388
|
}
|
|
13348
|
-
function augmentNpmGlobalBin(
|
|
13389
|
+
function augmentNpmGlobalBin(os51) {
|
|
13349
13390
|
try {
|
|
13350
|
-
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(
|
|
13391
|
+
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os51), ["prefix", "-g"], {
|
|
13351
13392
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13352
13393
|
});
|
|
13353
13394
|
if (result.status !== 0) return;
|
|
13354
13395
|
const prefix = result.stdout.toString().trim();
|
|
13355
13396
|
if (!prefix) return;
|
|
13356
|
-
const binDir =
|
|
13357
|
-
|
|
13397
|
+
const binDir = os51.id === "win32" ? prefix : path24.join(prefix, "bin");
|
|
13398
|
+
os51.augmentPath([binDir]);
|
|
13358
13399
|
} catch {
|
|
13359
13400
|
}
|
|
13360
13401
|
}
|
|
@@ -13438,9 +13479,9 @@ var import_node_child_process8 = require("child_process");
|
|
|
13438
13479
|
// src/agents/coderabbit/installer.ts
|
|
13439
13480
|
var import_node_child_process6 = require("child_process");
|
|
13440
13481
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
13441
|
-
async function ensureCoderabbitInstalled(
|
|
13442
|
-
if (
|
|
13443
|
-
if (
|
|
13482
|
+
async function ensureCoderabbitInstalled(os51) {
|
|
13483
|
+
if (os51.findInPath("coderabbit")) return true;
|
|
13484
|
+
if (os51.id === "win32") {
|
|
13444
13485
|
console.error(
|
|
13445
13486
|
"\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
|
|
13446
13487
|
);
|
|
@@ -13455,8 +13496,8 @@ async function ensureCoderabbitInstalled(os50) {
|
|
|
13455
13496
|
proc.on("error", () => resolve7(false));
|
|
13456
13497
|
});
|
|
13457
13498
|
if (!ok) return false;
|
|
13458
|
-
|
|
13459
|
-
return
|
|
13499
|
+
os51.augmentPath([`${os51.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
13500
|
+
return os51.findInPath("coderabbit") !== null;
|
|
13460
13501
|
}
|
|
13461
13502
|
|
|
13462
13503
|
// src/agents/coderabbit/link.ts
|
|
@@ -13491,10 +13532,10 @@ function coderabbitCredentialLocator() {
|
|
|
13491
13532
|
validate: validateNonEmptyCredential
|
|
13492
13533
|
};
|
|
13493
13534
|
}
|
|
13494
|
-
function coderabbitLoginLauncher(
|
|
13535
|
+
function coderabbitLoginLauncher(os51) {
|
|
13495
13536
|
return {
|
|
13496
13537
|
async ensureInstalled() {
|
|
13497
|
-
return ensureCoderabbitInstalled(
|
|
13538
|
+
return ensureCoderabbitInstalled(os51);
|
|
13498
13539
|
},
|
|
13499
13540
|
launch() {
|
|
13500
13541
|
return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13550,8 +13591,8 @@ function pickLine(obj) {
|
|
|
13550
13591
|
function toHunk(raw, groupSeverity) {
|
|
13551
13592
|
if (!raw || typeof raw !== "object") return null;
|
|
13552
13593
|
const o = raw;
|
|
13553
|
-
const
|
|
13554
|
-
if (!
|
|
13594
|
+
const path73 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
13595
|
+
if (!path73) return null;
|
|
13555
13596
|
const message = asString(
|
|
13556
13597
|
pick(o, [
|
|
13557
13598
|
"comment",
|
|
@@ -13568,7 +13609,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
13568
13609
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
13569
13610
|
const locObj = pick(o, ["location"]) ?? o;
|
|
13570
13611
|
return {
|
|
13571
|
-
path:
|
|
13612
|
+
path: path73.trim(),
|
|
13572
13613
|
line: pickLine(o) ?? pickLine(locObj),
|
|
13573
13614
|
severity,
|
|
13574
13615
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -13651,10 +13692,10 @@ function parsePlain(stdout) {
|
|
|
13651
13692
|
for (const line of stdout.split(/\r?\n/)) {
|
|
13652
13693
|
const m = line.match(HUNK_LINE_RE);
|
|
13653
13694
|
if (!m) continue;
|
|
13654
|
-
const [,
|
|
13655
|
-
if (!
|
|
13695
|
+
const [, path73, lineNo, sevToken, message] = m;
|
|
13696
|
+
if (!path73 || !lineNo || !message) continue;
|
|
13656
13697
|
hunks.push({
|
|
13657
|
-
path:
|
|
13698
|
+
path: path73.trim(),
|
|
13658
13699
|
line: Number(lineNo),
|
|
13659
13700
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
13660
13701
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -13714,8 +13755,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13714
13755
|
meta = getAgent("coderabbit");
|
|
13715
13756
|
mode = "batch";
|
|
13716
13757
|
os;
|
|
13717
|
-
constructor(
|
|
13718
|
-
this.os =
|
|
13758
|
+
constructor(os51) {
|
|
13759
|
+
this.os = os51;
|
|
13719
13760
|
}
|
|
13720
13761
|
getDefaultArgs() {
|
|
13721
13762
|
return ["review", "--agent"];
|
|
@@ -13986,10 +14027,10 @@ function cursorCredentialLocator() {
|
|
|
13986
14027
|
validate: validateNonEmptyCredential
|
|
13987
14028
|
};
|
|
13988
14029
|
}
|
|
13989
|
-
function cursorLoginLauncher(
|
|
14030
|
+
function cursorLoginLauncher(os51) {
|
|
13990
14031
|
return {
|
|
13991
14032
|
async ensureInstalled() {
|
|
13992
|
-
if (
|
|
14033
|
+
if (os51.findInPath("cursor-agent")) return true;
|
|
13993
14034
|
console.error(
|
|
13994
14035
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
13995
14036
|
);
|
|
@@ -14053,8 +14094,8 @@ var CursorRuntimeStrategy = class {
|
|
|
14053
14094
|
meta = getAgent("cursor");
|
|
14054
14095
|
mode = "interactive";
|
|
14055
14096
|
os;
|
|
14056
|
-
constructor(
|
|
14057
|
-
this.os =
|
|
14097
|
+
constructor(os51) {
|
|
14098
|
+
this.os = os51;
|
|
14058
14099
|
}
|
|
14059
14100
|
async prepareLaunch() {
|
|
14060
14101
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -14270,10 +14311,10 @@ function aiderCredentialLocator() {
|
|
|
14270
14311
|
validate: validateNonEmptyCredential
|
|
14271
14312
|
};
|
|
14272
14313
|
}
|
|
14273
|
-
function aiderLoginLauncher(
|
|
14314
|
+
function aiderLoginLauncher(os51) {
|
|
14274
14315
|
return {
|
|
14275
14316
|
async ensureInstalled() {
|
|
14276
|
-
if (
|
|
14317
|
+
if (os51.findInPath("aider")) return true;
|
|
14277
14318
|
console.error(
|
|
14278
14319
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
14279
14320
|
);
|
|
@@ -14283,7 +14324,7 @@ function aiderLoginLauncher(os50) {
|
|
|
14283
14324
|
console.error(
|
|
14284
14325
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
14285
14326
|
);
|
|
14286
|
-
return (0, import_node_child_process11.spawn)(
|
|
14327
|
+
return (0, import_node_child_process11.spawn)(os51.id === "win32" ? "cmd.exe" : "sh", os51.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
14287
14328
|
stdio: "ignore"
|
|
14288
14329
|
});
|
|
14289
14330
|
}
|
|
@@ -14355,8 +14396,8 @@ var AiderRuntimeStrategy = class {
|
|
|
14355
14396
|
meta = getAgent("aider");
|
|
14356
14397
|
mode = "interactive";
|
|
14357
14398
|
os;
|
|
14358
|
-
constructor(
|
|
14359
|
-
this.os =
|
|
14399
|
+
constructor(os51) {
|
|
14400
|
+
this.os = os51;
|
|
14360
14401
|
}
|
|
14361
14402
|
async prepareLaunch() {
|
|
14362
14403
|
const binary = this.os.findInPath("aider");
|
|
@@ -14488,8 +14529,8 @@ function geminiCredentialLocator() {
|
|
|
14488
14529
|
function geminiLoginLauncher() {
|
|
14489
14530
|
return {
|
|
14490
14531
|
async ensureInstalled() {
|
|
14491
|
-
const
|
|
14492
|
-
return
|
|
14532
|
+
const os51 = createOsStrategy();
|
|
14533
|
+
return os51.findInPath("gemini") !== null;
|
|
14493
14534
|
},
|
|
14494
14535
|
launch() {
|
|
14495
14536
|
return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -14679,8 +14720,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
14679
14720
|
meta = getAgent("gemini");
|
|
14680
14721
|
mode = "interactive";
|
|
14681
14722
|
os;
|
|
14682
|
-
constructor(
|
|
14683
|
-
this.os =
|
|
14723
|
+
constructor(os51) {
|
|
14724
|
+
this.os = os51;
|
|
14684
14725
|
}
|
|
14685
14726
|
async prepareLaunch() {
|
|
14686
14727
|
const binary = this.os.findInPath("gemini");
|
|
@@ -14971,8 +15012,8 @@ var KimiRuntimeStrategy = class {
|
|
|
14971
15012
|
meta = getAgent("kimi");
|
|
14972
15013
|
mode = "interactive";
|
|
14973
15014
|
os;
|
|
14974
|
-
constructor(
|
|
14975
|
-
this.os =
|
|
15015
|
+
constructor(os51) {
|
|
15016
|
+
this.os = os51;
|
|
14976
15017
|
}
|
|
14977
15018
|
async prepareLaunch() {
|
|
14978
15019
|
const binary = this.os.findInPath("kimi");
|
|
@@ -15085,19 +15126,19 @@ var KimiRuntimeStrategy = class {
|
|
|
15085
15126
|
|
|
15086
15127
|
// src/agents/registry.ts
|
|
15087
15128
|
var runtimeBuilders = {
|
|
15088
|
-
claude: (
|
|
15089
|
-
codex: (
|
|
15090
|
-
coderabbit: (
|
|
15091
|
-
cursor: (
|
|
15092
|
-
aider: (
|
|
15093
|
-
gemini: (
|
|
15094
|
-
kimi: (
|
|
15129
|
+
claude: (os51) => new ClaudeRuntimeStrategy(os51),
|
|
15130
|
+
codex: (os51) => new CodexRuntimeStrategy(os51),
|
|
15131
|
+
coderabbit: (os51) => new CoderabbitRuntimeStrategy(os51),
|
|
15132
|
+
cursor: (os51) => new CursorRuntimeStrategy(os51),
|
|
15133
|
+
aider: (os51) => new AiderRuntimeStrategy(os51),
|
|
15134
|
+
gemini: (os51) => new GeminiRuntimeStrategy(os51),
|
|
15135
|
+
kimi: (os51) => new KimiRuntimeStrategy(os51)
|
|
15095
15136
|
};
|
|
15096
15137
|
var deployBuilders = {
|
|
15097
15138
|
claude: () => new ClaudeDeployStrategy(),
|
|
15098
15139
|
codex: () => new CodexDeployStrategy()
|
|
15099
15140
|
};
|
|
15100
|
-
function createAgentStrategy(agent,
|
|
15141
|
+
function createAgentStrategy(agent, os51 = createOsStrategy()) {
|
|
15101
15142
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
15102
15143
|
throw new Error(
|
|
15103
15144
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -15107,10 +15148,10 @@ function createAgentStrategy(agent, os50 = createOsStrategy()) {
|
|
|
15107
15148
|
if (!build) {
|
|
15108
15149
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
15109
15150
|
}
|
|
15110
|
-
return build(
|
|
15151
|
+
return build(os51);
|
|
15111
15152
|
}
|
|
15112
|
-
function createInteractiveAgentStrategy(agent,
|
|
15113
|
-
const s = createAgentStrategy(agent,
|
|
15153
|
+
function createInteractiveAgentStrategy(agent, os51 = createOsStrategy()) {
|
|
15154
|
+
const s = createAgentStrategy(agent, os51);
|
|
15114
15155
|
if (s.mode !== "interactive") {
|
|
15115
15156
|
throw new Error(
|
|
15116
15157
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -15802,26 +15843,26 @@ function restoreCoderabbitOauthBlob(value) {
|
|
|
15802
15843
|
(0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
|
|
15803
15844
|
}
|
|
15804
15845
|
async function configureCoderabbit(input, deps = {}) {
|
|
15805
|
-
const
|
|
15846
|
+
const os51 = deps.os ?? createOsStrategy();
|
|
15806
15847
|
const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
|
|
15807
15848
|
const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
|
|
15808
15849
|
const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
|
|
15809
15850
|
const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
|
|
15810
15851
|
const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
|
|
15811
15852
|
const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
|
|
15812
|
-
const home =
|
|
15813
|
-
|
|
15814
|
-
|
|
15853
|
+
const home = os51.homeDir();
|
|
15854
|
+
os51.augmentPath(
|
|
15855
|
+
os51.id === "win32" ? [
|
|
15815
15856
|
path36.join(home, ".local", "bin"),
|
|
15816
15857
|
path36.join(process.env.APPDATA ?? path36.join(home, "AppData", "Roaming"), "npm"),
|
|
15817
15858
|
path36.join(home, "scoop", "shims")
|
|
15818
15859
|
] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
15819
15860
|
);
|
|
15820
|
-
const installed2 =
|
|
15861
|
+
const installed2 = os51.findInPath("coderabbit") !== null;
|
|
15821
15862
|
const base = () => ({
|
|
15822
15863
|
action: input.action,
|
|
15823
15864
|
supported: true,
|
|
15824
|
-
installed:
|
|
15865
|
+
installed: os51.findInPath("coderabbit") !== null,
|
|
15825
15866
|
loggedIn: false
|
|
15826
15867
|
});
|
|
15827
15868
|
if (input.action === "status") {
|
|
@@ -15835,7 +15876,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15835
15876
|
const key = (input.apiKey ?? "").trim();
|
|
15836
15877
|
if (!key) return { ...res2, error: "No API key provided" };
|
|
15837
15878
|
if (!res2.installed) {
|
|
15838
|
-
const ok = await ensureInstalled(
|
|
15879
|
+
const ok = await ensureInstalled(os51);
|
|
15839
15880
|
res2.installed = ok;
|
|
15840
15881
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15841
15882
|
}
|
|
@@ -15859,7 +15900,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15859
15900
|
}
|
|
15860
15901
|
if (!res2.installed) {
|
|
15861
15902
|
deps.onEvent?.({ kind: "installing" });
|
|
15862
|
-
const ok = await ensureInstalled(
|
|
15903
|
+
const ok = await ensureInstalled(os51);
|
|
15863
15904
|
res2.installed = ok;
|
|
15864
15905
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15865
15906
|
}
|
|
@@ -15889,7 +15930,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15889
15930
|
const res2 = base();
|
|
15890
15931
|
if (!installed2) {
|
|
15891
15932
|
deps.onEvent?.({ kind: "installing" });
|
|
15892
|
-
const ok = await ensureInstalled(
|
|
15933
|
+
const ok = await ensureInstalled(os51);
|
|
15893
15934
|
res2.installed = ok;
|
|
15894
15935
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15895
15936
|
}
|
|
@@ -15926,7 +15967,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15926
15967
|
}
|
|
15927
15968
|
const res = base();
|
|
15928
15969
|
if (!res.installed) {
|
|
15929
|
-
const ok = await ensureInstalled(
|
|
15970
|
+
const ok = await ensureInstalled(os51);
|
|
15930
15971
|
res.installed = ok;
|
|
15931
15972
|
if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
|
|
15932
15973
|
}
|
|
@@ -15955,14 +15996,14 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15955
15996
|
|
|
15956
15997
|
// src/commands/host-agent.ts
|
|
15957
15998
|
var import_node_child_process23 = require("child_process");
|
|
15958
|
-
var
|
|
15959
|
-
var
|
|
15960
|
-
var
|
|
15999
|
+
var os36 = __toESM(require("os"));
|
|
16000
|
+
var fs42 = __toESM(require("fs"));
|
|
16001
|
+
var path45 = __toESM(require("path"));
|
|
15961
16002
|
|
|
15962
|
-
// src/
|
|
15963
|
-
var
|
|
15964
|
-
var
|
|
15965
|
-
var
|
|
16003
|
+
// src/integrations/manifest.ts
|
|
16004
|
+
var import_node_fs7 = __toESM(require("fs"));
|
|
16005
|
+
var import_node_os6 = __toESM(require("os"));
|
|
16006
|
+
var import_node_path5 = __toESM(require("path"));
|
|
15966
16007
|
|
|
15967
16008
|
// src/lib/restrict-to-owner.ts
|
|
15968
16009
|
var import_node_fs6 = __toESM(require("fs"));
|
|
@@ -15997,11 +16038,49 @@ function restrictToOwner(filePath) {
|
|
|
15997
16038
|
}
|
|
15998
16039
|
}
|
|
15999
16040
|
|
|
16041
|
+
// src/integrations/manifest.ts
|
|
16042
|
+
function integrationsManifestPath() {
|
|
16043
|
+
return import_node_path5.default.join(import_node_os6.default.homedir(), ".codeam", "integrations.json");
|
|
16044
|
+
}
|
|
16045
|
+
function readIntegrationsManifest() {
|
|
16046
|
+
try {
|
|
16047
|
+
const raw = JSON.parse(import_node_fs7.default.readFileSync(integrationsManifestPath(), "utf8"));
|
|
16048
|
+
if (!Array.isArray(raw?.integrations)) return null;
|
|
16049
|
+
return raw;
|
|
16050
|
+
} catch {
|
|
16051
|
+
return null;
|
|
16052
|
+
}
|
|
16053
|
+
}
|
|
16054
|
+
function persistIntegrationsManifest(m) {
|
|
16055
|
+
try {
|
|
16056
|
+
const file = integrationsManifestPath();
|
|
16057
|
+
import_node_fs7.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true, mode: 448 });
|
|
16058
|
+
const tmp = `${file}.tmp-${process.pid}`;
|
|
16059
|
+
import_node_fs7.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
|
|
16060
|
+
import_node_fs7.default.renameSync(tmp, file);
|
|
16061
|
+
restrictToOwner(file);
|
|
16062
|
+
} catch (err) {
|
|
16063
|
+
log.warn(
|
|
16064
|
+
"integrations",
|
|
16065
|
+
`failed to persist integrations manifest (best-effort): ${err instanceof Error ? err.message : String(err)}`
|
|
16066
|
+
);
|
|
16067
|
+
}
|
|
16068
|
+
}
|
|
16069
|
+
function clearIntegrationsManifest() {
|
|
16070
|
+
try {
|
|
16071
|
+
import_node_fs7.default.rmSync(integrationsManifestPath(), { force: true });
|
|
16072
|
+
} catch {
|
|
16073
|
+
}
|
|
16074
|
+
}
|
|
16075
|
+
|
|
16000
16076
|
// src/commands/host/host-client.ts
|
|
16077
|
+
var fs34 = __toESM(require("fs"));
|
|
16078
|
+
var os30 = __toESM(require("os"));
|
|
16079
|
+
var path38 = __toESM(require("path"));
|
|
16001
16080
|
function sampleCpuTimes() {
|
|
16002
16081
|
let idle = 0;
|
|
16003
16082
|
let total = 0;
|
|
16004
|
-
for (const cpu of
|
|
16083
|
+
for (const cpu of os30.cpus()) {
|
|
16005
16084
|
const t2 = cpu.times;
|
|
16006
16085
|
idle += t2.idle;
|
|
16007
16086
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -16020,8 +16099,8 @@ var MetricsCollector = class {
|
|
|
16020
16099
|
const prev = this.prevCpu;
|
|
16021
16100
|
this.prevCpu = current;
|
|
16022
16101
|
if (!prev) {
|
|
16023
|
-
const cores =
|
|
16024
|
-
const proxy =
|
|
16102
|
+
const cores = os30.cpus().length || 1;
|
|
16103
|
+
const proxy = os30.loadavg()[0] / cores * 100;
|
|
16025
16104
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
16026
16105
|
}
|
|
16027
16106
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -16034,8 +16113,8 @@ var MetricsCollector = class {
|
|
|
16034
16113
|
collect() {
|
|
16035
16114
|
return {
|
|
16036
16115
|
cpuPct: this.cpuPct(),
|
|
16037
|
-
ramUsedMb: Math.round((
|
|
16038
|
-
ramTotalMb: Math.round(
|
|
16116
|
+
ramUsedMb: Math.round((os30.totalmem() - os30.freemem()) / 1048576),
|
|
16117
|
+
ramTotalMb: Math.round(os30.totalmem() / 1048576),
|
|
16039
16118
|
latencyMs: this.lastLatencyMs
|
|
16040
16119
|
};
|
|
16041
16120
|
}
|
|
@@ -16044,19 +16123,19 @@ function apiBase() {
|
|
|
16044
16123
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
16045
16124
|
}
|
|
16046
16125
|
function hostIdentityPath() {
|
|
16047
|
-
return
|
|
16126
|
+
return path38.join(os30.homedir(), ".codeam", "host-agent.json");
|
|
16048
16127
|
}
|
|
16049
16128
|
function collectOsInfo() {
|
|
16050
16129
|
return {
|
|
16051
|
-
distro:
|
|
16052
|
-
arch:
|
|
16053
|
-
kernel:
|
|
16130
|
+
distro: os30.platform(),
|
|
16131
|
+
arch: os30.arch(),
|
|
16132
|
+
kernel: os30.release(),
|
|
16054
16133
|
nodeVersion: process.versions.node
|
|
16055
16134
|
};
|
|
16056
16135
|
}
|
|
16057
16136
|
function loadHostIdentity() {
|
|
16058
16137
|
try {
|
|
16059
|
-
const raw =
|
|
16138
|
+
const raw = fs34.readFileSync(hostIdentityPath(), "utf8");
|
|
16060
16139
|
const parsed = JSON.parse(raw);
|
|
16061
16140
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
16062
16141
|
const p2 = parsed;
|
|
@@ -16069,8 +16148,8 @@ function loadHostIdentity() {
|
|
|
16069
16148
|
}
|
|
16070
16149
|
function saveHostIdentity(identity) {
|
|
16071
16150
|
const file = hostIdentityPath();
|
|
16072
|
-
|
|
16073
|
-
|
|
16151
|
+
fs34.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
|
|
16152
|
+
fs34.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
16074
16153
|
encoding: "utf8",
|
|
16075
16154
|
mode: 384
|
|
16076
16155
|
});
|
|
@@ -16115,7 +16194,7 @@ function isTerminalEnrollError(err) {
|
|
|
16115
16194
|
}
|
|
16116
16195
|
function deleteHostIdentity() {
|
|
16117
16196
|
try {
|
|
16118
|
-
|
|
16197
|
+
fs34.rmSync(hostIdentityPath(), { force: true });
|
|
16119
16198
|
} catch {
|
|
16120
16199
|
}
|
|
16121
16200
|
}
|
|
@@ -16238,17 +16317,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
16238
16317
|
}
|
|
16239
16318
|
|
|
16240
16319
|
// src/commands/host/workspace.ts
|
|
16241
|
-
var
|
|
16242
|
-
var
|
|
16243
|
-
var
|
|
16320
|
+
var fs35 = __toESM(require("fs"));
|
|
16321
|
+
var os31 = __toESM(require("os"));
|
|
16322
|
+
var path39 = __toESM(require("path"));
|
|
16244
16323
|
var import_node_child_process17 = require("child_process");
|
|
16245
16324
|
var import_node_util4 = require("util");
|
|
16246
16325
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process17.execFile);
|
|
16247
16326
|
function isAbsolutePathTarget(target) {
|
|
16248
|
-
return
|
|
16327
|
+
return path39.isAbsolute(target);
|
|
16249
16328
|
}
|
|
16250
16329
|
function selfHostedWorkspaceRoot() {
|
|
16251
|
-
return
|
|
16330
|
+
return path39.join(os31.homedir(), ".codeam", "self-hosted");
|
|
16252
16331
|
}
|
|
16253
16332
|
function nonInteractiveGitEnv() {
|
|
16254
16333
|
return {
|
|
@@ -16301,13 +16380,13 @@ async function fetchGithubIdentity(token) {
|
|
|
16301
16380
|
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
16302
16381
|
const gh = githubOwnerRepo(repoRef.trim());
|
|
16303
16382
|
if (!gh || !cloneToken) return;
|
|
16304
|
-
const credFile =
|
|
16305
|
-
|
|
16383
|
+
const credFile = path39.join(dest, ".git", "codeam-credentials");
|
|
16384
|
+
fs35.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
16306
16385
|
`, { mode: 384 });
|
|
16307
16386
|
restrictToOwner(credFile);
|
|
16308
16387
|
const env = nonInteractiveGitEnv();
|
|
16309
16388
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
16310
|
-
const credFilePosix = credFile.split(
|
|
16389
|
+
const credFilePosix = credFile.split(path39.sep).join("/");
|
|
16311
16390
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
16312
16391
|
});
|
|
16313
16392
|
await git2([
|
|
@@ -16343,17 +16422,17 @@ function maskToken(text, cloneToken) {
|
|
|
16343
16422
|
}
|
|
16344
16423
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
16345
16424
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
16346
|
-
if (!
|
|
16425
|
+
if (!fs35.existsSync(repoOrPath)) {
|
|
16347
16426
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
16348
16427
|
}
|
|
16349
16428
|
return repoOrPath;
|
|
16350
16429
|
}
|
|
16351
|
-
const dest =
|
|
16352
|
-
if (
|
|
16430
|
+
const dest = path39.join(selfHostedWorkspaceRoot(), deployId);
|
|
16431
|
+
if (fs35.existsSync(path39.join(dest, ".git"))) {
|
|
16353
16432
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
16354
16433
|
return dest;
|
|
16355
16434
|
}
|
|
16356
|
-
|
|
16435
|
+
fs35.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
16357
16436
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
16358
16437
|
try {
|
|
16359
16438
|
await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -16370,9 +16449,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
16370
16449
|
}
|
|
16371
16450
|
|
|
16372
16451
|
// src/commands/host/agent-provisioning.ts
|
|
16373
|
-
var
|
|
16374
|
-
var
|
|
16375
|
-
var
|
|
16452
|
+
var fs36 = __toESM(require("fs"));
|
|
16453
|
+
var os32 = __toESM(require("os"));
|
|
16454
|
+
var path40 = __toESM(require("path"));
|
|
16376
16455
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
16377
16456
|
claude_code: "claude",
|
|
16378
16457
|
claude: "claude",
|
|
@@ -16388,22 +16467,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
16388
16467
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
16389
16468
|
}
|
|
16390
16469
|
function ensureDir(dir) {
|
|
16391
|
-
|
|
16470
|
+
fs36.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
16392
16471
|
}
|
|
16393
16472
|
function writeFile0600(filePath, contents) {
|
|
16394
|
-
ensureDir(
|
|
16395
|
-
|
|
16473
|
+
ensureDir(path40.dirname(filePath));
|
|
16474
|
+
fs36.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
16396
16475
|
restrictToOwner(filePath);
|
|
16397
16476
|
}
|
|
16398
16477
|
function rmIfExists(filePath) {
|
|
16399
16478
|
try {
|
|
16400
|
-
|
|
16479
|
+
fs36.rmSync(filePath, { force: true });
|
|
16401
16480
|
} catch {
|
|
16402
16481
|
}
|
|
16403
16482
|
}
|
|
16404
16483
|
var claudeProvisioner = {
|
|
16405
16484
|
write(auth, home) {
|
|
16406
|
-
const credentialsJson =
|
|
16485
|
+
const credentialsJson = path40.join(home, ".claude", ".credentials.json");
|
|
16407
16486
|
if (auth.kind === "api_key") {
|
|
16408
16487
|
rmIfExists(credentialsJson);
|
|
16409
16488
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -16415,8 +16494,8 @@ var claudeProvisioner = {
|
|
|
16415
16494
|
} else {
|
|
16416
16495
|
rmIfExists(credentialsJson);
|
|
16417
16496
|
}
|
|
16418
|
-
const claudeJson =
|
|
16419
|
-
if (!
|
|
16497
|
+
const claudeJson = path40.join(home, ".claude.json");
|
|
16498
|
+
if (!fs36.existsSync(claudeJson)) {
|
|
16420
16499
|
writeFile0600(
|
|
16421
16500
|
claudeJson,
|
|
16422
16501
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -16427,7 +16506,7 @@ var claudeProvisioner = {
|
|
|
16427
16506
|
};
|
|
16428
16507
|
var codexProvisioner = {
|
|
16429
16508
|
write(auth, home) {
|
|
16430
|
-
const authJson =
|
|
16509
|
+
const authJson = path40.join(home, ".codex", "auth.json");
|
|
16431
16510
|
if (auth.kind === "api_key") {
|
|
16432
16511
|
rmIfExists(authJson);
|
|
16433
16512
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -16438,8 +16517,8 @@ var codexProvisioner = {
|
|
|
16438
16517
|
};
|
|
16439
16518
|
var geminiProvisioner = {
|
|
16440
16519
|
write(auth, home) {
|
|
16441
|
-
const settingsJson =
|
|
16442
|
-
const oauthCreds =
|
|
16520
|
+
const settingsJson = path40.join(home, ".gemini", "settings.json");
|
|
16521
|
+
const oauthCreds = path40.join(home, ".gemini", "oauth_creds.json");
|
|
16443
16522
|
if (auth.kind === "api_key") {
|
|
16444
16523
|
rmIfExists(oauthCreds);
|
|
16445
16524
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -16452,7 +16531,7 @@ var geminiProvisioner = {
|
|
|
16452
16531
|
};
|
|
16453
16532
|
var cursorProvisioner = {
|
|
16454
16533
|
write(auth, home) {
|
|
16455
|
-
const authJson =
|
|
16534
|
+
const authJson = path40.join(home, ".config", "cursor", "auth.json");
|
|
16456
16535
|
if (auth.kind === "api_key") {
|
|
16457
16536
|
rmIfExists(authJson);
|
|
16458
16537
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -16478,8 +16557,8 @@ var cursorProvisioner = {
|
|
|
16478
16557
|
var kimiProvisioner = {
|
|
16479
16558
|
write(auth, home) {
|
|
16480
16559
|
const credentialsFiles = [
|
|
16481
|
-
|
|
16482
|
-
|
|
16560
|
+
path40.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
16561
|
+
path40.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
16483
16562
|
];
|
|
16484
16563
|
if (auth.kind === "api_key") {
|
|
16485
16564
|
credentialsFiles.forEach(rmIfExists);
|
|
@@ -16491,8 +16570,8 @@ var kimiProvisioner = {
|
|
|
16491
16570
|
};
|
|
16492
16571
|
var coderabbitProvisioner = {
|
|
16493
16572
|
write(auth, home) {
|
|
16494
|
-
const dir =
|
|
16495
|
-
const authJson =
|
|
16573
|
+
const dir = path40.join(home, ".coderabbit");
|
|
16574
|
+
const authJson = path40.join(dir, "auth.json");
|
|
16496
16575
|
if (auth.kind === "api_key") {
|
|
16497
16576
|
rmIfExists(authJson);
|
|
16498
16577
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -16504,13 +16583,13 @@ var coderabbitProvisioner = {
|
|
|
16504
16583
|
try {
|
|
16505
16584
|
const parsed = JSON.parse(value);
|
|
16506
16585
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
16507
|
-
file =
|
|
16586
|
+
file = path40.basename(parsed.file);
|
|
16508
16587
|
contents = parsed.contents;
|
|
16509
16588
|
}
|
|
16510
16589
|
} catch {
|
|
16511
16590
|
}
|
|
16512
16591
|
}
|
|
16513
|
-
writeFile0600(
|
|
16592
|
+
writeFile0600(path40.join(dir, file), contents);
|
|
16514
16593
|
return {};
|
|
16515
16594
|
}
|
|
16516
16595
|
};
|
|
@@ -16530,7 +16609,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
16530
16609
|
this.agentId = agentId;
|
|
16531
16610
|
}
|
|
16532
16611
|
};
|
|
16533
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
16612
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir()) {
|
|
16534
16613
|
const internal = toInternalAgentId(publicAgentId);
|
|
16535
16614
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
16536
16615
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -16540,11 +16619,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os31.homedir(
|
|
|
16540
16619
|
|
|
16541
16620
|
// src/commands/host/git-tooling.ts
|
|
16542
16621
|
var import_node_child_process18 = require("child_process");
|
|
16543
|
-
var
|
|
16544
|
-
var
|
|
16545
|
-
var
|
|
16622
|
+
var fs37 = __toESM(require("fs"));
|
|
16623
|
+
var os33 = __toESM(require("os"));
|
|
16624
|
+
var path41 = __toESM(require("path"));
|
|
16546
16625
|
function codeamBinDir() {
|
|
16547
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
16626
|
+
return process.env.CODEAM_BIN_DIR ?? path41.join(os33.homedir(), ".codeam", "bin");
|
|
16548
16627
|
}
|
|
16549
16628
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
16550
16629
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -16576,7 +16655,7 @@ async function download(url, dest) {
|
|
|
16576
16655
|
const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
|
|
16577
16656
|
if (!res.ok || !res.body) return false;
|
|
16578
16657
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
16579
|
-
|
|
16658
|
+
fs37.writeFileSync(dest, buf);
|
|
16580
16659
|
return true;
|
|
16581
16660
|
} catch {
|
|
16582
16661
|
return false;
|
|
@@ -16599,8 +16678,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
16599
16678
|
const version3 = await resolveVersionFn(token);
|
|
16600
16679
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
16601
16680
|
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
16602
|
-
const tmpRoot =
|
|
16603
|
-
const archive =
|
|
16681
|
+
const tmpRoot = fs37.mkdtempSync(path41.join(os33.tmpdir(), "codeam-gh-"));
|
|
16682
|
+
const archive = path41.join(tmpRoot, `${asset}.${ext}`);
|
|
16604
16683
|
if (!await downloadFn(url, archive)) {
|
|
16605
16684
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
16606
16685
|
return null;
|
|
@@ -16610,16 +16689,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
16610
16689
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
16611
16690
|
return null;
|
|
16612
16691
|
}
|
|
16613
|
-
const extractedBin =
|
|
16614
|
-
if (!
|
|
16692
|
+
const extractedBin = path41.join(tmpRoot, asset, "bin", binaryName);
|
|
16693
|
+
if (!fs37.existsSync(extractedBin)) {
|
|
16615
16694
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
16616
16695
|
return null;
|
|
16617
16696
|
}
|
|
16618
16697
|
const binDir = codeamBinDir();
|
|
16619
|
-
|
|
16620
|
-
const target =
|
|
16621
|
-
|
|
16622
|
-
|
|
16698
|
+
fs37.mkdirSync(binDir, { recursive: true });
|
|
16699
|
+
const target = path41.join(binDir, binaryName);
|
|
16700
|
+
fs37.copyFileSync(extractedBin, target);
|
|
16701
|
+
fs37.chmodSync(target, 493);
|
|
16623
16702
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
16624
16703
|
return target;
|
|
16625
16704
|
} catch (e) {
|
|
@@ -17106,23 +17185,23 @@ async function ensureModernPython(runner) {
|
|
|
17106
17185
|
}
|
|
17107
17186
|
|
|
17108
17187
|
// src/commands/host/headroom-bootstrap.ts
|
|
17109
|
-
var
|
|
17110
|
-
var
|
|
17188
|
+
var fs39 = __toESM(require("fs"));
|
|
17189
|
+
var path43 = __toESM(require("path"));
|
|
17111
17190
|
|
|
17112
17191
|
// src/commands/host/headroom-config.ts
|
|
17113
|
-
var
|
|
17114
|
-
var
|
|
17115
|
-
var
|
|
17192
|
+
var fs38 = __toESM(require("fs"));
|
|
17193
|
+
var os34 = __toESM(require("os"));
|
|
17194
|
+
var path42 = __toESM(require("path"));
|
|
17116
17195
|
function headroomConfigPath() {
|
|
17117
|
-
return
|
|
17196
|
+
return path42.join(os34.homedir(), ".codeam", "headroom-config.json");
|
|
17118
17197
|
}
|
|
17119
17198
|
function persistHeadroomConfig(config) {
|
|
17120
17199
|
try {
|
|
17121
17200
|
const file = headroomConfigPath();
|
|
17122
|
-
|
|
17201
|
+
fs38.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
|
|
17123
17202
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
17124
|
-
|
|
17125
|
-
|
|
17203
|
+
fs38.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
17204
|
+
fs38.renameSync(tmp, file);
|
|
17126
17205
|
restrictToOwner(file);
|
|
17127
17206
|
} catch (err) {
|
|
17128
17207
|
log.warn(
|
|
@@ -17132,21 +17211,21 @@ function persistHeadroomConfig(config) {
|
|
|
17132
17211
|
}
|
|
17133
17212
|
}
|
|
17134
17213
|
function agentSettingsPath(kind) {
|
|
17135
|
-
const home =
|
|
17136
|
-
if (kind === "claude") return
|
|
17137
|
-
if (kind === "codex") return
|
|
17138
|
-
if (kind === "copilot") return
|
|
17214
|
+
const home = os34.homedir();
|
|
17215
|
+
if (kind === "claude") return path42.join(home, ".claude", "settings.json");
|
|
17216
|
+
if (kind === "codex") return path42.join(home, ".codex", "auth.json");
|
|
17217
|
+
if (kind === "copilot") return path42.join(home, ".config", "github-copilot", "hosts.json");
|
|
17139
17218
|
return null;
|
|
17140
17219
|
}
|
|
17141
17220
|
function backupAgentHeadroomConfig(kind) {
|
|
17142
17221
|
const src = agentSettingsPath(kind);
|
|
17143
17222
|
if (!src) return;
|
|
17144
17223
|
try {
|
|
17145
|
-
if (!
|
|
17146
|
-
const dest =
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17224
|
+
if (!fs38.existsSync(src)) return;
|
|
17225
|
+
const dest = path42.join(os34.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
17226
|
+
fs38.mkdirSync(path42.dirname(dest), { recursive: true, mode: 448 });
|
|
17227
|
+
fs38.copyFileSync(src, dest);
|
|
17228
|
+
fs38.chmodSync(dest, 384);
|
|
17150
17229
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
17151
17230
|
} catch (err) {
|
|
17152
17231
|
log.warn(
|
|
@@ -17158,12 +17237,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
17158
17237
|
function restoreAgentHeadroomConfig(kind) {
|
|
17159
17238
|
const dest = agentSettingsPath(kind);
|
|
17160
17239
|
if (!dest) return false;
|
|
17161
|
-
const src =
|
|
17162
|
-
if (!
|
|
17240
|
+
const src = path42.join(os34.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
17241
|
+
if (!fs38.existsSync(src)) return false;
|
|
17163
17242
|
try {
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17243
|
+
fs38.mkdirSync(path42.dirname(dest), { recursive: true, mode: 448 });
|
|
17244
|
+
fs38.copyFileSync(src, dest);
|
|
17245
|
+
fs38.chmodSync(dest, 384);
|
|
17167
17246
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
17168
17247
|
return true;
|
|
17169
17248
|
} catch (err) {
|
|
@@ -17176,7 +17255,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
17176
17255
|
}
|
|
17177
17256
|
function readHeadroomChildEnv() {
|
|
17178
17257
|
try {
|
|
17179
|
-
const raw =
|
|
17258
|
+
const raw = fs38.readFileSync(headroomConfigPath(), "utf8");
|
|
17180
17259
|
const parsed = JSON.parse(raw);
|
|
17181
17260
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
17182
17261
|
const o = parsed;
|
|
@@ -17212,37 +17291,37 @@ function bundledClaudeBinDir() {
|
|
|
17212
17291
|
const roots = /* @__PURE__ */ new Set();
|
|
17213
17292
|
let dir = __dirname;
|
|
17214
17293
|
for (let i = 0; i < 6; i++) {
|
|
17215
|
-
roots.add(
|
|
17216
|
-
const parent =
|
|
17294
|
+
roots.add(path43.join(dir, "node_modules"));
|
|
17295
|
+
const parent = path43.dirname(dir);
|
|
17217
17296
|
if (parent === dir) break;
|
|
17218
17297
|
dir = parent;
|
|
17219
17298
|
}
|
|
17220
17299
|
try {
|
|
17221
17300
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
17222
|
-
const marker = `${
|
|
17301
|
+
const marker = `${path43.sep}@anthropic-ai${path43.sep}`;
|
|
17223
17302
|
const idx = main2.lastIndexOf(marker);
|
|
17224
17303
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
17225
17304
|
} catch {
|
|
17226
17305
|
}
|
|
17227
17306
|
for (const nm of roots) {
|
|
17228
|
-
const atAnthropic =
|
|
17307
|
+
const atAnthropic = path43.join(nm, "@anthropic-ai");
|
|
17229
17308
|
let entries;
|
|
17230
17309
|
try {
|
|
17231
|
-
entries =
|
|
17310
|
+
entries = fs39.readdirSync(atAnthropic);
|
|
17232
17311
|
} catch {
|
|
17233
17312
|
continue;
|
|
17234
17313
|
}
|
|
17235
17314
|
for (const entry of entries) {
|
|
17236
17315
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
17237
|
-
const bin =
|
|
17238
|
-
if (
|
|
17316
|
+
const bin = path43.join(atAnthropic, entry, "claude");
|
|
17317
|
+
if (fs39.existsSync(bin)) return path43.dirname(bin);
|
|
17239
17318
|
}
|
|
17240
17319
|
}
|
|
17241
17320
|
return null;
|
|
17242
17321
|
}
|
|
17243
17322
|
async function getFreeDiskBytes(dir) {
|
|
17244
17323
|
try {
|
|
17245
|
-
const s = await
|
|
17324
|
+
const s = await fs39.promises.statfs(dir);
|
|
17246
17325
|
return s.bsize * s.bavail;
|
|
17247
17326
|
} catch {
|
|
17248
17327
|
return null;
|
|
@@ -17304,7 +17383,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17304
17383
|
if (initKind === "claude") {
|
|
17305
17384
|
const claudeDir = bundledClaudeBinDir();
|
|
17306
17385
|
if (claudeDir) {
|
|
17307
|
-
initEnv.PATH = `${claudeDir}${
|
|
17386
|
+
initEnv.PATH = `${claudeDir}${path43.delimiter}${process.env["PATH"] ?? ""}`;
|
|
17308
17387
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
17309
17388
|
} else {
|
|
17310
17389
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -17339,9 +17418,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17339
17418
|
var import_node_child_process21 = require("child_process");
|
|
17340
17419
|
|
|
17341
17420
|
// src/lib/updateNotifier.ts
|
|
17342
|
-
var
|
|
17343
|
-
var
|
|
17344
|
-
var
|
|
17421
|
+
var fs40 = __toESM(require("fs"));
|
|
17422
|
+
var os35 = __toESM(require("os"));
|
|
17423
|
+
var path44 = __toESM(require("path"));
|
|
17345
17424
|
var https6 = __toESM(require("https"));
|
|
17346
17425
|
var import_node_child_process20 = require("child_process");
|
|
17347
17426
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -17350,12 +17429,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
17350
17429
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
17351
17430
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
17352
17431
|
function cachePath() {
|
|
17353
|
-
const dir =
|
|
17354
|
-
return
|
|
17432
|
+
const dir = path44.join(os35.homedir(), ".codeam");
|
|
17433
|
+
return path44.join(dir, "update-check.json");
|
|
17355
17434
|
}
|
|
17356
17435
|
function readCache() {
|
|
17357
17436
|
try {
|
|
17358
|
-
const raw =
|
|
17437
|
+
const raw = fs40.readFileSync(cachePath(), "utf8");
|
|
17359
17438
|
const parsed = JSON.parse(raw);
|
|
17360
17439
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
17361
17440
|
return parsed;
|
|
@@ -17366,10 +17445,10 @@ function readCache() {
|
|
|
17366
17445
|
function writeCache(cache) {
|
|
17367
17446
|
try {
|
|
17368
17447
|
const file = cachePath();
|
|
17369
|
-
|
|
17448
|
+
fs40.mkdirSync(path44.dirname(file), { recursive: true });
|
|
17370
17449
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
17371
|
-
|
|
17372
|
-
|
|
17450
|
+
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
17451
|
+
fs40.renameSync(tmp, file);
|
|
17373
17452
|
} catch {
|
|
17374
17453
|
}
|
|
17375
17454
|
}
|
|
@@ -17443,8 +17522,8 @@ function isLinkedInstall() {
|
|
|
17443
17522
|
timeout: 2e3
|
|
17444
17523
|
}).trim();
|
|
17445
17524
|
if (!root) return false;
|
|
17446
|
-
const pkgPath =
|
|
17447
|
-
return
|
|
17525
|
+
const pkgPath = path44.join(root, PKG_NAME);
|
|
17526
|
+
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
17448
17527
|
} catch {
|
|
17449
17528
|
return false;
|
|
17450
17529
|
}
|
|
@@ -17480,7 +17559,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
17480
17559
|
return;
|
|
17481
17560
|
}
|
|
17482
17561
|
try {
|
|
17483
|
-
|
|
17562
|
+
fs40.unlinkSync(cachePath());
|
|
17484
17563
|
} catch {
|
|
17485
17564
|
}
|
|
17486
17565
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -17496,7 +17575,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17496
17575
|
if (process.env.NODE_ENV === "test") return;
|
|
17497
17576
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17498
17577
|
if (process.env.CI) return;
|
|
17499
|
-
const current = true ? "2.60.
|
|
17578
|
+
const current = true ? "2.60.48" : null;
|
|
17500
17579
|
if (!current) return;
|
|
17501
17580
|
const cache = readCache();
|
|
17502
17581
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17513,7 +17592,7 @@ function checkForUpdates() {
|
|
|
17513
17592
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17514
17593
|
if (process.env.CI) return;
|
|
17515
17594
|
if (!process.stdout.isTTY) return;
|
|
17516
|
-
const current = true ? "2.60.
|
|
17595
|
+
const current = true ? "2.60.48" : null;
|
|
17517
17596
|
if (!current) return;
|
|
17518
17597
|
const cache = readCache();
|
|
17519
17598
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17533,7 +17612,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17533
17612
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17534
17613
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17535
17614
|
function currentCliVersion() {
|
|
17536
|
-
return true ? "2.60.
|
|
17615
|
+
return true ? "2.60.48" : null;
|
|
17537
17616
|
}
|
|
17538
17617
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17539
17618
|
return new Promise((resolve7) => {
|
|
@@ -17600,7 +17679,7 @@ async function runSelfUpdate() {
|
|
|
17600
17679
|
|
|
17601
17680
|
// src/commands/host/teardown.ts
|
|
17602
17681
|
var import_node_child_process22 = require("child_process");
|
|
17603
|
-
var
|
|
17682
|
+
var fs41 = __toESM(require("fs"));
|
|
17604
17683
|
var defaultDisableService = () => {
|
|
17605
17684
|
try {
|
|
17606
17685
|
(0, import_node_child_process22.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
@@ -17609,7 +17688,7 @@ var defaultDisableService = () => {
|
|
|
17609
17688
|
};
|
|
17610
17689
|
var defaultTeardownHeadroom = () => {
|
|
17611
17690
|
try {
|
|
17612
|
-
const kind = JSON.parse(
|
|
17691
|
+
const kind = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
17613
17692
|
if (kind) {
|
|
17614
17693
|
(0, import_node_child_process22.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
17615
17694
|
}
|
|
@@ -17677,8 +17756,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
17677
17756
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
17678
17757
|
try {
|
|
17679
17758
|
const file = headroomConfigPath();
|
|
17680
|
-
if (!
|
|
17681
|
-
const cfg = JSON.parse(
|
|
17759
|
+
if (!fs42.existsSync(file)) return null;
|
|
17760
|
+
const cfg = JSON.parse(fs42.readFileSync(file, "utf8"));
|
|
17682
17761
|
if (!cfg?.enabled) return null;
|
|
17683
17762
|
const agent = cfg.agent ?? "claude";
|
|
17684
17763
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -17751,6 +17830,9 @@ function isDeployPayload(p2) {
|
|
|
17751
17830
|
if (p2.headroomSavingsIngestUrl !== void 0 && typeof p2.headroomSavingsIngestUrl !== "string") {
|
|
17752
17831
|
return false;
|
|
17753
17832
|
}
|
|
17833
|
+
if (p2.integrations !== void 0 && !Array.isArray(p2.integrations)) {
|
|
17834
|
+
return false;
|
|
17835
|
+
}
|
|
17754
17836
|
const hasHouse = isHouseProxy(p2.houseProxy);
|
|
17755
17837
|
const hasSealed = typeof p2.sealedAgentAuth === "string";
|
|
17756
17838
|
return hasHouse || hasSealed;
|
|
@@ -18083,9 +18165,9 @@ var HostAgentSupervisor = class {
|
|
|
18083
18165
|
API_TIMEOUT_MS: "3000000",
|
|
18084
18166
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
18085
18167
|
};
|
|
18086
|
-
const houseConfigDir =
|
|
18168
|
+
const houseConfigDir = path45.join(os36.homedir(), ".codeam", "house-claude");
|
|
18087
18169
|
try {
|
|
18088
|
-
|
|
18170
|
+
fs42.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
18089
18171
|
} catch {
|
|
18090
18172
|
}
|
|
18091
18173
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -18103,14 +18185,14 @@ var HostAgentSupervisor = class {
|
|
|
18103
18185
|
report("installing", "installing agent CLI");
|
|
18104
18186
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
18105
18187
|
}
|
|
18106
|
-
const home = process.env.HOME ||
|
|
18188
|
+
const home = process.env.HOME || os36.homedir();
|
|
18107
18189
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
18108
18190
|
if (payload.cloneToken) {
|
|
18109
18191
|
try {
|
|
18110
18192
|
report("preparing", "configuring git tooling");
|
|
18111
18193
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
18112
18194
|
if (ghCmd) {
|
|
18113
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
18195
|
+
childEnv.PATH = `${codeamBinDir()}${path45.delimiter}${childEnv.PATH}`;
|
|
18114
18196
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
18115
18197
|
}
|
|
18116
18198
|
} catch (e) {
|
|
@@ -18126,7 +18208,7 @@ var HostAgentSupervisor = class {
|
|
|
18126
18208
|
}
|
|
18127
18209
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
18128
18210
|
report("headroom", "setting up Headroom proxy");
|
|
18129
|
-
const freeBytes = await this.getFreeDisk(
|
|
18211
|
+
const freeBytes = await this.getFreeDisk(os36.homedir());
|
|
18130
18212
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
18131
18213
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
18132
18214
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -18175,6 +18257,11 @@ var HostAgentSupervisor = class {
|
|
|
18175
18257
|
);
|
|
18176
18258
|
persistHeadroomConfig({ enabled: false });
|
|
18177
18259
|
}
|
|
18260
|
+
if (payload.integrations?.length) {
|
|
18261
|
+
persistIntegrationsManifest({ integrations: payload.integrations });
|
|
18262
|
+
} else {
|
|
18263
|
+
clearIntegrationsManifest();
|
|
18264
|
+
}
|
|
18178
18265
|
report("spawning", "starting agent");
|
|
18179
18266
|
const proc = this.spawnSessionChild(childEnv, cwd, extraArgs);
|
|
18180
18267
|
const child = {
|
|
@@ -18248,7 +18335,7 @@ var HostAgentSupervisor = class {
|
|
|
18248
18335
|
*/
|
|
18249
18336
|
runAgentInstall(script) {
|
|
18250
18337
|
return new Promise((resolve7) => {
|
|
18251
|
-
const home = process.env.HOME ||
|
|
18338
|
+
const home = process.env.HOME || os36.homedir();
|
|
18252
18339
|
const child = (0, import_node_child_process23.spawn)("sh", ["-c", script], {
|
|
18253
18340
|
env: { ...process.env, HOME: home },
|
|
18254
18341
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -18432,9 +18519,9 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
18432
18519
|
}
|
|
18433
18520
|
|
|
18434
18521
|
// src/services/headroom/budget-relaunch.ts
|
|
18435
|
-
var
|
|
18436
|
-
var
|
|
18437
|
-
var
|
|
18522
|
+
var fs43 = __toESM(require("fs"));
|
|
18523
|
+
var os37 = __toESM(require("os"));
|
|
18524
|
+
var path46 = __toESM(require("path"));
|
|
18438
18525
|
var import_child_process13 = require("child_process");
|
|
18439
18526
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
18440
18527
|
const rawArgs = manifest.proxy_args ?? [];
|
|
@@ -18468,7 +18555,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
18468
18555
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
18469
18556
|
}
|
|
18470
18557
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
18471
|
-
const deployDir =
|
|
18558
|
+
const deployDir = path46.join(homeDir2, ".headroom", "deploy");
|
|
18472
18559
|
let profiles;
|
|
18473
18560
|
try {
|
|
18474
18561
|
profiles = deps.readDir(deployDir);
|
|
@@ -18477,7 +18564,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
18477
18564
|
}
|
|
18478
18565
|
const results = [];
|
|
18479
18566
|
for (const profile of profiles) {
|
|
18480
|
-
const manifestPath =
|
|
18567
|
+
const manifestPath = path46.join(deployDir, profile, "manifest.json");
|
|
18481
18568
|
let raw;
|
|
18482
18569
|
try {
|
|
18483
18570
|
raw = deps.readJson(manifestPath);
|
|
@@ -18509,8 +18596,8 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
18509
18596
|
}
|
|
18510
18597
|
function writeManifestReal(manifestPath, manifest) {
|
|
18511
18598
|
const tmp = manifestPath + ".codeam.tmp";
|
|
18512
|
-
|
|
18513
|
-
|
|
18599
|
+
fs43.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
18600
|
+
fs43.renameSync(tmp, manifestPath);
|
|
18514
18601
|
}
|
|
18515
18602
|
function restartDeploymentReal(profile) {
|
|
18516
18603
|
try {
|
|
@@ -18540,11 +18627,11 @@ function spawnProxyReal2(_budget) {
|
|
|
18540
18627
|
});
|
|
18541
18628
|
}
|
|
18542
18629
|
function makeRealApplyBudgetDeps() {
|
|
18543
|
-
const homeDir2 =
|
|
18630
|
+
const homeDir2 = os37.homedir();
|
|
18544
18631
|
return {
|
|
18545
18632
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
18546
|
-
readDir: (dir) =>
|
|
18547
|
-
readJson: (filePath) => JSON.parse(
|
|
18633
|
+
readDir: (dir) => fs43.readdirSync(dir),
|
|
18634
|
+
readJson: (filePath) => JSON.parse(fs43.readFileSync(filePath, "utf8"))
|
|
18548
18635
|
}),
|
|
18549
18636
|
writeManifest: writeManifestReal,
|
|
18550
18637
|
restartDeployment: restartDeploymentReal,
|
|
@@ -19224,8 +19311,8 @@ function activePreviewSessionIds() {
|
|
|
19224
19311
|
|
|
19225
19312
|
// src/services/preview/start-orchestrator.ts
|
|
19226
19313
|
var import_child_process17 = require("child_process");
|
|
19227
|
-
var
|
|
19228
|
-
var
|
|
19314
|
+
var fs48 = __toESM(require("fs"));
|
|
19315
|
+
var path51 = __toESM(require("path"));
|
|
19229
19316
|
var import_which2 = __toESM(require("which"));
|
|
19230
19317
|
var INSTALL_TIMEOUT_MS = 5 * 6e4;
|
|
19231
19318
|
var SETUP_TIMEOUT_MS = 2 * 6e4;
|
|
@@ -19292,8 +19379,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19292
19379
|
if (args2.length === 0) return detection;
|
|
19293
19380
|
const binName = args2[0];
|
|
19294
19381
|
if (binName.startsWith("-")) return detection;
|
|
19295
|
-
const binPath =
|
|
19296
|
-
if (!
|
|
19382
|
+
const binPath = path51.join(cwd, "node_modules", ".bin", binName);
|
|
19383
|
+
if (!fs48.existsSync(binPath)) return detection;
|
|
19297
19384
|
return {
|
|
19298
19385
|
...detection,
|
|
19299
19386
|
command: binPath,
|
|
@@ -19643,9 +19730,9 @@ async function establishTunnel(ctx, dev) {
|
|
|
19643
19730
|
|
|
19644
19731
|
// src/beads/bd-adapter.ts
|
|
19645
19732
|
var import_child_process18 = require("child_process");
|
|
19646
|
-
var
|
|
19647
|
-
var
|
|
19648
|
-
var
|
|
19733
|
+
var fs49 = __toESM(require("fs"));
|
|
19734
|
+
var os39 = __toESM(require("os"));
|
|
19735
|
+
var path52 = __toESM(require("path"));
|
|
19649
19736
|
var BD_PACKAGE = "@beads/bd";
|
|
19650
19737
|
function resolveBundledBdBinary() {
|
|
19651
19738
|
return _resolveSeam.resolveBundled();
|
|
@@ -19657,11 +19744,11 @@ function _defaultResolveBundled() {
|
|
|
19657
19744
|
} catch {
|
|
19658
19745
|
return null;
|
|
19659
19746
|
}
|
|
19660
|
-
const binDir =
|
|
19747
|
+
const binDir = path52.join(path52.dirname(pkgJsonPath), "bin");
|
|
19661
19748
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
19662
|
-
const binaryPath =
|
|
19749
|
+
const binaryPath = path52.join(binDir, binaryName);
|
|
19663
19750
|
try {
|
|
19664
|
-
|
|
19751
|
+
fs49.accessSync(binaryPath, fs49.constants.F_OK);
|
|
19665
19752
|
return binaryPath;
|
|
19666
19753
|
} catch {
|
|
19667
19754
|
return null;
|
|
@@ -19671,13 +19758,13 @@ function resolveBdOnPath() {
|
|
|
19671
19758
|
return _resolveSeam.resolveOnPath();
|
|
19672
19759
|
}
|
|
19673
19760
|
function _defaultResolveOnPath() {
|
|
19674
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
19761
|
+
const dirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
|
|
19675
19762
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
19676
19763
|
for (const dir of dirs) {
|
|
19677
19764
|
for (const candidate of candidates) {
|
|
19678
|
-
const full =
|
|
19765
|
+
const full = path52.join(dir, candidate);
|
|
19679
19766
|
try {
|
|
19680
|
-
|
|
19767
|
+
fs49.accessSync(full, fs49.constants.F_OK);
|
|
19681
19768
|
return full;
|
|
19682
19769
|
} catch {
|
|
19683
19770
|
}
|
|
@@ -19762,7 +19849,7 @@ var BdAdapter = class {
|
|
|
19762
19849
|
const env = { ...process.env };
|
|
19763
19850
|
if (!env.HOME) {
|
|
19764
19851
|
try {
|
|
19765
|
-
const home =
|
|
19852
|
+
const home = os39.homedir();
|
|
19766
19853
|
if (home) env.HOME = home;
|
|
19767
19854
|
} catch {
|
|
19768
19855
|
}
|
|
@@ -19854,9 +19941,9 @@ function coerceIssue(row, projectKey) {
|
|
|
19854
19941
|
|
|
19855
19942
|
// src/beads/provisioner.ts
|
|
19856
19943
|
var import_child_process22 = require("child_process");
|
|
19857
|
-
var
|
|
19858
|
-
var
|
|
19859
|
-
var
|
|
19944
|
+
var fs52 = __toESM(require("fs"));
|
|
19945
|
+
var os41 = __toESM(require("os"));
|
|
19946
|
+
var path55 = __toESM(require("path"));
|
|
19860
19947
|
|
|
19861
19948
|
// src/beads/install-bd.ts
|
|
19862
19949
|
var import_child_process19 = require("child_process");
|
|
@@ -19921,9 +20008,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
19921
20008
|
|
|
19922
20009
|
// src/beads/install-dolt.ts
|
|
19923
20010
|
var import_child_process20 = require("child_process");
|
|
19924
|
-
var
|
|
19925
|
-
var
|
|
19926
|
-
var
|
|
20011
|
+
var fs50 = __toESM(require("fs"));
|
|
20012
|
+
var os40 = __toESM(require("os"));
|
|
20013
|
+
var path53 = __toESM(require("path"));
|
|
19927
20014
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
19928
20015
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
19929
20016
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -19963,11 +20050,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
19963
20050
|
}
|
|
19964
20051
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
19965
20052
|
function doltPlatformTuple(platform3, arch2) {
|
|
19966
|
-
const
|
|
20053
|
+
const os51 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
19967
20054
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
19968
20055
|
if (!a) return null;
|
|
19969
|
-
if (
|
|
19970
|
-
return `${
|
|
20056
|
+
if (os51 === "windows" && a !== "amd64") return null;
|
|
20057
|
+
return `${os51}-${a}`;
|
|
19971
20058
|
}
|
|
19972
20059
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
19973
20060
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -20012,14 +20099,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
20012
20099
|
return result;
|
|
20013
20100
|
}
|
|
20014
20101
|
var _doltPathSeam = {
|
|
20015
|
-
homedir: () =>
|
|
20102
|
+
homedir: () => os40.homedir(),
|
|
20016
20103
|
getPath: () => process.env.PATH ?? "",
|
|
20017
20104
|
setPath: (p2) => {
|
|
20018
20105
|
process.env.PATH = p2;
|
|
20019
20106
|
},
|
|
20020
20107
|
exists: (p2) => {
|
|
20021
20108
|
try {
|
|
20022
|
-
|
|
20109
|
+
fs50.accessSync(p2, fs50.constants.F_OK);
|
|
20023
20110
|
return true;
|
|
20024
20111
|
} catch {
|
|
20025
20112
|
return false;
|
|
@@ -20030,7 +20117,7 @@ function doltBinaryNames(platform3) {
|
|
|
20030
20117
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
20031
20118
|
}
|
|
20032
20119
|
function knownDoltDirs(platform3) {
|
|
20033
|
-
const P3 = platform3 === "win32" ?
|
|
20120
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
20034
20121
|
const home = _doltPathSeam.homedir();
|
|
20035
20122
|
if (platform3 === "win32") {
|
|
20036
20123
|
return [
|
|
@@ -20046,7 +20133,7 @@ function knownDoltDirs(platform3) {
|
|
|
20046
20133
|
].filter(Boolean);
|
|
20047
20134
|
}
|
|
20048
20135
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
20049
|
-
const P3 = platform3 === "win32" ?
|
|
20136
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
20050
20137
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
20051
20138
|
const names = doltBinaryNames(platform3);
|
|
20052
20139
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -20182,8 +20269,8 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
20182
20269
|
// src/beads/project-key.ts
|
|
20183
20270
|
var import_child_process21 = require("child_process");
|
|
20184
20271
|
var crypto2 = __toESM(require("crypto"));
|
|
20185
|
-
var
|
|
20186
|
-
var
|
|
20272
|
+
var fs51 = __toESM(require("fs"));
|
|
20273
|
+
var path54 = __toESM(require("path"));
|
|
20187
20274
|
function normalizeOrigin(raw) {
|
|
20188
20275
|
const trimmed = raw.trim();
|
|
20189
20276
|
if (!trimmed) return null;
|
|
@@ -20209,17 +20296,17 @@ function normalizeOrigin(raw) {
|
|
|
20209
20296
|
return `${host2}/${pathPart}`;
|
|
20210
20297
|
}
|
|
20211
20298
|
function findRepoRoot(cwd) {
|
|
20212
|
-
let dir =
|
|
20299
|
+
let dir = path54.resolve(cwd);
|
|
20213
20300
|
const seen = /* @__PURE__ */ new Set();
|
|
20214
20301
|
for (let i = 0; i < 256; i++) {
|
|
20215
20302
|
if (seen.has(dir)) return null;
|
|
20216
20303
|
seen.add(dir);
|
|
20217
20304
|
try {
|
|
20218
|
-
const stat3 =
|
|
20305
|
+
const stat3 = fs51.statSync(path54.join(dir, ".git"), { throwIfNoEntry: false });
|
|
20219
20306
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
20220
20307
|
} catch {
|
|
20221
20308
|
}
|
|
20222
|
-
const parent =
|
|
20309
|
+
const parent = path54.dirname(dir);
|
|
20223
20310
|
if (parent === dir) return null;
|
|
20224
20311
|
dir = parent;
|
|
20225
20312
|
}
|
|
@@ -20230,7 +20317,7 @@ var _execSeam2 = {
|
|
|
20230
20317
|
const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
|
|
20231
20318
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
20232
20319
|
},
|
|
20233
|
-
realpath: (p2) =>
|
|
20320
|
+
realpath: (p2) => fs51.realpathSync(p2)
|
|
20234
20321
|
};
|
|
20235
20322
|
function readOrigin(cwd) {
|
|
20236
20323
|
try {
|
|
@@ -20259,7 +20346,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
20259
20346
|
} catch {
|
|
20260
20347
|
}
|
|
20261
20348
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
20262
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
20349
|
+
return { projectKey: `path:${hash}`, projectLabel: path54.basename(real) || "project" };
|
|
20263
20350
|
}
|
|
20264
20351
|
|
|
20265
20352
|
// src/beads/project-prefix.ts
|
|
@@ -20304,17 +20391,17 @@ var _provisionSeam = {
|
|
|
20304
20391
|
};
|
|
20305
20392
|
var _linkSeam = {
|
|
20306
20393
|
platform: () => process.platform,
|
|
20307
|
-
homedir: () =>
|
|
20394
|
+
homedir: () => os41.homedir(),
|
|
20308
20395
|
isWritableDir: (dir) => {
|
|
20309
20396
|
try {
|
|
20310
|
-
|
|
20397
|
+
fs52.accessSync(dir, fs52.constants.W_OK);
|
|
20311
20398
|
return true;
|
|
20312
20399
|
} catch {
|
|
20313
20400
|
return false;
|
|
20314
20401
|
}
|
|
20315
20402
|
},
|
|
20316
20403
|
ensureDir: (dir) => {
|
|
20317
|
-
|
|
20404
|
+
fs52.mkdirSync(dir, { recursive: true });
|
|
20318
20405
|
},
|
|
20319
20406
|
/**
|
|
20320
20407
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -20335,9 +20422,9 @@ var _linkSeam = {
|
|
|
20335
20422
|
* which `linkBdOntoPath` creates if missing.
|
|
20336
20423
|
*/
|
|
20337
20424
|
cliBinDir: () => {
|
|
20338
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
20425
|
+
const pathDirs = (process.env.PATH ?? "").split(path55.delimiter).filter(Boolean);
|
|
20339
20426
|
const home = _linkSeam.homedir();
|
|
20340
|
-
const localBin = home ?
|
|
20427
|
+
const localBin = home ? path55.join(home, ".local", "bin") : null;
|
|
20341
20428
|
if (localBin) {
|
|
20342
20429
|
try {
|
|
20343
20430
|
_linkSeam.ensureDir(localBin);
|
|
@@ -20347,16 +20434,16 @@ var _linkSeam = {
|
|
|
20347
20434
|
const candidates = [];
|
|
20348
20435
|
if (localBin) candidates.push(localBin);
|
|
20349
20436
|
try {
|
|
20350
|
-
candidates.push(
|
|
20437
|
+
candidates.push(path55.dirname(process.execPath));
|
|
20351
20438
|
} catch {
|
|
20352
20439
|
}
|
|
20353
20440
|
candidates.push("/usr/local/bin");
|
|
20354
20441
|
const entry = process.argv[1];
|
|
20355
20442
|
if (entry) {
|
|
20356
20443
|
try {
|
|
20357
|
-
candidates.push(
|
|
20444
|
+
candidates.push(path55.dirname(fs52.realpathSync(entry)));
|
|
20358
20445
|
} catch {
|
|
20359
|
-
candidates.push(
|
|
20446
|
+
candidates.push(path55.dirname(entry));
|
|
20360
20447
|
}
|
|
20361
20448
|
}
|
|
20362
20449
|
const onPathWritable = candidates.find(
|
|
@@ -20368,20 +20455,20 @@ var _linkSeam = {
|
|
|
20368
20455
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
20369
20456
|
readlink: (linkPath) => {
|
|
20370
20457
|
try {
|
|
20371
|
-
return
|
|
20458
|
+
return fs52.readlinkSync(linkPath);
|
|
20372
20459
|
} catch {
|
|
20373
20460
|
return null;
|
|
20374
20461
|
}
|
|
20375
20462
|
},
|
|
20376
|
-
unlink: (linkPath) =>
|
|
20377
|
-
symlink: (target, linkPath) =>
|
|
20463
|
+
unlink: (linkPath) => fs52.unlinkSync(linkPath),
|
|
20464
|
+
symlink: (target, linkPath) => fs52.symlinkSync(target, linkPath)
|
|
20378
20465
|
};
|
|
20379
20466
|
function linkBdOntoPath(binaryPath) {
|
|
20380
20467
|
if (_linkSeam.platform() === "win32") return;
|
|
20381
20468
|
const binDir = _linkSeam.cliBinDir();
|
|
20382
20469
|
if (!binDir) return;
|
|
20383
20470
|
_linkSeam.ensureDir(binDir);
|
|
20384
|
-
const linkPath =
|
|
20471
|
+
const linkPath = path55.join(binDir, "bd");
|
|
20385
20472
|
if (linkPath === binaryPath) return;
|
|
20386
20473
|
const current = _linkSeam.readlink(linkPath);
|
|
20387
20474
|
if (current === binaryPath) return;
|
|
@@ -20576,7 +20663,7 @@ function dedupeRecipes(agents) {
|
|
|
20576
20663
|
|
|
20577
20664
|
// src/beads/watcher.ts
|
|
20578
20665
|
var crypto4 = __toESM(require("crypto"));
|
|
20579
|
-
var
|
|
20666
|
+
var path56 = __toESM(require("path"));
|
|
20580
20667
|
var API_BASE6 = resolveApiBaseUrl();
|
|
20581
20668
|
var DEBOUNCE_MS2 = 400;
|
|
20582
20669
|
var ZERO_SUMMARY = {
|
|
@@ -20600,7 +20687,7 @@ var BeadsWatcher = class {
|
|
|
20600
20687
|
constructor(opts) {
|
|
20601
20688
|
this.opts = opts;
|
|
20602
20689
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
20603
|
-
this.feedPath = opts.feedPath ??
|
|
20690
|
+
this.feedPath = opts.feedPath ?? path56.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
20604
20691
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
20605
20692
|
}
|
|
20606
20693
|
opts;
|
|
@@ -20851,15 +20938,15 @@ async function handleBeadsActionCommand(action, started) {
|
|
|
20851
20938
|
}
|
|
20852
20939
|
|
|
20853
20940
|
// src/beads/config-store.ts
|
|
20854
|
-
var
|
|
20855
|
-
var
|
|
20856
|
-
var
|
|
20941
|
+
var import_node_fs8 = __toESM(require("fs"));
|
|
20942
|
+
var import_node_os7 = __toESM(require("os"));
|
|
20943
|
+
var import_node_path6 = __toESM(require("path"));
|
|
20857
20944
|
function beadsConfigPath() {
|
|
20858
|
-
return
|
|
20945
|
+
return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "beads-config.json");
|
|
20859
20946
|
}
|
|
20860
20947
|
function readBeadsEnabled() {
|
|
20861
20948
|
try {
|
|
20862
|
-
const raw =
|
|
20949
|
+
const raw = import_node_fs8.default.readFileSync(beadsConfigPath(), "utf8");
|
|
20863
20950
|
const cfg = JSON.parse(raw);
|
|
20864
20951
|
return cfg.enabled !== false;
|
|
20865
20952
|
} catch {
|
|
@@ -20868,10 +20955,10 @@ function readBeadsEnabled() {
|
|
|
20868
20955
|
}
|
|
20869
20956
|
function persistBeadsConfig(cfg) {
|
|
20870
20957
|
const file = beadsConfigPath();
|
|
20871
|
-
|
|
20958
|
+
import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true });
|
|
20872
20959
|
const tmp = `${file}.tmp`;
|
|
20873
|
-
|
|
20874
|
-
|
|
20960
|
+
import_node_fs8.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
|
|
20961
|
+
import_node_fs8.default.renameSync(tmp, file);
|
|
20875
20962
|
restrictToOwner(file);
|
|
20876
20963
|
}
|
|
20877
20964
|
|
|
@@ -21017,8 +21104,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
21017
21104
|
function saveFilesTemp(files) {
|
|
21018
21105
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
21019
21106
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
21020
|
-
const tmpPath =
|
|
21021
|
-
|
|
21107
|
+
const tmpPath = path58.join(os43.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
21108
|
+
fs54.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
21022
21109
|
pendingAttachmentFiles.add(tmpPath);
|
|
21023
21110
|
return tmpPath;
|
|
21024
21111
|
});
|
|
@@ -21230,9 +21317,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
21230
21317
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
21231
21318
|
};
|
|
21232
21319
|
var envReadH = async (ctx, cmd) => {
|
|
21233
|
-
const envPath =
|
|
21320
|
+
const envPath = path58.join(process.cwd(), ".env");
|
|
21234
21321
|
try {
|
|
21235
|
-
const raw = await
|
|
21322
|
+
const raw = await fs54.promises.readFile(envPath, "utf8");
|
|
21236
21323
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
21237
21324
|
exists: true,
|
|
21238
21325
|
vars: parseDotenv(raw)
|
|
@@ -21263,14 +21350,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
21263
21350
|
}
|
|
21264
21351
|
seen.add(v.key);
|
|
21265
21352
|
}
|
|
21266
|
-
const envPath =
|
|
21267
|
-
const tmpPath =
|
|
21353
|
+
const envPath = path58.join(process.cwd(), ".env");
|
|
21354
|
+
const tmpPath = path58.join(process.cwd(), ".env.codeam.tmp");
|
|
21268
21355
|
try {
|
|
21269
|
-
await
|
|
21270
|
-
await
|
|
21356
|
+
await fs54.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
21357
|
+
await fs54.promises.rename(tmpPath, envPath);
|
|
21271
21358
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
21272
21359
|
} catch (err) {
|
|
21273
|
-
await
|
|
21360
|
+
await fs54.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
21274
21361
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
21275
21362
|
}
|
|
21276
21363
|
};
|
|
@@ -21314,7 +21401,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21314
21401
|
let configuredAgent = rawAgentId;
|
|
21315
21402
|
if (!configuredAgent) {
|
|
21316
21403
|
try {
|
|
21317
|
-
const raw = JSON.parse(
|
|
21404
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21318
21405
|
configuredAgent = raw.agent ?? "";
|
|
21319
21406
|
} catch {
|
|
21320
21407
|
}
|
|
@@ -21348,7 +21435,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21348
21435
|
persist: persistHeadroomConfig,
|
|
21349
21436
|
readEnabled: () => {
|
|
21350
21437
|
try {
|
|
21351
|
-
const raw = JSON.parse(
|
|
21438
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21352
21439
|
return raw.enabled === true;
|
|
21353
21440
|
} catch {
|
|
21354
21441
|
return false;
|
|
@@ -21595,7 +21682,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
21595
21682
|
}
|
|
21596
21683
|
let headroomActive = false;
|
|
21597
21684
|
try {
|
|
21598
|
-
const raw = JSON.parse(
|
|
21685
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21599
21686
|
headroomActive = raw.enabled === true;
|
|
21600
21687
|
} catch {
|
|
21601
21688
|
}
|
|
@@ -21605,7 +21692,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
21605
21692
|
}
|
|
21606
21693
|
let existingConfig = { enabled: true };
|
|
21607
21694
|
try {
|
|
21608
|
-
existingConfig = JSON.parse(
|
|
21695
|
+
existingConfig = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21609
21696
|
} catch {
|
|
21610
21697
|
}
|
|
21611
21698
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -21718,13 +21805,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
21718
21805
|
function buildNpmInstallInvocation(opts) {
|
|
21719
21806
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
21720
21807
|
const execPath = opts?.execPath ?? process.execPath;
|
|
21721
|
-
const exists2 = opts?.existsSync ??
|
|
21722
|
-
const normalized = entryScript.split(
|
|
21808
|
+
const exists2 = opts?.existsSync ?? fs54.existsSync;
|
|
21809
|
+
const normalized = entryScript.split(path58.sep).join("/");
|
|
21723
21810
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
21724
21811
|
const markerIdx = normalized.indexOf(marker);
|
|
21725
21812
|
const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
|
|
21726
|
-
const siblingNpm =
|
|
21727
|
-
|
|
21813
|
+
const siblingNpm = path58.join(
|
|
21814
|
+
path58.dirname(execPath),
|
|
21728
21815
|
process.platform === "win32" ? "npm.cmd" : "npm"
|
|
21729
21816
|
);
|
|
21730
21817
|
const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
|
|
@@ -22591,11 +22678,11 @@ function resolveTokenValue(args2) {
|
|
|
22591
22678
|
}
|
|
22592
22679
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
22593
22680
|
if (fileFlag) {
|
|
22594
|
-
const
|
|
22681
|
+
const path73 = fileFlag.slice("--token-file=".length);
|
|
22595
22682
|
try {
|
|
22596
|
-
const content =
|
|
22597
|
-
if (content.length === 0) fail(`--token-file ${
|
|
22598
|
-
rmIfExistsQuiet(
|
|
22683
|
+
const content = fs55.readFileSync(path73, "utf8").trim();
|
|
22684
|
+
if (content.length === 0) fail(`--token-file ${path73} is empty`);
|
|
22685
|
+
rmIfExistsQuiet(path73);
|
|
22599
22686
|
return content;
|
|
22600
22687
|
} catch (err) {
|
|
22601
22688
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -22624,7 +22711,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
22624
22711
|
pluginId,
|
|
22625
22712
|
ideName: "codeam-cli (codespace)",
|
|
22626
22713
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
22627
|
-
hostname:
|
|
22714
|
+
hostname: os44.hostname(),
|
|
22628
22715
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
22629
22716
|
// Current git branch of the codespace's working directory, so the
|
|
22630
22717
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -22685,7 +22772,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
22685
22772
|
}
|
|
22686
22773
|
}
|
|
22687
22774
|
function pairAutoLockPath() {
|
|
22688
|
-
return
|
|
22775
|
+
return path59.join(os44.homedir(), ".codeam", "pair-auto.lock");
|
|
22689
22776
|
}
|
|
22690
22777
|
function isLivePairAuto(pid) {
|
|
22691
22778
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -22695,7 +22782,7 @@ function isLivePairAuto(pid) {
|
|
|
22695
22782
|
if (e.code !== "EPERM") return false;
|
|
22696
22783
|
}
|
|
22697
22784
|
try {
|
|
22698
|
-
return
|
|
22785
|
+
return fs55.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
22699
22786
|
} catch {
|
|
22700
22787
|
return true;
|
|
22701
22788
|
}
|
|
@@ -22705,24 +22792,24 @@ function isLiveCodeam(pid) {
|
|
|
22705
22792
|
}
|
|
22706
22793
|
function daemonLockPath(sessionId) {
|
|
22707
22794
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
22708
|
-
return
|
|
22795
|
+
return path59.join(os44.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
22709
22796
|
}
|
|
22710
22797
|
function acquireDaemonLock(sessionId) {
|
|
22711
22798
|
const lockPath = daemonLockPath(sessionId);
|
|
22712
22799
|
try {
|
|
22713
|
-
|
|
22800
|
+
fs55.mkdirSync(path59.dirname(lockPath), { recursive: true });
|
|
22714
22801
|
try {
|
|
22715
|
-
|
|
22802
|
+
fs55.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
22716
22803
|
} catch (e) {
|
|
22717
22804
|
if (e.code !== "EEXIST") throw e;
|
|
22718
|
-
const holder = Number(
|
|
22805
|
+
const holder = Number(fs55.readFileSync(lockPath, "utf8").trim());
|
|
22719
22806
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
22720
|
-
|
|
22807
|
+
fs55.writeFileSync(lockPath, String(process.pid));
|
|
22721
22808
|
}
|
|
22722
22809
|
const release3 = () => {
|
|
22723
22810
|
try {
|
|
22724
|
-
if (
|
|
22725
|
-
|
|
22811
|
+
if (fs55.existsSync(lockPath) && Number(fs55.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
22812
|
+
fs55.unlinkSync(lockPath);
|
|
22726
22813
|
}
|
|
22727
22814
|
} catch {
|
|
22728
22815
|
}
|
|
@@ -22744,19 +22831,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
22744
22831
|
function acquireSingletonLock() {
|
|
22745
22832
|
const lockPath = pairAutoLockPath();
|
|
22746
22833
|
try {
|
|
22747
|
-
|
|
22834
|
+
fs55.mkdirSync(path59.dirname(lockPath), { recursive: true });
|
|
22748
22835
|
try {
|
|
22749
|
-
|
|
22836
|
+
fs55.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
22750
22837
|
} catch (e) {
|
|
22751
22838
|
if (e.code !== "EEXIST") throw e;
|
|
22752
|
-
const holder = Number(
|
|
22839
|
+
const holder = Number(fs55.readFileSync(lockPath, "utf8").trim());
|
|
22753
22840
|
if (isLivePairAuto(holder)) return false;
|
|
22754
|
-
|
|
22841
|
+
fs55.writeFileSync(lockPath, String(process.pid));
|
|
22755
22842
|
}
|
|
22756
22843
|
process.once("exit", () => {
|
|
22757
22844
|
try {
|
|
22758
|
-
if (
|
|
22759
|
-
|
|
22845
|
+
if (fs55.existsSync(lockPath) && Number(fs55.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
22846
|
+
fs55.unlinkSync(lockPath);
|
|
22760
22847
|
}
|
|
22761
22848
|
} catch {
|
|
22762
22849
|
}
|
|
@@ -23202,7 +23289,7 @@ var AgentService = class _AgentService {
|
|
|
23202
23289
|
};
|
|
23203
23290
|
|
|
23204
23291
|
// src/agents/acp/adapters.ts
|
|
23205
|
-
var
|
|
23292
|
+
var path61 = __toESM(require("path"));
|
|
23206
23293
|
|
|
23207
23294
|
// src/agents/acp/agent-binary.ts
|
|
23208
23295
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -23378,11 +23465,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
23378
23465
|
|
|
23379
23466
|
// src/agents/kimi/installer.ts
|
|
23380
23467
|
var import_node_child_process25 = require("child_process");
|
|
23381
|
-
var
|
|
23382
|
-
var
|
|
23468
|
+
var import_node_os8 = require("os");
|
|
23469
|
+
var import_node_path7 = require("path");
|
|
23383
23470
|
var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
|
|
23384
23471
|
function kimiBinDir() {
|
|
23385
|
-
return (0,
|
|
23472
|
+
return (0, import_node_path7.join)(process.env.KIMI_CODE_HOME || (0, import_node_path7.join)((0, import_node_os8.homedir)(), ".kimi-code"), "bin");
|
|
23386
23473
|
}
|
|
23387
23474
|
function kimiRuns() {
|
|
23388
23475
|
const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
|
|
@@ -23445,13 +23532,13 @@ function resolveBin(pkgName, binName) {
|
|
|
23445
23532
|
try {
|
|
23446
23533
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
23447
23534
|
const manifest = require_(`${pkgName}/package.json`);
|
|
23448
|
-
const pkgDir =
|
|
23535
|
+
const pkgDir = path61.dirname(manifestPath);
|
|
23449
23536
|
const bin = manifest.bin;
|
|
23450
23537
|
if (!bin) return null;
|
|
23451
|
-
if (typeof bin === "string") return
|
|
23538
|
+
if (typeof bin === "string") return path61.resolve(pkgDir, bin);
|
|
23452
23539
|
const target = binName ?? Object.keys(bin)[0];
|
|
23453
23540
|
if (!target || !bin[target]) return null;
|
|
23454
|
-
return
|
|
23541
|
+
return path61.resolve(pkgDir, bin[target]);
|
|
23455
23542
|
} catch {
|
|
23456
23543
|
return null;
|
|
23457
23544
|
}
|
|
@@ -23555,9 +23642,9 @@ function requiresAcp(agent) {
|
|
|
23555
23642
|
var import_node_crypto10 = require("crypto");
|
|
23556
23643
|
|
|
23557
23644
|
// src/services/history.service.ts
|
|
23558
|
-
var
|
|
23559
|
-
var
|
|
23560
|
-
var
|
|
23645
|
+
var fs57 = __toESM(require("fs"));
|
|
23646
|
+
var path62 = __toESM(require("path"));
|
|
23647
|
+
var os46 = __toESM(require("os"));
|
|
23561
23648
|
var https7 = __toESM(require("https"));
|
|
23562
23649
|
var http6 = __toESM(require("http"));
|
|
23563
23650
|
var import_zod2 = require("zod");
|
|
@@ -23584,7 +23671,7 @@ function parseJsonl(filePath) {
|
|
|
23584
23671
|
const messages = [];
|
|
23585
23672
|
let raw;
|
|
23586
23673
|
try {
|
|
23587
|
-
raw =
|
|
23674
|
+
raw = fs57.readFileSync(filePath, "utf8");
|
|
23588
23675
|
} catch (err) {
|
|
23589
23676
|
if (err.code !== "ENOENT") {
|
|
23590
23677
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -23725,7 +23812,7 @@ var HistoryService = class _HistoryService {
|
|
|
23725
23812
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
23726
23813
|
}
|
|
23727
23814
|
get projectDir() {
|
|
23728
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23815
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path62.join(os46.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
23729
23816
|
}
|
|
23730
23817
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
23731
23818
|
setCurrentConversationId(id) {
|
|
@@ -23737,7 +23824,7 @@ var HistoryService = class _HistoryService {
|
|
|
23737
23824
|
/** Return the current message count in the active conversation. */
|
|
23738
23825
|
getCurrentMessageCount() {
|
|
23739
23826
|
if (!this.currentConversationId) return 0;
|
|
23740
|
-
const filePath =
|
|
23827
|
+
const filePath = path62.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23741
23828
|
return parseJsonl(filePath).length;
|
|
23742
23829
|
}
|
|
23743
23830
|
/**
|
|
@@ -23748,7 +23835,7 @@ var HistoryService = class _HistoryService {
|
|
|
23748
23835
|
const deadline = Date.now() + timeoutMs;
|
|
23749
23836
|
while (Date.now() < deadline) {
|
|
23750
23837
|
if (!this.currentConversationId) return null;
|
|
23751
|
-
const filePath =
|
|
23838
|
+
const filePath = path62.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23752
23839
|
const messages = parseJsonl(filePath);
|
|
23753
23840
|
if (messages.length > previousCount) {
|
|
23754
23841
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -23774,16 +23861,16 @@ var HistoryService = class _HistoryService {
|
|
|
23774
23861
|
const dir = this.projectDir;
|
|
23775
23862
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23776
23863
|
try {
|
|
23777
|
-
const files =
|
|
23864
|
+
const files = fs57.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23778
23865
|
try {
|
|
23779
|
-
const stat3 =
|
|
23866
|
+
const stat3 = fs57.statSync(path62.join(dir, e.name));
|
|
23780
23867
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23781
23868
|
} catch {
|
|
23782
23869
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
23783
23870
|
}
|
|
23784
23871
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
23785
23872
|
if (files.length > 0) {
|
|
23786
|
-
this.currentConversationId =
|
|
23873
|
+
this.currentConversationId = path62.basename(files[0].name, ".jsonl");
|
|
23787
23874
|
}
|
|
23788
23875
|
} catch {
|
|
23789
23876
|
}
|
|
@@ -23817,13 +23904,13 @@ var HistoryService = class _HistoryService {
|
|
|
23817
23904
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23818
23905
|
let entries;
|
|
23819
23906
|
try {
|
|
23820
|
-
entries =
|
|
23907
|
+
entries = fs57.readdirSync(dir, { withFileTypes: true });
|
|
23821
23908
|
} catch {
|
|
23822
23909
|
return null;
|
|
23823
23910
|
}
|
|
23824
23911
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23825
23912
|
try {
|
|
23826
|
-
const stat3 =
|
|
23913
|
+
const stat3 = fs57.statSync(path62.join(dir, e.name));
|
|
23827
23914
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23828
23915
|
} catch {
|
|
23829
23916
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -23832,12 +23919,12 @@ var HistoryService = class _HistoryService {
|
|
|
23832
23919
|
if (files.length === 0) return null;
|
|
23833
23920
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
23834
23921
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
23835
|
-
return this.extractUsageFromFile(
|
|
23922
|
+
return this.extractUsageFromFile(path62.join(dir, targetFile));
|
|
23836
23923
|
}
|
|
23837
23924
|
extractUsageFromFile(filePath) {
|
|
23838
23925
|
let raw;
|
|
23839
23926
|
try {
|
|
23840
|
-
raw =
|
|
23927
|
+
raw = fs57.readFileSync(filePath, "utf8");
|
|
23841
23928
|
} catch {
|
|
23842
23929
|
return null;
|
|
23843
23930
|
}
|
|
@@ -23882,9 +23969,9 @@ var HistoryService = class _HistoryService {
|
|
|
23882
23969
|
let totalCost = 0;
|
|
23883
23970
|
let files;
|
|
23884
23971
|
try {
|
|
23885
|
-
files =
|
|
23972
|
+
files = fs57.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23886
23973
|
try {
|
|
23887
|
-
return
|
|
23974
|
+
return fs57.statSync(path62.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23888
23975
|
} catch {
|
|
23889
23976
|
return false;
|
|
23890
23977
|
}
|
|
@@ -23895,7 +23982,7 @@ var HistoryService = class _HistoryService {
|
|
|
23895
23982
|
for (const file of files) {
|
|
23896
23983
|
let raw;
|
|
23897
23984
|
try {
|
|
23898
|
-
raw =
|
|
23985
|
+
raw = fs57.readFileSync(path62.join(projectDir, file), "utf8");
|
|
23899
23986
|
} catch {
|
|
23900
23987
|
continue;
|
|
23901
23988
|
}
|
|
@@ -23974,7 +24061,7 @@ var HistoryService = class _HistoryService {
|
|
|
23974
24061
|
if (this.runtime.resolveHistoryFile) {
|
|
23975
24062
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
23976
24063
|
}
|
|
23977
|
-
return
|
|
24064
|
+
return path62.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23978
24065
|
}
|
|
23979
24066
|
/**
|
|
23980
24067
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -24008,7 +24095,7 @@ var HistoryService = class _HistoryService {
|
|
|
24008
24095
|
};
|
|
24009
24096
|
});
|
|
24010
24097
|
}
|
|
24011
|
-
return parseJsonl(
|
|
24098
|
+
return parseJsonl(path62.join(this.projectDir, `${sessionId}.jsonl`));
|
|
24012
24099
|
}
|
|
24013
24100
|
async loadConversation(sessionId) {
|
|
24014
24101
|
const messages = this.readConversation(sessionId);
|
|
@@ -24064,7 +24151,7 @@ var HistoryService = class _HistoryService {
|
|
|
24064
24151
|
if (!filePath) return false;
|
|
24065
24152
|
let mtimeMs;
|
|
24066
24153
|
try {
|
|
24067
|
-
mtimeMs =
|
|
24154
|
+
mtimeMs = fs57.statSync(filePath).mtimeMs;
|
|
24068
24155
|
} catch {
|
|
24069
24156
|
return false;
|
|
24070
24157
|
}
|
|
@@ -24133,10 +24220,10 @@ var HistoryService = class _HistoryService {
|
|
|
24133
24220
|
|
|
24134
24221
|
// src/agents/acp/client.ts
|
|
24135
24222
|
var import_node_child_process26 = require("child_process");
|
|
24136
|
-
var
|
|
24223
|
+
var fs58 = __toESM(require("fs/promises"));
|
|
24137
24224
|
var fsSync = __toESM(require("fs"));
|
|
24138
|
-
var
|
|
24139
|
-
var
|
|
24225
|
+
var os47 = __toESM(require("os"));
|
|
24226
|
+
var path63 = __toESM(require("path"));
|
|
24140
24227
|
var import_node_stream = require("stream");
|
|
24141
24228
|
|
|
24142
24229
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -26860,7 +26947,7 @@ var AcpClient = class {
|
|
|
26860
26947
|
let newSession;
|
|
26861
26948
|
try {
|
|
26862
26949
|
newSession = await Promise.race([
|
|
26863
|
-
this.connection.newSession({ cwd, mcpServers: [] }),
|
|
26950
|
+
this.connection.newSession({ cwd, mcpServers: this.opts.mcpServers ?? [] }),
|
|
26864
26951
|
startupFailure,
|
|
26865
26952
|
startAborted
|
|
26866
26953
|
]);
|
|
@@ -26999,7 +27086,7 @@ var AcpClient = class {
|
|
|
26999
27086
|
await this.connection.loadSession({
|
|
27000
27087
|
sessionId,
|
|
27001
27088
|
cwd: this.opts.cwd,
|
|
27002
|
-
mcpServers: []
|
|
27089
|
+
mcpServers: this.opts.mcpServers ?? []
|
|
27003
27090
|
});
|
|
27004
27091
|
this.sessionId = sessionId;
|
|
27005
27092
|
log.info("acpClient", `loadSession \u2190 ok sessionId=${sessionId.slice(0, 8)}`);
|
|
@@ -27114,7 +27201,7 @@ var AcpClient = class {
|
|
|
27114
27201
|
},
|
|
27115
27202
|
readTextFile: async (params) => {
|
|
27116
27203
|
try {
|
|
27117
|
-
const content = await
|
|
27204
|
+
const content = await fs58.readFile(params.path, "utf8");
|
|
27118
27205
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
27119
27206
|
} catch (err) {
|
|
27120
27207
|
const code = err.code;
|
|
@@ -27134,7 +27221,7 @@ var AcpClient = class {
|
|
|
27134
27221
|
},
|
|
27135
27222
|
writeTextFile: async (params) => {
|
|
27136
27223
|
try {
|
|
27137
|
-
await
|
|
27224
|
+
await fs58.writeFile(params.path, params.content, "utf8");
|
|
27138
27225
|
return {};
|
|
27139
27226
|
} catch (err) {
|
|
27140
27227
|
const code = err.code;
|
|
@@ -27183,29 +27270,29 @@ function applyLineRange(content, line, limit) {
|
|
|
27183
27270
|
return { content: lines.slice(start2, end).join("\n") };
|
|
27184
27271
|
}
|
|
27185
27272
|
function knownAgentBinaryDirs() {
|
|
27186
|
-
const home =
|
|
27273
|
+
const home = os47.homedir();
|
|
27187
27274
|
const out2 = [];
|
|
27188
27275
|
out2.push("/tmp/codeam-node20/bin");
|
|
27189
27276
|
for (const root of [
|
|
27190
27277
|
"/usr/local/share/nvm/versions/node",
|
|
27191
|
-
|
|
27278
|
+
path63.join(home, ".nvm/versions/node")
|
|
27192
27279
|
]) {
|
|
27193
27280
|
try {
|
|
27194
27281
|
for (const child of fsSync.readdirSync(root)) {
|
|
27195
|
-
out2.push(
|
|
27282
|
+
out2.push(path63.join(root, child, "bin"));
|
|
27196
27283
|
}
|
|
27197
27284
|
} catch {
|
|
27198
27285
|
}
|
|
27199
27286
|
}
|
|
27200
|
-
out2.push(
|
|
27287
|
+
out2.push(path63.join(home, ".volta/bin"));
|
|
27201
27288
|
out2.push("/usr/local/bin");
|
|
27202
27289
|
out2.push("/usr/bin");
|
|
27203
|
-
out2.push(
|
|
27204
|
-
out2.push(
|
|
27290
|
+
out2.push(path63.join(home, ".local/bin"));
|
|
27291
|
+
out2.push(path63.join(home, "bin"));
|
|
27205
27292
|
if (process.platform === "win32") {
|
|
27206
27293
|
const { LOCALAPPDATA, APPDATA } = process.env;
|
|
27207
|
-
if (LOCALAPPDATA) out2.push(
|
|
27208
|
-
if (APPDATA) out2.push(
|
|
27294
|
+
if (LOCALAPPDATA) out2.push(path63.join(LOCALAPPDATA, "cursor-agent"));
|
|
27295
|
+
if (APPDATA) out2.push(path63.join(APPDATA, "npm"));
|
|
27209
27296
|
}
|
|
27210
27297
|
return out2.filter((p2) => {
|
|
27211
27298
|
try {
|
|
@@ -27217,7 +27304,7 @@ function knownAgentBinaryDirs() {
|
|
|
27217
27304
|
}
|
|
27218
27305
|
function expandPathForAgentBinaries(existingPath) {
|
|
27219
27306
|
const existing = new Set(
|
|
27220
|
-
existingPath.split(
|
|
27307
|
+
existingPath.split(path63.delimiter).filter((p2) => p2.length > 0)
|
|
27221
27308
|
);
|
|
27222
27309
|
const additions = [];
|
|
27223
27310
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -27227,7 +27314,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
27227
27314
|
}
|
|
27228
27315
|
}
|
|
27229
27316
|
if (additions.length === 0) return existingPath;
|
|
27230
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
27317
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path63.delimiter);
|
|
27231
27318
|
}
|
|
27232
27319
|
|
|
27233
27320
|
// src/agents/acp/headroom-budget-proxy.ts
|
|
@@ -27709,15 +27796,15 @@ function commonPrefixLength(a, b) {
|
|
|
27709
27796
|
|
|
27710
27797
|
// src/agents/acp/onboarding.ts
|
|
27711
27798
|
var import_child_process26 = require("child_process");
|
|
27712
|
-
var
|
|
27713
|
-
var
|
|
27714
|
-
var
|
|
27799
|
+
var fs59 = __toESM(require("fs"));
|
|
27800
|
+
var os48 = __toESM(require("os"));
|
|
27801
|
+
var path64 = __toESM(require("path"));
|
|
27715
27802
|
var _onboardingSeam = {
|
|
27716
|
-
markerPath: (sessionId) =>
|
|
27717
|
-
exists: (p2) =>
|
|
27803
|
+
markerPath: (sessionId) => path64.join(os48.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
27804
|
+
exists: (p2) => fs59.existsSync(p2),
|
|
27718
27805
|
write: (p2) => {
|
|
27719
|
-
|
|
27720
|
-
|
|
27806
|
+
fs59.mkdirSync(path64.dirname(p2), { recursive: true });
|
|
27807
|
+
fs59.writeFileSync(p2, "");
|
|
27721
27808
|
},
|
|
27722
27809
|
disabled: () => {
|
|
27723
27810
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -27754,7 +27841,7 @@ function resolveRepoName(cwd) {
|
|
|
27754
27841
|
if (name) return name;
|
|
27755
27842
|
}
|
|
27756
27843
|
}
|
|
27757
|
-
const base =
|
|
27844
|
+
const base = path64.basename(cwd || "");
|
|
27758
27845
|
if (base && !isUuid(base)) return base;
|
|
27759
27846
|
return "this project";
|
|
27760
27847
|
}
|
|
@@ -28006,8 +28093,8 @@ var import_crypto5 = require("crypto");
|
|
|
28006
28093
|
|
|
28007
28094
|
// src/services/turn-files/git-changeset.ts
|
|
28008
28095
|
var import_child_process27 = require("child_process");
|
|
28009
|
-
var
|
|
28010
|
-
var
|
|
28096
|
+
var fs60 = __toESM(require("fs/promises"));
|
|
28097
|
+
var path65 = __toESM(require("path"));
|
|
28011
28098
|
async function collectRepoChangeset(opts) {
|
|
28012
28099
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
28013
28100
|
if (status2 === null) return null;
|
|
@@ -28025,7 +28112,7 @@ async function collectRepoChangeset(opts) {
|
|
|
28025
28112
|
let stats;
|
|
28026
28113
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
28027
28114
|
const lineCount = await readUntrackedLineCount(
|
|
28028
|
-
|
|
28115
|
+
path65.join(opts.repoRoot, row.filePath)
|
|
28029
28116
|
);
|
|
28030
28117
|
stats = { added: lineCount, removed: 0 };
|
|
28031
28118
|
} else {
|
|
@@ -28056,7 +28143,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
28056
28143
|
}
|
|
28057
28144
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
28058
28145
|
try {
|
|
28059
|
-
const content = await
|
|
28146
|
+
const content = await fs60.readFile(absPath, "utf8");
|
|
28060
28147
|
let count = 0;
|
|
28061
28148
|
let pos = -1;
|
|
28062
28149
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -28148,7 +28235,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
28148
28235
|
});
|
|
28149
28236
|
}
|
|
28150
28237
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
28151
|
-
const
|
|
28238
|
+
const fs65 = await import("fs/promises");
|
|
28152
28239
|
const out2 = [];
|
|
28153
28240
|
await walk(workingDir, 0);
|
|
28154
28241
|
return out2;
|
|
@@ -28156,7 +28243,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28156
28243
|
if (depth > maxDepth) return;
|
|
28157
28244
|
let entries = [];
|
|
28158
28245
|
try {
|
|
28159
|
-
const dirents = await
|
|
28246
|
+
const dirents = await fs65.readdir(dir, { withFileTypes: true });
|
|
28160
28247
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
28161
28248
|
} catch {
|
|
28162
28249
|
return;
|
|
@@ -28167,8 +28254,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28167
28254
|
if (hasGit) {
|
|
28168
28255
|
out2.push({
|
|
28169
28256
|
repoRoot: dir,
|
|
28170
|
-
repoPath:
|
|
28171
|
-
repoName:
|
|
28257
|
+
repoPath: path65.relative(workingDir, dir),
|
|
28258
|
+
repoName: path65.basename(dir)
|
|
28172
28259
|
});
|
|
28173
28260
|
return;
|
|
28174
28261
|
}
|
|
@@ -28176,14 +28263,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28176
28263
|
if (!entry.isDirectory) continue;
|
|
28177
28264
|
if (entry.name === "node_modules") continue;
|
|
28178
28265
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
28179
|
-
await walk(
|
|
28266
|
+
await walk(path65.join(dir, entry.name), depth + 1);
|
|
28180
28267
|
}
|
|
28181
28268
|
}
|
|
28182
28269
|
}
|
|
28183
28270
|
|
|
28184
28271
|
// src/services/turn-files/files-outbox.ts
|
|
28185
|
-
var
|
|
28186
|
-
var
|
|
28272
|
+
var fs61 = __toESM(require("fs/promises"));
|
|
28273
|
+
var path66 = __toESM(require("path"));
|
|
28187
28274
|
var import_os11 = require("os");
|
|
28188
28275
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
28189
28276
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -28216,16 +28303,16 @@ var FilesOutbox = class {
|
|
|
28216
28303
|
backoffIndex = 0;
|
|
28217
28304
|
stopped = false;
|
|
28218
28305
|
constructor(opts) {
|
|
28219
|
-
const base = opts.baseDir ??
|
|
28220
|
-
this.filePath =
|
|
28306
|
+
const base = opts.baseDir ?? path66.join(homeDir(), HOME_OUTBOX_DIR);
|
|
28307
|
+
this.filePath = path66.join(base, `${opts.sessionId}.jsonl`);
|
|
28221
28308
|
this.post = opts.post;
|
|
28222
28309
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
28223
28310
|
}
|
|
28224
28311
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
28225
28312
|
* line is durable on disk (not once the POST succeeds). */
|
|
28226
28313
|
async enqueue(entry) {
|
|
28227
|
-
await
|
|
28228
|
-
await
|
|
28314
|
+
await fs61.mkdir(path66.dirname(this.filePath), { recursive: true });
|
|
28315
|
+
await fs61.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
28229
28316
|
this.backoffIndex = 0;
|
|
28230
28317
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
28231
28318
|
}
|
|
@@ -28316,7 +28403,7 @@ var FilesOutbox = class {
|
|
|
28316
28403
|
async readAll() {
|
|
28317
28404
|
let raw = "";
|
|
28318
28405
|
try {
|
|
28319
|
-
raw = await
|
|
28406
|
+
raw = await fs61.readFile(this.filePath, "utf8");
|
|
28320
28407
|
} catch {
|
|
28321
28408
|
return [];
|
|
28322
28409
|
}
|
|
@@ -28340,12 +28427,12 @@ var FilesOutbox = class {
|
|
|
28340
28427
|
async rewrite(entries) {
|
|
28341
28428
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
28342
28429
|
if (entries.length === 0) {
|
|
28343
|
-
await
|
|
28430
|
+
await fs61.unlink(this.filePath).catch(() => void 0);
|
|
28344
28431
|
return;
|
|
28345
28432
|
}
|
|
28346
28433
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
28347
|
-
await
|
|
28348
|
-
await
|
|
28434
|
+
await fs61.writeFile(tmpPath, payload, "utf8");
|
|
28435
|
+
await fs61.rename(tmpPath, this.filePath);
|
|
28349
28436
|
}
|
|
28350
28437
|
};
|
|
28351
28438
|
function applyJitter(ms) {
|
|
@@ -29843,6 +29930,7 @@ async function runAcpSession(opts) {
|
|
|
29843
29930
|
adapter: opts.adapter,
|
|
29844
29931
|
cwd: opts.cwd,
|
|
29845
29932
|
extraEnv,
|
|
29933
|
+
mcpServers: opts.mcpServers,
|
|
29846
29934
|
onSessionUpdate: (notification) => {
|
|
29847
29935
|
updateCount += 1;
|
|
29848
29936
|
const variant = notification.update?.sessionUpdate ?? "unknown";
|
|
@@ -31101,6 +31189,43 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
31101
31189
|
});
|
|
31102
31190
|
}
|
|
31103
31191
|
|
|
31192
|
+
// src/integrations/provision.ts
|
|
31193
|
+
function buildMcpServersForStart(ctx) {
|
|
31194
|
+
const manifest = readIntegrationsManifest();
|
|
31195
|
+
if (!manifest || manifest.integrations.length === 0) return [];
|
|
31196
|
+
if (!ctx.pluginAuthToken) {
|
|
31197
|
+
log.warn("integrations", "manifest present but no plugin auth token \u2014 skipping MCP injection");
|
|
31198
|
+
return [];
|
|
31199
|
+
}
|
|
31200
|
+
const servers = [];
|
|
31201
|
+
for (const entry of manifest.integrations) {
|
|
31202
|
+
if (!entry.delivery.mcp) continue;
|
|
31203
|
+
const env = [
|
|
31204
|
+
{ name: "CODEAM_MCP_INTEGRATION_ID", value: entry.id },
|
|
31205
|
+
{ name: "CODEAM_MCP_SESSION_ID", value: ctx.sessionId },
|
|
31206
|
+
{ name: "CODEAM_MCP_PLUGIN_ID", value: ctx.pluginId },
|
|
31207
|
+
// Plugin token in ENV, never argv — argv is visible via `ps`.
|
|
31208
|
+
{ name: "CODEAM_MCP_PLUGIN_TOKEN", value: ctx.pluginAuthToken },
|
|
31209
|
+
...ctx.pollSecret ? [{ name: "CODEAM_MCP_POLL_SECRET", value: ctx.pollSecret }] : []
|
|
31210
|
+
];
|
|
31211
|
+
servers.push({
|
|
31212
|
+
name: entry.id,
|
|
31213
|
+
// Never trust the agent's PATH for the shim binary (beads v2.39.5
|
|
31214
|
+
// lesson) — re-invoke this same Node runtime + CLI entrypoint.
|
|
31215
|
+
command: process.execPath,
|
|
31216
|
+
args: [process.argv[1], "mcp-run", entry.id],
|
|
31217
|
+
env
|
|
31218
|
+
});
|
|
31219
|
+
}
|
|
31220
|
+
if (servers.length) {
|
|
31221
|
+
log.info(
|
|
31222
|
+
"integrations",
|
|
31223
|
+
`injecting ${servers.length} MCP server(s): ${servers.map((s) => s.name).join(", ")}`
|
|
31224
|
+
);
|
|
31225
|
+
}
|
|
31226
|
+
return servers;
|
|
31227
|
+
}
|
|
31228
|
+
|
|
31104
31229
|
// src/baton/baton-controller.ts
|
|
31105
31230
|
var BatonController = class {
|
|
31106
31231
|
constructor(deps) {
|
|
@@ -31450,7 +31575,7 @@ var AcpDriver = class {
|
|
|
31450
31575
|
};
|
|
31451
31576
|
|
|
31452
31577
|
// src/baton/transcript-mirror.ts
|
|
31453
|
-
var
|
|
31578
|
+
var fs62 = __toESM(require("fs"));
|
|
31454
31579
|
var TranscriptMirror = class {
|
|
31455
31580
|
constructor(deps) {
|
|
31456
31581
|
this.deps = deps;
|
|
@@ -31517,7 +31642,7 @@ var TranscriptMirror = class {
|
|
|
31517
31642
|
}
|
|
31518
31643
|
};
|
|
31519
31644
|
function defaultWatch(file, onChange) {
|
|
31520
|
-
const w3 =
|
|
31645
|
+
const w3 = fs62.watch(file, { persistent: false }, () => onChange());
|
|
31521
31646
|
return () => w3.close();
|
|
31522
31647
|
}
|
|
31523
31648
|
|
|
@@ -31617,6 +31742,7 @@ async function runBatonSession(opts) {
|
|
|
31617
31742
|
const client2 = new AcpClient({
|
|
31618
31743
|
adapter: opts.adapter,
|
|
31619
31744
|
cwd: opts.cwd,
|
|
31745
|
+
mcpServers: opts.mcpServers,
|
|
31620
31746
|
onSessionUpdate: (notification) => {
|
|
31621
31747
|
for (const delta of mapSessionUpdate(notification)) streaming.append(delta);
|
|
31622
31748
|
},
|
|
@@ -31647,7 +31773,8 @@ async function runBatonSession(opts) {
|
|
|
31647
31773
|
adapter: opts.adapter,
|
|
31648
31774
|
cwd: opts.cwd,
|
|
31649
31775
|
getBeads: opts.getBeads,
|
|
31650
|
-
pollSecret: opts.pollSecret
|
|
31776
|
+
pollSecret: opts.pollSecret,
|
|
31777
|
+
mcpServers: opts.mcpServers
|
|
31651
31778
|
};
|
|
31652
31779
|
const mobileDriver = new AcpDriver({
|
|
31653
31780
|
client: client2,
|
|
@@ -31769,15 +31896,15 @@ function toEpochMs(ts) {
|
|
|
31769
31896
|
}
|
|
31770
31897
|
|
|
31771
31898
|
// src/agents/claude/onboarding.ts
|
|
31772
|
-
var
|
|
31773
|
-
var
|
|
31774
|
-
var
|
|
31899
|
+
var fs63 = __toESM(require("fs"));
|
|
31900
|
+
var os49 = __toESM(require("os"));
|
|
31901
|
+
var path67 = __toESM(require("path"));
|
|
31775
31902
|
function ensureClaudeOnboarded(cwd) {
|
|
31776
31903
|
try {
|
|
31777
|
-
const file =
|
|
31904
|
+
const file = path67.join(os49.homedir(), ".claude.json");
|
|
31778
31905
|
let config = {};
|
|
31779
31906
|
try {
|
|
31780
|
-
config = JSON.parse(
|
|
31907
|
+
config = JSON.parse(fs63.readFileSync(file, "utf8"));
|
|
31781
31908
|
} catch {
|
|
31782
31909
|
}
|
|
31783
31910
|
let changed = false;
|
|
@@ -31801,8 +31928,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
31801
31928
|
}
|
|
31802
31929
|
}
|
|
31803
31930
|
if (!changed) return;
|
|
31804
|
-
|
|
31805
|
-
|
|
31931
|
+
fs63.mkdirSync(path67.dirname(file), { recursive: true });
|
|
31932
|
+
fs63.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
31806
31933
|
log.info(
|
|
31807
31934
|
"claude",
|
|
31808
31935
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -31907,6 +32034,12 @@ async function start(requestedAgent) {
|
|
|
31907
32034
|
beads = started;
|
|
31908
32035
|
return started;
|
|
31909
32036
|
});
|
|
32037
|
+
const mcpServers = buildMcpServersForStart({
|
|
32038
|
+
sessionId: session.id,
|
|
32039
|
+
pluginId,
|
|
32040
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
32041
|
+
pollSecret: session.pollSecret
|
|
32042
|
+
});
|
|
31910
32043
|
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
31911
32044
|
if (process.env.CODESPACES === "true") {
|
|
31912
32045
|
const GATE_TIMEOUT_MS = 24e4;
|
|
@@ -31942,7 +32075,8 @@ async function start(requestedAgent) {
|
|
|
31942
32075
|
pollSecret: session.pollSecret,
|
|
31943
32076
|
cwd,
|
|
31944
32077
|
adapter,
|
|
31945
|
-
getBeads
|
|
32078
|
+
getBeads,
|
|
32079
|
+
mcpServers
|
|
31946
32080
|
});
|
|
31947
32081
|
return;
|
|
31948
32082
|
}
|
|
@@ -31964,6 +32098,7 @@ async function start(requestedAgent) {
|
|
|
31964
32098
|
cwd,
|
|
31965
32099
|
getBeads,
|
|
31966
32100
|
pollSecret: session.pollSecret,
|
|
32101
|
+
mcpServers,
|
|
31967
32102
|
// AUTO mode for headless, mobile-driven sessions: no human at the box
|
|
31968
32103
|
// to answer permission prompts, so auto-approve them rather than stall
|
|
31969
32104
|
// the turn (the agent-agnostic equivalent of
|
|
@@ -32480,7 +32615,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
32480
32615
|
var import_child_process28 = require("child_process");
|
|
32481
32616
|
var import_util4 = require("util");
|
|
32482
32617
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
32483
|
-
var
|
|
32618
|
+
var path68 = __toESM(require("path"));
|
|
32484
32619
|
var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
|
|
32485
32620
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
32486
32621
|
function resetStdinForChild() {
|
|
@@ -32969,7 +33104,7 @@ var GitHubCodespacesProvider = class {
|
|
|
32969
33104
|
});
|
|
32970
33105
|
}
|
|
32971
33106
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
32972
|
-
const remoteDir =
|
|
33107
|
+
const remoteDir = path68.posix.dirname(remotePath);
|
|
32973
33108
|
const parts = [
|
|
32974
33109
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
32975
33110
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -33039,7 +33174,7 @@ function shellQuote(s) {
|
|
|
33039
33174
|
// src/services/providers/gitpod.ts
|
|
33040
33175
|
var import_child_process29 = require("child_process");
|
|
33041
33176
|
var import_util5 = require("util");
|
|
33042
|
-
var
|
|
33177
|
+
var path69 = __toESM(require("path"));
|
|
33043
33178
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
33044
33179
|
var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
|
|
33045
33180
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -33279,7 +33414,7 @@ var GitpodProvider = class {
|
|
|
33279
33414
|
});
|
|
33280
33415
|
}
|
|
33281
33416
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
33282
|
-
const remoteDir =
|
|
33417
|
+
const remoteDir = path69.posix.dirname(remotePath);
|
|
33283
33418
|
const parts = [
|
|
33284
33419
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
33285
33420
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -33315,7 +33450,7 @@ function shellQuote2(s) {
|
|
|
33315
33450
|
// src/services/providers/gitlab-workspaces.ts
|
|
33316
33451
|
var import_child_process30 = require("child_process");
|
|
33317
33452
|
var import_util6 = require("util");
|
|
33318
|
-
var
|
|
33453
|
+
var path70 = __toESM(require("path"));
|
|
33319
33454
|
var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
|
|
33320
33455
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
33321
33456
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -33575,7 +33710,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
33575
33710
|
}
|
|
33576
33711
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
33577
33712
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
33578
|
-
const remoteDir =
|
|
33713
|
+
const remoteDir = path70.posix.dirname(remotePath);
|
|
33579
33714
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
33580
33715
|
if (options.mode != null) {
|
|
33581
33716
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -33643,7 +33778,7 @@ function shellQuote3(s) {
|
|
|
33643
33778
|
// src/services/providers/railway.ts
|
|
33644
33779
|
var import_child_process31 = require("child_process");
|
|
33645
33780
|
var import_util7 = require("util");
|
|
33646
|
-
var
|
|
33781
|
+
var path71 = __toESM(require("path"));
|
|
33647
33782
|
var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
|
|
33648
33783
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
33649
33784
|
function resetStdinForChild4() {
|
|
@@ -33879,7 +34014,7 @@ var RailwayProvider = class {
|
|
|
33879
34014
|
if (!projectId || !serviceId) {
|
|
33880
34015
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
33881
34016
|
}
|
|
33882
|
-
const remoteDir =
|
|
34017
|
+
const remoteDir = path71.posix.dirname(remotePath);
|
|
33883
34018
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
33884
34019
|
if (options.mode != null) {
|
|
33885
34020
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -34525,8 +34660,8 @@ async function invite() {
|
|
|
34525
34660
|
var import_node_dns = require("dns");
|
|
34526
34661
|
var import_node_util5 = require("util");
|
|
34527
34662
|
var import_node_crypto12 = require("crypto");
|
|
34528
|
-
var
|
|
34529
|
-
var
|
|
34663
|
+
var fs64 = __toESM(require("fs"));
|
|
34664
|
+
var path72 = __toESM(require("path"));
|
|
34530
34665
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
34531
34666
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
34532
34667
|
async function checkDns(apiBase2) {
|
|
@@ -34582,13 +34717,13 @@ async function checkHealth(apiBase2) {
|
|
|
34582
34717
|
}
|
|
34583
34718
|
}
|
|
34584
34719
|
function checkConfigDir() {
|
|
34585
|
-
const dir =
|
|
34720
|
+
const dir = path72.join(require("os").homedir(), ".codeam");
|
|
34586
34721
|
try {
|
|
34587
|
-
|
|
34588
|
-
const probe =
|
|
34589
|
-
|
|
34590
|
-
const read2 =
|
|
34591
|
-
|
|
34722
|
+
fs64.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
34723
|
+
const probe = path72.join(dir, ".doctor-probe");
|
|
34724
|
+
fs64.writeFileSync(probe, "ok", { mode: 384 });
|
|
34725
|
+
const read2 = fs64.readFileSync(probe, "utf8");
|
|
34726
|
+
fs64.unlinkSync(probe);
|
|
34592
34727
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
34593
34728
|
return {
|
|
34594
34729
|
id: "config-dir",
|
|
@@ -34628,9 +34763,9 @@ function checkSessions() {
|
|
|
34628
34763
|
}
|
|
34629
34764
|
}
|
|
34630
34765
|
function checkAgentBinaries() {
|
|
34631
|
-
const
|
|
34766
|
+
const os51 = createOsStrategy();
|
|
34632
34767
|
return getEnabledAgents().map((meta) => {
|
|
34633
|
-
const found =
|
|
34768
|
+
const found = os51.findInPath(meta.binaryName);
|
|
34634
34769
|
return {
|
|
34635
34770
|
id: `agent-${meta.id}`,
|
|
34636
34771
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -34652,7 +34787,7 @@ function checkNodePty() {
|
|
|
34652
34787
|
detail: "not required on this platform"
|
|
34653
34788
|
};
|
|
34654
34789
|
}
|
|
34655
|
-
const vendoredPath =
|
|
34790
|
+
const vendoredPath = path72.join(__dirname, "vendor", "node-pty");
|
|
34656
34791
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
34657
34792
|
try {
|
|
34658
34793
|
require(target);
|
|
@@ -34694,7 +34829,7 @@ function checkChokidar() {
|
|
|
34694
34829
|
}
|
|
34695
34830
|
async function doctor(args2 = []) {
|
|
34696
34831
|
const json = args2.includes("--json");
|
|
34697
|
-
const cliVersion = true ? "2.60.
|
|
34832
|
+
const cliVersion = true ? "2.60.48" : "0.0.0-dev";
|
|
34698
34833
|
const apiBase2 = resolveApiBaseUrl();
|
|
34699
34834
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
34700
34835
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -34890,10 +35025,288 @@ async function completion(args2) {
|
|
|
34890
35025
|
process.stdout.write(script);
|
|
34891
35026
|
}
|
|
34892
35027
|
|
|
35028
|
+
// src/integrations/mcp-run.ts
|
|
35029
|
+
var import_node_child_process28 = require("child_process");
|
|
35030
|
+
|
|
35031
|
+
// src/integrations/token-client.ts
|
|
35032
|
+
var REFRESH_AHEAD_MS = 5 * 60 * 1e3;
|
|
35033
|
+
var IntegrationTokenClient = class {
|
|
35034
|
+
constructor(ctx, fetchImpl = fetch) {
|
|
35035
|
+
this.ctx = ctx;
|
|
35036
|
+
this.fetchImpl = fetchImpl;
|
|
35037
|
+
this.token = ctx.pluginAuthToken;
|
|
35038
|
+
}
|
|
35039
|
+
ctx;
|
|
35040
|
+
fetchImpl;
|
|
35041
|
+
cache = /* @__PURE__ */ new Map();
|
|
35042
|
+
token;
|
|
35043
|
+
/**
|
|
35044
|
+
* Fetch (or return the cached) broker token for `integrationId`.
|
|
35045
|
+
* Throws `Error(<code>)` on a non-retryable / still-failing 4xx-5xx.
|
|
35046
|
+
*/
|
|
35047
|
+
async getToken(integrationId) {
|
|
35048
|
+
const cached2 = this.cache.get(integrationId);
|
|
35049
|
+
if (cached2 && new Date(cached2.expiresAt).getTime() - Date.now() > REFRESH_AHEAD_MS) {
|
|
35050
|
+
return cached2;
|
|
35051
|
+
}
|
|
35052
|
+
const url = `${resolveApiBaseUrl()}/api/plugin/integrations/${encodeURIComponent(integrationId)}/token`;
|
|
35053
|
+
const body = JSON.stringify({ sessionId: this.ctx.sessionId, pluginId: this.ctx.pluginId });
|
|
35054
|
+
const post2 = (tok) => this.fetchImpl(url, {
|
|
35055
|
+
method: "POST",
|
|
35056
|
+
headers: { "Content-Type": "application/json", "X-Plugin-Auth-Token": tok },
|
|
35057
|
+
body
|
|
35058
|
+
});
|
|
35059
|
+
let resp = await post2(this.token);
|
|
35060
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
35061
|
+
const fresh = await fetchCurrentPluginAuthToken(
|
|
35062
|
+
this.ctx.sessionId,
|
|
35063
|
+
this.ctx.pluginId,
|
|
35064
|
+
this.ctx.pollSecret
|
|
35065
|
+
);
|
|
35066
|
+
if (fresh !== null) {
|
|
35067
|
+
this.token = fresh;
|
|
35068
|
+
resp = await post2(fresh);
|
|
35069
|
+
}
|
|
35070
|
+
}
|
|
35071
|
+
if (!resp.ok) {
|
|
35072
|
+
const detail = await resp.text().catch(() => "");
|
|
35073
|
+
throw new Error(`INTEGRATION_TOKEN_FAILED status=${resp.status} ${detail.slice(0, 200)}`.trim());
|
|
35074
|
+
}
|
|
35075
|
+
const parsed = await resp.json();
|
|
35076
|
+
this.cache.set(integrationId, parsed.data);
|
|
35077
|
+
return parsed.data;
|
|
35078
|
+
}
|
|
35079
|
+
};
|
|
35080
|
+
|
|
35081
|
+
// src/integrations/stdio-proxy.ts
|
|
35082
|
+
var import_node_child_process27 = require("child_process");
|
|
35083
|
+
var import_node_readline3 = __toESM(require("readline"));
|
|
35084
|
+
var RESTART_CHECK_INTERVAL_MS = 3e4;
|
|
35085
|
+
var SIGKILL_ESCALATION_MS = 2e3;
|
|
35086
|
+
var REPLAY_INIT_ID = "__codeam_replay_init__";
|
|
35087
|
+
var RestartableStdioProxy = class {
|
|
35088
|
+
constructor(opts) {
|
|
35089
|
+
this.opts = opts;
|
|
35090
|
+
}
|
|
35091
|
+
opts;
|
|
35092
|
+
child = null;
|
|
35093
|
+
childRl = null;
|
|
35094
|
+
initializeLine = null;
|
|
35095
|
+
inflight = /* @__PURE__ */ new Set();
|
|
35096
|
+
swapping = false;
|
|
35097
|
+
pendingClientLines = [];
|
|
35098
|
+
ended = () => void 0;
|
|
35099
|
+
async start() {
|
|
35100
|
+
const stdin = this.opts.stdin ?? process.stdin;
|
|
35101
|
+
const stdout = this.opts.stdout ?? process.stdout;
|
|
35102
|
+
await this.spawnChild(stdout);
|
|
35103
|
+
const rl = import_node_readline3.default.createInterface({ input: stdin, crlfDelay: Infinity });
|
|
35104
|
+
rl.on("line", (line) => this.onClientLine(line));
|
|
35105
|
+
rl.on("close", () => this.child?.stdin?.end());
|
|
35106
|
+
const timer = setInterval(() => this.checkRestart(stdout), RESTART_CHECK_INTERVAL_MS);
|
|
35107
|
+
timer.unref();
|
|
35108
|
+
return new Promise((resolve7) => {
|
|
35109
|
+
this.ended = (code) => {
|
|
35110
|
+
clearInterval(timer);
|
|
35111
|
+
process.exitCode = code;
|
|
35112
|
+
resolve7();
|
|
35113
|
+
};
|
|
35114
|
+
});
|
|
35115
|
+
}
|
|
35116
|
+
onClientLine(line) {
|
|
35117
|
+
if (this.swapping) {
|
|
35118
|
+
this.pendingClientLines.push(line);
|
|
35119
|
+
return;
|
|
35120
|
+
}
|
|
35121
|
+
try {
|
|
35122
|
+
const msg = JSON.parse(line);
|
|
35123
|
+
if (msg.method === "initialize" && this.initializeLine === null) {
|
|
35124
|
+
this.initializeLine = line;
|
|
35125
|
+
}
|
|
35126
|
+
if (msg.method === "notifications/cancelled") {
|
|
35127
|
+
const requestId = msg.params?.requestId;
|
|
35128
|
+
if (requestId !== void 0) this.inflight.delete(requestId);
|
|
35129
|
+
}
|
|
35130
|
+
if (msg.id !== void 0 && msg.method !== void 0) this.inflight.add(msg.id);
|
|
35131
|
+
} catch {
|
|
35132
|
+
}
|
|
35133
|
+
this.child?.stdin?.write(line + "\n");
|
|
35134
|
+
}
|
|
35135
|
+
onChildLine(line, stdout) {
|
|
35136
|
+
try {
|
|
35137
|
+
const msg = JSON.parse(line);
|
|
35138
|
+
if (msg.id !== void 0 && msg.method === void 0) {
|
|
35139
|
+
if (msg.id === REPLAY_INIT_ID) {
|
|
35140
|
+
return;
|
|
35141
|
+
}
|
|
35142
|
+
this.inflight.delete(msg.id);
|
|
35143
|
+
}
|
|
35144
|
+
} catch {
|
|
35145
|
+
}
|
|
35146
|
+
stdout.write(line + "\n");
|
|
35147
|
+
if (this.inflight.size === 0) this.checkRestart(stdout);
|
|
35148
|
+
}
|
|
35149
|
+
/**
|
|
35150
|
+
* Failsafe wrapper for the fire-and-forget call sites (post-response check
|
|
35151
|
+
* + the 30 s timer): `maybeRestart` handles the token-fetch failure itself,
|
|
35152
|
+
* but nothing that escapes it may become an unhandled rejection — that
|
|
35153
|
+
* would kill the whole shim process.
|
|
35154
|
+
*/
|
|
35155
|
+
checkRestart(stdout) {
|
|
35156
|
+
this.maybeRestart(stdout).catch((err) => {
|
|
35157
|
+
process.stderr.write(
|
|
35158
|
+
`[codeam mcp-run] restart check failed (will retry): ${err instanceof Error ? err.message : String(err)}
|
|
35159
|
+
`
|
|
35160
|
+
);
|
|
35161
|
+
});
|
|
35162
|
+
}
|
|
35163
|
+
async maybeRestart(stdout) {
|
|
35164
|
+
if (this.swapping || !this.opts.shouldRestartNow()) return;
|
|
35165
|
+
if (this.inflight.size > 0 || this.initializeLine === null || !this.child) return;
|
|
35166
|
+
this.swapping = true;
|
|
35167
|
+
let spec;
|
|
35168
|
+
try {
|
|
35169
|
+
spec = await this.opts.spawnSpec();
|
|
35170
|
+
} catch (err) {
|
|
35171
|
+
process.stderr.write(
|
|
35172
|
+
`[codeam mcp-run] token refresh failed, keeping current server (will retry): ${err instanceof Error ? err.message : String(err)}
|
|
35173
|
+
`
|
|
35174
|
+
);
|
|
35175
|
+
this.swapping = false;
|
|
35176
|
+
for (const l of this.pendingClientLines.splice(0)) this.onClientLine(l);
|
|
35177
|
+
return;
|
|
35178
|
+
}
|
|
35179
|
+
const old = this.child;
|
|
35180
|
+
const oldRl = this.childRl;
|
|
35181
|
+
this.child = null;
|
|
35182
|
+
this.childRl = null;
|
|
35183
|
+
oldRl?.close();
|
|
35184
|
+
old.kill("SIGTERM");
|
|
35185
|
+
const escalation = setTimeout(() => {
|
|
35186
|
+
if (!old.killed || old.exitCode === null) old.kill("SIGKILL");
|
|
35187
|
+
}, SIGKILL_ESCALATION_MS);
|
|
35188
|
+
escalation.unref();
|
|
35189
|
+
try {
|
|
35190
|
+
await this.spawnChild(stdout, spec);
|
|
35191
|
+
const replayed = JSON.parse(this.initializeLine);
|
|
35192
|
+
this.child.stdin.write(JSON.stringify({ ...replayed, id: REPLAY_INIT_ID }) + "\n");
|
|
35193
|
+
this.child.stdin.write(
|
|
35194
|
+
JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }) + "\n"
|
|
35195
|
+
);
|
|
35196
|
+
} finally {
|
|
35197
|
+
this.swapping = false;
|
|
35198
|
+
for (const l of this.pendingClientLines.splice(0)) this.onClientLine(l);
|
|
35199
|
+
}
|
|
35200
|
+
}
|
|
35201
|
+
async spawnChild(stdout, preResolved) {
|
|
35202
|
+
const spec = preResolved ?? await this.opts.spawnSpec();
|
|
35203
|
+
const spawn41 = this.opts.spawnImpl ?? import_node_child_process27.spawn;
|
|
35204
|
+
const child = spawn41(spec.command, spec.args, {
|
|
35205
|
+
env: { ...process.env, ...spec.env },
|
|
35206
|
+
// env only — never argv
|
|
35207
|
+
stdio: ["pipe", "pipe", "inherit"]
|
|
35208
|
+
});
|
|
35209
|
+
this.child = child;
|
|
35210
|
+
child.stdin?.on("error", () => void 0);
|
|
35211
|
+
const rl = import_node_readline3.default.createInterface({ input: child.stdout, crlfDelay: Infinity });
|
|
35212
|
+
this.childRl = rl;
|
|
35213
|
+
rl.on("line", (line) => {
|
|
35214
|
+
if (child !== this.child) return;
|
|
35215
|
+
this.onChildLine(line, stdout);
|
|
35216
|
+
});
|
|
35217
|
+
child.on("exit", (code) => {
|
|
35218
|
+
if (child !== this.child) return;
|
|
35219
|
+
this.ended(code ?? 1);
|
|
35220
|
+
});
|
|
35221
|
+
}
|
|
35222
|
+
};
|
|
35223
|
+
|
|
35224
|
+
// src/integrations/mcp-run.ts
|
|
35225
|
+
var RESTART_AHEAD_MS = 5 * 60 * 1e3;
|
|
35226
|
+
function resolveDelivery(id) {
|
|
35227
|
+
const fromRegistry = isKnownIntegrationId(id) ? getIntegration(id).delivery.mcp ?? null : null;
|
|
35228
|
+
const fromManifest = readIntegrationsManifest()?.integrations.find((e) => e.id === id)?.delivery.mcp;
|
|
35229
|
+
if (fromManifest) {
|
|
35230
|
+
if (fromRegistry?.staticEnv) {
|
|
35231
|
+
return {
|
|
35232
|
+
...fromManifest,
|
|
35233
|
+
staticEnv: { ...fromRegistry.staticEnv, ...fromManifest.staticEnv }
|
|
35234
|
+
};
|
|
35235
|
+
}
|
|
35236
|
+
return fromManifest;
|
|
35237
|
+
}
|
|
35238
|
+
return fromRegistry;
|
|
35239
|
+
}
|
|
35240
|
+
function commandExists(command2) {
|
|
35241
|
+
try {
|
|
35242
|
+
const probe = process.platform === "win32" ? "where" : "which";
|
|
35243
|
+
(0, import_node_child_process28.execFileSync)(probe, [command2], { stdio: "ignore" });
|
|
35244
|
+
return true;
|
|
35245
|
+
} catch {
|
|
35246
|
+
return false;
|
|
35247
|
+
}
|
|
35248
|
+
}
|
|
35249
|
+
function ensureCommand(command2) {
|
|
35250
|
+
if (commandExists(command2)) return;
|
|
35251
|
+
if (process.platform === "win32") {
|
|
35252
|
+
process.stderr.write(
|
|
35253
|
+
`[codeam mcp-run] '${command2}' not found on PATH \u2014 install it and retry.
|
|
35254
|
+
`
|
|
35255
|
+
);
|
|
35256
|
+
return;
|
|
35257
|
+
}
|
|
35258
|
+
if (command2 === "uvx") {
|
|
35259
|
+
try {
|
|
35260
|
+
(0, import_node_child_process28.execSync)("python3 -m pip install --user --quiet uv", {
|
|
35261
|
+
stdio: ["ignore", process.stderr, process.stderr],
|
|
35262
|
+
timeout: 18e4
|
|
35263
|
+
});
|
|
35264
|
+
} catch {
|
|
35265
|
+
}
|
|
35266
|
+
}
|
|
35267
|
+
}
|
|
35268
|
+
async function mcpRun(args2) {
|
|
35269
|
+
const id = args2[0] ?? process.env.CODEAM_MCP_INTEGRATION_ID;
|
|
35270
|
+
const sessionId = process.env.CODEAM_MCP_SESSION_ID;
|
|
35271
|
+
const pluginId = process.env.CODEAM_MCP_PLUGIN_ID;
|
|
35272
|
+
const pluginAuthToken = process.env.CODEAM_MCP_PLUGIN_TOKEN;
|
|
35273
|
+
if (!id || !sessionId || !pluginId || !pluginAuthToken) {
|
|
35274
|
+
process.stderr.write("[codeam mcp-run] missing integration id or session credentials in env\n");
|
|
35275
|
+
process.exit(1);
|
|
35276
|
+
}
|
|
35277
|
+
const delivery = resolveDelivery(id);
|
|
35278
|
+
if (!delivery) {
|
|
35279
|
+
process.stderr.write(`[codeam mcp-run] no mcp delivery for '${id}'
|
|
35280
|
+
`);
|
|
35281
|
+
process.exit(1);
|
|
35282
|
+
}
|
|
35283
|
+
ensureCommand(delivery.command);
|
|
35284
|
+
const client2 = new IntegrationTokenClient({
|
|
35285
|
+
sessionId,
|
|
35286
|
+
pluginId,
|
|
35287
|
+
pluginAuthToken,
|
|
35288
|
+
pollSecret: process.env.CODEAM_MCP_POLL_SECRET
|
|
35289
|
+
});
|
|
35290
|
+
let current = null;
|
|
35291
|
+
const proxy = new RestartableStdioProxy({
|
|
35292
|
+
spawnSpec: async () => {
|
|
35293
|
+
current = await client2.getToken(id);
|
|
35294
|
+
const env = { ...delivery.staticEnv };
|
|
35295
|
+
for (const [envVar, field] of Object.entries(delivery.envMapping)) {
|
|
35296
|
+
const value = current[field];
|
|
35297
|
+
if (typeof value === "string" && value) env[envVar] = value;
|
|
35298
|
+
}
|
|
35299
|
+
return { command: delivery.command, args: delivery.args, env };
|
|
35300
|
+
},
|
|
35301
|
+
shouldRestartNow: () => current !== null && new Date(current.expiresAt).getTime() - Date.now() < RESTART_AHEAD_MS
|
|
35302
|
+
});
|
|
35303
|
+
await proxy.start();
|
|
35304
|
+
}
|
|
35305
|
+
|
|
34893
35306
|
// src/commands/version.ts
|
|
34894
35307
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
34895
35308
|
function version2() {
|
|
34896
|
-
const v = true ? "2.60.
|
|
35309
|
+
const v = true ? "2.60.48" : "unknown";
|
|
34897
35310
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
34898
35311
|
}
|
|
34899
35312
|
|
|
@@ -35042,10 +35455,10 @@ var EXIT_CODE_NAMES = {
|
|
|
35042
35455
|
};
|
|
35043
35456
|
|
|
35044
35457
|
// src/index.ts
|
|
35045
|
-
var
|
|
35458
|
+
var os50 = __toESM(require("os"));
|
|
35046
35459
|
if (!process.env.HOME) {
|
|
35047
35460
|
try {
|
|
35048
|
-
const home =
|
|
35461
|
+
const home = os50.homedir();
|
|
35049
35462
|
if (home) process.env.HOME = home;
|
|
35050
35463
|
} catch {
|
|
35051
35464
|
}
|
|
@@ -35091,6 +35504,9 @@ async function main() {
|
|
|
35091
35504
|
await commands[command]();
|
|
35092
35505
|
return;
|
|
35093
35506
|
}
|
|
35507
|
+
if (command === "mcp-run") {
|
|
35508
|
+
return mcpRun(args);
|
|
35509
|
+
}
|
|
35094
35510
|
if (command === "deploy") {
|
|
35095
35511
|
if (args[0] === "ls" || args[0] === "list") return deployList();
|
|
35096
35512
|
if (args[0] === "stop" || args[0] === "remove") return deployStop();
|