codeam-cli 2.39.33 → 2.39.35
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 +7 -0
- package/dist/index.js +136 -103
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ 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.34] — 2026-06-18
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Collapse all turn text onto one chunk so the reply can't double
|
|
12
|
+
- **cli:** Backfill $HOME so Beads provisioning works on detached self-hosted boxes
|
|
13
|
+
|
|
7
14
|
## [2.39.32] — 2026-06-18
|
|
8
15
|
|
|
9
16
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.39.
|
|
501
|
+
version: "2.39.35",
|
|
502
502
|
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.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -5908,7 +5908,7 @@ function readAnonId() {
|
|
|
5908
5908
|
}
|
|
5909
5909
|
function superProperties() {
|
|
5910
5910
|
return {
|
|
5911
|
-
cliVersion: true ? "2.39.
|
|
5911
|
+
cliVersion: true ? "2.39.35" : "0.0.0-dev",
|
|
5912
5912
|
nodeVersion: process.version,
|
|
5913
5913
|
platform: process.platform,
|
|
5914
5914
|
arch: process.arch,
|
|
@@ -7302,10 +7302,10 @@ function buildForPlatform(platform3) {
|
|
|
7302
7302
|
var import_node_crypto4 = require("crypto");
|
|
7303
7303
|
|
|
7304
7304
|
// src/agents/claude/resolver.ts
|
|
7305
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
7306
|
-
const found =
|
|
7305
|
+
function buildClaudeLaunch(extraArgs = [], os38 = createOsStrategy()) {
|
|
7306
|
+
const found = os38.findInPath("claude") ?? os38.findInPath("claude-code");
|
|
7307
7307
|
if (!found) return null;
|
|
7308
|
-
return
|
|
7308
|
+
return os38.buildLaunch(found, extraArgs);
|
|
7309
7309
|
}
|
|
7310
7310
|
|
|
7311
7311
|
// src/agents/claude/installer.ts
|
|
@@ -9754,8 +9754,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9754
9754
|
meta = getAgent("claude");
|
|
9755
9755
|
mode = "interactive";
|
|
9756
9756
|
os;
|
|
9757
|
-
constructor(
|
|
9758
|
-
this.os =
|
|
9757
|
+
constructor(os38) {
|
|
9758
|
+
this.os = os38;
|
|
9759
9759
|
}
|
|
9760
9760
|
/**
|
|
9761
9761
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -10374,8 +10374,8 @@ function codexCredentialLocator() {
|
|
|
10374
10374
|
function codexLoginLauncher() {
|
|
10375
10375
|
return {
|
|
10376
10376
|
async ensureInstalled() {
|
|
10377
|
-
const
|
|
10378
|
-
return
|
|
10377
|
+
const os38 = createOsStrategy();
|
|
10378
|
+
return os38.findInPath("codex") !== null;
|
|
10379
10379
|
},
|
|
10380
10380
|
launch() {
|
|
10381
10381
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -10398,8 +10398,8 @@ var CodexRuntimeStrategy = class {
|
|
|
10398
10398
|
meta = getAgent("codex");
|
|
10399
10399
|
mode = "interactive";
|
|
10400
10400
|
os;
|
|
10401
|
-
constructor(
|
|
10402
|
-
this.os =
|
|
10401
|
+
constructor(os38) {
|
|
10402
|
+
this.os = os38;
|
|
10403
10403
|
}
|
|
10404
10404
|
async prepareLaunch() {
|
|
10405
10405
|
let binary = this.os.findInPath("codex");
|
|
@@ -10495,12 +10495,12 @@ var CodexRuntimeStrategy = class {
|
|
|
10495
10495
|
});
|
|
10496
10496
|
}
|
|
10497
10497
|
};
|
|
10498
|
-
function resolveNpm(
|
|
10499
|
-
return
|
|
10498
|
+
function resolveNpm(os38) {
|
|
10499
|
+
return os38.id === "win32" ? "npm.cmd" : "npm";
|
|
10500
10500
|
}
|
|
10501
|
-
async function installCodexViaNpm(
|
|
10501
|
+
async function installCodexViaNpm(os38) {
|
|
10502
10502
|
return new Promise((resolve7, reject) => {
|
|
10503
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
10503
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os38), ["install", "-g", "@openai/codex"], {
|
|
10504
10504
|
stdio: "inherit"
|
|
10505
10505
|
});
|
|
10506
10506
|
proc.on("close", (code) => {
|
|
@@ -10517,16 +10517,16 @@ async function installCodexViaNpm(os36) {
|
|
|
10517
10517
|
});
|
|
10518
10518
|
});
|
|
10519
10519
|
}
|
|
10520
|
-
function augmentNpmGlobalBin(
|
|
10520
|
+
function augmentNpmGlobalBin(os38) {
|
|
10521
10521
|
try {
|
|
10522
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
10522
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os38), ["prefix", "-g"], {
|
|
10523
10523
|
stdio: ["ignore", "pipe", "ignore"]
|
|
10524
10524
|
});
|
|
10525
10525
|
if (result.status !== 0) return;
|
|
10526
10526
|
const prefix = result.stdout.toString().trim();
|
|
10527
10527
|
if (!prefix) return;
|
|
10528
|
-
const binDir =
|
|
10529
|
-
|
|
10528
|
+
const binDir = os38.id === "win32" ? prefix : path17.join(prefix, "bin");
|
|
10529
|
+
os38.augmentPath([binDir]);
|
|
10530
10530
|
} catch {
|
|
10531
10531
|
}
|
|
10532
10532
|
}
|
|
@@ -10610,9 +10610,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
10610
10610
|
// src/agents/coderabbit/installer.ts
|
|
10611
10611
|
var import_node_child_process5 = require("child_process");
|
|
10612
10612
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
10613
|
-
async function ensureCoderabbitInstalled(
|
|
10614
|
-
if (
|
|
10615
|
-
if (
|
|
10613
|
+
async function ensureCoderabbitInstalled(os38) {
|
|
10614
|
+
if (os38.findInPath("coderabbit")) return true;
|
|
10615
|
+
if (os38.id === "win32") {
|
|
10616
10616
|
console.error(
|
|
10617
10617
|
"\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"
|
|
10618
10618
|
);
|
|
@@ -10627,8 +10627,8 @@ async function ensureCoderabbitInstalled(os36) {
|
|
|
10627
10627
|
proc.on("error", () => resolve7(false));
|
|
10628
10628
|
});
|
|
10629
10629
|
if (!ok) return false;
|
|
10630
|
-
|
|
10631
|
-
return
|
|
10630
|
+
os38.augmentPath([`${os38.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
10631
|
+
return os38.findInPath("coderabbit") !== null;
|
|
10632
10632
|
}
|
|
10633
10633
|
|
|
10634
10634
|
// src/agents/coderabbit/link.ts
|
|
@@ -10655,10 +10655,10 @@ function coderabbitCredentialLocator() {
|
|
|
10655
10655
|
extract: extractLocalCoderabbitToken
|
|
10656
10656
|
};
|
|
10657
10657
|
}
|
|
10658
|
-
function coderabbitLoginLauncher(
|
|
10658
|
+
function coderabbitLoginLauncher(os38) {
|
|
10659
10659
|
return {
|
|
10660
10660
|
async ensureInstalled() {
|
|
10661
|
-
return ensureCoderabbitInstalled(
|
|
10661
|
+
return ensureCoderabbitInstalled(os38);
|
|
10662
10662
|
},
|
|
10663
10663
|
launch() {
|
|
10664
10664
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -10704,8 +10704,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
10704
10704
|
meta = getAgent("coderabbit");
|
|
10705
10705
|
mode = "batch";
|
|
10706
10706
|
os;
|
|
10707
|
-
constructor(
|
|
10708
|
-
this.os =
|
|
10707
|
+
constructor(os38) {
|
|
10708
|
+
this.os = os38;
|
|
10709
10709
|
}
|
|
10710
10710
|
getDefaultArgs() {
|
|
10711
10711
|
return ["review"];
|
|
@@ -10820,10 +10820,10 @@ function cursorCredentialLocator() {
|
|
|
10820
10820
|
extract: extractLocalCursorToken
|
|
10821
10821
|
};
|
|
10822
10822
|
}
|
|
10823
|
-
function cursorLoginLauncher(
|
|
10823
|
+
function cursorLoginLauncher(os38) {
|
|
10824
10824
|
return {
|
|
10825
10825
|
async ensureInstalled() {
|
|
10826
|
-
if (
|
|
10826
|
+
if (os38.findInPath("cursor-agent")) return true;
|
|
10827
10827
|
console.error(
|
|
10828
10828
|
"\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"
|
|
10829
10829
|
);
|
|
@@ -10885,8 +10885,8 @@ var CursorRuntimeStrategy = class {
|
|
|
10885
10885
|
meta = getAgent("cursor");
|
|
10886
10886
|
mode = "interactive";
|
|
10887
10887
|
os;
|
|
10888
|
-
constructor(
|
|
10889
|
-
this.os =
|
|
10888
|
+
constructor(os38) {
|
|
10889
|
+
this.os = os38;
|
|
10890
10890
|
}
|
|
10891
10891
|
async prepareLaunch() {
|
|
10892
10892
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -11006,10 +11006,10 @@ function aiderCredentialLocator() {
|
|
|
11006
11006
|
extract: extractLocalAiderToken
|
|
11007
11007
|
};
|
|
11008
11008
|
}
|
|
11009
|
-
function aiderLoginLauncher(
|
|
11009
|
+
function aiderLoginLauncher(os38) {
|
|
11010
11010
|
return {
|
|
11011
11011
|
async ensureInstalled() {
|
|
11012
|
-
if (
|
|
11012
|
+
if (os38.findInPath("aider")) return true;
|
|
11013
11013
|
console.error(
|
|
11014
11014
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
11015
11015
|
);
|
|
@@ -11019,7 +11019,7 @@ function aiderLoginLauncher(os36) {
|
|
|
11019
11019
|
console.error(
|
|
11020
11020
|
"\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"
|
|
11021
11021
|
);
|
|
11022
|
-
return (0, import_node_child_process9.spawn)(
|
|
11022
|
+
return (0, import_node_child_process9.spawn)(os38.id === "win32" ? "cmd.exe" : "sh", os38.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
11023
11023
|
stdio: "ignore"
|
|
11024
11024
|
});
|
|
11025
11025
|
}
|
|
@@ -11091,8 +11091,8 @@ var AiderRuntimeStrategy = class {
|
|
|
11091
11091
|
meta = getAgent("aider");
|
|
11092
11092
|
mode = "interactive";
|
|
11093
11093
|
os;
|
|
11094
|
-
constructor(
|
|
11095
|
-
this.os =
|
|
11094
|
+
constructor(os38) {
|
|
11095
|
+
this.os = os38;
|
|
11096
11096
|
}
|
|
11097
11097
|
async prepareLaunch() {
|
|
11098
11098
|
const binary = this.os.findInPath("aider");
|
|
@@ -11221,8 +11221,8 @@ function geminiCredentialLocator() {
|
|
|
11221
11221
|
function geminiLoginLauncher() {
|
|
11222
11222
|
return {
|
|
11223
11223
|
async ensureInstalled() {
|
|
11224
|
-
const
|
|
11225
|
-
return
|
|
11224
|
+
const os38 = createOsStrategy();
|
|
11225
|
+
return os38.findInPath("gemini") !== null;
|
|
11226
11226
|
},
|
|
11227
11227
|
launch() {
|
|
11228
11228
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -11255,8 +11255,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
11255
11255
|
meta = getAgent("gemini");
|
|
11256
11256
|
mode = "interactive";
|
|
11257
11257
|
os;
|
|
11258
|
-
constructor(
|
|
11259
|
-
this.os =
|
|
11258
|
+
constructor(os38) {
|
|
11259
|
+
this.os = os38;
|
|
11260
11260
|
}
|
|
11261
11261
|
async prepareLaunch() {
|
|
11262
11262
|
const binary = this.os.findInPath("gemini");
|
|
@@ -11355,18 +11355,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
11355
11355
|
|
|
11356
11356
|
// src/agents/registry.ts
|
|
11357
11357
|
var runtimeBuilders = {
|
|
11358
|
-
claude: (
|
|
11359
|
-
codex: (
|
|
11360
|
-
coderabbit: (
|
|
11361
|
-
cursor: (
|
|
11362
|
-
aider: (
|
|
11363
|
-
gemini: (
|
|
11358
|
+
claude: (os38) => new ClaudeRuntimeStrategy(os38),
|
|
11359
|
+
codex: (os38) => new CodexRuntimeStrategy(os38),
|
|
11360
|
+
coderabbit: (os38) => new CoderabbitRuntimeStrategy(os38),
|
|
11361
|
+
cursor: (os38) => new CursorRuntimeStrategy(os38),
|
|
11362
|
+
aider: (os38) => new AiderRuntimeStrategy(os38),
|
|
11363
|
+
gemini: (os38) => new GeminiRuntimeStrategy(os38)
|
|
11364
11364
|
};
|
|
11365
11365
|
var deployBuilders = {
|
|
11366
11366
|
claude: () => new ClaudeDeployStrategy(),
|
|
11367
11367
|
codex: () => new CodexDeployStrategy()
|
|
11368
11368
|
};
|
|
11369
|
-
function createAgentStrategy(agent,
|
|
11369
|
+
function createAgentStrategy(agent, os38 = createOsStrategy()) {
|
|
11370
11370
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
11371
11371
|
throw new Error(
|
|
11372
11372
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -11376,10 +11376,10 @@ function createAgentStrategy(agent, os36 = createOsStrategy()) {
|
|
|
11376
11376
|
if (!build) {
|
|
11377
11377
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
11378
11378
|
}
|
|
11379
|
-
return build(
|
|
11379
|
+
return build(os38);
|
|
11380
11380
|
}
|
|
11381
|
-
function createInteractiveAgentStrategy(agent,
|
|
11382
|
-
const s = createAgentStrategy(agent,
|
|
11381
|
+
function createInteractiveAgentStrategy(agent, os38 = createOsStrategy()) {
|
|
11382
|
+
const s = createAgentStrategy(agent, os38);
|
|
11383
11383
|
if (s.mode !== "interactive") {
|
|
11384
11384
|
throw new Error(
|
|
11385
11385
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -15256,7 +15256,7 @@ function extractSelectPrompt(text) {
|
|
|
15256
15256
|
|
|
15257
15257
|
// src/commands/start/handlers.ts
|
|
15258
15258
|
var fs35 = __toESM(require("fs"));
|
|
15259
|
-
var
|
|
15259
|
+
var os28 = __toESM(require("os"));
|
|
15260
15260
|
var path42 = __toESM(require("path"));
|
|
15261
15261
|
var import_crypto3 = require("crypto");
|
|
15262
15262
|
var import_child_process18 = require("child_process");
|
|
@@ -16965,16 +16965,10 @@ var import_path7 = __toESM(require("path"));
|
|
|
16965
16965
|
function detectMissingNodeDeps(cwd) {
|
|
16966
16966
|
if (!import_fs3.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
|
|
16967
16967
|
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
|
|
16968
|
-
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
16969
|
-
return { cmd: "pnpm", args: ["install"] };
|
|
16970
|
-
}
|
|
16971
16968
|
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
|
|
16972
16969
|
return { cmd: "yarn", args: ["install"] };
|
|
16973
16970
|
}
|
|
16974
|
-
|
|
16975
|
-
return { cmd: "bun", args: ["install"] };
|
|
16976
|
-
}
|
|
16977
|
-
return { cmd: "npm", args: ["install"] };
|
|
16971
|
+
return { cmd: "npm", args: ["install", "--legacy-peer-deps"] };
|
|
16978
16972
|
}
|
|
16979
16973
|
function isJsInstallCommand(cmd, args2) {
|
|
16980
16974
|
const known = ["npm", "pnpm", "yarn", "bun"];
|
|
@@ -17027,6 +17021,7 @@ function activePreviewSessionIds() {
|
|
|
17027
17021
|
// src/beads/bd-adapter.ts
|
|
17028
17022
|
var import_child_process13 = require("child_process");
|
|
17029
17023
|
var fs31 = __toESM(require("fs"));
|
|
17024
|
+
var os25 = __toESM(require("os"));
|
|
17030
17025
|
var path37 = __toESM(require("path"));
|
|
17031
17026
|
var BD_PACKAGE = "@beads/bd";
|
|
17032
17027
|
function resolveBundledBdBinary() {
|
|
@@ -17142,6 +17137,13 @@ var BdAdapter = class {
|
|
|
17142
17137
|
return { code: -1, stdout: "", stderr: "bd binary not resolved" };
|
|
17143
17138
|
}
|
|
17144
17139
|
const env = { ...process.env };
|
|
17140
|
+
if (!env.HOME) {
|
|
17141
|
+
try {
|
|
17142
|
+
const home = os25.homedir();
|
|
17143
|
+
if (home) env.HOME = home;
|
|
17144
|
+
} catch {
|
|
17145
|
+
}
|
|
17146
|
+
}
|
|
17145
17147
|
env.BEADS_DOLT_SHARED_SERVER = "1";
|
|
17146
17148
|
delete env.BEADS_DIR;
|
|
17147
17149
|
log.trace(
|
|
@@ -17227,7 +17229,7 @@ function coerceIssue(row, projectKey) {
|
|
|
17227
17229
|
// src/beads/provisioner.ts
|
|
17228
17230
|
var import_child_process17 = require("child_process");
|
|
17229
17231
|
var fs34 = __toESM(require("fs"));
|
|
17230
|
-
var
|
|
17232
|
+
var os27 = __toESM(require("os"));
|
|
17231
17233
|
var path40 = __toESM(require("path"));
|
|
17232
17234
|
|
|
17233
17235
|
// src/beads/install-bd.ts
|
|
@@ -17294,7 +17296,7 @@ async function installBd(platform3 = process.platform) {
|
|
|
17294
17296
|
// src/beads/install-dolt.ts
|
|
17295
17297
|
var import_child_process15 = require("child_process");
|
|
17296
17298
|
var fs32 = __toESM(require("fs"));
|
|
17297
|
-
var
|
|
17299
|
+
var os26 = __toESM(require("os"));
|
|
17298
17300
|
var path38 = __toESM(require("path"));
|
|
17299
17301
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17300
17302
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
@@ -17335,11 +17337,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
17335
17337
|
}
|
|
17336
17338
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17337
17339
|
function doltPlatformTuple(platform3, arch2) {
|
|
17338
|
-
const
|
|
17340
|
+
const os38 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
17339
17341
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
17340
17342
|
if (!a) return null;
|
|
17341
|
-
if (
|
|
17342
|
-
return `${
|
|
17343
|
+
if (os38 === "windows" && a !== "amd64") return null;
|
|
17344
|
+
return `${os38}-${a}`;
|
|
17343
17345
|
}
|
|
17344
17346
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
17345
17347
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -17384,7 +17386,7 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
17384
17386
|
return result;
|
|
17385
17387
|
}
|
|
17386
17388
|
var _doltPathSeam = {
|
|
17387
|
-
homedir: () =>
|
|
17389
|
+
homedir: () => os26.homedir(),
|
|
17388
17390
|
getPath: () => process.env.PATH ?? "",
|
|
17389
17391
|
setPath: (p2) => {
|
|
17390
17392
|
process.env.PATH = p2;
|
|
@@ -17648,7 +17650,7 @@ var _provisionSeam = {
|
|
|
17648
17650
|
};
|
|
17649
17651
|
var _linkSeam = {
|
|
17650
17652
|
platform: () => process.platform,
|
|
17651
|
-
homedir: () =>
|
|
17653
|
+
homedir: () => os27.homedir(),
|
|
17652
17654
|
isWritableDir: (dir) => {
|
|
17653
17655
|
try {
|
|
17654
17656
|
fs34.accessSync(dir, fs34.constants.W_OK);
|
|
@@ -18274,7 +18276,7 @@ function cleanupAttachmentTempFiles() {
|
|
|
18274
18276
|
function saveFilesTemp(files) {
|
|
18275
18277
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18276
18278
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18277
|
-
const tmpPath = path42.join(
|
|
18279
|
+
const tmpPath = path42.join(os28.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18278
18280
|
fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18279
18281
|
pendingAttachmentFiles.add(tmpPath);
|
|
18280
18282
|
return tmpPath;
|
|
@@ -19355,7 +19357,7 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19355
19357
|
// src/services/file-watcher.service.ts
|
|
19356
19358
|
var import_child_process19 = require("child_process");
|
|
19357
19359
|
var fs36 = __toESM(require("fs"));
|
|
19358
|
-
var
|
|
19360
|
+
var os29 = __toESM(require("os"));
|
|
19359
19361
|
var path43 = __toESM(require("path"));
|
|
19360
19362
|
var import_ignore = __toESM(require("ignore"));
|
|
19361
19363
|
|
|
@@ -19466,10 +19468,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19466
19468
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19467
19469
|
/[\\/]Templates([\\/]|$)/i
|
|
19468
19470
|
];
|
|
19469
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
19471
|
+
function isUnsafeWindowsWatchRoot(dir, homedir31) {
|
|
19470
19472
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19471
19473
|
const cwd = norm(dir);
|
|
19472
|
-
const home = norm(
|
|
19474
|
+
const home = norm(homedir31);
|
|
19473
19475
|
if (cwd === home) return true;
|
|
19474
19476
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19475
19477
|
const sysRoots = [
|
|
@@ -19568,7 +19570,7 @@ var FileWatcherService = class {
|
|
|
19568
19570
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
19569
19571
|
}
|
|
19570
19572
|
const isWin = process.platform === "win32";
|
|
19571
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
19573
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os29.homedir())) {
|
|
19572
19574
|
log.warn(
|
|
19573
19575
|
"fileWatcher",
|
|
19574
19576
|
`refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
|
|
@@ -20673,6 +20675,27 @@ var StreamingState = class {
|
|
|
20673
20675
|
* chunk is done streaming.
|
|
20674
20676
|
*/
|
|
20675
20677
|
streamingChunks = /* @__PURE__ */ new Map();
|
|
20678
|
+
/**
|
|
20679
|
+
* Stable chunkId that ALL `text` segments of the current turn collapse
|
|
20680
|
+
* onto (set to the first text chunk's id, reset each {@link beginTurn}).
|
|
20681
|
+
*
|
|
20682
|
+
* Why: `claude-agent-acp` (≥0.47) streams the reply live as
|
|
20683
|
+
* `agent_message_chunk` deltas under one message id, then — when its
|
|
20684
|
+
* own streamed-vs-consolidated dedupe misfires (the live path keys
|
|
20685
|
+
* `streamedTextIds` off the stream message id while consolidation
|
|
20686
|
+
* checks `messageIdForGrouping`, which can differ per gateway) —
|
|
20687
|
+
* RE-EMITS the complete assistant message as a fresh
|
|
20688
|
+
* `agent_message_chunk` under a DIFFERENT message id. Keying our buffer
|
|
20689
|
+
* off the adapter's chunkId then lands the two copies in two buckets,
|
|
20690
|
+
* and `recomputeText` concatenates them → the whole reply doubles
|
|
20691
|
+
* ("…del proyecto.¡Perfecto!…del proyecto."). Observed on BOTH real
|
|
20692
|
+
* Claude (codespace) and the MiniMax proxy (self-hosted) — anything
|
|
20693
|
+
* behind this adapter. Collapsing every text segment of a turn into one
|
|
20694
|
+
* reconcile buffer makes the re-emit a `reconcileCumulative` REPLACE
|
|
20695
|
+
* (identical snapshot) instead of an APPEND, so the reply can't double
|
|
20696
|
+
* no matter how many message ids the adapter spreads it across.
|
|
20697
|
+
*/
|
|
20698
|
+
turnTextChunkId = null;
|
|
20676
20699
|
/**
|
|
20677
20700
|
* Register a permission Promise. The Promise stays pending until
|
|
20678
20701
|
* `resolveSelection(index)` is called from the relay handler, OR
|
|
@@ -20764,6 +20787,7 @@ var StreamingState = class {
|
|
|
20764
20787
|
async beginTurn(opts) {
|
|
20765
20788
|
this.text = "";
|
|
20766
20789
|
this.streamingChunks.clear();
|
|
20790
|
+
this.turnTextChunkId = null;
|
|
20767
20791
|
if (this.pending?.kind === "permission") {
|
|
20768
20792
|
clearTimeout(this.pending.timeoutTimer);
|
|
20769
20793
|
}
|
|
@@ -20774,21 +20798,22 @@ var StreamingState = class {
|
|
|
20774
20798
|
await this.publisher.publishOutput({ type: "new_turn", done: false });
|
|
20775
20799
|
}
|
|
20776
20800
|
append(delta) {
|
|
20777
|
-
const
|
|
20801
|
+
const chunkId = delta.kind === "text" ? this.turnTextChunkId ??= delta.chunkId : delta.chunkId;
|
|
20802
|
+
const existing = this.streamingChunks.get(chunkId);
|
|
20778
20803
|
if (existing && existing.kind !== delta.kind) {
|
|
20779
20804
|
log.warn(
|
|
20780
20805
|
"acpRunner",
|
|
20781
|
-
`streaming-chunk kind flip chunkId=${
|
|
20806
|
+
`streaming-chunk kind flip chunkId=${chunkId.slice(0, 8)} from=${existing.kind} to=${delta.kind}`
|
|
20782
20807
|
);
|
|
20783
20808
|
}
|
|
20784
20809
|
const cumulativeContent = reconcileCumulative(existing?.content ?? "", delta.delta);
|
|
20785
|
-
this.streamingChunks.set(
|
|
20810
|
+
this.streamingChunks.set(chunkId, { kind: delta.kind, content: cumulativeContent });
|
|
20786
20811
|
if (delta.kind === "text") {
|
|
20787
20812
|
this.recomputeText();
|
|
20788
20813
|
void this.publisher.publishOutput({ type: "text", content: this.text, done: false });
|
|
20789
20814
|
}
|
|
20790
20815
|
void this.publisher.publishStreamingChunk({
|
|
20791
|
-
chunkId
|
|
20816
|
+
chunkId,
|
|
20792
20817
|
kind: delta.kind,
|
|
20793
20818
|
content: cumulativeContent,
|
|
20794
20819
|
isFinal: false
|
|
@@ -22335,7 +22360,7 @@ var OutputService = class _OutputService {
|
|
|
22335
22360
|
// src/services/history.service.ts
|
|
22336
22361
|
var fs38 = __toESM(require("fs"));
|
|
22337
22362
|
var path46 = __toESM(require("path"));
|
|
22338
|
-
var
|
|
22363
|
+
var os30 = __toESM(require("os"));
|
|
22339
22364
|
var https7 = __toESM(require("https"));
|
|
22340
22365
|
var http7 = __toESM(require("http"));
|
|
22341
22366
|
var import_zod2 = require("zod");
|
|
@@ -22503,7 +22528,7 @@ var HistoryService = class _HistoryService {
|
|
|
22503
22528
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22504
22529
|
}
|
|
22505
22530
|
get projectDir() {
|
|
22506
|
-
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(
|
|
22531
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os30.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22507
22532
|
}
|
|
22508
22533
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22509
22534
|
setCurrentConversationId(id) {
|
|
@@ -23265,11 +23290,11 @@ function buildKeepAlive(ctx) {
|
|
|
23265
23290
|
|
|
23266
23291
|
// src/agents/claude/onboarding.ts
|
|
23267
23292
|
var fs39 = __toESM(require("fs"));
|
|
23268
|
-
var
|
|
23293
|
+
var os31 = __toESM(require("os"));
|
|
23269
23294
|
var path47 = __toESM(require("path"));
|
|
23270
23295
|
function ensureClaudeOnboarded() {
|
|
23271
23296
|
try {
|
|
23272
|
-
const file = path47.join(
|
|
23297
|
+
const file = path47.join(os31.homedir(), ".claude.json");
|
|
23273
23298
|
let config = {};
|
|
23274
23299
|
try {
|
|
23275
23300
|
config = JSON.parse(fs39.readFileSync(file, "utf8"));
|
|
@@ -23776,7 +23801,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
23776
23801
|
|
|
23777
23802
|
// src/commands/pair-auto.ts
|
|
23778
23803
|
var fs40 = __toESM(require("fs"));
|
|
23779
|
-
var
|
|
23804
|
+
var os32 = __toESM(require("os"));
|
|
23780
23805
|
var path48 = __toESM(require("path"));
|
|
23781
23806
|
var import_crypto7 = require("crypto");
|
|
23782
23807
|
|
|
@@ -24003,7 +24028,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
24003
24028
|
pluginId,
|
|
24004
24029
|
ideName: "codeam-cli (codespace)",
|
|
24005
24030
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
24006
|
-
hostname:
|
|
24031
|
+
hostname: os32.hostname(),
|
|
24007
24032
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
24008
24033
|
// Current git branch of the codespace's working directory, so the
|
|
24009
24034
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24064,7 +24089,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
24064
24089
|
}
|
|
24065
24090
|
}
|
|
24066
24091
|
function pairAutoLockPath() {
|
|
24067
|
-
return path48.join(
|
|
24092
|
+
return path48.join(os32.homedir(), ".codeam", "pair-auto.lock");
|
|
24068
24093
|
}
|
|
24069
24094
|
function isLivePairAuto(pid) {
|
|
24070
24095
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -26237,12 +26262,12 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26237
26262
|
|
|
26238
26263
|
// src/commands/host/host-client.ts
|
|
26239
26264
|
var fs41 = __toESM(require("fs"));
|
|
26240
|
-
var
|
|
26265
|
+
var os33 = __toESM(require("os"));
|
|
26241
26266
|
var path53 = __toESM(require("path"));
|
|
26242
26267
|
function sampleCpuTimes() {
|
|
26243
26268
|
let idle = 0;
|
|
26244
26269
|
let total = 0;
|
|
26245
|
-
for (const cpu of
|
|
26270
|
+
for (const cpu of os33.cpus()) {
|
|
26246
26271
|
const t2 = cpu.times;
|
|
26247
26272
|
idle += t2.idle;
|
|
26248
26273
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -26261,8 +26286,8 @@ var MetricsCollector = class {
|
|
|
26261
26286
|
const prev = this.prevCpu;
|
|
26262
26287
|
this.prevCpu = current;
|
|
26263
26288
|
if (!prev) {
|
|
26264
|
-
const cores =
|
|
26265
|
-
const proxy =
|
|
26289
|
+
const cores = os33.cpus().length || 1;
|
|
26290
|
+
const proxy = os33.loadavg()[0] / cores * 100;
|
|
26266
26291
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
26267
26292
|
}
|
|
26268
26293
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -26275,8 +26300,8 @@ var MetricsCollector = class {
|
|
|
26275
26300
|
collect() {
|
|
26276
26301
|
return {
|
|
26277
26302
|
cpuPct: this.cpuPct(),
|
|
26278
|
-
ramUsedMb: Math.round((
|
|
26279
|
-
ramTotalMb: Math.round(
|
|
26303
|
+
ramUsedMb: Math.round((os33.totalmem() - os33.freemem()) / 1048576),
|
|
26304
|
+
ramTotalMb: Math.round(os33.totalmem() / 1048576),
|
|
26280
26305
|
latencyMs: this.lastLatencyMs
|
|
26281
26306
|
};
|
|
26282
26307
|
}
|
|
@@ -26285,13 +26310,13 @@ function apiBase() {
|
|
|
26285
26310
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
26286
26311
|
}
|
|
26287
26312
|
function hostIdentityPath() {
|
|
26288
|
-
return path53.join(
|
|
26313
|
+
return path53.join(os33.homedir(), ".codeam", "host-agent.json");
|
|
26289
26314
|
}
|
|
26290
26315
|
function collectOsInfo() {
|
|
26291
26316
|
return {
|
|
26292
|
-
distro:
|
|
26293
|
-
arch:
|
|
26294
|
-
kernel:
|
|
26317
|
+
distro: os33.platform(),
|
|
26318
|
+
arch: os33.arch(),
|
|
26319
|
+
kernel: os33.release(),
|
|
26295
26320
|
nodeVersion: process.versions.node
|
|
26296
26321
|
};
|
|
26297
26322
|
}
|
|
@@ -26502,7 +26527,7 @@ var import_node_child_process13 = require("child_process");
|
|
|
26502
26527
|
|
|
26503
26528
|
// src/commands/host/workspace.ts
|
|
26504
26529
|
var fs42 = __toESM(require("fs"));
|
|
26505
|
-
var
|
|
26530
|
+
var os34 = __toESM(require("os"));
|
|
26506
26531
|
var path54 = __toESM(require("path"));
|
|
26507
26532
|
var import_node_child_process12 = require("child_process");
|
|
26508
26533
|
var import_node_util4 = require("util");
|
|
@@ -26511,7 +26536,7 @@ function isAbsolutePathTarget(target) {
|
|
|
26511
26536
|
return path54.isAbsolute(target);
|
|
26512
26537
|
}
|
|
26513
26538
|
function selfHostedWorkspaceRoot() {
|
|
26514
|
-
return path54.join(
|
|
26539
|
+
return path54.join(os34.homedir(), ".codeam", "self-hosted");
|
|
26515
26540
|
}
|
|
26516
26541
|
function nonInteractiveGitEnv() {
|
|
26517
26542
|
return {
|
|
@@ -26580,7 +26605,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
26580
26605
|
|
|
26581
26606
|
// src/commands/host/agent-provisioning.ts
|
|
26582
26607
|
var fs43 = __toESM(require("fs"));
|
|
26583
|
-
var
|
|
26608
|
+
var os35 = __toESM(require("os"));
|
|
26584
26609
|
var path55 = __toESM(require("path"));
|
|
26585
26610
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
26586
26611
|
claude_code: "claude",
|
|
@@ -26640,7 +26665,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
26640
26665
|
this.agentId = agentId;
|
|
26641
26666
|
}
|
|
26642
26667
|
};
|
|
26643
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
26668
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os35.homedir()) {
|
|
26644
26669
|
const internal = toInternalAgentId(publicAgentId);
|
|
26645
26670
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
26646
26671
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -27081,9 +27106,9 @@ function checkSessions() {
|
|
|
27081
27106
|
}
|
|
27082
27107
|
}
|
|
27083
27108
|
function checkAgentBinaries() {
|
|
27084
|
-
const
|
|
27109
|
+
const os38 = createOsStrategy();
|
|
27085
27110
|
return getEnabledAgents().map((meta) => {
|
|
27086
|
-
const found =
|
|
27111
|
+
const found = os38.findInPath(meta.binaryName);
|
|
27087
27112
|
return {
|
|
27088
27113
|
id: `agent-${meta.id}`,
|
|
27089
27114
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -27147,7 +27172,7 @@ function checkChokidar() {
|
|
|
27147
27172
|
}
|
|
27148
27173
|
async function doctor(args2 = []) {
|
|
27149
27174
|
const json = args2.includes("--json");
|
|
27150
|
-
const cliVersion = true ? "2.39.
|
|
27175
|
+
const cliVersion = true ? "2.39.35" : "0.0.0-dev";
|
|
27151
27176
|
const apiBase2 = resolveApiBaseUrl();
|
|
27152
27177
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
27153
27178
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -27346,7 +27371,7 @@ async function completion(args2) {
|
|
|
27346
27371
|
// src/commands/version.ts
|
|
27347
27372
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
27348
27373
|
function version2() {
|
|
27349
|
-
const v = true ? "2.39.
|
|
27374
|
+
const v = true ? "2.39.35" : "unknown";
|
|
27350
27375
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
27351
27376
|
}
|
|
27352
27377
|
|
|
@@ -27475,7 +27500,7 @@ var _subcommandHelpKeys = Object.keys(HELPS);
|
|
|
27475
27500
|
|
|
27476
27501
|
// src/lib/updateNotifier.ts
|
|
27477
27502
|
var fs45 = __toESM(require("fs"));
|
|
27478
|
-
var
|
|
27503
|
+
var os36 = __toESM(require("os"));
|
|
27479
27504
|
var path57 = __toESM(require("path"));
|
|
27480
27505
|
var https8 = __toESM(require("https"));
|
|
27481
27506
|
var import_node_child_process14 = require("child_process");
|
|
@@ -27485,7 +27510,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27485
27510
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27486
27511
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27487
27512
|
function cachePath() {
|
|
27488
|
-
const dir = path57.join(
|
|
27513
|
+
const dir = path57.join(os36.homedir(), ".codeam");
|
|
27489
27514
|
return path57.join(dir, "update-check.json");
|
|
27490
27515
|
}
|
|
27491
27516
|
function readCache() {
|
|
@@ -27632,7 +27657,7 @@ function checkForUpdates() {
|
|
|
27632
27657
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27633
27658
|
if (process.env.CI) return;
|
|
27634
27659
|
if (!process.stdout.isTTY) return;
|
|
27635
|
-
const current = true ? "2.39.
|
|
27660
|
+
const current = true ? "2.39.35" : null;
|
|
27636
27661
|
if (!current) return;
|
|
27637
27662
|
const cache = readCache();
|
|
27638
27663
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -27663,6 +27688,14 @@ var EXIT_CODE_NAMES = {
|
|
|
27663
27688
|
};
|
|
27664
27689
|
|
|
27665
27690
|
// src/index.ts
|
|
27691
|
+
var os37 = __toESM(require("os"));
|
|
27692
|
+
if (!process.env.HOME) {
|
|
27693
|
+
try {
|
|
27694
|
+
const home = os37.homedir();
|
|
27695
|
+
if (home) process.env.HOME = home;
|
|
27696
|
+
} catch {
|
|
27697
|
+
}
|
|
27698
|
+
}
|
|
27666
27699
|
var [, , command, ...args] = process.argv;
|
|
27667
27700
|
async function main() {
|
|
27668
27701
|
const isMetaCommand = command === "--version" || command === "-v" || command === "version" || command === "--help" || command === "-h" || command === "help";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.35",
|
|
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",
|