codeam-cli 2.60.45 → 2.60.47
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 +12 -0
- package/dist/index.js +838 -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";
|
|
@@ -592,6 +633,9 @@ var USER_EVENTS = {
|
|
|
592
633
|
CLI_UPDATE_PROGRESS: "cli_update_progress",
|
|
593
634
|
CLI_UPDATE_FAILED: "cli_update_failed",
|
|
594
635
|
BATON_STATE: "baton_state",
|
|
636
|
+
INTEGRATION_LINKED: "integration_linked",
|
|
637
|
+
INTEGRATION_UNLINKED: "integration_unlinked",
|
|
638
|
+
INTEGRATION_CREDENTIAL_INVALID: "integration_credential_invalid",
|
|
595
639
|
// CodeRabbit reviewer — the CLI posts these to /api/coderabbit/events; the
|
|
596
640
|
// backend re-publishes them on the per-user SSE bus (mirrored in repo A).
|
|
597
641
|
CODERABBIT_PROGRESS: "coderabbit_progress",
|
|
@@ -787,11 +831,11 @@ function quiet(fn) {
|
|
|
787
831
|
log.debug(TAG, "ignored sync error", err);
|
|
788
832
|
}
|
|
789
833
|
}
|
|
790
|
-
function rmIfExistsQuiet(
|
|
834
|
+
function rmIfExistsQuiet(path73) {
|
|
791
835
|
try {
|
|
792
|
-
fs2.rmSync(
|
|
836
|
+
fs2.rmSync(path73, { force: true });
|
|
793
837
|
} catch (err) {
|
|
794
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
838
|
+
log.debug(TAG, `rmIfExists failed for ${path73}`, err);
|
|
795
839
|
}
|
|
796
840
|
}
|
|
797
841
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -937,9 +981,9 @@ var _default = makeConfig();
|
|
|
937
981
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
938
982
|
|
|
939
983
|
// src/commands/pair-auto.ts
|
|
940
|
-
var
|
|
941
|
-
var
|
|
942
|
-
var
|
|
984
|
+
var fs55 = __toESM(require("fs"));
|
|
985
|
+
var os44 = __toESM(require("os"));
|
|
986
|
+
var path59 = __toESM(require("path"));
|
|
943
987
|
var import_crypto4 = require("crypto");
|
|
944
988
|
|
|
945
989
|
// src/services/telemetry.service.ts
|
|
@@ -975,8 +1019,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
975
1019
|
return decodedFile;
|
|
976
1020
|
};
|
|
977
1021
|
}
|
|
978
|
-
function normalizeWindowsPath(
|
|
979
|
-
return
|
|
1022
|
+
function normalizeWindowsPath(path73) {
|
|
1023
|
+
return path73.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
980
1024
|
}
|
|
981
1025
|
|
|
982
1026
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3456,9 +3500,9 @@ async function addSourceContext(frames) {
|
|
|
3456
3500
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3457
3501
|
return frames;
|
|
3458
3502
|
}
|
|
3459
|
-
function getContextLinesFromFile(
|
|
3503
|
+
function getContextLinesFromFile(path73, ranges, output) {
|
|
3460
3504
|
return new Promise((resolve7) => {
|
|
3461
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3505
|
+
const stream = (0, import_node_fs.createReadStream)(path73);
|
|
3462
3506
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3463
3507
|
input: stream
|
|
3464
3508
|
});
|
|
@@ -3473,7 +3517,7 @@ function getContextLinesFromFile(path72, ranges, output) {
|
|
|
3473
3517
|
let rangeStart = range[0];
|
|
3474
3518
|
let rangeEnd = range[1];
|
|
3475
3519
|
function onStreamError() {
|
|
3476
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3520
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path73, 1);
|
|
3477
3521
|
lineReaded.close();
|
|
3478
3522
|
lineReaded.removeAllListeners();
|
|
3479
3523
|
destroyStreamAndResolve();
|
|
@@ -3534,8 +3578,8 @@ function clearLineContext(frame) {
|
|
|
3534
3578
|
delete frame.context_line;
|
|
3535
3579
|
delete frame.post_context;
|
|
3536
3580
|
}
|
|
3537
|
-
function shouldSkipContextLinesForFile(
|
|
3538
|
-
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:");
|
|
3539
3583
|
}
|
|
3540
3584
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3541
3585
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5689,7 +5733,7 @@ function readAnonId() {
|
|
|
5689
5733
|
}
|
|
5690
5734
|
function superProperties() {
|
|
5691
5735
|
return {
|
|
5692
|
-
cliVersion: true ? "2.60.
|
|
5736
|
+
cliVersion: true ? "2.60.47" : "0.0.0-dev",
|
|
5693
5737
|
nodeVersion: process.version,
|
|
5694
5738
|
platform: process.platform,
|
|
5695
5739
|
arch: process.arch,
|
|
@@ -5870,7 +5914,7 @@ var os4 = __toESM(require("os"));
|
|
|
5870
5914
|
// package.json
|
|
5871
5915
|
var package_default = {
|
|
5872
5916
|
name: "codeam-cli",
|
|
5873
|
-
version: "2.60.
|
|
5917
|
+
version: "2.60.47",
|
|
5874
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.",
|
|
5875
5919
|
type: "commonjs",
|
|
5876
5920
|
main: "dist/index.js",
|
|
@@ -6979,7 +7023,7 @@ var CommandRelayService = class {
|
|
|
6979
7023
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6980
7024
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6981
7025
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6982
|
-
..."2.60.
|
|
7026
|
+
..."2.60.47" ? { ideVersion: "2.60.47" } : {}
|
|
6983
7027
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6984
7028
|
}
|
|
6985
7029
|
/**
|
|
@@ -8353,9 +8397,9 @@ function closeAllTerminals() {
|
|
|
8353
8397
|
}
|
|
8354
8398
|
|
|
8355
8399
|
// src/commands/start/handlers.ts
|
|
8356
|
-
var
|
|
8357
|
-
var
|
|
8358
|
-
var
|
|
8400
|
+
var fs54 = __toESM(require("fs"));
|
|
8401
|
+
var os43 = __toESM(require("os"));
|
|
8402
|
+
var path58 = __toESM(require("path"));
|
|
8359
8403
|
var import_crypto3 = require("crypto");
|
|
8360
8404
|
var import_child_process23 = require("child_process");
|
|
8361
8405
|
|
|
@@ -11812,10 +11856,10 @@ function buildForPlatform(platform3) {
|
|
|
11812
11856
|
var import_node_crypto4 = require("crypto");
|
|
11813
11857
|
|
|
11814
11858
|
// src/agents/claude/resolver.ts
|
|
11815
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11816
|
-
const found =
|
|
11859
|
+
function buildClaudeLaunch(extraArgs = [], os51 = createOsStrategy()) {
|
|
11860
|
+
const found = os51.findInPath("claude") ?? os51.findInPath("claude-code");
|
|
11817
11861
|
if (!found) return null;
|
|
11818
|
-
return
|
|
11862
|
+
return os51.buildLaunch(found, extraArgs);
|
|
11819
11863
|
}
|
|
11820
11864
|
|
|
11821
11865
|
// src/agents/claude/installer.ts
|
|
@@ -12405,8 +12449,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
12405
12449
|
meta = getAgent("claude");
|
|
12406
12450
|
mode = "interactive";
|
|
12407
12451
|
os;
|
|
12408
|
-
constructor(
|
|
12409
|
-
this.os =
|
|
12452
|
+
constructor(os51) {
|
|
12453
|
+
this.os = os51;
|
|
12410
12454
|
}
|
|
12411
12455
|
/**
|
|
12412
12456
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -13186,8 +13230,8 @@ function codexCredentialLocator() {
|
|
|
13186
13230
|
function codexLoginLauncher() {
|
|
13187
13231
|
return {
|
|
13188
13232
|
async ensureInstalled() {
|
|
13189
|
-
const
|
|
13190
|
-
return
|
|
13233
|
+
const os51 = createOsStrategy();
|
|
13234
|
+
return os51.findInPath("codex") !== null;
|
|
13191
13235
|
},
|
|
13192
13236
|
launch() {
|
|
13193
13237
|
return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -13210,8 +13254,8 @@ var CodexRuntimeStrategy = class {
|
|
|
13210
13254
|
meta = getAgent("codex");
|
|
13211
13255
|
mode = "interactive";
|
|
13212
13256
|
os;
|
|
13213
|
-
constructor(
|
|
13214
|
-
this.os =
|
|
13257
|
+
constructor(os51) {
|
|
13258
|
+
this.os = os51;
|
|
13215
13259
|
}
|
|
13216
13260
|
async prepareLaunch() {
|
|
13217
13261
|
let binary = this.os.findInPath("codex");
|
|
@@ -13320,12 +13364,12 @@ var CodexRuntimeStrategy = class {
|
|
|
13320
13364
|
});
|
|
13321
13365
|
}
|
|
13322
13366
|
};
|
|
13323
|
-
function resolveNpm(
|
|
13324
|
-
return
|
|
13367
|
+
function resolveNpm(os51) {
|
|
13368
|
+
return os51.id === "win32" ? "npm.cmd" : "npm";
|
|
13325
13369
|
}
|
|
13326
|
-
async function installCodexViaNpm(
|
|
13370
|
+
async function installCodexViaNpm(os51) {
|
|
13327
13371
|
return new Promise((resolve7, reject) => {
|
|
13328
|
-
const proc = (0, import_node_child_process5.spawn)(resolveNpm(
|
|
13372
|
+
const proc = (0, import_node_child_process5.spawn)(resolveNpm(os51), ["install", "-g", "@openai/codex"], {
|
|
13329
13373
|
stdio: "inherit"
|
|
13330
13374
|
});
|
|
13331
13375
|
proc.on("close", (code) => {
|
|
@@ -13342,16 +13386,16 @@ async function installCodexViaNpm(os50) {
|
|
|
13342
13386
|
});
|
|
13343
13387
|
});
|
|
13344
13388
|
}
|
|
13345
|
-
function augmentNpmGlobalBin(
|
|
13389
|
+
function augmentNpmGlobalBin(os51) {
|
|
13346
13390
|
try {
|
|
13347
|
-
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(
|
|
13391
|
+
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os51), ["prefix", "-g"], {
|
|
13348
13392
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13349
13393
|
});
|
|
13350
13394
|
if (result.status !== 0) return;
|
|
13351
13395
|
const prefix = result.stdout.toString().trim();
|
|
13352
13396
|
if (!prefix) return;
|
|
13353
|
-
const binDir =
|
|
13354
|
-
|
|
13397
|
+
const binDir = os51.id === "win32" ? prefix : path24.join(prefix, "bin");
|
|
13398
|
+
os51.augmentPath([binDir]);
|
|
13355
13399
|
} catch {
|
|
13356
13400
|
}
|
|
13357
13401
|
}
|
|
@@ -13435,9 +13479,9 @@ var import_node_child_process8 = require("child_process");
|
|
|
13435
13479
|
// src/agents/coderabbit/installer.ts
|
|
13436
13480
|
var import_node_child_process6 = require("child_process");
|
|
13437
13481
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
13438
|
-
async function ensureCoderabbitInstalled(
|
|
13439
|
-
if (
|
|
13440
|
-
if (
|
|
13482
|
+
async function ensureCoderabbitInstalled(os51) {
|
|
13483
|
+
if (os51.findInPath("coderabbit")) return true;
|
|
13484
|
+
if (os51.id === "win32") {
|
|
13441
13485
|
console.error(
|
|
13442
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"
|
|
13443
13487
|
);
|
|
@@ -13452,8 +13496,8 @@ async function ensureCoderabbitInstalled(os50) {
|
|
|
13452
13496
|
proc.on("error", () => resolve7(false));
|
|
13453
13497
|
});
|
|
13454
13498
|
if (!ok) return false;
|
|
13455
|
-
|
|
13456
|
-
return
|
|
13499
|
+
os51.augmentPath([`${os51.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
13500
|
+
return os51.findInPath("coderabbit") !== null;
|
|
13457
13501
|
}
|
|
13458
13502
|
|
|
13459
13503
|
// src/agents/coderabbit/link.ts
|
|
@@ -13488,10 +13532,10 @@ function coderabbitCredentialLocator() {
|
|
|
13488
13532
|
validate: validateNonEmptyCredential
|
|
13489
13533
|
};
|
|
13490
13534
|
}
|
|
13491
|
-
function coderabbitLoginLauncher(
|
|
13535
|
+
function coderabbitLoginLauncher(os51) {
|
|
13492
13536
|
return {
|
|
13493
13537
|
async ensureInstalled() {
|
|
13494
|
-
return ensureCoderabbitInstalled(
|
|
13538
|
+
return ensureCoderabbitInstalled(os51);
|
|
13495
13539
|
},
|
|
13496
13540
|
launch() {
|
|
13497
13541
|
return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13547,8 +13591,8 @@ function pickLine(obj) {
|
|
|
13547
13591
|
function toHunk(raw, groupSeverity) {
|
|
13548
13592
|
if (!raw || typeof raw !== "object") return null;
|
|
13549
13593
|
const o = raw;
|
|
13550
|
-
const
|
|
13551
|
-
if (!
|
|
13594
|
+
const path73 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
13595
|
+
if (!path73) return null;
|
|
13552
13596
|
const message = asString(
|
|
13553
13597
|
pick(o, [
|
|
13554
13598
|
"comment",
|
|
@@ -13565,7 +13609,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
13565
13609
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
13566
13610
|
const locObj = pick(o, ["location"]) ?? o;
|
|
13567
13611
|
return {
|
|
13568
|
-
path:
|
|
13612
|
+
path: path73.trim(),
|
|
13569
13613
|
line: pickLine(o) ?? pickLine(locObj),
|
|
13570
13614
|
severity,
|
|
13571
13615
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -13648,10 +13692,10 @@ function parsePlain(stdout) {
|
|
|
13648
13692
|
for (const line of stdout.split(/\r?\n/)) {
|
|
13649
13693
|
const m = line.match(HUNK_LINE_RE);
|
|
13650
13694
|
if (!m) continue;
|
|
13651
|
-
const [,
|
|
13652
|
-
if (!
|
|
13695
|
+
const [, path73, lineNo, sevToken, message] = m;
|
|
13696
|
+
if (!path73 || !lineNo || !message) continue;
|
|
13653
13697
|
hunks.push({
|
|
13654
|
-
path:
|
|
13698
|
+
path: path73.trim(),
|
|
13655
13699
|
line: Number(lineNo),
|
|
13656
13700
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
13657
13701
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -13711,8 +13755,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13711
13755
|
meta = getAgent("coderabbit");
|
|
13712
13756
|
mode = "batch";
|
|
13713
13757
|
os;
|
|
13714
|
-
constructor(
|
|
13715
|
-
this.os =
|
|
13758
|
+
constructor(os51) {
|
|
13759
|
+
this.os = os51;
|
|
13716
13760
|
}
|
|
13717
13761
|
getDefaultArgs() {
|
|
13718
13762
|
return ["review", "--agent"];
|
|
@@ -13983,10 +14027,10 @@ function cursorCredentialLocator() {
|
|
|
13983
14027
|
validate: validateNonEmptyCredential
|
|
13984
14028
|
};
|
|
13985
14029
|
}
|
|
13986
|
-
function cursorLoginLauncher(
|
|
14030
|
+
function cursorLoginLauncher(os51) {
|
|
13987
14031
|
return {
|
|
13988
14032
|
async ensureInstalled() {
|
|
13989
|
-
if (
|
|
14033
|
+
if (os51.findInPath("cursor-agent")) return true;
|
|
13990
14034
|
console.error(
|
|
13991
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"
|
|
13992
14036
|
);
|
|
@@ -14050,8 +14094,8 @@ var CursorRuntimeStrategy = class {
|
|
|
14050
14094
|
meta = getAgent("cursor");
|
|
14051
14095
|
mode = "interactive";
|
|
14052
14096
|
os;
|
|
14053
|
-
constructor(
|
|
14054
|
-
this.os =
|
|
14097
|
+
constructor(os51) {
|
|
14098
|
+
this.os = os51;
|
|
14055
14099
|
}
|
|
14056
14100
|
async prepareLaunch() {
|
|
14057
14101
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -14267,10 +14311,10 @@ function aiderCredentialLocator() {
|
|
|
14267
14311
|
validate: validateNonEmptyCredential
|
|
14268
14312
|
};
|
|
14269
14313
|
}
|
|
14270
|
-
function aiderLoginLauncher(
|
|
14314
|
+
function aiderLoginLauncher(os51) {
|
|
14271
14315
|
return {
|
|
14272
14316
|
async ensureInstalled() {
|
|
14273
|
-
if (
|
|
14317
|
+
if (os51.findInPath("aider")) return true;
|
|
14274
14318
|
console.error(
|
|
14275
14319
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
14276
14320
|
);
|
|
@@ -14280,7 +14324,7 @@ function aiderLoginLauncher(os50) {
|
|
|
14280
14324
|
console.error(
|
|
14281
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"
|
|
14282
14326
|
);
|
|
14283
|
-
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"], {
|
|
14284
14328
|
stdio: "ignore"
|
|
14285
14329
|
});
|
|
14286
14330
|
}
|
|
@@ -14352,8 +14396,8 @@ var AiderRuntimeStrategy = class {
|
|
|
14352
14396
|
meta = getAgent("aider");
|
|
14353
14397
|
mode = "interactive";
|
|
14354
14398
|
os;
|
|
14355
|
-
constructor(
|
|
14356
|
-
this.os =
|
|
14399
|
+
constructor(os51) {
|
|
14400
|
+
this.os = os51;
|
|
14357
14401
|
}
|
|
14358
14402
|
async prepareLaunch() {
|
|
14359
14403
|
const binary = this.os.findInPath("aider");
|
|
@@ -14485,8 +14529,8 @@ function geminiCredentialLocator() {
|
|
|
14485
14529
|
function geminiLoginLauncher() {
|
|
14486
14530
|
return {
|
|
14487
14531
|
async ensureInstalled() {
|
|
14488
|
-
const
|
|
14489
|
-
return
|
|
14532
|
+
const os51 = createOsStrategy();
|
|
14533
|
+
return os51.findInPath("gemini") !== null;
|
|
14490
14534
|
},
|
|
14491
14535
|
launch() {
|
|
14492
14536
|
return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -14676,8 +14720,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
14676
14720
|
meta = getAgent("gemini");
|
|
14677
14721
|
mode = "interactive";
|
|
14678
14722
|
os;
|
|
14679
|
-
constructor(
|
|
14680
|
-
this.os =
|
|
14723
|
+
constructor(os51) {
|
|
14724
|
+
this.os = os51;
|
|
14681
14725
|
}
|
|
14682
14726
|
async prepareLaunch() {
|
|
14683
14727
|
const binary = this.os.findInPath("gemini");
|
|
@@ -14968,8 +15012,8 @@ var KimiRuntimeStrategy = class {
|
|
|
14968
15012
|
meta = getAgent("kimi");
|
|
14969
15013
|
mode = "interactive";
|
|
14970
15014
|
os;
|
|
14971
|
-
constructor(
|
|
14972
|
-
this.os =
|
|
15015
|
+
constructor(os51) {
|
|
15016
|
+
this.os = os51;
|
|
14973
15017
|
}
|
|
14974
15018
|
async prepareLaunch() {
|
|
14975
15019
|
const binary = this.os.findInPath("kimi");
|
|
@@ -15082,19 +15126,19 @@ var KimiRuntimeStrategy = class {
|
|
|
15082
15126
|
|
|
15083
15127
|
// src/agents/registry.ts
|
|
15084
15128
|
var runtimeBuilders = {
|
|
15085
|
-
claude: (
|
|
15086
|
-
codex: (
|
|
15087
|
-
coderabbit: (
|
|
15088
|
-
cursor: (
|
|
15089
|
-
aider: (
|
|
15090
|
-
gemini: (
|
|
15091
|
-
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)
|
|
15092
15136
|
};
|
|
15093
15137
|
var deployBuilders = {
|
|
15094
15138
|
claude: () => new ClaudeDeployStrategy(),
|
|
15095
15139
|
codex: () => new CodexDeployStrategy()
|
|
15096
15140
|
};
|
|
15097
|
-
function createAgentStrategy(agent,
|
|
15141
|
+
function createAgentStrategy(agent, os51 = createOsStrategy()) {
|
|
15098
15142
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
15099
15143
|
throw new Error(
|
|
15100
15144
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -15104,10 +15148,10 @@ function createAgentStrategy(agent, os50 = createOsStrategy()) {
|
|
|
15104
15148
|
if (!build) {
|
|
15105
15149
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
15106
15150
|
}
|
|
15107
|
-
return build(
|
|
15151
|
+
return build(os51);
|
|
15108
15152
|
}
|
|
15109
|
-
function createInteractiveAgentStrategy(agent,
|
|
15110
|
-
const s = createAgentStrategy(agent,
|
|
15153
|
+
function createInteractiveAgentStrategy(agent, os51 = createOsStrategy()) {
|
|
15154
|
+
const s = createAgentStrategy(agent, os51);
|
|
15111
15155
|
if (s.mode !== "interactive") {
|
|
15112
15156
|
throw new Error(
|
|
15113
15157
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -15799,26 +15843,26 @@ function restoreCoderabbitOauthBlob(value) {
|
|
|
15799
15843
|
(0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
|
|
15800
15844
|
}
|
|
15801
15845
|
async function configureCoderabbit(input, deps = {}) {
|
|
15802
|
-
const
|
|
15846
|
+
const os51 = deps.os ?? createOsStrategy();
|
|
15803
15847
|
const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
|
|
15804
15848
|
const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
|
|
15805
15849
|
const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
|
|
15806
15850
|
const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
|
|
15807
15851
|
const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
|
|
15808
15852
|
const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
|
|
15809
|
-
const home =
|
|
15810
|
-
|
|
15811
|
-
|
|
15853
|
+
const home = os51.homeDir();
|
|
15854
|
+
os51.augmentPath(
|
|
15855
|
+
os51.id === "win32" ? [
|
|
15812
15856
|
path36.join(home, ".local", "bin"),
|
|
15813
15857
|
path36.join(process.env.APPDATA ?? path36.join(home, "AppData", "Roaming"), "npm"),
|
|
15814
15858
|
path36.join(home, "scoop", "shims")
|
|
15815
15859
|
] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
15816
15860
|
);
|
|
15817
|
-
const installed2 =
|
|
15861
|
+
const installed2 = os51.findInPath("coderabbit") !== null;
|
|
15818
15862
|
const base = () => ({
|
|
15819
15863
|
action: input.action,
|
|
15820
15864
|
supported: true,
|
|
15821
|
-
installed:
|
|
15865
|
+
installed: os51.findInPath("coderabbit") !== null,
|
|
15822
15866
|
loggedIn: false
|
|
15823
15867
|
});
|
|
15824
15868
|
if (input.action === "status") {
|
|
@@ -15832,7 +15876,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15832
15876
|
const key = (input.apiKey ?? "").trim();
|
|
15833
15877
|
if (!key) return { ...res2, error: "No API key provided" };
|
|
15834
15878
|
if (!res2.installed) {
|
|
15835
|
-
const ok = await ensureInstalled(
|
|
15879
|
+
const ok = await ensureInstalled(os51);
|
|
15836
15880
|
res2.installed = ok;
|
|
15837
15881
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15838
15882
|
}
|
|
@@ -15856,7 +15900,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15856
15900
|
}
|
|
15857
15901
|
if (!res2.installed) {
|
|
15858
15902
|
deps.onEvent?.({ kind: "installing" });
|
|
15859
|
-
const ok = await ensureInstalled(
|
|
15903
|
+
const ok = await ensureInstalled(os51);
|
|
15860
15904
|
res2.installed = ok;
|
|
15861
15905
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15862
15906
|
}
|
|
@@ -15886,7 +15930,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15886
15930
|
const res2 = base();
|
|
15887
15931
|
if (!installed2) {
|
|
15888
15932
|
deps.onEvent?.({ kind: "installing" });
|
|
15889
|
-
const ok = await ensureInstalled(
|
|
15933
|
+
const ok = await ensureInstalled(os51);
|
|
15890
15934
|
res2.installed = ok;
|
|
15891
15935
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
15892
15936
|
}
|
|
@@ -15923,7 +15967,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15923
15967
|
}
|
|
15924
15968
|
const res = base();
|
|
15925
15969
|
if (!res.installed) {
|
|
15926
|
-
const ok = await ensureInstalled(
|
|
15970
|
+
const ok = await ensureInstalled(os51);
|
|
15927
15971
|
res.installed = ok;
|
|
15928
15972
|
if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
|
|
15929
15973
|
}
|
|
@@ -15952,14 +15996,14 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15952
15996
|
|
|
15953
15997
|
// src/commands/host-agent.ts
|
|
15954
15998
|
var import_node_child_process23 = require("child_process");
|
|
15955
|
-
var
|
|
15956
|
-
var
|
|
15957
|
-
var
|
|
15999
|
+
var os36 = __toESM(require("os"));
|
|
16000
|
+
var fs42 = __toESM(require("fs"));
|
|
16001
|
+
var path45 = __toESM(require("path"));
|
|
15958
16002
|
|
|
15959
|
-
// src/
|
|
15960
|
-
var
|
|
15961
|
-
var
|
|
15962
|
-
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"));
|
|
15963
16007
|
|
|
15964
16008
|
// src/lib/restrict-to-owner.ts
|
|
15965
16009
|
var import_node_fs6 = __toESM(require("fs"));
|
|
@@ -15994,11 +16038,49 @@ function restrictToOwner(filePath) {
|
|
|
15994
16038
|
}
|
|
15995
16039
|
}
|
|
15996
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
|
+
|
|
15997
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"));
|
|
15998
16080
|
function sampleCpuTimes() {
|
|
15999
16081
|
let idle = 0;
|
|
16000
16082
|
let total = 0;
|
|
16001
|
-
for (const cpu of
|
|
16083
|
+
for (const cpu of os30.cpus()) {
|
|
16002
16084
|
const t2 = cpu.times;
|
|
16003
16085
|
idle += t2.idle;
|
|
16004
16086
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -16017,8 +16099,8 @@ var MetricsCollector = class {
|
|
|
16017
16099
|
const prev = this.prevCpu;
|
|
16018
16100
|
this.prevCpu = current;
|
|
16019
16101
|
if (!prev) {
|
|
16020
|
-
const cores =
|
|
16021
|
-
const proxy =
|
|
16102
|
+
const cores = os30.cpus().length || 1;
|
|
16103
|
+
const proxy = os30.loadavg()[0] / cores * 100;
|
|
16022
16104
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
16023
16105
|
}
|
|
16024
16106
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -16031,8 +16113,8 @@ var MetricsCollector = class {
|
|
|
16031
16113
|
collect() {
|
|
16032
16114
|
return {
|
|
16033
16115
|
cpuPct: this.cpuPct(),
|
|
16034
|
-
ramUsedMb: Math.round((
|
|
16035
|
-
ramTotalMb: Math.round(
|
|
16116
|
+
ramUsedMb: Math.round((os30.totalmem() - os30.freemem()) / 1048576),
|
|
16117
|
+
ramTotalMb: Math.round(os30.totalmem() / 1048576),
|
|
16036
16118
|
latencyMs: this.lastLatencyMs
|
|
16037
16119
|
};
|
|
16038
16120
|
}
|
|
@@ -16041,19 +16123,19 @@ function apiBase() {
|
|
|
16041
16123
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
16042
16124
|
}
|
|
16043
16125
|
function hostIdentityPath() {
|
|
16044
|
-
return
|
|
16126
|
+
return path38.join(os30.homedir(), ".codeam", "host-agent.json");
|
|
16045
16127
|
}
|
|
16046
16128
|
function collectOsInfo() {
|
|
16047
16129
|
return {
|
|
16048
|
-
distro:
|
|
16049
|
-
arch:
|
|
16050
|
-
kernel:
|
|
16130
|
+
distro: os30.platform(),
|
|
16131
|
+
arch: os30.arch(),
|
|
16132
|
+
kernel: os30.release(),
|
|
16051
16133
|
nodeVersion: process.versions.node
|
|
16052
16134
|
};
|
|
16053
16135
|
}
|
|
16054
16136
|
function loadHostIdentity() {
|
|
16055
16137
|
try {
|
|
16056
|
-
const raw =
|
|
16138
|
+
const raw = fs34.readFileSync(hostIdentityPath(), "utf8");
|
|
16057
16139
|
const parsed = JSON.parse(raw);
|
|
16058
16140
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
16059
16141
|
const p2 = parsed;
|
|
@@ -16066,8 +16148,8 @@ function loadHostIdentity() {
|
|
|
16066
16148
|
}
|
|
16067
16149
|
function saveHostIdentity(identity) {
|
|
16068
16150
|
const file = hostIdentityPath();
|
|
16069
|
-
|
|
16070
|
-
|
|
16151
|
+
fs34.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
|
|
16152
|
+
fs34.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
16071
16153
|
encoding: "utf8",
|
|
16072
16154
|
mode: 384
|
|
16073
16155
|
});
|
|
@@ -16112,7 +16194,7 @@ function isTerminalEnrollError(err) {
|
|
|
16112
16194
|
}
|
|
16113
16195
|
function deleteHostIdentity() {
|
|
16114
16196
|
try {
|
|
16115
|
-
|
|
16197
|
+
fs34.rmSync(hostIdentityPath(), { force: true });
|
|
16116
16198
|
} catch {
|
|
16117
16199
|
}
|
|
16118
16200
|
}
|
|
@@ -16235,17 +16317,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
16235
16317
|
}
|
|
16236
16318
|
|
|
16237
16319
|
// src/commands/host/workspace.ts
|
|
16238
|
-
var
|
|
16239
|
-
var
|
|
16240
|
-
var
|
|
16320
|
+
var fs35 = __toESM(require("fs"));
|
|
16321
|
+
var os31 = __toESM(require("os"));
|
|
16322
|
+
var path39 = __toESM(require("path"));
|
|
16241
16323
|
var import_node_child_process17 = require("child_process");
|
|
16242
16324
|
var import_node_util4 = require("util");
|
|
16243
16325
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process17.execFile);
|
|
16244
16326
|
function isAbsolutePathTarget(target) {
|
|
16245
|
-
return
|
|
16327
|
+
return path39.isAbsolute(target);
|
|
16246
16328
|
}
|
|
16247
16329
|
function selfHostedWorkspaceRoot() {
|
|
16248
|
-
return
|
|
16330
|
+
return path39.join(os31.homedir(), ".codeam", "self-hosted");
|
|
16249
16331
|
}
|
|
16250
16332
|
function nonInteractiveGitEnv() {
|
|
16251
16333
|
return {
|
|
@@ -16298,13 +16380,13 @@ async function fetchGithubIdentity(token) {
|
|
|
16298
16380
|
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
16299
16381
|
const gh = githubOwnerRepo(repoRef.trim());
|
|
16300
16382
|
if (!gh || !cloneToken) return;
|
|
16301
|
-
const credFile =
|
|
16302
|
-
|
|
16383
|
+
const credFile = path39.join(dest, ".git", "codeam-credentials");
|
|
16384
|
+
fs35.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
16303
16385
|
`, { mode: 384 });
|
|
16304
16386
|
restrictToOwner(credFile);
|
|
16305
16387
|
const env = nonInteractiveGitEnv();
|
|
16306
16388
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
16307
|
-
const credFilePosix = credFile.split(
|
|
16389
|
+
const credFilePosix = credFile.split(path39.sep).join("/");
|
|
16308
16390
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
16309
16391
|
});
|
|
16310
16392
|
await git2([
|
|
@@ -16340,17 +16422,17 @@ function maskToken(text, cloneToken) {
|
|
|
16340
16422
|
}
|
|
16341
16423
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
16342
16424
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
16343
|
-
if (!
|
|
16425
|
+
if (!fs35.existsSync(repoOrPath)) {
|
|
16344
16426
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
16345
16427
|
}
|
|
16346
16428
|
return repoOrPath;
|
|
16347
16429
|
}
|
|
16348
|
-
const dest =
|
|
16349
|
-
if (
|
|
16430
|
+
const dest = path39.join(selfHostedWorkspaceRoot(), deployId);
|
|
16431
|
+
if (fs35.existsSync(path39.join(dest, ".git"))) {
|
|
16350
16432
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
16351
16433
|
return dest;
|
|
16352
16434
|
}
|
|
16353
|
-
|
|
16435
|
+
fs35.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
16354
16436
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
16355
16437
|
try {
|
|
16356
16438
|
await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -16367,9 +16449,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
16367
16449
|
}
|
|
16368
16450
|
|
|
16369
16451
|
// src/commands/host/agent-provisioning.ts
|
|
16370
|
-
var
|
|
16371
|
-
var
|
|
16372
|
-
var
|
|
16452
|
+
var fs36 = __toESM(require("fs"));
|
|
16453
|
+
var os32 = __toESM(require("os"));
|
|
16454
|
+
var path40 = __toESM(require("path"));
|
|
16373
16455
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
16374
16456
|
claude_code: "claude",
|
|
16375
16457
|
claude: "claude",
|
|
@@ -16385,22 +16467,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
16385
16467
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
16386
16468
|
}
|
|
16387
16469
|
function ensureDir(dir) {
|
|
16388
|
-
|
|
16470
|
+
fs36.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
16389
16471
|
}
|
|
16390
16472
|
function writeFile0600(filePath, contents) {
|
|
16391
|
-
ensureDir(
|
|
16392
|
-
|
|
16473
|
+
ensureDir(path40.dirname(filePath));
|
|
16474
|
+
fs36.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
16393
16475
|
restrictToOwner(filePath);
|
|
16394
16476
|
}
|
|
16395
16477
|
function rmIfExists(filePath) {
|
|
16396
16478
|
try {
|
|
16397
|
-
|
|
16479
|
+
fs36.rmSync(filePath, { force: true });
|
|
16398
16480
|
} catch {
|
|
16399
16481
|
}
|
|
16400
16482
|
}
|
|
16401
16483
|
var claudeProvisioner = {
|
|
16402
16484
|
write(auth, home) {
|
|
16403
|
-
const credentialsJson =
|
|
16485
|
+
const credentialsJson = path40.join(home, ".claude", ".credentials.json");
|
|
16404
16486
|
if (auth.kind === "api_key") {
|
|
16405
16487
|
rmIfExists(credentialsJson);
|
|
16406
16488
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -16412,8 +16494,8 @@ var claudeProvisioner = {
|
|
|
16412
16494
|
} else {
|
|
16413
16495
|
rmIfExists(credentialsJson);
|
|
16414
16496
|
}
|
|
16415
|
-
const claudeJson =
|
|
16416
|
-
if (!
|
|
16497
|
+
const claudeJson = path40.join(home, ".claude.json");
|
|
16498
|
+
if (!fs36.existsSync(claudeJson)) {
|
|
16417
16499
|
writeFile0600(
|
|
16418
16500
|
claudeJson,
|
|
16419
16501
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -16424,7 +16506,7 @@ var claudeProvisioner = {
|
|
|
16424
16506
|
};
|
|
16425
16507
|
var codexProvisioner = {
|
|
16426
16508
|
write(auth, home) {
|
|
16427
|
-
const authJson =
|
|
16509
|
+
const authJson = path40.join(home, ".codex", "auth.json");
|
|
16428
16510
|
if (auth.kind === "api_key") {
|
|
16429
16511
|
rmIfExists(authJson);
|
|
16430
16512
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -16435,8 +16517,8 @@ var codexProvisioner = {
|
|
|
16435
16517
|
};
|
|
16436
16518
|
var geminiProvisioner = {
|
|
16437
16519
|
write(auth, home) {
|
|
16438
|
-
const settingsJson =
|
|
16439
|
-
const oauthCreds =
|
|
16520
|
+
const settingsJson = path40.join(home, ".gemini", "settings.json");
|
|
16521
|
+
const oauthCreds = path40.join(home, ".gemini", "oauth_creds.json");
|
|
16440
16522
|
if (auth.kind === "api_key") {
|
|
16441
16523
|
rmIfExists(oauthCreds);
|
|
16442
16524
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -16449,7 +16531,7 @@ var geminiProvisioner = {
|
|
|
16449
16531
|
};
|
|
16450
16532
|
var cursorProvisioner = {
|
|
16451
16533
|
write(auth, home) {
|
|
16452
|
-
const authJson =
|
|
16534
|
+
const authJson = path40.join(home, ".config", "cursor", "auth.json");
|
|
16453
16535
|
if (auth.kind === "api_key") {
|
|
16454
16536
|
rmIfExists(authJson);
|
|
16455
16537
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -16475,8 +16557,8 @@ var cursorProvisioner = {
|
|
|
16475
16557
|
var kimiProvisioner = {
|
|
16476
16558
|
write(auth, home) {
|
|
16477
16559
|
const credentialsFiles = [
|
|
16478
|
-
|
|
16479
|
-
|
|
16560
|
+
path40.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
16561
|
+
path40.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
16480
16562
|
];
|
|
16481
16563
|
if (auth.kind === "api_key") {
|
|
16482
16564
|
credentialsFiles.forEach(rmIfExists);
|
|
@@ -16488,8 +16570,8 @@ var kimiProvisioner = {
|
|
|
16488
16570
|
};
|
|
16489
16571
|
var coderabbitProvisioner = {
|
|
16490
16572
|
write(auth, home) {
|
|
16491
|
-
const dir =
|
|
16492
|
-
const authJson =
|
|
16573
|
+
const dir = path40.join(home, ".coderabbit");
|
|
16574
|
+
const authJson = path40.join(dir, "auth.json");
|
|
16493
16575
|
if (auth.kind === "api_key") {
|
|
16494
16576
|
rmIfExists(authJson);
|
|
16495
16577
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -16501,13 +16583,13 @@ var coderabbitProvisioner = {
|
|
|
16501
16583
|
try {
|
|
16502
16584
|
const parsed = JSON.parse(value);
|
|
16503
16585
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
16504
|
-
file =
|
|
16586
|
+
file = path40.basename(parsed.file);
|
|
16505
16587
|
contents = parsed.contents;
|
|
16506
16588
|
}
|
|
16507
16589
|
} catch {
|
|
16508
16590
|
}
|
|
16509
16591
|
}
|
|
16510
|
-
writeFile0600(
|
|
16592
|
+
writeFile0600(path40.join(dir, file), contents);
|
|
16511
16593
|
return {};
|
|
16512
16594
|
}
|
|
16513
16595
|
};
|
|
@@ -16527,7 +16609,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
16527
16609
|
this.agentId = agentId;
|
|
16528
16610
|
}
|
|
16529
16611
|
};
|
|
16530
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
16612
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir()) {
|
|
16531
16613
|
const internal = toInternalAgentId(publicAgentId);
|
|
16532
16614
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
16533
16615
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -16537,11 +16619,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os31.homedir(
|
|
|
16537
16619
|
|
|
16538
16620
|
// src/commands/host/git-tooling.ts
|
|
16539
16621
|
var import_node_child_process18 = require("child_process");
|
|
16540
|
-
var
|
|
16541
|
-
var
|
|
16542
|
-
var
|
|
16622
|
+
var fs37 = __toESM(require("fs"));
|
|
16623
|
+
var os33 = __toESM(require("os"));
|
|
16624
|
+
var path41 = __toESM(require("path"));
|
|
16543
16625
|
function codeamBinDir() {
|
|
16544
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
16626
|
+
return process.env.CODEAM_BIN_DIR ?? path41.join(os33.homedir(), ".codeam", "bin");
|
|
16545
16627
|
}
|
|
16546
16628
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
16547
16629
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -16573,7 +16655,7 @@ async function download(url, dest) {
|
|
|
16573
16655
|
const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
|
|
16574
16656
|
if (!res.ok || !res.body) return false;
|
|
16575
16657
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
16576
|
-
|
|
16658
|
+
fs37.writeFileSync(dest, buf);
|
|
16577
16659
|
return true;
|
|
16578
16660
|
} catch {
|
|
16579
16661
|
return false;
|
|
@@ -16596,8 +16678,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
16596
16678
|
const version3 = await resolveVersionFn(token);
|
|
16597
16679
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
16598
16680
|
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
16599
|
-
const tmpRoot =
|
|
16600
|
-
const archive =
|
|
16681
|
+
const tmpRoot = fs37.mkdtempSync(path41.join(os33.tmpdir(), "codeam-gh-"));
|
|
16682
|
+
const archive = path41.join(tmpRoot, `${asset}.${ext}`);
|
|
16601
16683
|
if (!await downloadFn(url, archive)) {
|
|
16602
16684
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
16603
16685
|
return null;
|
|
@@ -16607,16 +16689,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
16607
16689
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
16608
16690
|
return null;
|
|
16609
16691
|
}
|
|
16610
|
-
const extractedBin =
|
|
16611
|
-
if (!
|
|
16692
|
+
const extractedBin = path41.join(tmpRoot, asset, "bin", binaryName);
|
|
16693
|
+
if (!fs37.existsSync(extractedBin)) {
|
|
16612
16694
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
16613
16695
|
return null;
|
|
16614
16696
|
}
|
|
16615
16697
|
const binDir = codeamBinDir();
|
|
16616
|
-
|
|
16617
|
-
const target =
|
|
16618
|
-
|
|
16619
|
-
|
|
16698
|
+
fs37.mkdirSync(binDir, { recursive: true });
|
|
16699
|
+
const target = path41.join(binDir, binaryName);
|
|
16700
|
+
fs37.copyFileSync(extractedBin, target);
|
|
16701
|
+
fs37.chmodSync(target, 493);
|
|
16620
16702
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
16621
16703
|
return target;
|
|
16622
16704
|
} catch (e) {
|
|
@@ -17103,23 +17185,23 @@ async function ensureModernPython(runner) {
|
|
|
17103
17185
|
}
|
|
17104
17186
|
|
|
17105
17187
|
// src/commands/host/headroom-bootstrap.ts
|
|
17106
|
-
var
|
|
17107
|
-
var
|
|
17188
|
+
var fs39 = __toESM(require("fs"));
|
|
17189
|
+
var path43 = __toESM(require("path"));
|
|
17108
17190
|
|
|
17109
17191
|
// src/commands/host/headroom-config.ts
|
|
17110
|
-
var
|
|
17111
|
-
var
|
|
17112
|
-
var
|
|
17192
|
+
var fs38 = __toESM(require("fs"));
|
|
17193
|
+
var os34 = __toESM(require("os"));
|
|
17194
|
+
var path42 = __toESM(require("path"));
|
|
17113
17195
|
function headroomConfigPath() {
|
|
17114
|
-
return
|
|
17196
|
+
return path42.join(os34.homedir(), ".codeam", "headroom-config.json");
|
|
17115
17197
|
}
|
|
17116
17198
|
function persistHeadroomConfig(config) {
|
|
17117
17199
|
try {
|
|
17118
17200
|
const file = headroomConfigPath();
|
|
17119
|
-
|
|
17201
|
+
fs38.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
|
|
17120
17202
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
17121
|
-
|
|
17122
|
-
|
|
17203
|
+
fs38.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
17204
|
+
fs38.renameSync(tmp, file);
|
|
17123
17205
|
restrictToOwner(file);
|
|
17124
17206
|
} catch (err) {
|
|
17125
17207
|
log.warn(
|
|
@@ -17129,21 +17211,21 @@ function persistHeadroomConfig(config) {
|
|
|
17129
17211
|
}
|
|
17130
17212
|
}
|
|
17131
17213
|
function agentSettingsPath(kind) {
|
|
17132
|
-
const home =
|
|
17133
|
-
if (kind === "claude") return
|
|
17134
|
-
if (kind === "codex") return
|
|
17135
|
-
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");
|
|
17136
17218
|
return null;
|
|
17137
17219
|
}
|
|
17138
17220
|
function backupAgentHeadroomConfig(kind) {
|
|
17139
17221
|
const src = agentSettingsPath(kind);
|
|
17140
17222
|
if (!src) return;
|
|
17141
17223
|
try {
|
|
17142
|
-
if (!
|
|
17143
|
-
const dest =
|
|
17144
|
-
|
|
17145
|
-
|
|
17146
|
-
|
|
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);
|
|
17147
17229
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
17148
17230
|
} catch (err) {
|
|
17149
17231
|
log.warn(
|
|
@@ -17155,12 +17237,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
17155
17237
|
function restoreAgentHeadroomConfig(kind) {
|
|
17156
17238
|
const dest = agentSettingsPath(kind);
|
|
17157
17239
|
if (!dest) return false;
|
|
17158
|
-
const src =
|
|
17159
|
-
if (!
|
|
17240
|
+
const src = path42.join(os34.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
17241
|
+
if (!fs38.existsSync(src)) return false;
|
|
17160
17242
|
try {
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17243
|
+
fs38.mkdirSync(path42.dirname(dest), { recursive: true, mode: 448 });
|
|
17244
|
+
fs38.copyFileSync(src, dest);
|
|
17245
|
+
fs38.chmodSync(dest, 384);
|
|
17164
17246
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
17165
17247
|
return true;
|
|
17166
17248
|
} catch (err) {
|
|
@@ -17173,7 +17255,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
17173
17255
|
}
|
|
17174
17256
|
function readHeadroomChildEnv() {
|
|
17175
17257
|
try {
|
|
17176
|
-
const raw =
|
|
17258
|
+
const raw = fs38.readFileSync(headroomConfigPath(), "utf8");
|
|
17177
17259
|
const parsed = JSON.parse(raw);
|
|
17178
17260
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
17179
17261
|
const o = parsed;
|
|
@@ -17209,37 +17291,37 @@ function bundledClaudeBinDir() {
|
|
|
17209
17291
|
const roots = /* @__PURE__ */ new Set();
|
|
17210
17292
|
let dir = __dirname;
|
|
17211
17293
|
for (let i = 0; i < 6; i++) {
|
|
17212
|
-
roots.add(
|
|
17213
|
-
const parent =
|
|
17294
|
+
roots.add(path43.join(dir, "node_modules"));
|
|
17295
|
+
const parent = path43.dirname(dir);
|
|
17214
17296
|
if (parent === dir) break;
|
|
17215
17297
|
dir = parent;
|
|
17216
17298
|
}
|
|
17217
17299
|
try {
|
|
17218
17300
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
17219
|
-
const marker = `${
|
|
17301
|
+
const marker = `${path43.sep}@anthropic-ai${path43.sep}`;
|
|
17220
17302
|
const idx = main2.lastIndexOf(marker);
|
|
17221
17303
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
17222
17304
|
} catch {
|
|
17223
17305
|
}
|
|
17224
17306
|
for (const nm of roots) {
|
|
17225
|
-
const atAnthropic =
|
|
17307
|
+
const atAnthropic = path43.join(nm, "@anthropic-ai");
|
|
17226
17308
|
let entries;
|
|
17227
17309
|
try {
|
|
17228
|
-
entries =
|
|
17310
|
+
entries = fs39.readdirSync(atAnthropic);
|
|
17229
17311
|
} catch {
|
|
17230
17312
|
continue;
|
|
17231
17313
|
}
|
|
17232
17314
|
for (const entry of entries) {
|
|
17233
17315
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
17234
|
-
const bin =
|
|
17235
|
-
if (
|
|
17316
|
+
const bin = path43.join(atAnthropic, entry, "claude");
|
|
17317
|
+
if (fs39.existsSync(bin)) return path43.dirname(bin);
|
|
17236
17318
|
}
|
|
17237
17319
|
}
|
|
17238
17320
|
return null;
|
|
17239
17321
|
}
|
|
17240
17322
|
async function getFreeDiskBytes(dir) {
|
|
17241
17323
|
try {
|
|
17242
|
-
const s = await
|
|
17324
|
+
const s = await fs39.promises.statfs(dir);
|
|
17243
17325
|
return s.bsize * s.bavail;
|
|
17244
17326
|
} catch {
|
|
17245
17327
|
return null;
|
|
@@ -17301,7 +17383,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17301
17383
|
if (initKind === "claude") {
|
|
17302
17384
|
const claudeDir = bundledClaudeBinDir();
|
|
17303
17385
|
if (claudeDir) {
|
|
17304
|
-
initEnv.PATH = `${claudeDir}${
|
|
17386
|
+
initEnv.PATH = `${claudeDir}${path43.delimiter}${process.env["PATH"] ?? ""}`;
|
|
17305
17387
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
17306
17388
|
} else {
|
|
17307
17389
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -17336,9 +17418,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17336
17418
|
var import_node_child_process21 = require("child_process");
|
|
17337
17419
|
|
|
17338
17420
|
// src/lib/updateNotifier.ts
|
|
17339
|
-
var
|
|
17340
|
-
var
|
|
17341
|
-
var
|
|
17421
|
+
var fs40 = __toESM(require("fs"));
|
|
17422
|
+
var os35 = __toESM(require("os"));
|
|
17423
|
+
var path44 = __toESM(require("path"));
|
|
17342
17424
|
var https6 = __toESM(require("https"));
|
|
17343
17425
|
var import_node_child_process20 = require("child_process");
|
|
17344
17426
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -17347,12 +17429,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
17347
17429
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
17348
17430
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
17349
17431
|
function cachePath() {
|
|
17350
|
-
const dir =
|
|
17351
|
-
return
|
|
17432
|
+
const dir = path44.join(os35.homedir(), ".codeam");
|
|
17433
|
+
return path44.join(dir, "update-check.json");
|
|
17352
17434
|
}
|
|
17353
17435
|
function readCache() {
|
|
17354
17436
|
try {
|
|
17355
|
-
const raw =
|
|
17437
|
+
const raw = fs40.readFileSync(cachePath(), "utf8");
|
|
17356
17438
|
const parsed = JSON.parse(raw);
|
|
17357
17439
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
17358
17440
|
return parsed;
|
|
@@ -17363,10 +17445,10 @@ function readCache() {
|
|
|
17363
17445
|
function writeCache(cache) {
|
|
17364
17446
|
try {
|
|
17365
17447
|
const file = cachePath();
|
|
17366
|
-
|
|
17448
|
+
fs40.mkdirSync(path44.dirname(file), { recursive: true });
|
|
17367
17449
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
17368
|
-
|
|
17369
|
-
|
|
17450
|
+
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
17451
|
+
fs40.renameSync(tmp, file);
|
|
17370
17452
|
} catch {
|
|
17371
17453
|
}
|
|
17372
17454
|
}
|
|
@@ -17440,8 +17522,8 @@ function isLinkedInstall() {
|
|
|
17440
17522
|
timeout: 2e3
|
|
17441
17523
|
}).trim();
|
|
17442
17524
|
if (!root) return false;
|
|
17443
|
-
const pkgPath =
|
|
17444
|
-
return
|
|
17525
|
+
const pkgPath = path44.join(root, PKG_NAME);
|
|
17526
|
+
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
17445
17527
|
} catch {
|
|
17446
17528
|
return false;
|
|
17447
17529
|
}
|
|
@@ -17477,7 +17559,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
17477
17559
|
return;
|
|
17478
17560
|
}
|
|
17479
17561
|
try {
|
|
17480
|
-
|
|
17562
|
+
fs40.unlinkSync(cachePath());
|
|
17481
17563
|
} catch {
|
|
17482
17564
|
}
|
|
17483
17565
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -17493,7 +17575,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17493
17575
|
if (process.env.NODE_ENV === "test") return;
|
|
17494
17576
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17495
17577
|
if (process.env.CI) return;
|
|
17496
|
-
const current = true ? "2.60.
|
|
17578
|
+
const current = true ? "2.60.47" : null;
|
|
17497
17579
|
if (!current) return;
|
|
17498
17580
|
const cache = readCache();
|
|
17499
17581
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17510,7 +17592,7 @@ function checkForUpdates() {
|
|
|
17510
17592
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17511
17593
|
if (process.env.CI) return;
|
|
17512
17594
|
if (!process.stdout.isTTY) return;
|
|
17513
|
-
const current = true ? "2.60.
|
|
17595
|
+
const current = true ? "2.60.47" : null;
|
|
17514
17596
|
if (!current) return;
|
|
17515
17597
|
const cache = readCache();
|
|
17516
17598
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17530,7 +17612,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17530
17612
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17531
17613
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17532
17614
|
function currentCliVersion() {
|
|
17533
|
-
return true ? "2.60.
|
|
17615
|
+
return true ? "2.60.47" : null;
|
|
17534
17616
|
}
|
|
17535
17617
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17536
17618
|
return new Promise((resolve7) => {
|
|
@@ -17597,7 +17679,7 @@ async function runSelfUpdate() {
|
|
|
17597
17679
|
|
|
17598
17680
|
// src/commands/host/teardown.ts
|
|
17599
17681
|
var import_node_child_process22 = require("child_process");
|
|
17600
|
-
var
|
|
17682
|
+
var fs41 = __toESM(require("fs"));
|
|
17601
17683
|
var defaultDisableService = () => {
|
|
17602
17684
|
try {
|
|
17603
17685
|
(0, import_node_child_process22.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
@@ -17606,7 +17688,7 @@ var defaultDisableService = () => {
|
|
|
17606
17688
|
};
|
|
17607
17689
|
var defaultTeardownHeadroom = () => {
|
|
17608
17690
|
try {
|
|
17609
|
-
const kind = JSON.parse(
|
|
17691
|
+
const kind = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
17610
17692
|
if (kind) {
|
|
17611
17693
|
(0, import_node_child_process22.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
17612
17694
|
}
|
|
@@ -17674,8 +17756,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
17674
17756
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
17675
17757
|
try {
|
|
17676
17758
|
const file = headroomConfigPath();
|
|
17677
|
-
if (!
|
|
17678
|
-
const cfg = JSON.parse(
|
|
17759
|
+
if (!fs42.existsSync(file)) return null;
|
|
17760
|
+
const cfg = JSON.parse(fs42.readFileSync(file, "utf8"));
|
|
17679
17761
|
if (!cfg?.enabled) return null;
|
|
17680
17762
|
const agent = cfg.agent ?? "claude";
|
|
17681
17763
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -17748,6 +17830,9 @@ function isDeployPayload(p2) {
|
|
|
17748
17830
|
if (p2.headroomSavingsIngestUrl !== void 0 && typeof p2.headroomSavingsIngestUrl !== "string") {
|
|
17749
17831
|
return false;
|
|
17750
17832
|
}
|
|
17833
|
+
if (p2.integrations !== void 0 && !Array.isArray(p2.integrations)) {
|
|
17834
|
+
return false;
|
|
17835
|
+
}
|
|
17751
17836
|
const hasHouse = isHouseProxy(p2.houseProxy);
|
|
17752
17837
|
const hasSealed = typeof p2.sealedAgentAuth === "string";
|
|
17753
17838
|
return hasHouse || hasSealed;
|
|
@@ -18080,9 +18165,9 @@ var HostAgentSupervisor = class {
|
|
|
18080
18165
|
API_TIMEOUT_MS: "3000000",
|
|
18081
18166
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
18082
18167
|
};
|
|
18083
|
-
const houseConfigDir =
|
|
18168
|
+
const houseConfigDir = path45.join(os36.homedir(), ".codeam", "house-claude");
|
|
18084
18169
|
try {
|
|
18085
|
-
|
|
18170
|
+
fs42.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
18086
18171
|
} catch {
|
|
18087
18172
|
}
|
|
18088
18173
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -18100,14 +18185,14 @@ var HostAgentSupervisor = class {
|
|
|
18100
18185
|
report("installing", "installing agent CLI");
|
|
18101
18186
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
18102
18187
|
}
|
|
18103
|
-
const home = process.env.HOME ||
|
|
18188
|
+
const home = process.env.HOME || os36.homedir();
|
|
18104
18189
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
18105
18190
|
if (payload.cloneToken) {
|
|
18106
18191
|
try {
|
|
18107
18192
|
report("preparing", "configuring git tooling");
|
|
18108
18193
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
18109
18194
|
if (ghCmd) {
|
|
18110
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
18195
|
+
childEnv.PATH = `${codeamBinDir()}${path45.delimiter}${childEnv.PATH}`;
|
|
18111
18196
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
18112
18197
|
}
|
|
18113
18198
|
} catch (e) {
|
|
@@ -18123,7 +18208,7 @@ var HostAgentSupervisor = class {
|
|
|
18123
18208
|
}
|
|
18124
18209
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
18125
18210
|
report("headroom", "setting up Headroom proxy");
|
|
18126
|
-
const freeBytes = await this.getFreeDisk(
|
|
18211
|
+
const freeBytes = await this.getFreeDisk(os36.homedir());
|
|
18127
18212
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
18128
18213
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
18129
18214
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -18172,6 +18257,11 @@ var HostAgentSupervisor = class {
|
|
|
18172
18257
|
);
|
|
18173
18258
|
persistHeadroomConfig({ enabled: false });
|
|
18174
18259
|
}
|
|
18260
|
+
if (payload.integrations?.length) {
|
|
18261
|
+
persistIntegrationsManifest({ integrations: payload.integrations });
|
|
18262
|
+
} else {
|
|
18263
|
+
clearIntegrationsManifest();
|
|
18264
|
+
}
|
|
18175
18265
|
report("spawning", "starting agent");
|
|
18176
18266
|
const proc = this.spawnSessionChild(childEnv, cwd, extraArgs);
|
|
18177
18267
|
const child = {
|
|
@@ -18245,7 +18335,7 @@ var HostAgentSupervisor = class {
|
|
|
18245
18335
|
*/
|
|
18246
18336
|
runAgentInstall(script) {
|
|
18247
18337
|
return new Promise((resolve7) => {
|
|
18248
|
-
const home = process.env.HOME ||
|
|
18338
|
+
const home = process.env.HOME || os36.homedir();
|
|
18249
18339
|
const child = (0, import_node_child_process23.spawn)("sh", ["-c", script], {
|
|
18250
18340
|
env: { ...process.env, HOME: home },
|
|
18251
18341
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -18429,9 +18519,9 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
18429
18519
|
}
|
|
18430
18520
|
|
|
18431
18521
|
// src/services/headroom/budget-relaunch.ts
|
|
18432
|
-
var
|
|
18433
|
-
var
|
|
18434
|
-
var
|
|
18522
|
+
var fs43 = __toESM(require("fs"));
|
|
18523
|
+
var os37 = __toESM(require("os"));
|
|
18524
|
+
var path46 = __toESM(require("path"));
|
|
18435
18525
|
var import_child_process13 = require("child_process");
|
|
18436
18526
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
18437
18527
|
const rawArgs = manifest.proxy_args ?? [];
|
|
@@ -18465,7 +18555,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
18465
18555
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
18466
18556
|
}
|
|
18467
18557
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
18468
|
-
const deployDir =
|
|
18558
|
+
const deployDir = path46.join(homeDir2, ".headroom", "deploy");
|
|
18469
18559
|
let profiles;
|
|
18470
18560
|
try {
|
|
18471
18561
|
profiles = deps.readDir(deployDir);
|
|
@@ -18474,7 +18564,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
18474
18564
|
}
|
|
18475
18565
|
const results = [];
|
|
18476
18566
|
for (const profile of profiles) {
|
|
18477
|
-
const manifestPath =
|
|
18567
|
+
const manifestPath = path46.join(deployDir, profile, "manifest.json");
|
|
18478
18568
|
let raw;
|
|
18479
18569
|
try {
|
|
18480
18570
|
raw = deps.readJson(manifestPath);
|
|
@@ -18506,8 +18596,8 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
18506
18596
|
}
|
|
18507
18597
|
function writeManifestReal(manifestPath, manifest) {
|
|
18508
18598
|
const tmp = manifestPath + ".codeam.tmp";
|
|
18509
|
-
|
|
18510
|
-
|
|
18599
|
+
fs43.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
18600
|
+
fs43.renameSync(tmp, manifestPath);
|
|
18511
18601
|
}
|
|
18512
18602
|
function restartDeploymentReal(profile) {
|
|
18513
18603
|
try {
|
|
@@ -18537,11 +18627,11 @@ function spawnProxyReal2(_budget) {
|
|
|
18537
18627
|
});
|
|
18538
18628
|
}
|
|
18539
18629
|
function makeRealApplyBudgetDeps() {
|
|
18540
|
-
const homeDir2 =
|
|
18630
|
+
const homeDir2 = os37.homedir();
|
|
18541
18631
|
return {
|
|
18542
18632
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
18543
|
-
readDir: (dir) =>
|
|
18544
|
-
readJson: (filePath) => JSON.parse(
|
|
18633
|
+
readDir: (dir) => fs43.readdirSync(dir),
|
|
18634
|
+
readJson: (filePath) => JSON.parse(fs43.readFileSync(filePath, "utf8"))
|
|
18545
18635
|
}),
|
|
18546
18636
|
writeManifest: writeManifestReal,
|
|
18547
18637
|
restartDeployment: restartDeploymentReal,
|
|
@@ -19221,8 +19311,8 @@ function activePreviewSessionIds() {
|
|
|
19221
19311
|
|
|
19222
19312
|
// src/services/preview/start-orchestrator.ts
|
|
19223
19313
|
var import_child_process17 = require("child_process");
|
|
19224
|
-
var
|
|
19225
|
-
var
|
|
19314
|
+
var fs48 = __toESM(require("fs"));
|
|
19315
|
+
var path51 = __toESM(require("path"));
|
|
19226
19316
|
var import_which2 = __toESM(require("which"));
|
|
19227
19317
|
var INSTALL_TIMEOUT_MS = 5 * 6e4;
|
|
19228
19318
|
var SETUP_TIMEOUT_MS = 2 * 6e4;
|
|
@@ -19289,8 +19379,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19289
19379
|
if (args2.length === 0) return detection;
|
|
19290
19380
|
const binName = args2[0];
|
|
19291
19381
|
if (binName.startsWith("-")) return detection;
|
|
19292
|
-
const binPath =
|
|
19293
|
-
if (!
|
|
19382
|
+
const binPath = path51.join(cwd, "node_modules", ".bin", binName);
|
|
19383
|
+
if (!fs48.existsSync(binPath)) return detection;
|
|
19294
19384
|
return {
|
|
19295
19385
|
...detection,
|
|
19296
19386
|
command: binPath,
|
|
@@ -19640,9 +19730,9 @@ async function establishTunnel(ctx, dev) {
|
|
|
19640
19730
|
|
|
19641
19731
|
// src/beads/bd-adapter.ts
|
|
19642
19732
|
var import_child_process18 = require("child_process");
|
|
19643
|
-
var
|
|
19644
|
-
var
|
|
19645
|
-
var
|
|
19733
|
+
var fs49 = __toESM(require("fs"));
|
|
19734
|
+
var os39 = __toESM(require("os"));
|
|
19735
|
+
var path52 = __toESM(require("path"));
|
|
19646
19736
|
var BD_PACKAGE = "@beads/bd";
|
|
19647
19737
|
function resolveBundledBdBinary() {
|
|
19648
19738
|
return _resolveSeam.resolveBundled();
|
|
@@ -19654,11 +19744,11 @@ function _defaultResolveBundled() {
|
|
|
19654
19744
|
} catch {
|
|
19655
19745
|
return null;
|
|
19656
19746
|
}
|
|
19657
|
-
const binDir =
|
|
19747
|
+
const binDir = path52.join(path52.dirname(pkgJsonPath), "bin");
|
|
19658
19748
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
19659
|
-
const binaryPath =
|
|
19749
|
+
const binaryPath = path52.join(binDir, binaryName);
|
|
19660
19750
|
try {
|
|
19661
|
-
|
|
19751
|
+
fs49.accessSync(binaryPath, fs49.constants.F_OK);
|
|
19662
19752
|
return binaryPath;
|
|
19663
19753
|
} catch {
|
|
19664
19754
|
return null;
|
|
@@ -19668,13 +19758,13 @@ function resolveBdOnPath() {
|
|
|
19668
19758
|
return _resolveSeam.resolveOnPath();
|
|
19669
19759
|
}
|
|
19670
19760
|
function _defaultResolveOnPath() {
|
|
19671
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
19761
|
+
const dirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
|
|
19672
19762
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
19673
19763
|
for (const dir of dirs) {
|
|
19674
19764
|
for (const candidate of candidates) {
|
|
19675
|
-
const full =
|
|
19765
|
+
const full = path52.join(dir, candidate);
|
|
19676
19766
|
try {
|
|
19677
|
-
|
|
19767
|
+
fs49.accessSync(full, fs49.constants.F_OK);
|
|
19678
19768
|
return full;
|
|
19679
19769
|
} catch {
|
|
19680
19770
|
}
|
|
@@ -19759,7 +19849,7 @@ var BdAdapter = class {
|
|
|
19759
19849
|
const env = { ...process.env };
|
|
19760
19850
|
if (!env.HOME) {
|
|
19761
19851
|
try {
|
|
19762
|
-
const home =
|
|
19852
|
+
const home = os39.homedir();
|
|
19763
19853
|
if (home) env.HOME = home;
|
|
19764
19854
|
} catch {
|
|
19765
19855
|
}
|
|
@@ -19851,9 +19941,9 @@ function coerceIssue(row, projectKey) {
|
|
|
19851
19941
|
|
|
19852
19942
|
// src/beads/provisioner.ts
|
|
19853
19943
|
var import_child_process22 = require("child_process");
|
|
19854
|
-
var
|
|
19855
|
-
var
|
|
19856
|
-
var
|
|
19944
|
+
var fs52 = __toESM(require("fs"));
|
|
19945
|
+
var os41 = __toESM(require("os"));
|
|
19946
|
+
var path55 = __toESM(require("path"));
|
|
19857
19947
|
|
|
19858
19948
|
// src/beads/install-bd.ts
|
|
19859
19949
|
var import_child_process19 = require("child_process");
|
|
@@ -19918,9 +20008,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
19918
20008
|
|
|
19919
20009
|
// src/beads/install-dolt.ts
|
|
19920
20010
|
var import_child_process20 = require("child_process");
|
|
19921
|
-
var
|
|
19922
|
-
var
|
|
19923
|
-
var
|
|
20011
|
+
var fs50 = __toESM(require("fs"));
|
|
20012
|
+
var os40 = __toESM(require("os"));
|
|
20013
|
+
var path53 = __toESM(require("path"));
|
|
19924
20014
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
19925
20015
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
19926
20016
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -19960,11 +20050,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
19960
20050
|
}
|
|
19961
20051
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
19962
20052
|
function doltPlatformTuple(platform3, arch2) {
|
|
19963
|
-
const
|
|
20053
|
+
const os51 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
19964
20054
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
19965
20055
|
if (!a) return null;
|
|
19966
|
-
if (
|
|
19967
|
-
return `${
|
|
20056
|
+
if (os51 === "windows" && a !== "amd64") return null;
|
|
20057
|
+
return `${os51}-${a}`;
|
|
19968
20058
|
}
|
|
19969
20059
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
19970
20060
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -20009,14 +20099,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
20009
20099
|
return result;
|
|
20010
20100
|
}
|
|
20011
20101
|
var _doltPathSeam = {
|
|
20012
|
-
homedir: () =>
|
|
20102
|
+
homedir: () => os40.homedir(),
|
|
20013
20103
|
getPath: () => process.env.PATH ?? "",
|
|
20014
20104
|
setPath: (p2) => {
|
|
20015
20105
|
process.env.PATH = p2;
|
|
20016
20106
|
},
|
|
20017
20107
|
exists: (p2) => {
|
|
20018
20108
|
try {
|
|
20019
|
-
|
|
20109
|
+
fs50.accessSync(p2, fs50.constants.F_OK);
|
|
20020
20110
|
return true;
|
|
20021
20111
|
} catch {
|
|
20022
20112
|
return false;
|
|
@@ -20027,7 +20117,7 @@ function doltBinaryNames(platform3) {
|
|
|
20027
20117
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
20028
20118
|
}
|
|
20029
20119
|
function knownDoltDirs(platform3) {
|
|
20030
|
-
const P3 = platform3 === "win32" ?
|
|
20120
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
20031
20121
|
const home = _doltPathSeam.homedir();
|
|
20032
20122
|
if (platform3 === "win32") {
|
|
20033
20123
|
return [
|
|
@@ -20043,7 +20133,7 @@ function knownDoltDirs(platform3) {
|
|
|
20043
20133
|
].filter(Boolean);
|
|
20044
20134
|
}
|
|
20045
20135
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
20046
|
-
const P3 = platform3 === "win32" ?
|
|
20136
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
20047
20137
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
20048
20138
|
const names = doltBinaryNames(platform3);
|
|
20049
20139
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -20179,8 +20269,8 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
20179
20269
|
// src/beads/project-key.ts
|
|
20180
20270
|
var import_child_process21 = require("child_process");
|
|
20181
20271
|
var crypto2 = __toESM(require("crypto"));
|
|
20182
|
-
var
|
|
20183
|
-
var
|
|
20272
|
+
var fs51 = __toESM(require("fs"));
|
|
20273
|
+
var path54 = __toESM(require("path"));
|
|
20184
20274
|
function normalizeOrigin(raw) {
|
|
20185
20275
|
const trimmed = raw.trim();
|
|
20186
20276
|
if (!trimmed) return null;
|
|
@@ -20206,17 +20296,17 @@ function normalizeOrigin(raw) {
|
|
|
20206
20296
|
return `${host2}/${pathPart}`;
|
|
20207
20297
|
}
|
|
20208
20298
|
function findRepoRoot(cwd) {
|
|
20209
|
-
let dir =
|
|
20299
|
+
let dir = path54.resolve(cwd);
|
|
20210
20300
|
const seen = /* @__PURE__ */ new Set();
|
|
20211
20301
|
for (let i = 0; i < 256; i++) {
|
|
20212
20302
|
if (seen.has(dir)) return null;
|
|
20213
20303
|
seen.add(dir);
|
|
20214
20304
|
try {
|
|
20215
|
-
const stat3 =
|
|
20305
|
+
const stat3 = fs51.statSync(path54.join(dir, ".git"), { throwIfNoEntry: false });
|
|
20216
20306
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
20217
20307
|
} catch {
|
|
20218
20308
|
}
|
|
20219
|
-
const parent =
|
|
20309
|
+
const parent = path54.dirname(dir);
|
|
20220
20310
|
if (parent === dir) return null;
|
|
20221
20311
|
dir = parent;
|
|
20222
20312
|
}
|
|
@@ -20227,7 +20317,7 @@ var _execSeam2 = {
|
|
|
20227
20317
|
const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
|
|
20228
20318
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
20229
20319
|
},
|
|
20230
|
-
realpath: (p2) =>
|
|
20320
|
+
realpath: (p2) => fs51.realpathSync(p2)
|
|
20231
20321
|
};
|
|
20232
20322
|
function readOrigin(cwd) {
|
|
20233
20323
|
try {
|
|
@@ -20256,7 +20346,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
20256
20346
|
} catch {
|
|
20257
20347
|
}
|
|
20258
20348
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
20259
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
20349
|
+
return { projectKey: `path:${hash}`, projectLabel: path54.basename(real) || "project" };
|
|
20260
20350
|
}
|
|
20261
20351
|
|
|
20262
20352
|
// src/beads/project-prefix.ts
|
|
@@ -20301,17 +20391,17 @@ var _provisionSeam = {
|
|
|
20301
20391
|
};
|
|
20302
20392
|
var _linkSeam = {
|
|
20303
20393
|
platform: () => process.platform,
|
|
20304
|
-
homedir: () =>
|
|
20394
|
+
homedir: () => os41.homedir(),
|
|
20305
20395
|
isWritableDir: (dir) => {
|
|
20306
20396
|
try {
|
|
20307
|
-
|
|
20397
|
+
fs52.accessSync(dir, fs52.constants.W_OK);
|
|
20308
20398
|
return true;
|
|
20309
20399
|
} catch {
|
|
20310
20400
|
return false;
|
|
20311
20401
|
}
|
|
20312
20402
|
},
|
|
20313
20403
|
ensureDir: (dir) => {
|
|
20314
|
-
|
|
20404
|
+
fs52.mkdirSync(dir, { recursive: true });
|
|
20315
20405
|
},
|
|
20316
20406
|
/**
|
|
20317
20407
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -20332,9 +20422,9 @@ var _linkSeam = {
|
|
|
20332
20422
|
* which `linkBdOntoPath` creates if missing.
|
|
20333
20423
|
*/
|
|
20334
20424
|
cliBinDir: () => {
|
|
20335
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
20425
|
+
const pathDirs = (process.env.PATH ?? "").split(path55.delimiter).filter(Boolean);
|
|
20336
20426
|
const home = _linkSeam.homedir();
|
|
20337
|
-
const localBin = home ?
|
|
20427
|
+
const localBin = home ? path55.join(home, ".local", "bin") : null;
|
|
20338
20428
|
if (localBin) {
|
|
20339
20429
|
try {
|
|
20340
20430
|
_linkSeam.ensureDir(localBin);
|
|
@@ -20344,16 +20434,16 @@ var _linkSeam = {
|
|
|
20344
20434
|
const candidates = [];
|
|
20345
20435
|
if (localBin) candidates.push(localBin);
|
|
20346
20436
|
try {
|
|
20347
|
-
candidates.push(
|
|
20437
|
+
candidates.push(path55.dirname(process.execPath));
|
|
20348
20438
|
} catch {
|
|
20349
20439
|
}
|
|
20350
20440
|
candidates.push("/usr/local/bin");
|
|
20351
20441
|
const entry = process.argv[1];
|
|
20352
20442
|
if (entry) {
|
|
20353
20443
|
try {
|
|
20354
|
-
candidates.push(
|
|
20444
|
+
candidates.push(path55.dirname(fs52.realpathSync(entry)));
|
|
20355
20445
|
} catch {
|
|
20356
|
-
candidates.push(
|
|
20446
|
+
candidates.push(path55.dirname(entry));
|
|
20357
20447
|
}
|
|
20358
20448
|
}
|
|
20359
20449
|
const onPathWritable = candidates.find(
|
|
@@ -20365,20 +20455,20 @@ var _linkSeam = {
|
|
|
20365
20455
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
20366
20456
|
readlink: (linkPath) => {
|
|
20367
20457
|
try {
|
|
20368
|
-
return
|
|
20458
|
+
return fs52.readlinkSync(linkPath);
|
|
20369
20459
|
} catch {
|
|
20370
20460
|
return null;
|
|
20371
20461
|
}
|
|
20372
20462
|
},
|
|
20373
|
-
unlink: (linkPath) =>
|
|
20374
|
-
symlink: (target, linkPath) =>
|
|
20463
|
+
unlink: (linkPath) => fs52.unlinkSync(linkPath),
|
|
20464
|
+
symlink: (target, linkPath) => fs52.symlinkSync(target, linkPath)
|
|
20375
20465
|
};
|
|
20376
20466
|
function linkBdOntoPath(binaryPath) {
|
|
20377
20467
|
if (_linkSeam.platform() === "win32") return;
|
|
20378
20468
|
const binDir = _linkSeam.cliBinDir();
|
|
20379
20469
|
if (!binDir) return;
|
|
20380
20470
|
_linkSeam.ensureDir(binDir);
|
|
20381
|
-
const linkPath =
|
|
20471
|
+
const linkPath = path55.join(binDir, "bd");
|
|
20382
20472
|
if (linkPath === binaryPath) return;
|
|
20383
20473
|
const current = _linkSeam.readlink(linkPath);
|
|
20384
20474
|
if (current === binaryPath) return;
|
|
@@ -20573,7 +20663,7 @@ function dedupeRecipes(agents) {
|
|
|
20573
20663
|
|
|
20574
20664
|
// src/beads/watcher.ts
|
|
20575
20665
|
var crypto4 = __toESM(require("crypto"));
|
|
20576
|
-
var
|
|
20666
|
+
var path56 = __toESM(require("path"));
|
|
20577
20667
|
var API_BASE6 = resolveApiBaseUrl();
|
|
20578
20668
|
var DEBOUNCE_MS2 = 400;
|
|
20579
20669
|
var ZERO_SUMMARY = {
|
|
@@ -20597,7 +20687,7 @@ var BeadsWatcher = class {
|
|
|
20597
20687
|
constructor(opts) {
|
|
20598
20688
|
this.opts = opts;
|
|
20599
20689
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
20600
|
-
this.feedPath = opts.feedPath ??
|
|
20690
|
+
this.feedPath = opts.feedPath ?? path56.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
20601
20691
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
20602
20692
|
}
|
|
20603
20693
|
opts;
|
|
@@ -20848,15 +20938,15 @@ async function handleBeadsActionCommand(action, started) {
|
|
|
20848
20938
|
}
|
|
20849
20939
|
|
|
20850
20940
|
// src/beads/config-store.ts
|
|
20851
|
-
var
|
|
20852
|
-
var
|
|
20853
|
-
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"));
|
|
20854
20944
|
function beadsConfigPath() {
|
|
20855
|
-
return
|
|
20945
|
+
return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "beads-config.json");
|
|
20856
20946
|
}
|
|
20857
20947
|
function readBeadsEnabled() {
|
|
20858
20948
|
try {
|
|
20859
|
-
const raw =
|
|
20949
|
+
const raw = import_node_fs8.default.readFileSync(beadsConfigPath(), "utf8");
|
|
20860
20950
|
const cfg = JSON.parse(raw);
|
|
20861
20951
|
return cfg.enabled !== false;
|
|
20862
20952
|
} catch {
|
|
@@ -20865,10 +20955,10 @@ function readBeadsEnabled() {
|
|
|
20865
20955
|
}
|
|
20866
20956
|
function persistBeadsConfig(cfg) {
|
|
20867
20957
|
const file = beadsConfigPath();
|
|
20868
|
-
|
|
20958
|
+
import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true });
|
|
20869
20959
|
const tmp = `${file}.tmp`;
|
|
20870
|
-
|
|
20871
|
-
|
|
20960
|
+
import_node_fs8.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
|
|
20961
|
+
import_node_fs8.default.renameSync(tmp, file);
|
|
20872
20962
|
restrictToOwner(file);
|
|
20873
20963
|
}
|
|
20874
20964
|
|
|
@@ -21014,8 +21104,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
21014
21104
|
function saveFilesTemp(files) {
|
|
21015
21105
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
21016
21106
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
21017
|
-
const tmpPath =
|
|
21018
|
-
|
|
21107
|
+
const tmpPath = path58.join(os43.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
21108
|
+
fs54.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
21019
21109
|
pendingAttachmentFiles.add(tmpPath);
|
|
21020
21110
|
return tmpPath;
|
|
21021
21111
|
});
|
|
@@ -21227,9 +21317,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
21227
21317
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
21228
21318
|
};
|
|
21229
21319
|
var envReadH = async (ctx, cmd) => {
|
|
21230
|
-
const envPath =
|
|
21320
|
+
const envPath = path58.join(process.cwd(), ".env");
|
|
21231
21321
|
try {
|
|
21232
|
-
const raw = await
|
|
21322
|
+
const raw = await fs54.promises.readFile(envPath, "utf8");
|
|
21233
21323
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
21234
21324
|
exists: true,
|
|
21235
21325
|
vars: parseDotenv(raw)
|
|
@@ -21260,14 +21350,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
21260
21350
|
}
|
|
21261
21351
|
seen.add(v.key);
|
|
21262
21352
|
}
|
|
21263
|
-
const envPath =
|
|
21264
|
-
const tmpPath =
|
|
21353
|
+
const envPath = path58.join(process.cwd(), ".env");
|
|
21354
|
+
const tmpPath = path58.join(process.cwd(), ".env.codeam.tmp");
|
|
21265
21355
|
try {
|
|
21266
|
-
await
|
|
21267
|
-
await
|
|
21356
|
+
await fs54.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
21357
|
+
await fs54.promises.rename(tmpPath, envPath);
|
|
21268
21358
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
21269
21359
|
} catch (err) {
|
|
21270
|
-
await
|
|
21360
|
+
await fs54.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
21271
21361
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
21272
21362
|
}
|
|
21273
21363
|
};
|
|
@@ -21311,7 +21401,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21311
21401
|
let configuredAgent = rawAgentId;
|
|
21312
21402
|
if (!configuredAgent) {
|
|
21313
21403
|
try {
|
|
21314
|
-
const raw = JSON.parse(
|
|
21404
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21315
21405
|
configuredAgent = raw.agent ?? "";
|
|
21316
21406
|
} catch {
|
|
21317
21407
|
}
|
|
@@ -21345,7 +21435,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21345
21435
|
persist: persistHeadroomConfig,
|
|
21346
21436
|
readEnabled: () => {
|
|
21347
21437
|
try {
|
|
21348
|
-
const raw = JSON.parse(
|
|
21438
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21349
21439
|
return raw.enabled === true;
|
|
21350
21440
|
} catch {
|
|
21351
21441
|
return false;
|
|
@@ -21592,7 +21682,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
21592
21682
|
}
|
|
21593
21683
|
let headroomActive = false;
|
|
21594
21684
|
try {
|
|
21595
|
-
const raw = JSON.parse(
|
|
21685
|
+
const raw = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21596
21686
|
headroomActive = raw.enabled === true;
|
|
21597
21687
|
} catch {
|
|
21598
21688
|
}
|
|
@@ -21602,7 +21692,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
21602
21692
|
}
|
|
21603
21693
|
let existingConfig = { enabled: true };
|
|
21604
21694
|
try {
|
|
21605
|
-
existingConfig = JSON.parse(
|
|
21695
|
+
existingConfig = JSON.parse(fs54.readFileSync(headroomConfigPath(), "utf8"));
|
|
21606
21696
|
} catch {
|
|
21607
21697
|
}
|
|
21608
21698
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -21715,13 +21805,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
21715
21805
|
function buildNpmInstallInvocation(opts) {
|
|
21716
21806
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
21717
21807
|
const execPath = opts?.execPath ?? process.execPath;
|
|
21718
|
-
const exists2 = opts?.existsSync ??
|
|
21719
|
-
const normalized = entryScript.split(
|
|
21808
|
+
const exists2 = opts?.existsSync ?? fs54.existsSync;
|
|
21809
|
+
const normalized = entryScript.split(path58.sep).join("/");
|
|
21720
21810
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
21721
21811
|
const markerIdx = normalized.indexOf(marker);
|
|
21722
21812
|
const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
|
|
21723
|
-
const siblingNpm =
|
|
21724
|
-
|
|
21813
|
+
const siblingNpm = path58.join(
|
|
21814
|
+
path58.dirname(execPath),
|
|
21725
21815
|
process.platform === "win32" ? "npm.cmd" : "npm"
|
|
21726
21816
|
);
|
|
21727
21817
|
const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
|
|
@@ -22588,11 +22678,11 @@ function resolveTokenValue(args2) {
|
|
|
22588
22678
|
}
|
|
22589
22679
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
22590
22680
|
if (fileFlag) {
|
|
22591
|
-
const
|
|
22681
|
+
const path73 = fileFlag.slice("--token-file=".length);
|
|
22592
22682
|
try {
|
|
22593
|
-
const content =
|
|
22594
|
-
if (content.length === 0) fail(`--token-file ${
|
|
22595
|
-
rmIfExistsQuiet(
|
|
22683
|
+
const content = fs55.readFileSync(path73, "utf8").trim();
|
|
22684
|
+
if (content.length === 0) fail(`--token-file ${path73} is empty`);
|
|
22685
|
+
rmIfExistsQuiet(path73);
|
|
22596
22686
|
return content;
|
|
22597
22687
|
} catch (err) {
|
|
22598
22688
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -22621,7 +22711,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
22621
22711
|
pluginId,
|
|
22622
22712
|
ideName: "codeam-cli (codespace)",
|
|
22623
22713
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
22624
|
-
hostname:
|
|
22714
|
+
hostname: os44.hostname(),
|
|
22625
22715
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
22626
22716
|
// Current git branch of the codespace's working directory, so the
|
|
22627
22717
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -22682,7 +22772,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
22682
22772
|
}
|
|
22683
22773
|
}
|
|
22684
22774
|
function pairAutoLockPath() {
|
|
22685
|
-
return
|
|
22775
|
+
return path59.join(os44.homedir(), ".codeam", "pair-auto.lock");
|
|
22686
22776
|
}
|
|
22687
22777
|
function isLivePairAuto(pid) {
|
|
22688
22778
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -22692,7 +22782,7 @@ function isLivePairAuto(pid) {
|
|
|
22692
22782
|
if (e.code !== "EPERM") return false;
|
|
22693
22783
|
}
|
|
22694
22784
|
try {
|
|
22695
|
-
return
|
|
22785
|
+
return fs55.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
22696
22786
|
} catch {
|
|
22697
22787
|
return true;
|
|
22698
22788
|
}
|
|
@@ -22702,24 +22792,24 @@ function isLiveCodeam(pid) {
|
|
|
22702
22792
|
}
|
|
22703
22793
|
function daemonLockPath(sessionId) {
|
|
22704
22794
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
22705
|
-
return
|
|
22795
|
+
return path59.join(os44.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
22706
22796
|
}
|
|
22707
22797
|
function acquireDaemonLock(sessionId) {
|
|
22708
22798
|
const lockPath = daemonLockPath(sessionId);
|
|
22709
22799
|
try {
|
|
22710
|
-
|
|
22800
|
+
fs55.mkdirSync(path59.dirname(lockPath), { recursive: true });
|
|
22711
22801
|
try {
|
|
22712
|
-
|
|
22802
|
+
fs55.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
22713
22803
|
} catch (e) {
|
|
22714
22804
|
if (e.code !== "EEXIST") throw e;
|
|
22715
|
-
const holder = Number(
|
|
22805
|
+
const holder = Number(fs55.readFileSync(lockPath, "utf8").trim());
|
|
22716
22806
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
22717
|
-
|
|
22807
|
+
fs55.writeFileSync(lockPath, String(process.pid));
|
|
22718
22808
|
}
|
|
22719
22809
|
const release3 = () => {
|
|
22720
22810
|
try {
|
|
22721
|
-
if (
|
|
22722
|
-
|
|
22811
|
+
if (fs55.existsSync(lockPath) && Number(fs55.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
22812
|
+
fs55.unlinkSync(lockPath);
|
|
22723
22813
|
}
|
|
22724
22814
|
} catch {
|
|
22725
22815
|
}
|
|
@@ -22741,19 +22831,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
22741
22831
|
function acquireSingletonLock() {
|
|
22742
22832
|
const lockPath = pairAutoLockPath();
|
|
22743
22833
|
try {
|
|
22744
|
-
|
|
22834
|
+
fs55.mkdirSync(path59.dirname(lockPath), { recursive: true });
|
|
22745
22835
|
try {
|
|
22746
|
-
|
|
22836
|
+
fs55.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
22747
22837
|
} catch (e) {
|
|
22748
22838
|
if (e.code !== "EEXIST") throw e;
|
|
22749
|
-
const holder = Number(
|
|
22839
|
+
const holder = Number(fs55.readFileSync(lockPath, "utf8").trim());
|
|
22750
22840
|
if (isLivePairAuto(holder)) return false;
|
|
22751
|
-
|
|
22841
|
+
fs55.writeFileSync(lockPath, String(process.pid));
|
|
22752
22842
|
}
|
|
22753
22843
|
process.once("exit", () => {
|
|
22754
22844
|
try {
|
|
22755
|
-
if (
|
|
22756
|
-
|
|
22845
|
+
if (fs55.existsSync(lockPath) && Number(fs55.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
22846
|
+
fs55.unlinkSync(lockPath);
|
|
22757
22847
|
}
|
|
22758
22848
|
} catch {
|
|
22759
22849
|
}
|
|
@@ -23199,7 +23289,7 @@ var AgentService = class _AgentService {
|
|
|
23199
23289
|
};
|
|
23200
23290
|
|
|
23201
23291
|
// src/agents/acp/adapters.ts
|
|
23202
|
-
var
|
|
23292
|
+
var path61 = __toESM(require("path"));
|
|
23203
23293
|
|
|
23204
23294
|
// src/agents/acp/agent-binary.ts
|
|
23205
23295
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -23375,11 +23465,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
23375
23465
|
|
|
23376
23466
|
// src/agents/kimi/installer.ts
|
|
23377
23467
|
var import_node_child_process25 = require("child_process");
|
|
23378
|
-
var
|
|
23379
|
-
var
|
|
23468
|
+
var import_node_os8 = require("os");
|
|
23469
|
+
var import_node_path7 = require("path");
|
|
23380
23470
|
var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
|
|
23381
23471
|
function kimiBinDir() {
|
|
23382
|
-
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");
|
|
23383
23473
|
}
|
|
23384
23474
|
function kimiRuns() {
|
|
23385
23475
|
const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
|
|
@@ -23442,13 +23532,13 @@ function resolveBin(pkgName, binName) {
|
|
|
23442
23532
|
try {
|
|
23443
23533
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
23444
23534
|
const manifest = require_(`${pkgName}/package.json`);
|
|
23445
|
-
const pkgDir =
|
|
23535
|
+
const pkgDir = path61.dirname(manifestPath);
|
|
23446
23536
|
const bin = manifest.bin;
|
|
23447
23537
|
if (!bin) return null;
|
|
23448
|
-
if (typeof bin === "string") return
|
|
23538
|
+
if (typeof bin === "string") return path61.resolve(pkgDir, bin);
|
|
23449
23539
|
const target = binName ?? Object.keys(bin)[0];
|
|
23450
23540
|
if (!target || !bin[target]) return null;
|
|
23451
|
-
return
|
|
23541
|
+
return path61.resolve(pkgDir, bin[target]);
|
|
23452
23542
|
} catch {
|
|
23453
23543
|
return null;
|
|
23454
23544
|
}
|
|
@@ -23552,9 +23642,9 @@ function requiresAcp(agent) {
|
|
|
23552
23642
|
var import_node_crypto10 = require("crypto");
|
|
23553
23643
|
|
|
23554
23644
|
// src/services/history.service.ts
|
|
23555
|
-
var
|
|
23556
|
-
var
|
|
23557
|
-
var
|
|
23645
|
+
var fs57 = __toESM(require("fs"));
|
|
23646
|
+
var path62 = __toESM(require("path"));
|
|
23647
|
+
var os46 = __toESM(require("os"));
|
|
23558
23648
|
var https7 = __toESM(require("https"));
|
|
23559
23649
|
var http6 = __toESM(require("http"));
|
|
23560
23650
|
var import_zod2 = require("zod");
|
|
@@ -23581,7 +23671,7 @@ function parseJsonl(filePath) {
|
|
|
23581
23671
|
const messages = [];
|
|
23582
23672
|
let raw;
|
|
23583
23673
|
try {
|
|
23584
|
-
raw =
|
|
23674
|
+
raw = fs57.readFileSync(filePath, "utf8");
|
|
23585
23675
|
} catch (err) {
|
|
23586
23676
|
if (err.code !== "ENOENT") {
|
|
23587
23677
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -23722,7 +23812,7 @@ var HistoryService = class _HistoryService {
|
|
|
23722
23812
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
23723
23813
|
}
|
|
23724
23814
|
get projectDir() {
|
|
23725
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23815
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path62.join(os46.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
23726
23816
|
}
|
|
23727
23817
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
23728
23818
|
setCurrentConversationId(id) {
|
|
@@ -23734,7 +23824,7 @@ var HistoryService = class _HistoryService {
|
|
|
23734
23824
|
/** Return the current message count in the active conversation. */
|
|
23735
23825
|
getCurrentMessageCount() {
|
|
23736
23826
|
if (!this.currentConversationId) return 0;
|
|
23737
|
-
const filePath =
|
|
23827
|
+
const filePath = path62.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23738
23828
|
return parseJsonl(filePath).length;
|
|
23739
23829
|
}
|
|
23740
23830
|
/**
|
|
@@ -23745,7 +23835,7 @@ var HistoryService = class _HistoryService {
|
|
|
23745
23835
|
const deadline = Date.now() + timeoutMs;
|
|
23746
23836
|
while (Date.now() < deadline) {
|
|
23747
23837
|
if (!this.currentConversationId) return null;
|
|
23748
|
-
const filePath =
|
|
23838
|
+
const filePath = path62.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23749
23839
|
const messages = parseJsonl(filePath);
|
|
23750
23840
|
if (messages.length > previousCount) {
|
|
23751
23841
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -23771,16 +23861,16 @@ var HistoryService = class _HistoryService {
|
|
|
23771
23861
|
const dir = this.projectDir;
|
|
23772
23862
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23773
23863
|
try {
|
|
23774
|
-
const files =
|
|
23864
|
+
const files = fs57.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23775
23865
|
try {
|
|
23776
|
-
const stat3 =
|
|
23866
|
+
const stat3 = fs57.statSync(path62.join(dir, e.name));
|
|
23777
23867
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23778
23868
|
} catch {
|
|
23779
23869
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
23780
23870
|
}
|
|
23781
23871
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
23782
23872
|
if (files.length > 0) {
|
|
23783
|
-
this.currentConversationId =
|
|
23873
|
+
this.currentConversationId = path62.basename(files[0].name, ".jsonl");
|
|
23784
23874
|
}
|
|
23785
23875
|
} catch {
|
|
23786
23876
|
}
|
|
@@ -23814,13 +23904,13 @@ var HistoryService = class _HistoryService {
|
|
|
23814
23904
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23815
23905
|
let entries;
|
|
23816
23906
|
try {
|
|
23817
|
-
entries =
|
|
23907
|
+
entries = fs57.readdirSync(dir, { withFileTypes: true });
|
|
23818
23908
|
} catch {
|
|
23819
23909
|
return null;
|
|
23820
23910
|
}
|
|
23821
23911
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23822
23912
|
try {
|
|
23823
|
-
const stat3 =
|
|
23913
|
+
const stat3 = fs57.statSync(path62.join(dir, e.name));
|
|
23824
23914
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23825
23915
|
} catch {
|
|
23826
23916
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -23829,12 +23919,12 @@ var HistoryService = class _HistoryService {
|
|
|
23829
23919
|
if (files.length === 0) return null;
|
|
23830
23920
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
23831
23921
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
23832
|
-
return this.extractUsageFromFile(
|
|
23922
|
+
return this.extractUsageFromFile(path62.join(dir, targetFile));
|
|
23833
23923
|
}
|
|
23834
23924
|
extractUsageFromFile(filePath) {
|
|
23835
23925
|
let raw;
|
|
23836
23926
|
try {
|
|
23837
|
-
raw =
|
|
23927
|
+
raw = fs57.readFileSync(filePath, "utf8");
|
|
23838
23928
|
} catch {
|
|
23839
23929
|
return null;
|
|
23840
23930
|
}
|
|
@@ -23879,9 +23969,9 @@ var HistoryService = class _HistoryService {
|
|
|
23879
23969
|
let totalCost = 0;
|
|
23880
23970
|
let files;
|
|
23881
23971
|
try {
|
|
23882
|
-
files =
|
|
23972
|
+
files = fs57.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23883
23973
|
try {
|
|
23884
|
-
return
|
|
23974
|
+
return fs57.statSync(path62.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23885
23975
|
} catch {
|
|
23886
23976
|
return false;
|
|
23887
23977
|
}
|
|
@@ -23892,7 +23982,7 @@ var HistoryService = class _HistoryService {
|
|
|
23892
23982
|
for (const file of files) {
|
|
23893
23983
|
let raw;
|
|
23894
23984
|
try {
|
|
23895
|
-
raw =
|
|
23985
|
+
raw = fs57.readFileSync(path62.join(projectDir, file), "utf8");
|
|
23896
23986
|
} catch {
|
|
23897
23987
|
continue;
|
|
23898
23988
|
}
|
|
@@ -23971,7 +24061,7 @@ var HistoryService = class _HistoryService {
|
|
|
23971
24061
|
if (this.runtime.resolveHistoryFile) {
|
|
23972
24062
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
23973
24063
|
}
|
|
23974
|
-
return
|
|
24064
|
+
return path62.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23975
24065
|
}
|
|
23976
24066
|
/**
|
|
23977
24067
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -24005,7 +24095,7 @@ var HistoryService = class _HistoryService {
|
|
|
24005
24095
|
};
|
|
24006
24096
|
});
|
|
24007
24097
|
}
|
|
24008
|
-
return parseJsonl(
|
|
24098
|
+
return parseJsonl(path62.join(this.projectDir, `${sessionId}.jsonl`));
|
|
24009
24099
|
}
|
|
24010
24100
|
async loadConversation(sessionId) {
|
|
24011
24101
|
const messages = this.readConversation(sessionId);
|
|
@@ -24061,7 +24151,7 @@ var HistoryService = class _HistoryService {
|
|
|
24061
24151
|
if (!filePath) return false;
|
|
24062
24152
|
let mtimeMs;
|
|
24063
24153
|
try {
|
|
24064
|
-
mtimeMs =
|
|
24154
|
+
mtimeMs = fs57.statSync(filePath).mtimeMs;
|
|
24065
24155
|
} catch {
|
|
24066
24156
|
return false;
|
|
24067
24157
|
}
|
|
@@ -24130,10 +24220,10 @@ var HistoryService = class _HistoryService {
|
|
|
24130
24220
|
|
|
24131
24221
|
// src/agents/acp/client.ts
|
|
24132
24222
|
var import_node_child_process26 = require("child_process");
|
|
24133
|
-
var
|
|
24223
|
+
var fs58 = __toESM(require("fs/promises"));
|
|
24134
24224
|
var fsSync = __toESM(require("fs"));
|
|
24135
|
-
var
|
|
24136
|
-
var
|
|
24225
|
+
var os47 = __toESM(require("os"));
|
|
24226
|
+
var path63 = __toESM(require("path"));
|
|
24137
24227
|
var import_node_stream = require("stream");
|
|
24138
24228
|
|
|
24139
24229
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -26857,7 +26947,7 @@ var AcpClient = class {
|
|
|
26857
26947
|
let newSession;
|
|
26858
26948
|
try {
|
|
26859
26949
|
newSession = await Promise.race([
|
|
26860
|
-
this.connection.newSession({ cwd, mcpServers: [] }),
|
|
26950
|
+
this.connection.newSession({ cwd, mcpServers: this.opts.mcpServers ?? [] }),
|
|
26861
26951
|
startupFailure,
|
|
26862
26952
|
startAborted
|
|
26863
26953
|
]);
|
|
@@ -26996,7 +27086,7 @@ var AcpClient = class {
|
|
|
26996
27086
|
await this.connection.loadSession({
|
|
26997
27087
|
sessionId,
|
|
26998
27088
|
cwd: this.opts.cwd,
|
|
26999
|
-
mcpServers: []
|
|
27089
|
+
mcpServers: this.opts.mcpServers ?? []
|
|
27000
27090
|
});
|
|
27001
27091
|
this.sessionId = sessionId;
|
|
27002
27092
|
log.info("acpClient", `loadSession \u2190 ok sessionId=${sessionId.slice(0, 8)}`);
|
|
@@ -27111,7 +27201,7 @@ var AcpClient = class {
|
|
|
27111
27201
|
},
|
|
27112
27202
|
readTextFile: async (params) => {
|
|
27113
27203
|
try {
|
|
27114
|
-
const content = await
|
|
27204
|
+
const content = await fs58.readFile(params.path, "utf8");
|
|
27115
27205
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
27116
27206
|
} catch (err) {
|
|
27117
27207
|
const code = err.code;
|
|
@@ -27131,7 +27221,7 @@ var AcpClient = class {
|
|
|
27131
27221
|
},
|
|
27132
27222
|
writeTextFile: async (params) => {
|
|
27133
27223
|
try {
|
|
27134
|
-
await
|
|
27224
|
+
await fs58.writeFile(params.path, params.content, "utf8");
|
|
27135
27225
|
return {};
|
|
27136
27226
|
} catch (err) {
|
|
27137
27227
|
const code = err.code;
|
|
@@ -27180,29 +27270,29 @@ function applyLineRange(content, line, limit) {
|
|
|
27180
27270
|
return { content: lines.slice(start2, end).join("\n") };
|
|
27181
27271
|
}
|
|
27182
27272
|
function knownAgentBinaryDirs() {
|
|
27183
|
-
const home =
|
|
27273
|
+
const home = os47.homedir();
|
|
27184
27274
|
const out2 = [];
|
|
27185
27275
|
out2.push("/tmp/codeam-node20/bin");
|
|
27186
27276
|
for (const root of [
|
|
27187
27277
|
"/usr/local/share/nvm/versions/node",
|
|
27188
|
-
|
|
27278
|
+
path63.join(home, ".nvm/versions/node")
|
|
27189
27279
|
]) {
|
|
27190
27280
|
try {
|
|
27191
27281
|
for (const child of fsSync.readdirSync(root)) {
|
|
27192
|
-
out2.push(
|
|
27282
|
+
out2.push(path63.join(root, child, "bin"));
|
|
27193
27283
|
}
|
|
27194
27284
|
} catch {
|
|
27195
27285
|
}
|
|
27196
27286
|
}
|
|
27197
|
-
out2.push(
|
|
27287
|
+
out2.push(path63.join(home, ".volta/bin"));
|
|
27198
27288
|
out2.push("/usr/local/bin");
|
|
27199
27289
|
out2.push("/usr/bin");
|
|
27200
|
-
out2.push(
|
|
27201
|
-
out2.push(
|
|
27290
|
+
out2.push(path63.join(home, ".local/bin"));
|
|
27291
|
+
out2.push(path63.join(home, "bin"));
|
|
27202
27292
|
if (process.platform === "win32") {
|
|
27203
27293
|
const { LOCALAPPDATA, APPDATA } = process.env;
|
|
27204
|
-
if (LOCALAPPDATA) out2.push(
|
|
27205
|
-
if (APPDATA) out2.push(
|
|
27294
|
+
if (LOCALAPPDATA) out2.push(path63.join(LOCALAPPDATA, "cursor-agent"));
|
|
27295
|
+
if (APPDATA) out2.push(path63.join(APPDATA, "npm"));
|
|
27206
27296
|
}
|
|
27207
27297
|
return out2.filter((p2) => {
|
|
27208
27298
|
try {
|
|
@@ -27214,7 +27304,7 @@ function knownAgentBinaryDirs() {
|
|
|
27214
27304
|
}
|
|
27215
27305
|
function expandPathForAgentBinaries(existingPath) {
|
|
27216
27306
|
const existing = new Set(
|
|
27217
|
-
existingPath.split(
|
|
27307
|
+
existingPath.split(path63.delimiter).filter((p2) => p2.length > 0)
|
|
27218
27308
|
);
|
|
27219
27309
|
const additions = [];
|
|
27220
27310
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -27224,7 +27314,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
27224
27314
|
}
|
|
27225
27315
|
}
|
|
27226
27316
|
if (additions.length === 0) return existingPath;
|
|
27227
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
27317
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path63.delimiter);
|
|
27228
27318
|
}
|
|
27229
27319
|
|
|
27230
27320
|
// src/agents/acp/headroom-budget-proxy.ts
|
|
@@ -27706,15 +27796,15 @@ function commonPrefixLength(a, b) {
|
|
|
27706
27796
|
|
|
27707
27797
|
// src/agents/acp/onboarding.ts
|
|
27708
27798
|
var import_child_process26 = require("child_process");
|
|
27709
|
-
var
|
|
27710
|
-
var
|
|
27711
|
-
var
|
|
27799
|
+
var fs59 = __toESM(require("fs"));
|
|
27800
|
+
var os48 = __toESM(require("os"));
|
|
27801
|
+
var path64 = __toESM(require("path"));
|
|
27712
27802
|
var _onboardingSeam = {
|
|
27713
|
-
markerPath: (sessionId) =>
|
|
27714
|
-
exists: (p2) =>
|
|
27803
|
+
markerPath: (sessionId) => path64.join(os48.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
27804
|
+
exists: (p2) => fs59.existsSync(p2),
|
|
27715
27805
|
write: (p2) => {
|
|
27716
|
-
|
|
27717
|
-
|
|
27806
|
+
fs59.mkdirSync(path64.dirname(p2), { recursive: true });
|
|
27807
|
+
fs59.writeFileSync(p2, "");
|
|
27718
27808
|
},
|
|
27719
27809
|
disabled: () => {
|
|
27720
27810
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -27751,7 +27841,7 @@ function resolveRepoName(cwd) {
|
|
|
27751
27841
|
if (name) return name;
|
|
27752
27842
|
}
|
|
27753
27843
|
}
|
|
27754
|
-
const base =
|
|
27844
|
+
const base = path64.basename(cwd || "");
|
|
27755
27845
|
if (base && !isUuid(base)) return base;
|
|
27756
27846
|
return "this project";
|
|
27757
27847
|
}
|
|
@@ -28003,8 +28093,8 @@ var import_crypto5 = require("crypto");
|
|
|
28003
28093
|
|
|
28004
28094
|
// src/services/turn-files/git-changeset.ts
|
|
28005
28095
|
var import_child_process27 = require("child_process");
|
|
28006
|
-
var
|
|
28007
|
-
var
|
|
28096
|
+
var fs60 = __toESM(require("fs/promises"));
|
|
28097
|
+
var path65 = __toESM(require("path"));
|
|
28008
28098
|
async function collectRepoChangeset(opts) {
|
|
28009
28099
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
28010
28100
|
if (status2 === null) return null;
|
|
@@ -28022,7 +28112,7 @@ async function collectRepoChangeset(opts) {
|
|
|
28022
28112
|
let stats;
|
|
28023
28113
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
28024
28114
|
const lineCount = await readUntrackedLineCount(
|
|
28025
|
-
|
|
28115
|
+
path65.join(opts.repoRoot, row.filePath)
|
|
28026
28116
|
);
|
|
28027
28117
|
stats = { added: lineCount, removed: 0 };
|
|
28028
28118
|
} else {
|
|
@@ -28053,7 +28143,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
28053
28143
|
}
|
|
28054
28144
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
28055
28145
|
try {
|
|
28056
|
-
const content = await
|
|
28146
|
+
const content = await fs60.readFile(absPath, "utf8");
|
|
28057
28147
|
let count = 0;
|
|
28058
28148
|
let pos = -1;
|
|
28059
28149
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -28145,7 +28235,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
28145
28235
|
});
|
|
28146
28236
|
}
|
|
28147
28237
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
28148
|
-
const
|
|
28238
|
+
const fs65 = await import("fs/promises");
|
|
28149
28239
|
const out2 = [];
|
|
28150
28240
|
await walk(workingDir, 0);
|
|
28151
28241
|
return out2;
|
|
@@ -28153,7 +28243,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28153
28243
|
if (depth > maxDepth) return;
|
|
28154
28244
|
let entries = [];
|
|
28155
28245
|
try {
|
|
28156
|
-
const dirents = await
|
|
28246
|
+
const dirents = await fs65.readdir(dir, { withFileTypes: true });
|
|
28157
28247
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
28158
28248
|
} catch {
|
|
28159
28249
|
return;
|
|
@@ -28164,8 +28254,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28164
28254
|
if (hasGit) {
|
|
28165
28255
|
out2.push({
|
|
28166
28256
|
repoRoot: dir,
|
|
28167
|
-
repoPath:
|
|
28168
|
-
repoName:
|
|
28257
|
+
repoPath: path65.relative(workingDir, dir),
|
|
28258
|
+
repoName: path65.basename(dir)
|
|
28169
28259
|
});
|
|
28170
28260
|
return;
|
|
28171
28261
|
}
|
|
@@ -28173,14 +28263,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
28173
28263
|
if (!entry.isDirectory) continue;
|
|
28174
28264
|
if (entry.name === "node_modules") continue;
|
|
28175
28265
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
28176
|
-
await walk(
|
|
28266
|
+
await walk(path65.join(dir, entry.name), depth + 1);
|
|
28177
28267
|
}
|
|
28178
28268
|
}
|
|
28179
28269
|
}
|
|
28180
28270
|
|
|
28181
28271
|
// src/services/turn-files/files-outbox.ts
|
|
28182
|
-
var
|
|
28183
|
-
var
|
|
28272
|
+
var fs61 = __toESM(require("fs/promises"));
|
|
28273
|
+
var path66 = __toESM(require("path"));
|
|
28184
28274
|
var import_os11 = require("os");
|
|
28185
28275
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
28186
28276
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -28213,16 +28303,16 @@ var FilesOutbox = class {
|
|
|
28213
28303
|
backoffIndex = 0;
|
|
28214
28304
|
stopped = false;
|
|
28215
28305
|
constructor(opts) {
|
|
28216
|
-
const base = opts.baseDir ??
|
|
28217
|
-
this.filePath =
|
|
28306
|
+
const base = opts.baseDir ?? path66.join(homeDir(), HOME_OUTBOX_DIR);
|
|
28307
|
+
this.filePath = path66.join(base, `${opts.sessionId}.jsonl`);
|
|
28218
28308
|
this.post = opts.post;
|
|
28219
28309
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
28220
28310
|
}
|
|
28221
28311
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
28222
28312
|
* line is durable on disk (not once the POST succeeds). */
|
|
28223
28313
|
async enqueue(entry) {
|
|
28224
|
-
await
|
|
28225
|
-
await
|
|
28314
|
+
await fs61.mkdir(path66.dirname(this.filePath), { recursive: true });
|
|
28315
|
+
await fs61.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
28226
28316
|
this.backoffIndex = 0;
|
|
28227
28317
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
28228
28318
|
}
|
|
@@ -28313,7 +28403,7 @@ var FilesOutbox = class {
|
|
|
28313
28403
|
async readAll() {
|
|
28314
28404
|
let raw = "";
|
|
28315
28405
|
try {
|
|
28316
|
-
raw = await
|
|
28406
|
+
raw = await fs61.readFile(this.filePath, "utf8");
|
|
28317
28407
|
} catch {
|
|
28318
28408
|
return [];
|
|
28319
28409
|
}
|
|
@@ -28337,12 +28427,12 @@ var FilesOutbox = class {
|
|
|
28337
28427
|
async rewrite(entries) {
|
|
28338
28428
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
28339
28429
|
if (entries.length === 0) {
|
|
28340
|
-
await
|
|
28430
|
+
await fs61.unlink(this.filePath).catch(() => void 0);
|
|
28341
28431
|
return;
|
|
28342
28432
|
}
|
|
28343
28433
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
28344
|
-
await
|
|
28345
|
-
await
|
|
28434
|
+
await fs61.writeFile(tmpPath, payload, "utf8");
|
|
28435
|
+
await fs61.rename(tmpPath, this.filePath);
|
|
28346
28436
|
}
|
|
28347
28437
|
};
|
|
28348
28438
|
function applyJitter(ms) {
|
|
@@ -29840,6 +29930,7 @@ async function runAcpSession(opts) {
|
|
|
29840
29930
|
adapter: opts.adapter,
|
|
29841
29931
|
cwd: opts.cwd,
|
|
29842
29932
|
extraEnv,
|
|
29933
|
+
mcpServers: opts.mcpServers,
|
|
29843
29934
|
onSessionUpdate: (notification) => {
|
|
29844
29935
|
updateCount += 1;
|
|
29845
29936
|
const variant = notification.update?.sessionUpdate ?? "unknown";
|
|
@@ -31098,6 +31189,43 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
31098
31189
|
});
|
|
31099
31190
|
}
|
|
31100
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
|
+
|
|
31101
31229
|
// src/baton/baton-controller.ts
|
|
31102
31230
|
var BatonController = class {
|
|
31103
31231
|
constructor(deps) {
|
|
@@ -31447,7 +31575,7 @@ var AcpDriver = class {
|
|
|
31447
31575
|
};
|
|
31448
31576
|
|
|
31449
31577
|
// src/baton/transcript-mirror.ts
|
|
31450
|
-
var
|
|
31578
|
+
var fs62 = __toESM(require("fs"));
|
|
31451
31579
|
var TranscriptMirror = class {
|
|
31452
31580
|
constructor(deps) {
|
|
31453
31581
|
this.deps = deps;
|
|
@@ -31514,7 +31642,7 @@ var TranscriptMirror = class {
|
|
|
31514
31642
|
}
|
|
31515
31643
|
};
|
|
31516
31644
|
function defaultWatch(file, onChange) {
|
|
31517
|
-
const w3 =
|
|
31645
|
+
const w3 = fs62.watch(file, { persistent: false }, () => onChange());
|
|
31518
31646
|
return () => w3.close();
|
|
31519
31647
|
}
|
|
31520
31648
|
|
|
@@ -31614,6 +31742,7 @@ async function runBatonSession(opts) {
|
|
|
31614
31742
|
const client2 = new AcpClient({
|
|
31615
31743
|
adapter: opts.adapter,
|
|
31616
31744
|
cwd: opts.cwd,
|
|
31745
|
+
mcpServers: opts.mcpServers,
|
|
31617
31746
|
onSessionUpdate: (notification) => {
|
|
31618
31747
|
for (const delta of mapSessionUpdate(notification)) streaming.append(delta);
|
|
31619
31748
|
},
|
|
@@ -31644,7 +31773,8 @@ async function runBatonSession(opts) {
|
|
|
31644
31773
|
adapter: opts.adapter,
|
|
31645
31774
|
cwd: opts.cwd,
|
|
31646
31775
|
getBeads: opts.getBeads,
|
|
31647
|
-
pollSecret: opts.pollSecret
|
|
31776
|
+
pollSecret: opts.pollSecret,
|
|
31777
|
+
mcpServers: opts.mcpServers
|
|
31648
31778
|
};
|
|
31649
31779
|
const mobileDriver = new AcpDriver({
|
|
31650
31780
|
client: client2,
|
|
@@ -31766,15 +31896,15 @@ function toEpochMs(ts) {
|
|
|
31766
31896
|
}
|
|
31767
31897
|
|
|
31768
31898
|
// src/agents/claude/onboarding.ts
|
|
31769
|
-
var
|
|
31770
|
-
var
|
|
31771
|
-
var
|
|
31899
|
+
var fs63 = __toESM(require("fs"));
|
|
31900
|
+
var os49 = __toESM(require("os"));
|
|
31901
|
+
var path67 = __toESM(require("path"));
|
|
31772
31902
|
function ensureClaudeOnboarded(cwd) {
|
|
31773
31903
|
try {
|
|
31774
|
-
const file =
|
|
31904
|
+
const file = path67.join(os49.homedir(), ".claude.json");
|
|
31775
31905
|
let config = {};
|
|
31776
31906
|
try {
|
|
31777
|
-
config = JSON.parse(
|
|
31907
|
+
config = JSON.parse(fs63.readFileSync(file, "utf8"));
|
|
31778
31908
|
} catch {
|
|
31779
31909
|
}
|
|
31780
31910
|
let changed = false;
|
|
@@ -31798,8 +31928,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
31798
31928
|
}
|
|
31799
31929
|
}
|
|
31800
31930
|
if (!changed) return;
|
|
31801
|
-
|
|
31802
|
-
|
|
31931
|
+
fs63.mkdirSync(path67.dirname(file), { recursive: true });
|
|
31932
|
+
fs63.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
31803
31933
|
log.info(
|
|
31804
31934
|
"claude",
|
|
31805
31935
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -31904,6 +32034,12 @@ async function start(requestedAgent) {
|
|
|
31904
32034
|
beads = started;
|
|
31905
32035
|
return started;
|
|
31906
32036
|
});
|
|
32037
|
+
const mcpServers = buildMcpServersForStart({
|
|
32038
|
+
sessionId: session.id,
|
|
32039
|
+
pluginId,
|
|
32040
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
32041
|
+
pollSecret: session.pollSecret
|
|
32042
|
+
});
|
|
31907
32043
|
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
31908
32044
|
if (process.env.CODESPACES === "true") {
|
|
31909
32045
|
const GATE_TIMEOUT_MS = 24e4;
|
|
@@ -31939,7 +32075,8 @@ async function start(requestedAgent) {
|
|
|
31939
32075
|
pollSecret: session.pollSecret,
|
|
31940
32076
|
cwd,
|
|
31941
32077
|
adapter,
|
|
31942
|
-
getBeads
|
|
32078
|
+
getBeads,
|
|
32079
|
+
mcpServers
|
|
31943
32080
|
});
|
|
31944
32081
|
return;
|
|
31945
32082
|
}
|
|
@@ -31961,6 +32098,7 @@ async function start(requestedAgent) {
|
|
|
31961
32098
|
cwd,
|
|
31962
32099
|
getBeads,
|
|
31963
32100
|
pollSecret: session.pollSecret,
|
|
32101
|
+
mcpServers,
|
|
31964
32102
|
// AUTO mode for headless, mobile-driven sessions: no human at the box
|
|
31965
32103
|
// to answer permission prompts, so auto-approve them rather than stall
|
|
31966
32104
|
// the turn (the agent-agnostic equivalent of
|
|
@@ -32477,7 +32615,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
32477
32615
|
var import_child_process28 = require("child_process");
|
|
32478
32616
|
var import_util4 = require("util");
|
|
32479
32617
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
32480
|
-
var
|
|
32618
|
+
var path68 = __toESM(require("path"));
|
|
32481
32619
|
var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
|
|
32482
32620
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
32483
32621
|
function resetStdinForChild() {
|
|
@@ -32966,7 +33104,7 @@ var GitHubCodespacesProvider = class {
|
|
|
32966
33104
|
});
|
|
32967
33105
|
}
|
|
32968
33106
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
32969
|
-
const remoteDir =
|
|
33107
|
+
const remoteDir = path68.posix.dirname(remotePath);
|
|
32970
33108
|
const parts = [
|
|
32971
33109
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
32972
33110
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -33036,7 +33174,7 @@ function shellQuote(s) {
|
|
|
33036
33174
|
// src/services/providers/gitpod.ts
|
|
33037
33175
|
var import_child_process29 = require("child_process");
|
|
33038
33176
|
var import_util5 = require("util");
|
|
33039
|
-
var
|
|
33177
|
+
var path69 = __toESM(require("path"));
|
|
33040
33178
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
33041
33179
|
var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
|
|
33042
33180
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -33276,7 +33414,7 @@ var GitpodProvider = class {
|
|
|
33276
33414
|
});
|
|
33277
33415
|
}
|
|
33278
33416
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
33279
|
-
const remoteDir =
|
|
33417
|
+
const remoteDir = path69.posix.dirname(remotePath);
|
|
33280
33418
|
const parts = [
|
|
33281
33419
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
33282
33420
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -33312,7 +33450,7 @@ function shellQuote2(s) {
|
|
|
33312
33450
|
// src/services/providers/gitlab-workspaces.ts
|
|
33313
33451
|
var import_child_process30 = require("child_process");
|
|
33314
33452
|
var import_util6 = require("util");
|
|
33315
|
-
var
|
|
33453
|
+
var path70 = __toESM(require("path"));
|
|
33316
33454
|
var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
|
|
33317
33455
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
33318
33456
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -33572,7 +33710,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
33572
33710
|
}
|
|
33573
33711
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
33574
33712
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
33575
|
-
const remoteDir =
|
|
33713
|
+
const remoteDir = path70.posix.dirname(remotePath);
|
|
33576
33714
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
33577
33715
|
if (options.mode != null) {
|
|
33578
33716
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -33640,7 +33778,7 @@ function shellQuote3(s) {
|
|
|
33640
33778
|
// src/services/providers/railway.ts
|
|
33641
33779
|
var import_child_process31 = require("child_process");
|
|
33642
33780
|
var import_util7 = require("util");
|
|
33643
|
-
var
|
|
33781
|
+
var path71 = __toESM(require("path"));
|
|
33644
33782
|
var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
|
|
33645
33783
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
33646
33784
|
function resetStdinForChild4() {
|
|
@@ -33876,7 +34014,7 @@ var RailwayProvider = class {
|
|
|
33876
34014
|
if (!projectId || !serviceId) {
|
|
33877
34015
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
33878
34016
|
}
|
|
33879
|
-
const remoteDir =
|
|
34017
|
+
const remoteDir = path71.posix.dirname(remotePath);
|
|
33880
34018
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
33881
34019
|
if (options.mode != null) {
|
|
33882
34020
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -34522,8 +34660,8 @@ async function invite() {
|
|
|
34522
34660
|
var import_node_dns = require("dns");
|
|
34523
34661
|
var import_node_util5 = require("util");
|
|
34524
34662
|
var import_node_crypto12 = require("crypto");
|
|
34525
|
-
var
|
|
34526
|
-
var
|
|
34663
|
+
var fs64 = __toESM(require("fs"));
|
|
34664
|
+
var path72 = __toESM(require("path"));
|
|
34527
34665
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
34528
34666
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
34529
34667
|
async function checkDns(apiBase2) {
|
|
@@ -34579,13 +34717,13 @@ async function checkHealth(apiBase2) {
|
|
|
34579
34717
|
}
|
|
34580
34718
|
}
|
|
34581
34719
|
function checkConfigDir() {
|
|
34582
|
-
const dir =
|
|
34720
|
+
const dir = path72.join(require("os").homedir(), ".codeam");
|
|
34583
34721
|
try {
|
|
34584
|
-
|
|
34585
|
-
const probe =
|
|
34586
|
-
|
|
34587
|
-
const read2 =
|
|
34588
|
-
|
|
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);
|
|
34589
34727
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
34590
34728
|
return {
|
|
34591
34729
|
id: "config-dir",
|
|
@@ -34625,9 +34763,9 @@ function checkSessions() {
|
|
|
34625
34763
|
}
|
|
34626
34764
|
}
|
|
34627
34765
|
function checkAgentBinaries() {
|
|
34628
|
-
const
|
|
34766
|
+
const os51 = createOsStrategy();
|
|
34629
34767
|
return getEnabledAgents().map((meta) => {
|
|
34630
|
-
const found =
|
|
34768
|
+
const found = os51.findInPath(meta.binaryName);
|
|
34631
34769
|
return {
|
|
34632
34770
|
id: `agent-${meta.id}`,
|
|
34633
34771
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -34649,7 +34787,7 @@ function checkNodePty() {
|
|
|
34649
34787
|
detail: "not required on this platform"
|
|
34650
34788
|
};
|
|
34651
34789
|
}
|
|
34652
|
-
const vendoredPath =
|
|
34790
|
+
const vendoredPath = path72.join(__dirname, "vendor", "node-pty");
|
|
34653
34791
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
34654
34792
|
try {
|
|
34655
34793
|
require(target);
|
|
@@ -34691,7 +34829,7 @@ function checkChokidar() {
|
|
|
34691
34829
|
}
|
|
34692
34830
|
async function doctor(args2 = []) {
|
|
34693
34831
|
const json = args2.includes("--json");
|
|
34694
|
-
const cliVersion = true ? "2.60.
|
|
34832
|
+
const cliVersion = true ? "2.60.47" : "0.0.0-dev";
|
|
34695
34833
|
const apiBase2 = resolveApiBaseUrl();
|
|
34696
34834
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
34697
34835
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -34887,10 +35025,288 @@ async function completion(args2) {
|
|
|
34887
35025
|
process.stdout.write(script);
|
|
34888
35026
|
}
|
|
34889
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
|
+
|
|
34890
35306
|
// src/commands/version.ts
|
|
34891
35307
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
34892
35308
|
function version2() {
|
|
34893
|
-
const v = true ? "2.60.
|
|
35309
|
+
const v = true ? "2.60.47" : "unknown";
|
|
34894
35310
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
34895
35311
|
}
|
|
34896
35312
|
|
|
@@ -35039,10 +35455,10 @@ var EXIT_CODE_NAMES = {
|
|
|
35039
35455
|
};
|
|
35040
35456
|
|
|
35041
35457
|
// src/index.ts
|
|
35042
|
-
var
|
|
35458
|
+
var os50 = __toESM(require("os"));
|
|
35043
35459
|
if (!process.env.HOME) {
|
|
35044
35460
|
try {
|
|
35045
|
-
const home =
|
|
35461
|
+
const home = os50.homedir();
|
|
35046
35462
|
if (home) process.env.HOME = home;
|
|
35047
35463
|
} catch {
|
|
35048
35464
|
}
|
|
@@ -35088,6 +35504,9 @@ async function main() {
|
|
|
35088
35504
|
await commands[command]();
|
|
35089
35505
|
return;
|
|
35090
35506
|
}
|
|
35507
|
+
if (command === "mcp-run") {
|
|
35508
|
+
return mcpRun(args);
|
|
35509
|
+
}
|
|
35091
35510
|
if (command === "deploy") {
|
|
35092
35511
|
if (args[0] === "ls" || args[0] === "list") return deployList();
|
|
35093
35512
|
if (args[0] === "stop" || args[0] === "remove") return deployStop();
|