codeam-cli 2.39.83 → 2.39.85
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 +21 -0
- package/dist/index.js +65 -32
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.39.84] — 2026-06-22
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Agent-agnostic credential validation in codeam link
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **cli:** Make self-hosted git credential helper + gh install OS-agnostic
|
|
16
|
+
|
|
17
|
+
## [2.39.83] — 2026-06-22
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **cli:** Install + authenticate gh on bare self-hosted boxes
|
|
22
|
+
- **cli:** Synchronous auto-upgrade for link/pair on stale CLIs
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **cli:** Persist git credentials + commit identity for self-hosted workspaces
|
|
27
|
+
|
|
7
28
|
## [2.39.82] — 2026-06-22
|
|
8
29
|
|
|
9
30
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -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.85" : "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.85",
|
|
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",
|
|
@@ -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() {
|
|
@@ -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,7 +12514,8 @@ 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
12521
|
function coderabbitLoginLauncher(os40) {
|
|
@@ -12651,7 +12680,8 @@ 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
12687
|
function cursorLoginLauncher(os40) {
|
|
@@ -12837,7 +12867,8 @@ 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
12874
|
function aiderLoginLauncher(os40) {
|
|
@@ -17140,6 +17171,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
|
17140
17171
|
}
|
|
17141
17172
|
const env = nonInteractiveGitEnv();
|
|
17142
17173
|
const git2 = (args2) => execFileP5("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
17174
|
+
const credFilePosix = credFile.split(path42.sep).join("/");
|
|
17143
17175
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
17144
17176
|
});
|
|
17145
17177
|
await git2([
|
|
@@ -17147,7 +17179,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
|
17147
17179
|
"--local",
|
|
17148
17180
|
"--add",
|
|
17149
17181
|
"credential.helper",
|
|
17150
|
-
`store --file=${
|
|
17182
|
+
`store --file=${credFilePosix}`
|
|
17151
17183
|
]).catch(() => {
|
|
17152
17184
|
});
|
|
17153
17185
|
await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef)]).catch(() => {
|
|
@@ -17319,16 +17351,17 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
17319
17351
|
if (runner.which("gh")) return "gh";
|
|
17320
17352
|
const arch2 = ghArch();
|
|
17321
17353
|
const platform3 = process.platform;
|
|
17322
|
-
if (arch2 === null || platform3 !== "linux" && platform3 !== "darwin") {
|
|
17354
|
+
if (arch2 === null || platform3 !== "linux" && platform3 !== "darwin" && platform3 !== "win32") {
|
|
17323
17355
|
log.warn("host-agent", `gh auto-install unsupported on ${platform3}/${process.arch} \u2014 skipping`);
|
|
17324
17356
|
return null;
|
|
17325
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";
|
|
17326
17361
|
const downloadFn = deps.downloadFn ?? download;
|
|
17327
17362
|
const resolveVersionFn = deps.resolveVersionFn ?? resolveLatestGhVersion;
|
|
17328
17363
|
try {
|
|
17329
17364
|
const version3 = await resolveVersionFn(token);
|
|
17330
|
-
const osToken = platform3 === "darwin" ? "macOS" : "linux";
|
|
17331
|
-
const ext = platform3 === "darwin" ? "zip" : "tar.gz";
|
|
17332
17365
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
17333
17366
|
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
17334
17367
|
const tmpRoot = fs38.mkdtempSync(path44.join(os31.tmpdir(), "codeam-gh-"));
|
|
@@ -17337,26 +17370,19 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
17337
17370
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
17338
17371
|
return null;
|
|
17339
17372
|
}
|
|
17340
|
-
|
|
17341
|
-
if (
|
|
17342
|
-
|
|
17343
|
-
extractCode = r.code;
|
|
17344
|
-
} else {
|
|
17345
|
-
const r = await runner.run("tar", ["-xzf", archive, "-C", tmpRoot], { timeoutMs: 6e4 });
|
|
17346
|
-
extractCode = r.code;
|
|
17347
|
-
}
|
|
17348
|
-
if (extractCode !== 0) {
|
|
17349
|
-
log.warn("host-agent", `gh archive extraction failed (code=${String(extractCode)}) \u2014 skipping`);
|
|
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`);
|
|
17350
17376
|
return null;
|
|
17351
17377
|
}
|
|
17352
|
-
const extractedBin = path44.join(tmpRoot, asset, "bin",
|
|
17378
|
+
const extractedBin = path44.join(tmpRoot, asset, "bin", binaryName);
|
|
17353
17379
|
if (!fs38.existsSync(extractedBin)) {
|
|
17354
17380
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
17355
17381
|
return null;
|
|
17356
17382
|
}
|
|
17357
17383
|
const binDir = codeamBinDir();
|
|
17358
17384
|
fs38.mkdirSync(binDir, { recursive: true });
|
|
17359
|
-
const target = path44.join(binDir,
|
|
17385
|
+
const target = path44.join(binDir, binaryName);
|
|
17360
17386
|
fs38.copyFileSync(extractedBin, target);
|
|
17361
17387
|
fs38.chmodSync(target, 493);
|
|
17362
17388
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
@@ -17391,7 +17417,8 @@ async function ensureGhAuth(runner, ghCmd, token) {
|
|
|
17391
17417
|
var defaultGitToolingRunner = {
|
|
17392
17418
|
which(cmd) {
|
|
17393
17419
|
try {
|
|
17394
|
-
|
|
17420
|
+
const probe = process.platform === "win32" ? "where" : "which";
|
|
17421
|
+
(0, import_node_child_process12.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
17395
17422
|
return true;
|
|
17396
17423
|
} catch {
|
|
17397
17424
|
return false;
|
|
@@ -17677,7 +17704,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17677
17704
|
if (process.env.NODE_ENV === "test") return;
|
|
17678
17705
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17679
17706
|
if (process.env.CI) return;
|
|
17680
|
-
const current = true ? "2.39.
|
|
17707
|
+
const current = true ? "2.39.85" : null;
|
|
17681
17708
|
if (!current) return;
|
|
17682
17709
|
const cache = readCache();
|
|
17683
17710
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17694,7 +17721,7 @@ function checkForUpdates() {
|
|
|
17694
17721
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17695
17722
|
if (process.env.CI) return;
|
|
17696
17723
|
if (!process.stdout.isTTY) return;
|
|
17697
|
-
const current = true ? "2.39.
|
|
17724
|
+
const current = true ? "2.39.85" : null;
|
|
17698
17725
|
if (!current) return;
|
|
17699
17726
|
const cache = readCache();
|
|
17700
17727
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18132,7 +18159,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.s
|
|
|
18132
18159
|
detached: false
|
|
18133
18160
|
});
|
|
18134
18161
|
function currentCliVersion() {
|
|
18135
|
-
return true ? "2.39.
|
|
18162
|
+
return true ? "2.39.85" : null;
|
|
18136
18163
|
}
|
|
18137
18164
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18138
18165
|
return new Promise((resolve7) => {
|
|
@@ -18527,6 +18554,12 @@ var HostAgentSupervisor = class {
|
|
|
18527
18554
|
API_TIMEOUT_MS: "3000000",
|
|
18528
18555
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
18529
18556
|
};
|
|
18557
|
+
const houseConfigDir = path46.join(os33.homedir(), ".codeam", "house-claude");
|
|
18558
|
+
try {
|
|
18559
|
+
fs40.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
18560
|
+
} catch {
|
|
18561
|
+
}
|
|
18562
|
+
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
18530
18563
|
extraArgs = [`--agent=${agentKind || "claude"}`];
|
|
18531
18564
|
} else {
|
|
18532
18565
|
const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
|
|
@@ -18548,7 +18581,7 @@ var HostAgentSupervisor = class {
|
|
|
18548
18581
|
report("preparing", "configuring git tooling");
|
|
18549
18582
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
18550
18583
|
if (ghCmd) {
|
|
18551
|
-
childEnv.PATH = `${codeamBinDir()}
|
|
18584
|
+
childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
|
|
18552
18585
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
18553
18586
|
}
|
|
18554
18587
|
} catch (e) {
|
|
@@ -28937,7 +28970,7 @@ function checkChokidar() {
|
|
|
28937
28970
|
}
|
|
28938
28971
|
async function doctor(args2 = []) {
|
|
28939
28972
|
const json = args2.includes("--json");
|
|
28940
|
-
const cliVersion = true ? "2.39.
|
|
28973
|
+
const cliVersion = true ? "2.39.85" : "0.0.0-dev";
|
|
28941
28974
|
const apiBase2 = resolveApiBaseUrl();
|
|
28942
28975
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
28943
28976
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -29136,7 +29169,7 @@ async function completion(args2) {
|
|
|
29136
29169
|
// src/commands/version.ts
|
|
29137
29170
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
29138
29171
|
function version2() {
|
|
29139
|
-
const v = true ? "2.39.
|
|
29172
|
+
const v = true ? "2.39.85" : "unknown";
|
|
29140
29173
|
console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
|
|
29141
29174
|
}
|
|
29142
29175
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.85",
|
|
4
4
|
"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 — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|