codeam-cli 2.39.82 → 2.39.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/index.js +532 -246
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -515,9 +515,9 @@ var _default = makeConfig();
|
|
|
515
515
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
516
516
|
|
|
517
517
|
// src/commands/pair-auto.ts
|
|
518
|
-
var
|
|
519
|
-
var
|
|
520
|
-
var
|
|
518
|
+
var fs41 = __toESM(require("fs"));
|
|
519
|
+
var os34 = __toESM(require("os"));
|
|
520
|
+
var path47 = __toESM(require("path"));
|
|
521
521
|
var import_crypto4 = require("crypto");
|
|
522
522
|
|
|
523
523
|
// src/services/telemetry.service.ts
|
|
@@ -553,8 +553,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
553
553
|
return decodedFile;
|
|
554
554
|
};
|
|
555
555
|
}
|
|
556
|
-
function normalizeWindowsPath(
|
|
557
|
-
return
|
|
556
|
+
function normalizeWindowsPath(path60) {
|
|
557
|
+
return path60.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3034,9 +3034,9 @@ async function addSourceContext(frames) {
|
|
|
3034
3034
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3035
3035
|
return frames;
|
|
3036
3036
|
}
|
|
3037
|
-
function getContextLinesFromFile(
|
|
3037
|
+
function getContextLinesFromFile(path60, ranges, output) {
|
|
3038
3038
|
return new Promise((resolve7) => {
|
|
3039
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3039
|
+
const stream = (0, import_node_fs.createReadStream)(path60);
|
|
3040
3040
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3041
3041
|
input: stream
|
|
3042
3042
|
});
|
|
@@ -3051,7 +3051,7 @@ function getContextLinesFromFile(path59, ranges, output) {
|
|
|
3051
3051
|
let rangeStart = range[0];
|
|
3052
3052
|
let rangeEnd = range[1];
|
|
3053
3053
|
function onStreamError() {
|
|
3054
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3054
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path60, 1);
|
|
3055
3055
|
lineReaded.close();
|
|
3056
3056
|
lineReaded.removeAllListeners();
|
|
3057
3057
|
destroyStreamAndResolve();
|
|
@@ -3112,8 +3112,8 @@ function clearLineContext(frame) {
|
|
|
3112
3112
|
delete frame.context_line;
|
|
3113
3113
|
delete frame.post_context;
|
|
3114
3114
|
}
|
|
3115
|
-
function shouldSkipContextLinesForFile(
|
|
3116
|
-
return
|
|
3115
|
+
function shouldSkipContextLinesForFile(path60) {
|
|
3116
|
+
return path60.startsWith("node:") || path60.endsWith(".min.js") || path60.endsWith(".min.cjs") || path60.endsWith(".min.mjs") || path60.startsWith("data:");
|
|
3117
3117
|
}
|
|
3118
3118
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3119
3119
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5390,7 +5390,7 @@ function readAnonId() {
|
|
|
5390
5390
|
}
|
|
5391
5391
|
function superProperties() {
|
|
5392
5392
|
return {
|
|
5393
|
-
cliVersion: true ? "2.39.
|
|
5393
|
+
cliVersion: true ? "2.39.84" : "0.0.0-dev",
|
|
5394
5394
|
nodeVersion: process.version,
|
|
5395
5395
|
platform: process.platform,
|
|
5396
5396
|
arch: process.arch,
|
|
@@ -5549,7 +5549,7 @@ var os4 = __toESM(require("os"));
|
|
|
5549
5549
|
// package.json
|
|
5550
5550
|
var package_default = {
|
|
5551
5551
|
name: "codeam-cli",
|
|
5552
|
-
version: "2.39.
|
|
5552
|
+
version: "2.39.84",
|
|
5553
5553
|
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.",
|
|
5554
5554
|
type: "commonjs",
|
|
5555
5555
|
main: "dist/index.js",
|
|
@@ -6506,10 +6506,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
6506
6506
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
6507
6507
|
/[\\/]Templates([\\/]|$)/i
|
|
6508
6508
|
];
|
|
6509
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
6509
|
+
function isUnsafeWindowsWatchRoot(dir, homedir33) {
|
|
6510
6510
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
6511
6511
|
const cwd = norm(dir);
|
|
6512
|
-
const home = norm(
|
|
6512
|
+
const home = norm(homedir33);
|
|
6513
6513
|
if (cwd === home) return true;
|
|
6514
6514
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
6515
6515
|
const sysRoots = [
|
|
@@ -11048,10 +11048,10 @@ function buildForPlatform(platform3) {
|
|
|
11048
11048
|
var import_node_crypto4 = require("crypto");
|
|
11049
11049
|
|
|
11050
11050
|
// src/agents/claude/resolver.ts
|
|
11051
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11052
|
-
const found =
|
|
11051
|
+
function buildClaudeLaunch(extraArgs = [], os40 = createOsStrategy()) {
|
|
11052
|
+
const found = os40.findInPath("claude") ?? os40.findInPath("claude-code");
|
|
11053
11053
|
if (!found) return null;
|
|
11054
|
-
return
|
|
11054
|
+
return os40.buildLaunch(found, extraArgs);
|
|
11055
11055
|
}
|
|
11056
11056
|
|
|
11057
11057
|
// src/agents/claude/installer.ts
|
|
@@ -11078,12 +11078,12 @@ function isAvailable() {
|
|
|
11078
11078
|
}
|
|
11079
11079
|
function augmentPath() {
|
|
11080
11080
|
const dirs = probeInstallDirs();
|
|
11081
|
-
const
|
|
11081
|
+
const sep6 = path14.delimiter;
|
|
11082
11082
|
const current = process.env.PATH ?? "";
|
|
11083
|
-
const existing = new Set(current.split(
|
|
11083
|
+
const existing = new Set(current.split(sep6).filter(Boolean));
|
|
11084
11084
|
const additions = dirs.filter((d3) => !existing.has(d3));
|
|
11085
11085
|
if (additions.length === 0) return;
|
|
11086
|
-
process.env.PATH = additions.join(
|
|
11086
|
+
process.env.PATH = additions.join(sep6) + sep6 + current;
|
|
11087
11087
|
}
|
|
11088
11088
|
function runInstaller() {
|
|
11089
11089
|
const isWindows = process.platform === "win32";
|
|
@@ -11200,13 +11200,34 @@ function readClaudeAgentState() {
|
|
|
11200
11200
|
}
|
|
11201
11201
|
|
|
11202
11202
|
// src/agents/claude/link.ts
|
|
11203
|
+
function validateClaudeToken(token) {
|
|
11204
|
+
if (token.method !== "oauth") return { status: "unknown" };
|
|
11205
|
+
let oauth;
|
|
11206
|
+
try {
|
|
11207
|
+
const parsed = JSON.parse(token.credential);
|
|
11208
|
+
const inner = parsed.claudeAiOauth;
|
|
11209
|
+
oauth = inner && typeof inner === "object" ? inner : parsed;
|
|
11210
|
+
} catch {
|
|
11211
|
+
return { status: "unknown" };
|
|
11212
|
+
}
|
|
11213
|
+
const expiresAt = typeof oauth.expiresAt === "number" ? oauth.expiresAt : null;
|
|
11214
|
+
if (expiresAt === null) return { status: "unknown" };
|
|
11215
|
+
if (expiresAt >= Date.now()) return { status: "valid" };
|
|
11216
|
+
const hasRefresh = typeof oauth.refreshToken === "string" && oauth.refreshToken.length > 0;
|
|
11217
|
+
if (hasRefresh) return { status: "unknown" };
|
|
11218
|
+
return {
|
|
11219
|
+
status: "expired",
|
|
11220
|
+
reason: "Your local Claude session has expired with no refresh token."
|
|
11221
|
+
};
|
|
11222
|
+
}
|
|
11203
11223
|
function claudeCredentialLocator() {
|
|
11204
11224
|
return {
|
|
11205
11225
|
publicId: "claude_code",
|
|
11206
11226
|
vendor: "Anthropic",
|
|
11207
11227
|
hint: "~/.claude/.credentials.json or the macOS Keychain",
|
|
11208
11228
|
watchPaths: claudeCredentialsPaths,
|
|
11209
|
-
extract: extractLocalClaudeToken
|
|
11229
|
+
extract: extractLocalClaudeToken,
|
|
11230
|
+
validate: validateClaudeToken
|
|
11210
11231
|
};
|
|
11211
11232
|
}
|
|
11212
11233
|
function claudeLoginLauncher() {
|
|
@@ -11588,8 +11609,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
11588
11609
|
meta = getAgent("claude");
|
|
11589
11610
|
mode = "interactive";
|
|
11590
11611
|
os;
|
|
11591
|
-
constructor(
|
|
11592
|
-
this.os =
|
|
11612
|
+
constructor(os40) {
|
|
11613
|
+
this.os = os40;
|
|
11593
11614
|
}
|
|
11594
11615
|
/**
|
|
11595
11616
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -12208,8 +12229,8 @@ function codexCredentialLocator() {
|
|
|
12208
12229
|
function codexLoginLauncher() {
|
|
12209
12230
|
return {
|
|
12210
12231
|
async ensureInstalled() {
|
|
12211
|
-
const
|
|
12212
|
-
return
|
|
12232
|
+
const os40 = createOsStrategy();
|
|
12233
|
+
return os40.findInPath("codex") !== null;
|
|
12213
12234
|
},
|
|
12214
12235
|
launch() {
|
|
12215
12236
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -12232,8 +12253,8 @@ var CodexRuntimeStrategy = class {
|
|
|
12232
12253
|
meta = getAgent("codex");
|
|
12233
12254
|
mode = "interactive";
|
|
12234
12255
|
os;
|
|
12235
|
-
constructor(
|
|
12236
|
-
this.os =
|
|
12256
|
+
constructor(os40) {
|
|
12257
|
+
this.os = os40;
|
|
12237
12258
|
}
|
|
12238
12259
|
async prepareLaunch() {
|
|
12239
12260
|
let binary = this.os.findInPath("codex");
|
|
@@ -12329,12 +12350,12 @@ var CodexRuntimeStrategy = class {
|
|
|
12329
12350
|
});
|
|
12330
12351
|
}
|
|
12331
12352
|
};
|
|
12332
|
-
function resolveNpm(
|
|
12333
|
-
return
|
|
12353
|
+
function resolveNpm(os40) {
|
|
12354
|
+
return os40.id === "win32" ? "npm.cmd" : "npm";
|
|
12334
12355
|
}
|
|
12335
|
-
async function installCodexViaNpm(
|
|
12356
|
+
async function installCodexViaNpm(os40) {
|
|
12336
12357
|
return new Promise((resolve7, reject) => {
|
|
12337
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
12358
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os40), ["install", "-g", "@openai/codex"], {
|
|
12338
12359
|
stdio: "inherit"
|
|
12339
12360
|
});
|
|
12340
12361
|
proc.on("close", (code) => {
|
|
@@ -12351,16 +12372,16 @@ async function installCodexViaNpm(os39) {
|
|
|
12351
12372
|
});
|
|
12352
12373
|
});
|
|
12353
12374
|
}
|
|
12354
|
-
function augmentNpmGlobalBin(
|
|
12375
|
+
function augmentNpmGlobalBin(os40) {
|
|
12355
12376
|
try {
|
|
12356
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
12377
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os40), ["prefix", "-g"], {
|
|
12357
12378
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12358
12379
|
});
|
|
12359
12380
|
if (result.status !== 0) return;
|
|
12360
12381
|
const prefix = result.stdout.toString().trim();
|
|
12361
12382
|
if (!prefix) return;
|
|
12362
|
-
const binDir =
|
|
12363
|
-
|
|
12383
|
+
const binDir = os40.id === "win32" ? prefix : path22.join(prefix, "bin");
|
|
12384
|
+
os40.augmentPath([binDir]);
|
|
12364
12385
|
} catch {
|
|
12365
12386
|
}
|
|
12366
12387
|
}
|
|
@@ -12444,9 +12465,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
12444
12465
|
// src/agents/coderabbit/installer.ts
|
|
12445
12466
|
var import_node_child_process5 = require("child_process");
|
|
12446
12467
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
12447
|
-
async function ensureCoderabbitInstalled(
|
|
12448
|
-
if (
|
|
12449
|
-
if (
|
|
12468
|
+
async function ensureCoderabbitInstalled(os40) {
|
|
12469
|
+
if (os40.findInPath("coderabbit")) return true;
|
|
12470
|
+
if (os40.id === "win32") {
|
|
12450
12471
|
console.error(
|
|
12451
12472
|
"\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"
|
|
12452
12473
|
);
|
|
@@ -12461,8 +12482,8 @@ async function ensureCoderabbitInstalled(os39) {
|
|
|
12461
12482
|
proc.on("error", () => resolve7(false));
|
|
12462
12483
|
});
|
|
12463
12484
|
if (!ok) return false;
|
|
12464
|
-
|
|
12465
|
-
return
|
|
12485
|
+
os40.augmentPath([`${os40.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
12486
|
+
return os40.findInPath("coderabbit") !== null;
|
|
12466
12487
|
}
|
|
12467
12488
|
|
|
12468
12489
|
// src/agents/coderabbit/link.ts
|
|
@@ -12470,6 +12491,13 @@ var import_node_child_process6 = require("child_process");
|
|
|
12470
12491
|
var fs19 = __toESM(require("fs"));
|
|
12471
12492
|
var os18 = __toESM(require("os"));
|
|
12472
12493
|
var path24 = __toESM(require("path"));
|
|
12494
|
+
|
|
12495
|
+
// src/agents/strategy.ts
|
|
12496
|
+
function validateNonEmptyCredential(token) {
|
|
12497
|
+
return { status: token.credential.trim().length > 0 ? "valid" : "unknown" };
|
|
12498
|
+
}
|
|
12499
|
+
|
|
12500
|
+
// src/agents/coderabbit/link.ts
|
|
12473
12501
|
function authPath() {
|
|
12474
12502
|
return path24.join(os18.homedir(), ".coderabbit", "auth.json");
|
|
12475
12503
|
}
|
|
@@ -12486,13 +12514,14 @@ function coderabbitCredentialLocator() {
|
|
|
12486
12514
|
vendor: "CodeRabbit",
|
|
12487
12515
|
hint: "~/.coderabbit/auth.json",
|
|
12488
12516
|
watchPaths: () => [authPath()],
|
|
12489
|
-
extract: extractLocalCoderabbitToken
|
|
12517
|
+
extract: extractLocalCoderabbitToken,
|
|
12518
|
+
validate: validateNonEmptyCredential
|
|
12490
12519
|
};
|
|
12491
12520
|
}
|
|
12492
|
-
function coderabbitLoginLauncher(
|
|
12521
|
+
function coderabbitLoginLauncher(os40) {
|
|
12493
12522
|
return {
|
|
12494
12523
|
async ensureInstalled() {
|
|
12495
|
-
return ensureCoderabbitInstalled(
|
|
12524
|
+
return ensureCoderabbitInstalled(os40);
|
|
12496
12525
|
},
|
|
12497
12526
|
launch() {
|
|
12498
12527
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -12515,11 +12544,11 @@ function parseReview(stdout) {
|
|
|
12515
12544
|
for (const line of lines) {
|
|
12516
12545
|
const m = line.match(HUNK_LINE_RE);
|
|
12517
12546
|
if (!m) continue;
|
|
12518
|
-
const [,
|
|
12519
|
-
if (!
|
|
12547
|
+
const [, path60, lineNo, sevToken, message] = m;
|
|
12548
|
+
if (!path60 || !lineNo || !message) continue;
|
|
12520
12549
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
12521
12550
|
hunks.push({
|
|
12522
|
-
path:
|
|
12551
|
+
path: path60.trim(),
|
|
12523
12552
|
line: Number(lineNo),
|
|
12524
12553
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
12525
12554
|
message: cleanedMessage
|
|
@@ -12538,8 +12567,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
12538
12567
|
meta = getAgent("coderabbit");
|
|
12539
12568
|
mode = "batch";
|
|
12540
12569
|
os;
|
|
12541
|
-
constructor(
|
|
12542
|
-
this.os =
|
|
12570
|
+
constructor(os40) {
|
|
12571
|
+
this.os = os40;
|
|
12543
12572
|
}
|
|
12544
12573
|
getDefaultArgs() {
|
|
12545
12574
|
return ["review"];
|
|
@@ -12651,13 +12680,14 @@ function cursorCredentialLocator() {
|
|
|
12651
12680
|
vendor: "Cursor",
|
|
12652
12681
|
hint: "~/.cursor/auth.json",
|
|
12653
12682
|
watchPaths: cursorCredentialsPaths,
|
|
12654
|
-
extract: extractLocalCursorToken
|
|
12683
|
+
extract: extractLocalCursorToken,
|
|
12684
|
+
validate: validateNonEmptyCredential
|
|
12655
12685
|
};
|
|
12656
12686
|
}
|
|
12657
|
-
function cursorLoginLauncher(
|
|
12687
|
+
function cursorLoginLauncher(os40) {
|
|
12658
12688
|
return {
|
|
12659
12689
|
async ensureInstalled() {
|
|
12660
|
-
if (
|
|
12690
|
+
if (os40.findInPath("cursor-agent")) return true;
|
|
12661
12691
|
console.error(
|
|
12662
12692
|
"\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"
|
|
12663
12693
|
);
|
|
@@ -12719,8 +12749,8 @@ var CursorRuntimeStrategy = class {
|
|
|
12719
12749
|
meta = getAgent("cursor");
|
|
12720
12750
|
mode = "interactive";
|
|
12721
12751
|
os;
|
|
12722
|
-
constructor(
|
|
12723
|
-
this.os =
|
|
12752
|
+
constructor(os40) {
|
|
12753
|
+
this.os = os40;
|
|
12724
12754
|
}
|
|
12725
12755
|
async prepareLaunch() {
|
|
12726
12756
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -12837,13 +12867,14 @@ function aiderCredentialLocator() {
|
|
|
12837
12867
|
vendor: "Aider",
|
|
12838
12868
|
hint: "ANTHROPIC_API_KEY / OPENAI_API_KEY env var or ~/.aider.conf.yml",
|
|
12839
12869
|
watchPaths: aiderCredentialsPaths,
|
|
12840
|
-
extract: extractLocalAiderToken
|
|
12870
|
+
extract: extractLocalAiderToken,
|
|
12871
|
+
validate: validateNonEmptyCredential
|
|
12841
12872
|
};
|
|
12842
12873
|
}
|
|
12843
|
-
function aiderLoginLauncher(
|
|
12874
|
+
function aiderLoginLauncher(os40) {
|
|
12844
12875
|
return {
|
|
12845
12876
|
async ensureInstalled() {
|
|
12846
|
-
if (
|
|
12877
|
+
if (os40.findInPath("aider")) return true;
|
|
12847
12878
|
console.error(
|
|
12848
12879
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
12849
12880
|
);
|
|
@@ -12853,7 +12884,7 @@ function aiderLoginLauncher(os39) {
|
|
|
12853
12884
|
console.error(
|
|
12854
12885
|
"\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"
|
|
12855
12886
|
);
|
|
12856
|
-
return (0, import_node_child_process9.spawn)(
|
|
12887
|
+
return (0, import_node_child_process9.spawn)(os40.id === "win32" ? "cmd.exe" : "sh", os40.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
12857
12888
|
stdio: "ignore"
|
|
12858
12889
|
});
|
|
12859
12890
|
}
|
|
@@ -12925,8 +12956,8 @@ var AiderRuntimeStrategy = class {
|
|
|
12925
12956
|
meta = getAgent("aider");
|
|
12926
12957
|
mode = "interactive";
|
|
12927
12958
|
os;
|
|
12928
|
-
constructor(
|
|
12929
|
-
this.os =
|
|
12959
|
+
constructor(os40) {
|
|
12960
|
+
this.os = os40;
|
|
12930
12961
|
}
|
|
12931
12962
|
async prepareLaunch() {
|
|
12932
12963
|
const binary = this.os.findInPath("aider");
|
|
@@ -13055,8 +13086,8 @@ function geminiCredentialLocator() {
|
|
|
13055
13086
|
function geminiLoginLauncher() {
|
|
13056
13087
|
return {
|
|
13057
13088
|
async ensureInstalled() {
|
|
13058
|
-
const
|
|
13059
|
-
return
|
|
13089
|
+
const os40 = createOsStrategy();
|
|
13090
|
+
return os40.findInPath("gemini") !== null;
|
|
13060
13091
|
},
|
|
13061
13092
|
launch() {
|
|
13062
13093
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13089,8 +13120,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
13089
13120
|
meta = getAgent("gemini");
|
|
13090
13121
|
mode = "interactive";
|
|
13091
13122
|
os;
|
|
13092
|
-
constructor(
|
|
13093
|
-
this.os =
|
|
13123
|
+
constructor(os40) {
|
|
13124
|
+
this.os = os40;
|
|
13094
13125
|
}
|
|
13095
13126
|
async prepareLaunch() {
|
|
13096
13127
|
const binary = this.os.findInPath("gemini");
|
|
@@ -13189,18 +13220,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
13189
13220
|
|
|
13190
13221
|
// src/agents/registry.ts
|
|
13191
13222
|
var runtimeBuilders = {
|
|
13192
|
-
claude: (
|
|
13193
|
-
codex: (
|
|
13194
|
-
coderabbit: (
|
|
13195
|
-
cursor: (
|
|
13196
|
-
aider: (
|
|
13197
|
-
gemini: (
|
|
13223
|
+
claude: (os40) => new ClaudeRuntimeStrategy(os40),
|
|
13224
|
+
codex: (os40) => new CodexRuntimeStrategy(os40),
|
|
13225
|
+
coderabbit: (os40) => new CoderabbitRuntimeStrategy(os40),
|
|
13226
|
+
cursor: (os40) => new CursorRuntimeStrategy(os40),
|
|
13227
|
+
aider: (os40) => new AiderRuntimeStrategy(os40),
|
|
13228
|
+
gemini: (os40) => new GeminiRuntimeStrategy(os40)
|
|
13198
13229
|
};
|
|
13199
13230
|
var deployBuilders = {
|
|
13200
13231
|
claude: () => new ClaudeDeployStrategy(),
|
|
13201
13232
|
codex: () => new CodexDeployStrategy()
|
|
13202
13233
|
};
|
|
13203
|
-
function createAgentStrategy(agent,
|
|
13234
|
+
function createAgentStrategy(agent, os40 = createOsStrategy()) {
|
|
13204
13235
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
13205
13236
|
throw new Error(
|
|
13206
13237
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -13210,10 +13241,10 @@ function createAgentStrategy(agent, os39 = createOsStrategy()) {
|
|
|
13210
13241
|
if (!build) {
|
|
13211
13242
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
13212
13243
|
}
|
|
13213
|
-
return build(
|
|
13244
|
+
return build(os40);
|
|
13214
13245
|
}
|
|
13215
|
-
function createInteractiveAgentStrategy(agent,
|
|
13216
|
-
const s = createAgentStrategy(agent,
|
|
13246
|
+
function createInteractiveAgentStrategy(agent, os40 = createOsStrategy()) {
|
|
13247
|
+
const s = createAgentStrategy(agent, os40);
|
|
13217
13248
|
if (s.mode !== "interactive") {
|
|
13218
13249
|
throw new Error(
|
|
13219
13250
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -14516,11 +14547,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
14516
14547
|
}
|
|
14517
14548
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
14518
14549
|
function doltPlatformTuple(platform3, arch2) {
|
|
14519
|
-
const
|
|
14550
|
+
const os40 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
14520
14551
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
14521
14552
|
if (!a) return null;
|
|
14522
|
-
if (
|
|
14523
|
-
return `${
|
|
14553
|
+
if (os40 === "windows" && a !== "amd64") return null;
|
|
14554
|
+
return `${os40}-${a}`;
|
|
14524
14555
|
}
|
|
14525
14556
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
14526
14557
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -16838,10 +16869,10 @@ async function startInfraOnly(agentId) {
|
|
|
16838
16869
|
}
|
|
16839
16870
|
|
|
16840
16871
|
// src/commands/host-agent.ts
|
|
16841
|
-
var
|
|
16842
|
-
var
|
|
16843
|
-
var
|
|
16844
|
-
var
|
|
16872
|
+
var import_node_child_process14 = require("child_process");
|
|
16873
|
+
var os33 = __toESM(require("os"));
|
|
16874
|
+
var fs40 = __toESM(require("fs"));
|
|
16875
|
+
var path46 = __toESM(require("path"));
|
|
16845
16876
|
|
|
16846
16877
|
// src/commands/host/host-client.ts
|
|
16847
16878
|
var fs35 = __toESM(require("fs"));
|
|
@@ -17112,6 +17143,61 @@ function repoCloneUrl(repoRef, cloneToken) {
|
|
|
17112
17143
|
function maskCloneUrl(url) {
|
|
17113
17144
|
return url.replace(/(https?:\/\/)[^@/]+@/, "$1***@");
|
|
17114
17145
|
}
|
|
17146
|
+
async function fetchGithubIdentity(token) {
|
|
17147
|
+
try {
|
|
17148
|
+
const res = await fetch("https://api.github.com/user", {
|
|
17149
|
+
headers: {
|
|
17150
|
+
Authorization: `Bearer ${token}`,
|
|
17151
|
+
"User-Agent": "codeam-cli",
|
|
17152
|
+
Accept: "application/vnd.github+json"
|
|
17153
|
+
}
|
|
17154
|
+
});
|
|
17155
|
+
if (!res.ok) return null;
|
|
17156
|
+
const body = await res.json();
|
|
17157
|
+
return { login: body.login, email: body.email ?? void 0 };
|
|
17158
|
+
} catch {
|
|
17159
|
+
return null;
|
|
17160
|
+
}
|
|
17161
|
+
}
|
|
17162
|
+
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
17163
|
+
const gh = githubOwnerRepo(repoRef.trim());
|
|
17164
|
+
if (!gh || !cloneToken) return;
|
|
17165
|
+
const credFile = path42.join(dest, ".git", "codeam-credentials");
|
|
17166
|
+
fs36.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
17167
|
+
`, { mode: 384 });
|
|
17168
|
+
try {
|
|
17169
|
+
fs36.chmodSync(credFile, 384);
|
|
17170
|
+
} catch {
|
|
17171
|
+
}
|
|
17172
|
+
const env = nonInteractiveGitEnv();
|
|
17173
|
+
const git2 = (args2) => execFileP5("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
17174
|
+
const credFilePosix = credFile.split(path42.sep).join("/");
|
|
17175
|
+
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
17176
|
+
});
|
|
17177
|
+
await git2([
|
|
17178
|
+
"config",
|
|
17179
|
+
"--local",
|
|
17180
|
+
"--add",
|
|
17181
|
+
"credential.helper",
|
|
17182
|
+
`store --file=${credFilePosix}`
|
|
17183
|
+
]).catch(() => {
|
|
17184
|
+
});
|
|
17185
|
+
await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef)]).catch(() => {
|
|
17186
|
+
});
|
|
17187
|
+
const hasIdentity = await git2(["config", "user.email"]).then(() => true).catch(() => false);
|
|
17188
|
+
if (!hasIdentity) {
|
|
17189
|
+
const who = await fetchGithubIdentity(cloneToken);
|
|
17190
|
+
if (who?.login) {
|
|
17191
|
+
await git2(["config", "--local", "user.name", who.login]).catch(() => {
|
|
17192
|
+
});
|
|
17193
|
+
}
|
|
17194
|
+
const email = who?.email ?? (who?.login ? `${who.login}@users.noreply.github.com` : void 0);
|
|
17195
|
+
if (email) {
|
|
17196
|
+
await git2(["config", "--local", "user.email", email]).catch(() => {
|
|
17197
|
+
});
|
|
17198
|
+
}
|
|
17199
|
+
}
|
|
17200
|
+
}
|
|
17115
17201
|
function maskToken(text, cloneToken) {
|
|
17116
17202
|
const masked = maskCloneUrl(text);
|
|
17117
17203
|
if (cloneToken && cloneToken.length > 0) {
|
|
@@ -17128,6 +17214,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
17128
17214
|
}
|
|
17129
17215
|
const dest = path42.join(selfHostedWorkspaceRoot(), deployId);
|
|
17130
17216
|
if (fs36.existsSync(path42.join(dest, ".git"))) {
|
|
17217
|
+
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
17131
17218
|
return dest;
|
|
17132
17219
|
}
|
|
17133
17220
|
fs36.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
@@ -17142,6 +17229,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
17142
17229
|
const reason = err instanceof Error ? err.message : String(err);
|
|
17143
17230
|
throw new Error(`git clone failed for ${maskCloneUrl(cloneUrl)}: ${maskToken(reason, cloneToken)}`);
|
|
17144
17231
|
}
|
|
17232
|
+
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
17145
17233
|
return dest;
|
|
17146
17234
|
}
|
|
17147
17235
|
|
|
@@ -17215,6 +17303,167 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
|
|
|
17215
17303
|
return provisioner.write(auth, homeDir2);
|
|
17216
17304
|
}
|
|
17217
17305
|
|
|
17306
|
+
// src/commands/host/git-tooling.ts
|
|
17307
|
+
var import_node_child_process12 = require("child_process");
|
|
17308
|
+
var fs38 = __toESM(require("fs"));
|
|
17309
|
+
var os31 = __toESM(require("os"));
|
|
17310
|
+
var path44 = __toESM(require("path"));
|
|
17311
|
+
function codeamBinDir() {
|
|
17312
|
+
return process.env.CODEAM_BIN_DIR ?? path44.join(os31.homedir(), ".codeam", "bin");
|
|
17313
|
+
}
|
|
17314
|
+
var FALLBACK_GH_VERSION = "2.62.0";
|
|
17315
|
+
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
17316
|
+
function ghArch() {
|
|
17317
|
+
if (process.arch === "x64") return "amd64";
|
|
17318
|
+
if (process.arch === "arm64") return "arm64";
|
|
17319
|
+
return null;
|
|
17320
|
+
}
|
|
17321
|
+
async function resolveLatestGhVersion(token) {
|
|
17322
|
+
try {
|
|
17323
|
+
const headers = {
|
|
17324
|
+
Accept: "application/vnd.github+json",
|
|
17325
|
+
"User-Agent": "codeam-cli"
|
|
17326
|
+
};
|
|
17327
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
17328
|
+
const res = await fetch(RELEASE_API, { headers });
|
|
17329
|
+
if (!res.ok) return FALLBACK_GH_VERSION;
|
|
17330
|
+
const body = await res.json();
|
|
17331
|
+
if (typeof body.tag_name === "string" && body.tag_name) {
|
|
17332
|
+
return body.tag_name.replace(/^v/, "");
|
|
17333
|
+
}
|
|
17334
|
+
return FALLBACK_GH_VERSION;
|
|
17335
|
+
} catch {
|
|
17336
|
+
return FALLBACK_GH_VERSION;
|
|
17337
|
+
}
|
|
17338
|
+
}
|
|
17339
|
+
async function download(url, dest) {
|
|
17340
|
+
try {
|
|
17341
|
+
const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
|
|
17342
|
+
if (!res.ok || !res.body) return false;
|
|
17343
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
17344
|
+
fs38.writeFileSync(dest, buf);
|
|
17345
|
+
return true;
|
|
17346
|
+
} catch {
|
|
17347
|
+
return false;
|
|
17348
|
+
}
|
|
17349
|
+
}
|
|
17350
|
+
async function ensureGhCli(runner, token, deps = {}) {
|
|
17351
|
+
if (runner.which("gh")) return "gh";
|
|
17352
|
+
const arch2 = ghArch();
|
|
17353
|
+
const platform3 = process.platform;
|
|
17354
|
+
if (arch2 === null || platform3 !== "linux" && platform3 !== "darwin" && platform3 !== "win32") {
|
|
17355
|
+
log.warn("host-agent", `gh auto-install unsupported on ${platform3}/${process.arch} \u2014 skipping`);
|
|
17356
|
+
return null;
|
|
17357
|
+
}
|
|
17358
|
+
const osToken = platform3 === "darwin" ? "macOS" : platform3 === "win32" ? "windows" : "linux";
|
|
17359
|
+
const ext = platform3 === "linux" ? "tar.gz" : "zip";
|
|
17360
|
+
const binaryName = platform3 === "win32" ? "gh.exe" : "gh";
|
|
17361
|
+
const downloadFn = deps.downloadFn ?? download;
|
|
17362
|
+
const resolveVersionFn = deps.resolveVersionFn ?? resolveLatestGhVersion;
|
|
17363
|
+
try {
|
|
17364
|
+
const version3 = await resolveVersionFn(token);
|
|
17365
|
+
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
17366
|
+
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
17367
|
+
const tmpRoot = fs38.mkdtempSync(path44.join(os31.tmpdir(), "codeam-gh-"));
|
|
17368
|
+
const archive = path44.join(tmpRoot, `${asset}.${ext}`);
|
|
17369
|
+
if (!await downloadFn(url, archive)) {
|
|
17370
|
+
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
17371
|
+
return null;
|
|
17372
|
+
}
|
|
17373
|
+
const extract = await runner.run("tar", ["-xf", archive, "-C", tmpRoot], { timeoutMs: 6e4 });
|
|
17374
|
+
if (extract.code !== 0) {
|
|
17375
|
+
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
17376
|
+
return null;
|
|
17377
|
+
}
|
|
17378
|
+
const extractedBin = path44.join(tmpRoot, asset, "bin", binaryName);
|
|
17379
|
+
if (!fs38.existsSync(extractedBin)) {
|
|
17380
|
+
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
17381
|
+
return null;
|
|
17382
|
+
}
|
|
17383
|
+
const binDir = codeamBinDir();
|
|
17384
|
+
fs38.mkdirSync(binDir, { recursive: true });
|
|
17385
|
+
const target = path44.join(binDir, binaryName);
|
|
17386
|
+
fs38.copyFileSync(extractedBin, target);
|
|
17387
|
+
fs38.chmodSync(target, 493);
|
|
17388
|
+
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
17389
|
+
return target;
|
|
17390
|
+
} catch (e) {
|
|
17391
|
+
log.warn("host-agent", `gh auto-install errored: ${e instanceof Error ? e.message : String(e)} \u2014 skipping`);
|
|
17392
|
+
return null;
|
|
17393
|
+
}
|
|
17394
|
+
}
|
|
17395
|
+
async function ensureGhAuth(runner, ghCmd, token) {
|
|
17396
|
+
if (!token) return;
|
|
17397
|
+
try {
|
|
17398
|
+
const status2 = await runner.run(ghCmd, ["auth", "status"], { timeoutMs: 15e3 });
|
|
17399
|
+
if (status2.code === 0) {
|
|
17400
|
+
log.info("host-agent", "gh already authenticated \u2014 leaving the existing login untouched");
|
|
17401
|
+
return;
|
|
17402
|
+
}
|
|
17403
|
+
const login = await runner.run(ghCmd, ["auth", "login", "--with-token"], {
|
|
17404
|
+
timeoutMs: 2e4,
|
|
17405
|
+
input: `${token}
|
|
17406
|
+
`
|
|
17407
|
+
});
|
|
17408
|
+
if (login.code === 0) {
|
|
17409
|
+
log.info("host-agent", "gh authenticated with the linked GitHub token");
|
|
17410
|
+
} else {
|
|
17411
|
+
log.warn("host-agent", `gh auth login failed (code=${String(login.code)}) \u2014 gh unauthenticated`);
|
|
17412
|
+
}
|
|
17413
|
+
} catch (e) {
|
|
17414
|
+
log.warn("host-agent", `gh auth errored: ${e instanceof Error ? e.message : String(e)}`);
|
|
17415
|
+
}
|
|
17416
|
+
}
|
|
17417
|
+
var defaultGitToolingRunner = {
|
|
17418
|
+
which(cmd) {
|
|
17419
|
+
try {
|
|
17420
|
+
const probe = process.platform === "win32" ? "where" : "which";
|
|
17421
|
+
(0, import_node_child_process12.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
17422
|
+
return true;
|
|
17423
|
+
} catch {
|
|
17424
|
+
return false;
|
|
17425
|
+
}
|
|
17426
|
+
},
|
|
17427
|
+
run(cmd, args2, opts = {}) {
|
|
17428
|
+
return new Promise((resolve7) => {
|
|
17429
|
+
const child = (0, import_node_child_process12.spawn)(cmd, args2, {
|
|
17430
|
+
stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
|
|
17431
|
+
});
|
|
17432
|
+
let stderr = "";
|
|
17433
|
+
let settled = false;
|
|
17434
|
+
const done = (code) => {
|
|
17435
|
+
if (settled) return;
|
|
17436
|
+
settled = true;
|
|
17437
|
+
resolve7({ code, stderr });
|
|
17438
|
+
};
|
|
17439
|
+
child.stderr?.on("data", (b) => {
|
|
17440
|
+
stderr += b.toString();
|
|
17441
|
+
});
|
|
17442
|
+
if (opts.input !== void 0) {
|
|
17443
|
+
child.stdin?.end(opts.input);
|
|
17444
|
+
}
|
|
17445
|
+
let timer;
|
|
17446
|
+
if (opts.timeoutMs !== void 0) {
|
|
17447
|
+
timer = setTimeout(() => {
|
|
17448
|
+
try {
|
|
17449
|
+
child.kill("SIGTERM");
|
|
17450
|
+
} catch {
|
|
17451
|
+
}
|
|
17452
|
+
done(null);
|
|
17453
|
+
}, opts.timeoutMs);
|
|
17454
|
+
}
|
|
17455
|
+
child.once("exit", (code) => {
|
|
17456
|
+
if (timer) clearTimeout(timer);
|
|
17457
|
+
done(code);
|
|
17458
|
+
});
|
|
17459
|
+
child.once("error", () => {
|
|
17460
|
+
if (timer) clearTimeout(timer);
|
|
17461
|
+
done(null);
|
|
17462
|
+
});
|
|
17463
|
+
});
|
|
17464
|
+
}
|
|
17465
|
+
};
|
|
17466
|
+
|
|
17218
17467
|
// src/services/headroom/stats-reporter.ts
|
|
17219
17468
|
var DEFAULT_INPUT_PRICE_PER_MILLION = 3;
|
|
17220
17469
|
var ZERO = {
|
|
@@ -17298,23 +17547,23 @@ var HeadroomStatsReporter = class {
|
|
|
17298
17547
|
};
|
|
17299
17548
|
|
|
17300
17549
|
// src/lib/updateNotifier.ts
|
|
17301
|
-
var
|
|
17302
|
-
var
|
|
17303
|
-
var
|
|
17550
|
+
var fs39 = __toESM(require("fs"));
|
|
17551
|
+
var os32 = __toESM(require("os"));
|
|
17552
|
+
var path45 = __toESM(require("path"));
|
|
17304
17553
|
var https6 = __toESM(require("https"));
|
|
17305
|
-
var
|
|
17554
|
+
var import_node_child_process13 = require("child_process");
|
|
17306
17555
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
17307
17556
|
var PKG_NAME = "codeam-cli";
|
|
17308
17557
|
var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
17309
17558
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
17310
17559
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
17311
17560
|
function cachePath() {
|
|
17312
|
-
const dir =
|
|
17313
|
-
return
|
|
17561
|
+
const dir = path45.join(os32.homedir(), ".codeam");
|
|
17562
|
+
return path45.join(dir, "update-check.json");
|
|
17314
17563
|
}
|
|
17315
17564
|
function readCache() {
|
|
17316
17565
|
try {
|
|
17317
|
-
const raw =
|
|
17566
|
+
const raw = fs39.readFileSync(cachePath(), "utf8");
|
|
17318
17567
|
const parsed = JSON.parse(raw);
|
|
17319
17568
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
17320
17569
|
return parsed;
|
|
@@ -17325,10 +17574,10 @@ function readCache() {
|
|
|
17325
17574
|
function writeCache(cache) {
|
|
17326
17575
|
try {
|
|
17327
17576
|
const file = cachePath();
|
|
17328
|
-
|
|
17577
|
+
fs39.mkdirSync(path45.dirname(file), { recursive: true });
|
|
17329
17578
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
17330
|
-
|
|
17331
|
-
|
|
17579
|
+
fs39.writeFileSync(tmp, JSON.stringify(cache));
|
|
17580
|
+
fs39.renameSync(tmp, file);
|
|
17332
17581
|
} catch {
|
|
17333
17582
|
}
|
|
17334
17583
|
}
|
|
@@ -17396,14 +17645,14 @@ function notifyIfStale(currentVersion, latest) {
|
|
|
17396
17645
|
}
|
|
17397
17646
|
function isLinkedInstall() {
|
|
17398
17647
|
try {
|
|
17399
|
-
const root = (0,
|
|
17648
|
+
const root = (0, import_node_child_process13.execSync)("npm root -g", {
|
|
17400
17649
|
encoding: "utf8",
|
|
17401
17650
|
stdio: ["ignore", "pipe", "ignore"],
|
|
17402
17651
|
timeout: 2e3
|
|
17403
17652
|
}).trim();
|
|
17404
17653
|
if (!root) return false;
|
|
17405
|
-
const pkgPath =
|
|
17406
|
-
return
|
|
17654
|
+
const pkgPath = path45.join(root, PKG_NAME);
|
|
17655
|
+
return fs39.lstatSync(pkgPath).isSymbolicLink();
|
|
17407
17656
|
} catch {
|
|
17408
17657
|
return false;
|
|
17409
17658
|
}
|
|
@@ -17424,7 +17673,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
17424
17673
|
|
|
17425
17674
|
`
|
|
17426
17675
|
);
|
|
17427
|
-
const install = (0,
|
|
17676
|
+
const install = (0, import_node_child_process13.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
|
|
17428
17677
|
stdio: "inherit",
|
|
17429
17678
|
env: process.env
|
|
17430
17679
|
});
|
|
@@ -17439,24 +17688,40 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
17439
17688
|
return;
|
|
17440
17689
|
}
|
|
17441
17690
|
try {
|
|
17442
|
-
|
|
17691
|
+
fs39.unlinkSync(cachePath());
|
|
17443
17692
|
} catch {
|
|
17444
17693
|
}
|
|
17445
17694
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
17446
17695
|
|
|
17447
17696
|
`);
|
|
17448
|
-
const child = (0,
|
|
17697
|
+
const child = (0, import_node_child_process13.spawnSync)("codeam", process.argv.slice(2), {
|
|
17449
17698
|
stdio: "inherit",
|
|
17450
17699
|
env: process.env
|
|
17451
17700
|
});
|
|
17452
17701
|
process.exit(child.status ?? 0);
|
|
17453
17702
|
}
|
|
17703
|
+
async function autoUpgradeBeforeCriticalCommand() {
|
|
17704
|
+
if (process.env.NODE_ENV === "test") return;
|
|
17705
|
+
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17706
|
+
if (process.env.CI) return;
|
|
17707
|
+
const current = true ? "2.39.84" : null;
|
|
17708
|
+
if (!current) return;
|
|
17709
|
+
const cache = readCache();
|
|
17710
|
+
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
17711
|
+
let latest = fresh && cache ? cache.latest : null;
|
|
17712
|
+
if (!latest) {
|
|
17713
|
+
latest = await fetchLatest();
|
|
17714
|
+
if (latest) writeCache({ fetchedAt: Date.now(), latest });
|
|
17715
|
+
}
|
|
17716
|
+
if (!latest) return;
|
|
17717
|
+
maybeAutoUpdate(current, latest);
|
|
17718
|
+
}
|
|
17454
17719
|
function checkForUpdates() {
|
|
17455
17720
|
if (process.env.NODE_ENV === "test") return;
|
|
17456
17721
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17457
17722
|
if (process.env.CI) return;
|
|
17458
17723
|
if (!process.stdout.isTTY) return;
|
|
17459
|
-
const current = true ? "2.39.
|
|
17724
|
+
const current = true ? "2.39.84" : null;
|
|
17460
17725
|
if (!current) return;
|
|
17461
17726
|
const cache = readCache();
|
|
17462
17727
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17565,7 +17830,7 @@ var HEADROOM_MIN_FREE_DISK_BYTES = 2 * 1024 * 1024 * 1024;
|
|
|
17565
17830
|
var defaultHeadroomRunner = {
|
|
17566
17831
|
which(cmd) {
|
|
17567
17832
|
try {
|
|
17568
|
-
(0,
|
|
17833
|
+
(0, import_node_child_process14.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
17569
17834
|
return true;
|
|
17570
17835
|
} catch {
|
|
17571
17836
|
return false;
|
|
@@ -17573,7 +17838,7 @@ var defaultHeadroomRunner = {
|
|
|
17573
17838
|
},
|
|
17574
17839
|
run(cmd, args2, opts = {}) {
|
|
17575
17840
|
return new Promise((resolve7) => {
|
|
17576
|
-
const child = (0,
|
|
17841
|
+
const child = (0, import_node_child_process14.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"] });
|
|
17577
17842
|
let stderrBuf = "";
|
|
17578
17843
|
let settled = false;
|
|
17579
17844
|
const done = (code) => {
|
|
@@ -17727,15 +17992,15 @@ function agentIdToHeadroomKind(agentId) {
|
|
|
17727
17992
|
return "claude";
|
|
17728
17993
|
}
|
|
17729
17994
|
function headroomConfigPath() {
|
|
17730
|
-
return
|
|
17995
|
+
return path46.join(os33.homedir(), ".codeam", "headroom-config.json");
|
|
17731
17996
|
}
|
|
17732
17997
|
function persistHeadroomConfig(config) {
|
|
17733
17998
|
try {
|
|
17734
17999
|
const file = headroomConfigPath();
|
|
17735
|
-
|
|
18000
|
+
fs40.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
|
|
17736
18001
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
17737
|
-
|
|
17738
|
-
|
|
18002
|
+
fs40.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
18003
|
+
fs40.renameSync(tmp, file);
|
|
17739
18004
|
} catch (err) {
|
|
17740
18005
|
log.warn(
|
|
17741
18006
|
"host-agent",
|
|
@@ -17745,7 +18010,7 @@ function persistHeadroomConfig(config) {
|
|
|
17745
18010
|
}
|
|
17746
18011
|
function readHeadroomChildEnv() {
|
|
17747
18012
|
try {
|
|
17748
|
-
const raw =
|
|
18013
|
+
const raw = fs40.readFileSync(headroomConfigPath(), "utf8");
|
|
17749
18014
|
const parsed = JSON.parse(raw);
|
|
17750
18015
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
17751
18016
|
const o = parsed;
|
|
@@ -17765,37 +18030,37 @@ function bundledClaudeBinDir() {
|
|
|
17765
18030
|
const roots = /* @__PURE__ */ new Set();
|
|
17766
18031
|
let dir = __dirname;
|
|
17767
18032
|
for (let i = 0; i < 6; i++) {
|
|
17768
|
-
roots.add(
|
|
17769
|
-
const parent =
|
|
18033
|
+
roots.add(path46.join(dir, "node_modules"));
|
|
18034
|
+
const parent = path46.dirname(dir);
|
|
17770
18035
|
if (parent === dir) break;
|
|
17771
18036
|
dir = parent;
|
|
17772
18037
|
}
|
|
17773
18038
|
try {
|
|
17774
18039
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
17775
|
-
const marker = `${
|
|
18040
|
+
const marker = `${path46.sep}@anthropic-ai${path46.sep}`;
|
|
17776
18041
|
const idx = main2.lastIndexOf(marker);
|
|
17777
18042
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
17778
18043
|
} catch {
|
|
17779
18044
|
}
|
|
17780
18045
|
for (const nm of roots) {
|
|
17781
|
-
const atAnthropic =
|
|
18046
|
+
const atAnthropic = path46.join(nm, "@anthropic-ai");
|
|
17782
18047
|
let entries;
|
|
17783
18048
|
try {
|
|
17784
|
-
entries =
|
|
18049
|
+
entries = fs40.readdirSync(atAnthropic);
|
|
17785
18050
|
} catch {
|
|
17786
18051
|
continue;
|
|
17787
18052
|
}
|
|
17788
18053
|
for (const entry of entries) {
|
|
17789
18054
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
17790
|
-
const bin =
|
|
17791
|
-
if (
|
|
18055
|
+
const bin = path46.join(atAnthropic, entry, "claude");
|
|
18056
|
+
if (fs40.existsSync(bin)) return path46.dirname(bin);
|
|
17792
18057
|
}
|
|
17793
18058
|
}
|
|
17794
18059
|
return null;
|
|
17795
18060
|
}
|
|
17796
18061
|
async function getFreeDiskBytes(dir) {
|
|
17797
18062
|
try {
|
|
17798
|
-
const s = await
|
|
18063
|
+
const s = await fs40.promises.statfs(dir);
|
|
17799
18064
|
return s.bsize * s.bavail;
|
|
17800
18065
|
} catch {
|
|
17801
18066
|
return null;
|
|
@@ -17845,14 +18110,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner)
|
|
|
17845
18110
|
if (initKind === "claude") {
|
|
17846
18111
|
const claudeDir = bundledClaudeBinDir();
|
|
17847
18112
|
if (claudeDir) {
|
|
17848
|
-
initEnv.PATH = `${claudeDir}${
|
|
18113
|
+
initEnv.PATH = `${claudeDir}${path46.delimiter}${process.env["PATH"] ?? ""}`;
|
|
17849
18114
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
17850
18115
|
} else {
|
|
17851
18116
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
17852
18117
|
}
|
|
17853
18118
|
}
|
|
17854
18119
|
const initOk = await new Promise((resolve7) => {
|
|
17855
|
-
(0,
|
|
18120
|
+
(0, import_node_child_process14.execFile)(
|
|
17856
18121
|
"headroom",
|
|
17857
18122
|
["init", "--global", initKind],
|
|
17858
18123
|
{ env: initEnv },
|
|
@@ -17873,7 +18138,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner)
|
|
|
17873
18138
|
return false;
|
|
17874
18139
|
}
|
|
17875
18140
|
try {
|
|
17876
|
-
const proxy = (0,
|
|
18141
|
+
const proxy = (0, import_node_child_process14.spawn)("headroom", ["proxy", "--port", "8787"], {
|
|
17877
18142
|
stdio: "ignore",
|
|
17878
18143
|
detached: true,
|
|
17879
18144
|
env: { ...process.env, HEADROOM_KOMPRESS_BACKEND: "onnx_cpu" }
|
|
@@ -17887,18 +18152,18 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner)
|
|
|
17887
18152
|
}
|
|
17888
18153
|
return true;
|
|
17889
18154
|
}
|
|
17890
|
-
var defaultSpawner = (env, cwd, args2 = []) => (0,
|
|
18155
|
+
var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
|
|
17891
18156
|
cwd,
|
|
17892
18157
|
env: { ...process.env, ...env },
|
|
17893
18158
|
stdio: ["ignore", "pipe", "pipe"],
|
|
17894
18159
|
detached: false
|
|
17895
18160
|
});
|
|
17896
18161
|
function currentCliVersion() {
|
|
17897
|
-
return true ? "2.39.
|
|
18162
|
+
return true ? "2.39.84" : null;
|
|
17898
18163
|
}
|
|
17899
18164
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17900
18165
|
return new Promise((resolve7) => {
|
|
17901
|
-
(0,
|
|
18166
|
+
(0, import_node_child_process14.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
17902
18167
|
const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
|
|
17903
18168
|
resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
17904
18169
|
});
|
|
@@ -17969,20 +18234,20 @@ var defaultOnUpdated = (version3) => {
|
|
|
17969
18234
|
};
|
|
17970
18235
|
var defaultDisableService = () => {
|
|
17971
18236
|
try {
|
|
17972
|
-
(0,
|
|
18237
|
+
(0, import_node_child_process14.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
17973
18238
|
} catch {
|
|
17974
18239
|
}
|
|
17975
18240
|
};
|
|
17976
18241
|
var defaultTeardownHeadroom = () => {
|
|
17977
18242
|
try {
|
|
17978
|
-
const kind = JSON.parse(
|
|
18243
|
+
const kind = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
17979
18244
|
if (kind) {
|
|
17980
|
-
(0,
|
|
18245
|
+
(0, import_node_child_process14.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
17981
18246
|
}
|
|
17982
18247
|
} catch {
|
|
17983
18248
|
}
|
|
17984
18249
|
try {
|
|
17985
|
-
(0,
|
|
18250
|
+
(0, import_node_child_process14.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
|
|
17986
18251
|
} catch {
|
|
17987
18252
|
}
|
|
17988
18253
|
persistHeadroomConfig({ enabled: false });
|
|
@@ -18303,15 +18568,30 @@ var HostAgentSupervisor = class {
|
|
|
18303
18568
|
report("installing", "installing agent CLI");
|
|
18304
18569
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
18305
18570
|
}
|
|
18306
|
-
const home = process.env.HOME ||
|
|
18571
|
+
const home = process.env.HOME || os33.homedir();
|
|
18307
18572
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
18573
|
+
if (payload.cloneToken) {
|
|
18574
|
+
try {
|
|
18575
|
+
report("preparing", "configuring git tooling");
|
|
18576
|
+
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
18577
|
+
if (ghCmd) {
|
|
18578
|
+
childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
|
|
18579
|
+
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
18580
|
+
}
|
|
18581
|
+
} catch (e) {
|
|
18582
|
+
log.warn(
|
|
18583
|
+
"host-agent",
|
|
18584
|
+
`gh tooling setup skipped: ${e instanceof Error ? e.message : String(e)}`
|
|
18585
|
+
);
|
|
18586
|
+
}
|
|
18587
|
+
}
|
|
18308
18588
|
if (payload.previewTunnelToken && payload.previewHostname) {
|
|
18309
18589
|
childEnv.PREVIEW_TUNNEL_TOKEN = payload.previewTunnelToken;
|
|
18310
18590
|
childEnv.PREVIEW_TUNNEL_HOSTNAME = payload.previewHostname;
|
|
18311
18591
|
}
|
|
18312
18592
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl) {
|
|
18313
18593
|
report("headroom", "setting up Headroom proxy");
|
|
18314
|
-
const freeBytes = await this.getFreeDisk(
|
|
18594
|
+
const freeBytes = await this.getFreeDisk(os33.homedir());
|
|
18315
18595
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
18316
18596
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
18317
18597
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -18427,8 +18707,8 @@ var HostAgentSupervisor = class {
|
|
|
18427
18707
|
*/
|
|
18428
18708
|
runAgentInstall(script) {
|
|
18429
18709
|
return new Promise((resolve7) => {
|
|
18430
|
-
const home = process.env.HOME ||
|
|
18431
|
-
const child = (0,
|
|
18710
|
+
const home = process.env.HOME || os33.homedir();
|
|
18711
|
+
const child = (0, import_node_child_process14.spawn)("sh", ["-c", script], {
|
|
18432
18712
|
env: { ...process.env, HOME: home },
|
|
18433
18713
|
stdio: ["ignore", "pipe", "pipe"]
|
|
18434
18714
|
});
|
|
@@ -18582,12 +18862,12 @@ function readTokenFromArgs(args2) {
|
|
|
18582
18862
|
}
|
|
18583
18863
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
18584
18864
|
if (fileFlag) {
|
|
18585
|
-
const
|
|
18865
|
+
const path60 = fileFlag.slice("--token-file=".length);
|
|
18586
18866
|
try {
|
|
18587
|
-
const content =
|
|
18588
|
-
if (content.length === 0) fail(`--token-file ${
|
|
18867
|
+
const content = fs41.readFileSync(path60, "utf8").trim();
|
|
18868
|
+
if (content.length === 0) fail(`--token-file ${path60} is empty`);
|
|
18589
18869
|
try {
|
|
18590
|
-
|
|
18870
|
+
fs41.unlinkSync(path60);
|
|
18591
18871
|
} catch {
|
|
18592
18872
|
}
|
|
18593
18873
|
return content;
|
|
@@ -18613,7 +18893,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
18613
18893
|
pluginId,
|
|
18614
18894
|
ideName: "codeam-cli (codespace)",
|
|
18615
18895
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
18616
|
-
hostname:
|
|
18896
|
+
hostname: os34.hostname(),
|
|
18617
18897
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
18618
18898
|
// Current git branch of the codespace's working directory, so the
|
|
18619
18899
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -18674,7 +18954,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
18674
18954
|
}
|
|
18675
18955
|
}
|
|
18676
18956
|
function pairAutoLockPath() {
|
|
18677
|
-
return
|
|
18957
|
+
return path47.join(os34.homedir(), ".codeam", "pair-auto.lock");
|
|
18678
18958
|
}
|
|
18679
18959
|
function isLivePairAuto(pid) {
|
|
18680
18960
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -18684,7 +18964,7 @@ function isLivePairAuto(pid) {
|
|
|
18684
18964
|
if (e.code !== "EPERM") return false;
|
|
18685
18965
|
}
|
|
18686
18966
|
try {
|
|
18687
|
-
return
|
|
18967
|
+
return fs41.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
18688
18968
|
} catch {
|
|
18689
18969
|
return true;
|
|
18690
18970
|
}
|
|
@@ -18694,24 +18974,24 @@ function isLiveCodeam(pid) {
|
|
|
18694
18974
|
}
|
|
18695
18975
|
function daemonLockPath(sessionId) {
|
|
18696
18976
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
18697
|
-
return
|
|
18977
|
+
return path47.join(os34.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
18698
18978
|
}
|
|
18699
18979
|
function acquireDaemonLock(sessionId) {
|
|
18700
18980
|
const lockPath = daemonLockPath(sessionId);
|
|
18701
18981
|
try {
|
|
18702
|
-
|
|
18982
|
+
fs41.mkdirSync(path47.dirname(lockPath), { recursive: true });
|
|
18703
18983
|
try {
|
|
18704
|
-
|
|
18984
|
+
fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
18705
18985
|
} catch (e) {
|
|
18706
18986
|
if (e.code !== "EEXIST") throw e;
|
|
18707
|
-
const holder = Number(
|
|
18987
|
+
const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
|
|
18708
18988
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
18709
|
-
|
|
18989
|
+
fs41.writeFileSync(lockPath, String(process.pid));
|
|
18710
18990
|
}
|
|
18711
18991
|
const release3 = () => {
|
|
18712
18992
|
try {
|
|
18713
|
-
if (
|
|
18714
|
-
|
|
18993
|
+
if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
18994
|
+
fs41.unlinkSync(lockPath);
|
|
18715
18995
|
}
|
|
18716
18996
|
} catch {
|
|
18717
18997
|
}
|
|
@@ -18733,19 +19013,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
18733
19013
|
function acquireSingletonLock() {
|
|
18734
19014
|
const lockPath = pairAutoLockPath();
|
|
18735
19015
|
try {
|
|
18736
|
-
|
|
19016
|
+
fs41.mkdirSync(path47.dirname(lockPath), { recursive: true });
|
|
18737
19017
|
try {
|
|
18738
|
-
|
|
19018
|
+
fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
18739
19019
|
} catch (e) {
|
|
18740
19020
|
if (e.code !== "EEXIST") throw e;
|
|
18741
|
-
const holder = Number(
|
|
19021
|
+
const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
|
|
18742
19022
|
if (isLivePairAuto(holder)) return false;
|
|
18743
|
-
|
|
19023
|
+
fs41.writeFileSync(lockPath, String(process.pid));
|
|
18744
19024
|
}
|
|
18745
19025
|
process.once("exit", () => {
|
|
18746
19026
|
try {
|
|
18747
|
-
if (
|
|
18748
|
-
|
|
19027
|
+
if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
19028
|
+
fs41.unlinkSync(lockPath);
|
|
18749
19029
|
}
|
|
18750
19030
|
} catch {
|
|
18751
19031
|
}
|
|
@@ -18827,7 +19107,7 @@ async function pairAuto(args2) {
|
|
|
18827
19107
|
}
|
|
18828
19108
|
|
|
18829
19109
|
// src/services/headroom/wrap-launch.ts
|
|
18830
|
-
var
|
|
19110
|
+
var import_node_child_process15 = require("child_process");
|
|
18831
19111
|
function wrapWithHeadroom(launch, opts) {
|
|
18832
19112
|
if (!opts.enabled || !opts.headroomPresent) return launch;
|
|
18833
19113
|
return {
|
|
@@ -18840,7 +19120,7 @@ var _present;
|
|
|
18840
19120
|
function headroomPresent() {
|
|
18841
19121
|
if (_present !== void 0) return Promise.resolve(_present);
|
|
18842
19122
|
return new Promise((resolve7) => {
|
|
18843
|
-
(0,
|
|
19123
|
+
(0, import_node_child_process15.execFile)("headroom", ["--version"], (err) => {
|
|
18844
19124
|
_present = !err;
|
|
18845
19125
|
resolve7(_present);
|
|
18846
19126
|
});
|
|
@@ -19190,19 +19470,19 @@ var AgentService = class _AgentService {
|
|
|
19190
19470
|
};
|
|
19191
19471
|
|
|
19192
19472
|
// src/agents/acp/adapters.ts
|
|
19193
|
-
var
|
|
19473
|
+
var path48 = __toESM(require("path"));
|
|
19194
19474
|
var require_ = require;
|
|
19195
19475
|
function resolveBin(pkgName, binName) {
|
|
19196
19476
|
try {
|
|
19197
19477
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
19198
19478
|
const manifest = require_(`${pkgName}/package.json`);
|
|
19199
|
-
const pkgDir =
|
|
19479
|
+
const pkgDir = path48.dirname(manifestPath);
|
|
19200
19480
|
const bin = manifest.bin;
|
|
19201
19481
|
if (!bin) return null;
|
|
19202
|
-
if (typeof bin === "string") return
|
|
19482
|
+
if (typeof bin === "string") return path48.resolve(pkgDir, bin);
|
|
19203
19483
|
const target = binName ?? Object.keys(bin)[0];
|
|
19204
19484
|
if (!target || !bin[target]) return null;
|
|
19205
|
-
return
|
|
19485
|
+
return path48.resolve(pkgDir, bin[target]);
|
|
19206
19486
|
} catch {
|
|
19207
19487
|
return null;
|
|
19208
19488
|
}
|
|
@@ -19278,9 +19558,9 @@ function requiresAcp(agent) {
|
|
|
19278
19558
|
var import_node_crypto7 = require("crypto");
|
|
19279
19559
|
|
|
19280
19560
|
// src/services/history.service.ts
|
|
19281
|
-
var
|
|
19282
|
-
var
|
|
19283
|
-
var
|
|
19561
|
+
var fs42 = __toESM(require("fs"));
|
|
19562
|
+
var path49 = __toESM(require("path"));
|
|
19563
|
+
var os35 = __toESM(require("os"));
|
|
19284
19564
|
var https7 = __toESM(require("https"));
|
|
19285
19565
|
var http6 = __toESM(require("http"));
|
|
19286
19566
|
var import_zod2 = require("zod");
|
|
@@ -19307,7 +19587,7 @@ function parseJsonl(filePath) {
|
|
|
19307
19587
|
const messages = [];
|
|
19308
19588
|
let raw;
|
|
19309
19589
|
try {
|
|
19310
|
-
raw =
|
|
19590
|
+
raw = fs42.readFileSync(filePath, "utf8");
|
|
19311
19591
|
} catch (err) {
|
|
19312
19592
|
if (err.code !== "ENOENT") {
|
|
19313
19593
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -19448,7 +19728,7 @@ var HistoryService = class _HistoryService {
|
|
|
19448
19728
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
19449
19729
|
}
|
|
19450
19730
|
get projectDir() {
|
|
19451
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
19731
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path49.join(os35.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
19452
19732
|
}
|
|
19453
19733
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
19454
19734
|
setCurrentConversationId(id) {
|
|
@@ -19460,7 +19740,7 @@ var HistoryService = class _HistoryService {
|
|
|
19460
19740
|
/** Return the current message count in the active conversation. */
|
|
19461
19741
|
getCurrentMessageCount() {
|
|
19462
19742
|
if (!this.currentConversationId) return 0;
|
|
19463
|
-
const filePath =
|
|
19743
|
+
const filePath = path49.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
19464
19744
|
return parseJsonl(filePath).length;
|
|
19465
19745
|
}
|
|
19466
19746
|
/**
|
|
@@ -19471,7 +19751,7 @@ var HistoryService = class _HistoryService {
|
|
|
19471
19751
|
const deadline = Date.now() + timeoutMs;
|
|
19472
19752
|
while (Date.now() < deadline) {
|
|
19473
19753
|
if (!this.currentConversationId) return null;
|
|
19474
|
-
const filePath =
|
|
19754
|
+
const filePath = path49.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
19475
19755
|
const messages = parseJsonl(filePath);
|
|
19476
19756
|
if (messages.length > previousCount) {
|
|
19477
19757
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -19497,16 +19777,16 @@ var HistoryService = class _HistoryService {
|
|
|
19497
19777
|
const dir = this.projectDir;
|
|
19498
19778
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
19499
19779
|
try {
|
|
19500
|
-
const files =
|
|
19780
|
+
const files = fs42.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
19501
19781
|
try {
|
|
19502
|
-
const stat3 =
|
|
19782
|
+
const stat3 = fs42.statSync(path49.join(dir, e.name));
|
|
19503
19783
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
19504
19784
|
} catch {
|
|
19505
19785
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
19506
19786
|
}
|
|
19507
19787
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
19508
19788
|
if (files.length > 0) {
|
|
19509
|
-
this.currentConversationId =
|
|
19789
|
+
this.currentConversationId = path49.basename(files[0].name, ".jsonl");
|
|
19510
19790
|
}
|
|
19511
19791
|
} catch {
|
|
19512
19792
|
}
|
|
@@ -19540,13 +19820,13 @@ var HistoryService = class _HistoryService {
|
|
|
19540
19820
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
19541
19821
|
let entries;
|
|
19542
19822
|
try {
|
|
19543
|
-
entries =
|
|
19823
|
+
entries = fs42.readdirSync(dir, { withFileTypes: true });
|
|
19544
19824
|
} catch {
|
|
19545
19825
|
return null;
|
|
19546
19826
|
}
|
|
19547
19827
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
19548
19828
|
try {
|
|
19549
|
-
const stat3 =
|
|
19829
|
+
const stat3 = fs42.statSync(path49.join(dir, e.name));
|
|
19550
19830
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
19551
19831
|
} catch {
|
|
19552
19832
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -19555,12 +19835,12 @@ var HistoryService = class _HistoryService {
|
|
|
19555
19835
|
if (files.length === 0) return null;
|
|
19556
19836
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
19557
19837
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
19558
|
-
return this.extractUsageFromFile(
|
|
19838
|
+
return this.extractUsageFromFile(path49.join(dir, targetFile));
|
|
19559
19839
|
}
|
|
19560
19840
|
extractUsageFromFile(filePath) {
|
|
19561
19841
|
let raw;
|
|
19562
19842
|
try {
|
|
19563
|
-
raw =
|
|
19843
|
+
raw = fs42.readFileSync(filePath, "utf8");
|
|
19564
19844
|
} catch {
|
|
19565
19845
|
return null;
|
|
19566
19846
|
}
|
|
@@ -19605,9 +19885,9 @@ var HistoryService = class _HistoryService {
|
|
|
19605
19885
|
let totalCost = 0;
|
|
19606
19886
|
let files;
|
|
19607
19887
|
try {
|
|
19608
|
-
files =
|
|
19888
|
+
files = fs42.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
19609
19889
|
try {
|
|
19610
|
-
return
|
|
19890
|
+
return fs42.statSync(path49.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
19611
19891
|
} catch {
|
|
19612
19892
|
return false;
|
|
19613
19893
|
}
|
|
@@ -19618,7 +19898,7 @@ var HistoryService = class _HistoryService {
|
|
|
19618
19898
|
for (const file of files) {
|
|
19619
19899
|
let raw;
|
|
19620
19900
|
try {
|
|
19621
|
-
raw =
|
|
19901
|
+
raw = fs42.readFileSync(path49.join(projectDir, file), "utf8");
|
|
19622
19902
|
} catch {
|
|
19623
19903
|
continue;
|
|
19624
19904
|
}
|
|
@@ -19686,7 +19966,7 @@ var HistoryService = class _HistoryService {
|
|
|
19686
19966
|
* showing an empty conversation.
|
|
19687
19967
|
*/
|
|
19688
19968
|
async loadConversation(sessionId) {
|
|
19689
|
-
const filePath =
|
|
19969
|
+
const filePath = path49.join(this.projectDir, `${sessionId}.jsonl`);
|
|
19690
19970
|
const messages = parseJsonl(filePath);
|
|
19691
19971
|
if (messages.length === 0) return;
|
|
19692
19972
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -19736,10 +20016,10 @@ var HistoryService = class _HistoryService {
|
|
|
19736
20016
|
* or no transcript exists yet (not an error).
|
|
19737
20017
|
*/
|
|
19738
20018
|
async uploadConversationIfChanged(sessionId) {
|
|
19739
|
-
const filePath =
|
|
20019
|
+
const filePath = path49.join(this.projectDir, `${sessionId}.jsonl`);
|
|
19740
20020
|
let mtimeMs;
|
|
19741
20021
|
try {
|
|
19742
|
-
mtimeMs =
|
|
20022
|
+
mtimeMs = fs42.statSync(filePath).mtimeMs;
|
|
19743
20023
|
} catch {
|
|
19744
20024
|
return false;
|
|
19745
20025
|
}
|
|
@@ -19778,7 +20058,7 @@ var HistoryService = class _HistoryService {
|
|
|
19778
20058
|
sessionId = this.currentConversationId;
|
|
19779
20059
|
if (!sessionId) return 0;
|
|
19780
20060
|
}
|
|
19781
|
-
const filePath =
|
|
20061
|
+
const filePath = path49.join(this.projectDir, `${sessionId}.jsonl`);
|
|
19782
20062
|
const messages = parseJsonl(filePath);
|
|
19783
20063
|
if (messages.length === 0) return 0;
|
|
19784
20064
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -19808,11 +20088,11 @@ var HistoryService = class _HistoryService {
|
|
|
19808
20088
|
};
|
|
19809
20089
|
|
|
19810
20090
|
// src/agents/acp/client.ts
|
|
19811
|
-
var
|
|
19812
|
-
var
|
|
20091
|
+
var import_node_child_process16 = require("child_process");
|
|
20092
|
+
var fs43 = __toESM(require("fs/promises"));
|
|
19813
20093
|
var fsSync = __toESM(require("fs"));
|
|
19814
|
-
var
|
|
19815
|
-
var
|
|
20094
|
+
var os36 = __toESM(require("os"));
|
|
20095
|
+
var path50 = __toESM(require("path"));
|
|
19816
20096
|
var import_node_stream = require("stream");
|
|
19817
20097
|
|
|
19818
20098
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -22349,7 +22629,7 @@ var AcpClient = class {
|
|
|
22349
22629
|
"acpClient",
|
|
22350
22630
|
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
22351
22631
|
);
|
|
22352
|
-
const child = (0,
|
|
22632
|
+
const child = (0, import_node_child_process16.spawn)(adapter.command, adapter.args, {
|
|
22353
22633
|
cwd,
|
|
22354
22634
|
env: { ...process.env, PATH: augmentedPath },
|
|
22355
22635
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -22606,7 +22886,7 @@ var AcpClient = class {
|
|
|
22606
22886
|
},
|
|
22607
22887
|
readTextFile: async (params) => {
|
|
22608
22888
|
try {
|
|
22609
|
-
const content = await
|
|
22889
|
+
const content = await fs43.readFile(params.path, "utf8");
|
|
22610
22890
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
22611
22891
|
} catch (err) {
|
|
22612
22892
|
const code = err.code;
|
|
@@ -22626,7 +22906,7 @@ var AcpClient = class {
|
|
|
22626
22906
|
},
|
|
22627
22907
|
writeTextFile: async (params) => {
|
|
22628
22908
|
try {
|
|
22629
|
-
await
|
|
22909
|
+
await fs43.writeFile(params.path, params.content, "utf8");
|
|
22630
22910
|
return {};
|
|
22631
22911
|
} catch (err) {
|
|
22632
22912
|
const code = err.code;
|
|
@@ -22675,25 +22955,25 @@ function applyLineRange(content, line, limit) {
|
|
|
22675
22955
|
return { content: lines.slice(start2, end).join("\n") };
|
|
22676
22956
|
}
|
|
22677
22957
|
function knownAgentBinaryDirs() {
|
|
22678
|
-
const home =
|
|
22958
|
+
const home = os36.homedir();
|
|
22679
22959
|
const out2 = [];
|
|
22680
22960
|
out2.push("/tmp/codeam-node20/bin");
|
|
22681
22961
|
for (const root of [
|
|
22682
22962
|
"/usr/local/share/nvm/versions/node",
|
|
22683
|
-
|
|
22963
|
+
path50.join(home, ".nvm/versions/node")
|
|
22684
22964
|
]) {
|
|
22685
22965
|
try {
|
|
22686
22966
|
for (const child of fsSync.readdirSync(root)) {
|
|
22687
|
-
out2.push(
|
|
22967
|
+
out2.push(path50.join(root, child, "bin"));
|
|
22688
22968
|
}
|
|
22689
22969
|
} catch {
|
|
22690
22970
|
}
|
|
22691
22971
|
}
|
|
22692
|
-
out2.push(
|
|
22972
|
+
out2.push(path50.join(home, ".volta/bin"));
|
|
22693
22973
|
out2.push("/usr/local/bin");
|
|
22694
22974
|
out2.push("/usr/bin");
|
|
22695
|
-
out2.push(
|
|
22696
|
-
out2.push(
|
|
22975
|
+
out2.push(path50.join(home, ".local/bin"));
|
|
22976
|
+
out2.push(path50.join(home, "bin"));
|
|
22697
22977
|
return out2.filter((p2) => {
|
|
22698
22978
|
try {
|
|
22699
22979
|
return fsSync.statSync(p2).isDirectory();
|
|
@@ -22704,7 +22984,7 @@ function knownAgentBinaryDirs() {
|
|
|
22704
22984
|
}
|
|
22705
22985
|
function expandPathForAgentBinaries(existingPath) {
|
|
22706
22986
|
const existing = new Set(
|
|
22707
|
-
existingPath.split(
|
|
22987
|
+
existingPath.split(path50.delimiter).filter((p2) => p2.length > 0)
|
|
22708
22988
|
);
|
|
22709
22989
|
const additions = [];
|
|
22710
22990
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -22714,7 +22994,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
22714
22994
|
}
|
|
22715
22995
|
}
|
|
22716
22996
|
if (additions.length === 0) return existingPath;
|
|
22717
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
22997
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path50.delimiter);
|
|
22718
22998
|
}
|
|
22719
22999
|
|
|
22720
23000
|
// src/services/streaming/transport.ts
|
|
@@ -23041,15 +23321,15 @@ function reconcileCumulative(existing, incoming) {
|
|
|
23041
23321
|
}
|
|
23042
23322
|
|
|
23043
23323
|
// src/agents/acp/onboarding.ts
|
|
23044
|
-
var
|
|
23045
|
-
var
|
|
23046
|
-
var
|
|
23324
|
+
var fs44 = __toESM(require("fs"));
|
|
23325
|
+
var os37 = __toESM(require("os"));
|
|
23326
|
+
var path51 = __toESM(require("path"));
|
|
23047
23327
|
var _onboardingSeam = {
|
|
23048
|
-
markerPath: (sessionId) =>
|
|
23049
|
-
exists: (p2) =>
|
|
23328
|
+
markerPath: (sessionId) => path51.join(os37.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
23329
|
+
exists: (p2) => fs44.existsSync(p2),
|
|
23050
23330
|
write: (p2) => {
|
|
23051
|
-
|
|
23052
|
-
|
|
23331
|
+
fs44.mkdirSync(path51.dirname(p2), { recursive: true });
|
|
23332
|
+
fs44.writeFileSync(p2, "");
|
|
23053
23333
|
},
|
|
23054
23334
|
disabled: () => {
|
|
23055
23335
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -23057,7 +23337,7 @@ var _onboardingSeam = {
|
|
|
23057
23337
|
}
|
|
23058
23338
|
};
|
|
23059
23339
|
function buildOnboardingWelcome(cwd) {
|
|
23060
|
-
const repo =
|
|
23340
|
+
const repo = path51.basename(cwd || "") || "this project";
|
|
23061
23341
|
return [
|
|
23062
23342
|
`Welcome to CodeAgent Mobile! \u{1F44B} You're now driving this agent from your phone \u2014 and it comes fully wired, zero setup:`,
|
|
23063
23343
|
"",
|
|
@@ -23323,8 +23603,8 @@ var import_crypto5 = require("crypto");
|
|
|
23323
23603
|
|
|
23324
23604
|
// src/services/turn-files/git-changeset.ts
|
|
23325
23605
|
var import_child_process22 = require("child_process");
|
|
23326
|
-
var
|
|
23327
|
-
var
|
|
23606
|
+
var fs45 = __toESM(require("fs/promises"));
|
|
23607
|
+
var path52 = __toESM(require("path"));
|
|
23328
23608
|
async function collectRepoChangeset(opts) {
|
|
23329
23609
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
23330
23610
|
if (status2 === null) return null;
|
|
@@ -23342,7 +23622,7 @@ async function collectRepoChangeset(opts) {
|
|
|
23342
23622
|
let stats;
|
|
23343
23623
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
23344
23624
|
const lineCount = await readUntrackedLineCount(
|
|
23345
|
-
|
|
23625
|
+
path52.join(opts.repoRoot, row.filePath)
|
|
23346
23626
|
);
|
|
23347
23627
|
stats = { added: lineCount, removed: 0 };
|
|
23348
23628
|
} else {
|
|
@@ -23373,7 +23653,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
23373
23653
|
}
|
|
23374
23654
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
23375
23655
|
try {
|
|
23376
|
-
const content = await
|
|
23656
|
+
const content = await fs45.readFile(absPath, "utf8");
|
|
23377
23657
|
let count = 0;
|
|
23378
23658
|
let pos = -1;
|
|
23379
23659
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -23465,7 +23745,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
23465
23745
|
});
|
|
23466
23746
|
}
|
|
23467
23747
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
23468
|
-
const
|
|
23748
|
+
const fs49 = await import("fs/promises");
|
|
23469
23749
|
const out2 = [];
|
|
23470
23750
|
await walk(workingDir, 0);
|
|
23471
23751
|
return out2;
|
|
@@ -23473,7 +23753,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
23473
23753
|
if (depth > maxDepth) return;
|
|
23474
23754
|
let entries = [];
|
|
23475
23755
|
try {
|
|
23476
|
-
const dirents = await
|
|
23756
|
+
const dirents = await fs49.readdir(dir, { withFileTypes: true });
|
|
23477
23757
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
23478
23758
|
} catch {
|
|
23479
23759
|
return;
|
|
@@ -23484,8 +23764,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
23484
23764
|
if (hasGit) {
|
|
23485
23765
|
out2.push({
|
|
23486
23766
|
repoRoot: dir,
|
|
23487
|
-
repoPath:
|
|
23488
|
-
repoName:
|
|
23767
|
+
repoPath: path52.relative(workingDir, dir),
|
|
23768
|
+
repoName: path52.basename(dir)
|
|
23489
23769
|
});
|
|
23490
23770
|
return;
|
|
23491
23771
|
}
|
|
@@ -23493,14 +23773,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
23493
23773
|
if (!entry.isDirectory) continue;
|
|
23494
23774
|
if (entry.name === "node_modules") continue;
|
|
23495
23775
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
23496
|
-
await walk(
|
|
23776
|
+
await walk(path52.join(dir, entry.name), depth + 1);
|
|
23497
23777
|
}
|
|
23498
23778
|
}
|
|
23499
23779
|
}
|
|
23500
23780
|
|
|
23501
23781
|
// src/services/turn-files/files-outbox.ts
|
|
23502
|
-
var
|
|
23503
|
-
var
|
|
23782
|
+
var fs46 = __toESM(require("fs/promises"));
|
|
23783
|
+
var path53 = __toESM(require("path"));
|
|
23504
23784
|
var import_os7 = require("os");
|
|
23505
23785
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
23506
23786
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -23533,16 +23813,16 @@ var FilesOutbox = class {
|
|
|
23533
23813
|
backoffIndex = 0;
|
|
23534
23814
|
stopped = false;
|
|
23535
23815
|
constructor(opts) {
|
|
23536
|
-
const base = opts.baseDir ??
|
|
23537
|
-
this.filePath =
|
|
23816
|
+
const base = opts.baseDir ?? path53.join(homeDir(), HOME_OUTBOX_DIR);
|
|
23817
|
+
this.filePath = path53.join(base, `${opts.sessionId}.jsonl`);
|
|
23538
23818
|
this.post = opts.post;
|
|
23539
23819
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
23540
23820
|
}
|
|
23541
23821
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
23542
23822
|
* line is durable on disk (not once the POST succeeds). */
|
|
23543
23823
|
async enqueue(entry) {
|
|
23544
|
-
await
|
|
23545
|
-
await
|
|
23824
|
+
await fs46.mkdir(path53.dirname(this.filePath), { recursive: true });
|
|
23825
|
+
await fs46.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
23546
23826
|
this.backoffIndex = 0;
|
|
23547
23827
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
23548
23828
|
}
|
|
@@ -23631,7 +23911,7 @@ var FilesOutbox = class {
|
|
|
23631
23911
|
async readAll() {
|
|
23632
23912
|
let raw = "";
|
|
23633
23913
|
try {
|
|
23634
|
-
raw = await
|
|
23914
|
+
raw = await fs46.readFile(this.filePath, "utf8");
|
|
23635
23915
|
} catch {
|
|
23636
23916
|
return [];
|
|
23637
23917
|
}
|
|
@@ -23655,12 +23935,12 @@ var FilesOutbox = class {
|
|
|
23655
23935
|
async rewrite(entries) {
|
|
23656
23936
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
23657
23937
|
if (entries.length === 0) {
|
|
23658
|
-
await
|
|
23938
|
+
await fs46.unlink(this.filePath).catch(() => void 0);
|
|
23659
23939
|
return;
|
|
23660
23940
|
}
|
|
23661
23941
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
23662
|
-
await
|
|
23663
|
-
await
|
|
23942
|
+
await fs46.writeFile(tmpPath, payload, "utf8");
|
|
23943
|
+
await fs46.rename(tmpPath, this.filePath);
|
|
23664
23944
|
}
|
|
23665
23945
|
};
|
|
23666
23946
|
function applyJitter(ms) {
|
|
@@ -25868,15 +26148,15 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
25868
26148
|
}
|
|
25869
26149
|
|
|
25870
26150
|
// src/agents/claude/onboarding.ts
|
|
25871
|
-
var
|
|
25872
|
-
var
|
|
25873
|
-
var
|
|
26151
|
+
var fs47 = __toESM(require("fs"));
|
|
26152
|
+
var os38 = __toESM(require("os"));
|
|
26153
|
+
var path54 = __toESM(require("path"));
|
|
25874
26154
|
function ensureClaudeOnboarded() {
|
|
25875
26155
|
try {
|
|
25876
|
-
const file =
|
|
26156
|
+
const file = path54.join(os38.homedir(), ".claude.json");
|
|
25877
26157
|
let config = {};
|
|
25878
26158
|
try {
|
|
25879
|
-
config = JSON.parse(
|
|
26159
|
+
config = JSON.parse(fs47.readFileSync(file, "utf8"));
|
|
25880
26160
|
} catch {
|
|
25881
26161
|
}
|
|
25882
26162
|
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
@@ -25887,8 +26167,8 @@ function ensureClaudeOnboarded() {
|
|
|
25887
26167
|
if (typeof config.lastOnboardingVersion !== "string") {
|
|
25888
26168
|
config.lastOnboardingVersion = "2.1.177";
|
|
25889
26169
|
}
|
|
25890
|
-
|
|
25891
|
-
|
|
26170
|
+
fs47.mkdirSync(path54.dirname(file), { recursive: true });
|
|
26171
|
+
fs47.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
25892
26172
|
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
25893
26173
|
} catch (err) {
|
|
25894
26174
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
@@ -26528,7 +26808,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
26528
26808
|
var import_child_process23 = require("child_process");
|
|
26529
26809
|
var import_util4 = require("util");
|
|
26530
26810
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
26531
|
-
var
|
|
26811
|
+
var path55 = __toESM(require("path"));
|
|
26532
26812
|
var execFileP6 = (0, import_util4.promisify)(import_child_process23.execFile);
|
|
26533
26813
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
26534
26814
|
function resetStdinForChild() {
|
|
@@ -27017,7 +27297,7 @@ var GitHubCodespacesProvider = class {
|
|
|
27017
27297
|
});
|
|
27018
27298
|
}
|
|
27019
27299
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
27020
|
-
const remoteDir =
|
|
27300
|
+
const remoteDir = path55.posix.dirname(remotePath);
|
|
27021
27301
|
const parts = [
|
|
27022
27302
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
27023
27303
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -27087,7 +27367,7 @@ function shellQuote(s) {
|
|
|
27087
27367
|
// src/services/providers/gitpod.ts
|
|
27088
27368
|
var import_child_process24 = require("child_process");
|
|
27089
27369
|
var import_util5 = require("util");
|
|
27090
|
-
var
|
|
27370
|
+
var path56 = __toESM(require("path"));
|
|
27091
27371
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
27092
27372
|
var execFileP7 = (0, import_util5.promisify)(import_child_process24.execFile);
|
|
27093
27373
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -27327,7 +27607,7 @@ var GitpodProvider = class {
|
|
|
27327
27607
|
});
|
|
27328
27608
|
}
|
|
27329
27609
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
27330
|
-
const remoteDir =
|
|
27610
|
+
const remoteDir = path56.posix.dirname(remotePath);
|
|
27331
27611
|
const parts = [
|
|
27332
27612
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
27333
27613
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -27363,7 +27643,7 @@ function shellQuote2(s) {
|
|
|
27363
27643
|
// src/services/providers/gitlab-workspaces.ts
|
|
27364
27644
|
var import_child_process25 = require("child_process");
|
|
27365
27645
|
var import_util6 = require("util");
|
|
27366
|
-
var
|
|
27646
|
+
var path57 = __toESM(require("path"));
|
|
27367
27647
|
var execFileP8 = (0, import_util6.promisify)(import_child_process25.execFile);
|
|
27368
27648
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
27369
27649
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -27623,7 +27903,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
27623
27903
|
}
|
|
27624
27904
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
27625
27905
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
27626
|
-
const remoteDir =
|
|
27906
|
+
const remoteDir = path57.posix.dirname(remotePath);
|
|
27627
27907
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
27628
27908
|
if (options.mode != null) {
|
|
27629
27909
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -27691,7 +27971,7 @@ function shellQuote3(s) {
|
|
|
27691
27971
|
// src/services/providers/railway.ts
|
|
27692
27972
|
var import_child_process26 = require("child_process");
|
|
27693
27973
|
var import_util7 = require("util");
|
|
27694
|
-
var
|
|
27974
|
+
var path58 = __toESM(require("path"));
|
|
27695
27975
|
var execFileP9 = (0, import_util7.promisify)(import_child_process26.execFile);
|
|
27696
27976
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
27697
27977
|
function resetStdinForChild4() {
|
|
@@ -27927,7 +28207,7 @@ var RailwayProvider = class {
|
|
|
27927
28207
|
if (!projectId || !serviceId) {
|
|
27928
28208
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
27929
28209
|
}
|
|
27930
|
-
const remoteDir =
|
|
28210
|
+
const remoteDir = path58.posix.dirname(remotePath);
|
|
27931
28211
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
27932
28212
|
if (options.mode != null) {
|
|
27933
28213
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -28515,8 +28795,8 @@ async function host(args2) {
|
|
|
28515
28795
|
var import_node_dns = require("dns");
|
|
28516
28796
|
var import_node_util5 = require("util");
|
|
28517
28797
|
var import_node_crypto8 = require("crypto");
|
|
28518
|
-
var
|
|
28519
|
-
var
|
|
28798
|
+
var fs48 = __toESM(require("fs"));
|
|
28799
|
+
var path59 = __toESM(require("path"));
|
|
28520
28800
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
28521
28801
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
28522
28802
|
async function checkDns(apiBase2) {
|
|
@@ -28572,13 +28852,13 @@ async function checkHealth(apiBase2) {
|
|
|
28572
28852
|
}
|
|
28573
28853
|
}
|
|
28574
28854
|
function checkConfigDir() {
|
|
28575
|
-
const dir =
|
|
28855
|
+
const dir = path59.join(require("os").homedir(), ".codeam");
|
|
28576
28856
|
try {
|
|
28577
|
-
|
|
28578
|
-
const probe =
|
|
28579
|
-
|
|
28580
|
-
const read2 =
|
|
28581
|
-
|
|
28857
|
+
fs48.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
28858
|
+
const probe = path59.join(dir, ".doctor-probe");
|
|
28859
|
+
fs48.writeFileSync(probe, "ok", { mode: 384 });
|
|
28860
|
+
const read2 = fs48.readFileSync(probe, "utf8");
|
|
28861
|
+
fs48.unlinkSync(probe);
|
|
28582
28862
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
28583
28863
|
return {
|
|
28584
28864
|
id: "config-dir",
|
|
@@ -28618,9 +28898,9 @@ function checkSessions() {
|
|
|
28618
28898
|
}
|
|
28619
28899
|
}
|
|
28620
28900
|
function checkAgentBinaries() {
|
|
28621
|
-
const
|
|
28901
|
+
const os40 = createOsStrategy();
|
|
28622
28902
|
return getEnabledAgents().map((meta) => {
|
|
28623
|
-
const found =
|
|
28903
|
+
const found = os40.findInPath(meta.binaryName);
|
|
28624
28904
|
return {
|
|
28625
28905
|
id: `agent-${meta.id}`,
|
|
28626
28906
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -28642,7 +28922,7 @@ function checkNodePty() {
|
|
|
28642
28922
|
detail: "not required on this platform"
|
|
28643
28923
|
};
|
|
28644
28924
|
}
|
|
28645
|
-
const vendoredPath =
|
|
28925
|
+
const vendoredPath = path59.join(__dirname, "vendor", "node-pty");
|
|
28646
28926
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
28647
28927
|
try {
|
|
28648
28928
|
require(target);
|
|
@@ -28684,7 +28964,7 @@ function checkChokidar() {
|
|
|
28684
28964
|
}
|
|
28685
28965
|
async function doctor(args2 = []) {
|
|
28686
28966
|
const json = args2.includes("--json");
|
|
28687
|
-
const cliVersion = true ? "2.39.
|
|
28967
|
+
const cliVersion = true ? "2.39.84" : "0.0.0-dev";
|
|
28688
28968
|
const apiBase2 = resolveApiBaseUrl();
|
|
28689
28969
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
28690
28970
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -28883,7 +29163,7 @@ async function completion(args2) {
|
|
|
28883
29163
|
// src/commands/version.ts
|
|
28884
29164
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
28885
29165
|
function version2() {
|
|
28886
|
-
const v = true ? "2.39.
|
|
29166
|
+
const v = true ? "2.39.84" : "unknown";
|
|
28887
29167
|
console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
|
|
28888
29168
|
}
|
|
28889
29169
|
|
|
@@ -29027,10 +29307,10 @@ var EXIT_CODE_NAMES = {
|
|
|
29027
29307
|
};
|
|
29028
29308
|
|
|
29029
29309
|
// src/index.ts
|
|
29030
|
-
var
|
|
29310
|
+
var os39 = __toESM(require("os"));
|
|
29031
29311
|
if (!process.env.HOME) {
|
|
29032
29312
|
try {
|
|
29033
|
-
const home =
|
|
29313
|
+
const home = os39.homedir();
|
|
29034
29314
|
if (home) process.env.HOME = home;
|
|
29035
29315
|
} catch {
|
|
29036
29316
|
}
|
|
@@ -29039,7 +29319,13 @@ loadCodespaceEnv();
|
|
|
29039
29319
|
var [, , command, ...args] = process.argv;
|
|
29040
29320
|
async function main() {
|
|
29041
29321
|
const isMetaCommand = command === "--version" || command === "-v" || command === "version" || command === "--help" || command === "-h" || command === "help";
|
|
29042
|
-
if (!isMetaCommand)
|
|
29322
|
+
if (!isMetaCommand) {
|
|
29323
|
+
if (command === "link" || command === "pair") {
|
|
29324
|
+
await autoUpgradeBeforeCriticalCommand();
|
|
29325
|
+
} else {
|
|
29326
|
+
checkForUpdates();
|
|
29327
|
+
}
|
|
29328
|
+
}
|
|
29043
29329
|
if (initTelemetry()) {
|
|
29044
29330
|
maybePrintFirstRunBanner();
|
|
29045
29331
|
capture("cli_boot", { command: command ?? "(default)" });
|