codeam-cli 2.75.37 → 2.75.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +71 -25
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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.75.38] — 2026-09-27
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Beads never commits to the user's repo (bd init --stealth) (#844)
|
|
12
|
+
|
|
13
|
+
## [2.75.37] — 2026-09-27
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** The review lists files, not new folders; skip sockets and beads state (#839)
|
|
18
|
+
|
|
7
19
|
## [2.75.36] — 2026-09-26
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -10529,7 +10529,7 @@ function readAnonId() {
|
|
|
10529
10529
|
}
|
|
10530
10530
|
function superProperties() {
|
|
10531
10531
|
return {
|
|
10532
|
-
cliVersion: true ? "2.75.
|
|
10532
|
+
cliVersion: true ? "2.75.39" : "0.0.0-dev",
|
|
10533
10533
|
nodeVersion: process.version,
|
|
10534
10534
|
platform: process.platform,
|
|
10535
10535
|
arch: process.arch,
|
|
@@ -10771,7 +10771,7 @@ var http = __toESM(require("http"));
|
|
|
10771
10771
|
// package.json
|
|
10772
10772
|
var package_default = {
|
|
10773
10773
|
name: "codeam-cli",
|
|
10774
|
-
version: "2.75.
|
|
10774
|
+
version: "2.75.39",
|
|
10775
10775
|
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.",
|
|
10776
10776
|
type: "commonjs",
|
|
10777
10777
|
main: "dist/index.js",
|
|
@@ -12101,7 +12101,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12101
12101
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12102
12102
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12103
12103
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12104
|
-
..."2.75.
|
|
12104
|
+
..."2.75.39" ? { ideVersion: "2.75.39" } : {}
|
|
12105
12105
|
};
|
|
12106
12106
|
try {
|
|
12107
12107
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -12436,6 +12436,10 @@ function isUnsafeWindowsWatchRoot(dir, homedir53) {
|
|
|
12436
12436
|
}
|
|
12437
12437
|
return false;
|
|
12438
12438
|
}
|
|
12439
|
+
function isFilesystemRoot(dir) {
|
|
12440
|
+
const resolved = path5.resolve(dir);
|
|
12441
|
+
return resolved === path5.parse(resolved).root;
|
|
12442
|
+
}
|
|
12439
12443
|
var _chokidarSeam = {
|
|
12440
12444
|
load: () => {
|
|
12441
12445
|
try {
|
|
@@ -12520,6 +12524,13 @@ var FileWatcherService = class {
|
|
|
12520
12524
|
if (this.stopped) {
|
|
12521
12525
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
12522
12526
|
}
|
|
12527
|
+
if (isFilesystemRoot(this.opts.workingDir)) {
|
|
12528
|
+
log.warn(
|
|
12529
|
+
"fileWatcher",
|
|
12530
|
+
`refusing to watch ${this.opts.workingDir} \u2014 the filesystem root. Run codeam from your project folder to enable file change emission.`
|
|
12531
|
+
);
|
|
12532
|
+
return;
|
|
12533
|
+
}
|
|
12523
12534
|
const isWin = process.platform === "win32";
|
|
12524
12535
|
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os5.homedir())) {
|
|
12525
12536
|
log.warn(
|
|
@@ -20458,14 +20469,14 @@ function defaultSdkDir() {
|
|
|
20458
20469
|
return resolveSdkDirViaRequire();
|
|
20459
20470
|
}
|
|
20460
20471
|
function resolveClaudeNativeBinary(deps = {}) {
|
|
20461
|
-
const
|
|
20472
|
+
const existsSync32 = deps.existsSync ?? import_fs.default.existsSync;
|
|
20462
20473
|
const platformKey = deps.platformKey ?? currentPlatformKey();
|
|
20463
20474
|
const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
|
|
20464
20475
|
if (!sdkDir) return null;
|
|
20465
20476
|
const scopeDir = import_path4.default.dirname(sdkDir);
|
|
20466
20477
|
const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
|
|
20467
20478
|
const candidate = import_path4.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
|
|
20468
|
-
return
|
|
20479
|
+
return existsSync32(candidate) ? candidate : null;
|
|
20469
20480
|
}
|
|
20470
20481
|
var realSleep = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
20471
20482
|
async function waitForClaudeNativeBinary(opts = {}) {
|
|
@@ -20547,18 +20558,18 @@ function augmentUserLocalBinPaths(deps = {}) {
|
|
|
20547
20558
|
env.PATH = [...additions, ...parts].join(p2.delimiter);
|
|
20548
20559
|
}
|
|
20549
20560
|
function resolveCursorAgentBinary(deps = {}) {
|
|
20550
|
-
const
|
|
20561
|
+
const existsSync32 = deps.existsSync ?? import_fs.default.existsSync;
|
|
20551
20562
|
const platform3 = deps.platform ?? process.platform;
|
|
20552
20563
|
const env = deps.env ?? process.env;
|
|
20553
20564
|
if (platform3 === "win32") {
|
|
20554
20565
|
const localAppData = env.LOCALAPPDATA;
|
|
20555
20566
|
if (!localAppData) return null;
|
|
20556
20567
|
const exe = import_path4.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
|
|
20557
|
-
return
|
|
20568
|
+
return existsSync32(exe) ? exe : null;
|
|
20558
20569
|
}
|
|
20559
20570
|
const home = deps.homedir ?? import_os4.default.homedir();
|
|
20560
20571
|
const unix = import_path4.default.posix.join(home, ".local", "bin", "cursor-agent");
|
|
20561
|
-
return
|
|
20572
|
+
return existsSync32(unix) ? unix : null;
|
|
20562
20573
|
}
|
|
20563
20574
|
async function waitForCursorAgent(opts = {}) {
|
|
20564
20575
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
@@ -26214,7 +26225,14 @@ async function provisionBeads(opts = {}) {
|
|
|
26214
26225
|
"--shared-server",
|
|
26215
26226
|
"--skip-agents",
|
|
26216
26227
|
"--skip-hooks",
|
|
26217
|
-
"--non-interactive"
|
|
26228
|
+
"--non-interactive",
|
|
26229
|
+
// ⚠️ Without it `bd init` COMMITS ("bd init: initialize beads issue
|
|
26230
|
+
// tracking") on whatever branch the user's repo is on — verified with bd
|
|
26231
|
+
// 1.0.5 on a scratch repo, and seen on a fleet box's feature branch
|
|
26232
|
+
// (break-it 2026-09-24/26). Stealth keeps beads out of git: it only writes
|
|
26233
|
+
// `.git/info/exclude` (local, never committed); the global git config was
|
|
26234
|
+
// verified untouched.
|
|
26235
|
+
"--stealth"
|
|
26218
26236
|
]);
|
|
26219
26237
|
const alreadyInit = /already initialized|already exists/i.test(init.stderr + init.stdout);
|
|
26220
26238
|
if (init.code !== 0 && !alreadyInit) {
|
|
@@ -26222,6 +26240,8 @@ async function provisionBeads(opts = {}) {
|
|
|
26222
26240
|
return result;
|
|
26223
26241
|
}
|
|
26224
26242
|
result.initialized = true;
|
|
26243
|
+
const workdir = opts.cwd ?? process.cwd();
|
|
26244
|
+
ensureLocalGitExclude(findRepoRoot(workdir) ?? workdir, [".beads/", ".dolt/"]);
|
|
26225
26245
|
const server = await _provisionSeam.ensureSharedServer(bd);
|
|
26226
26246
|
result.serverUp = server.up;
|
|
26227
26247
|
if (!server.up) {
|
|
@@ -26264,7 +26284,8 @@ async function provisionBeads(opts = {}) {
|
|
|
26264
26284
|
// `git push` on a box without git-lfs (fleet box 2026-09-24).
|
|
26265
26285
|
"--skip-agents",
|
|
26266
26286
|
"--skip-hooks",
|
|
26267
|
-
"--non-interactive"
|
|
26287
|
+
"--non-interactive",
|
|
26288
|
+
"--stealth"
|
|
26268
26289
|
]);
|
|
26269
26290
|
if (mint.code !== 0) {
|
|
26270
26291
|
log.warn(
|
|
@@ -26335,6 +26356,23 @@ function dedupeRecipes(agents) {
|
|
|
26335
26356
|
}
|
|
26336
26357
|
return [...seen2];
|
|
26337
26358
|
}
|
|
26359
|
+
function ensureLocalGitExclude(cwd, patterns) {
|
|
26360
|
+
try {
|
|
26361
|
+
const gitDir = path54.join(cwd, ".git");
|
|
26362
|
+
if (!fs46.statSync(gitDir).isDirectory()) return;
|
|
26363
|
+
const file = path54.join(gitDir, "info", "exclude");
|
|
26364
|
+
fs46.mkdirSync(path54.dirname(file), { recursive: true });
|
|
26365
|
+
const current2 = fs46.existsSync(file) ? fs46.readFileSync(file, "utf8") : "";
|
|
26366
|
+
const have = new Set(current2.split(/\r?\n/).map((l) => l.trim()));
|
|
26367
|
+
const missing = patterns.filter((p2) => !have.has(p2));
|
|
26368
|
+
if (missing.length === 0) return;
|
|
26369
|
+
const prefix = current2.length > 0 && !current2.endsWith("\n") ? "\n" : "";
|
|
26370
|
+
fs46.appendFileSync(file, `${prefix}# CodeAgent: beads state stays local
|
|
26371
|
+
${missing.join("\n")}
|
|
26372
|
+
`);
|
|
26373
|
+
} catch {
|
|
26374
|
+
}
|
|
26375
|
+
}
|
|
26338
26376
|
|
|
26339
26377
|
// src/beads/watcher.ts
|
|
26340
26378
|
var crypto4 = __toESM(require("crypto"));
|
|
@@ -27620,7 +27658,7 @@ var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
|
|
|
27620
27658
|
function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
27621
27659
|
if (!nodeModulesDir) return 0;
|
|
27622
27660
|
const readdirSync14 = deps?.readdirSync ?? fs51.readdirSync;
|
|
27623
|
-
const
|
|
27661
|
+
const statSync16 = deps?.statSync ?? fs51.statSync;
|
|
27624
27662
|
const rmSync10 = deps?.rmSync ?? fs51.rmSync;
|
|
27625
27663
|
let removed = 0;
|
|
27626
27664
|
let entries;
|
|
@@ -27633,7 +27671,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
|
27633
27671
|
if (!/^\.codeam-cli-/.test(name)) continue;
|
|
27634
27672
|
const full = path59.join(nodeModulesDir, name);
|
|
27635
27673
|
try {
|
|
27636
|
-
const st3 =
|
|
27674
|
+
const st3 = statSync16(full);
|
|
27637
27675
|
if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
|
|
27638
27676
|
rmSync10(full, { recursive: true, force: true });
|
|
27639
27677
|
removed++;
|
|
@@ -33071,13 +33109,13 @@ var ConnectionBuilder = class {
|
|
|
33071
33109
|
/**
|
|
33072
33110
|
* Adds a typed request handler for one method.
|
|
33073
33111
|
*/
|
|
33074
|
-
onReceiveRequest(method,
|
|
33112
|
+
onReceiveRequest(method, parse2, handler) {
|
|
33075
33113
|
return this.withHandler({
|
|
33076
33114
|
handleMessage: async (message, cx) => {
|
|
33077
33115
|
if (message.kind !== "request" || message.method !== method) {
|
|
33078
33116
|
return Handled.no(message);
|
|
33079
33117
|
}
|
|
33080
|
-
const request2 =
|
|
33118
|
+
const request2 = parse2(message.params);
|
|
33081
33119
|
return await handler(request2, message.responder, cx) ?? Handled.yes();
|
|
33082
33120
|
},
|
|
33083
33121
|
describe: () => `${this.connectionName ?? "request"}:${method}`
|
|
@@ -33086,13 +33124,13 @@ var ConnectionBuilder = class {
|
|
|
33086
33124
|
/**
|
|
33087
33125
|
* Adds a typed notification handler for one method.
|
|
33088
33126
|
*/
|
|
33089
|
-
onReceiveNotification(method,
|
|
33127
|
+
onReceiveNotification(method, parse2, handler) {
|
|
33090
33128
|
return this.withHandler({
|
|
33091
33129
|
handleMessage: async (message, cx) => {
|
|
33092
33130
|
if (message.kind !== "notification" || message.method !== method) {
|
|
33093
33131
|
return Handled.no(message);
|
|
33094
33132
|
}
|
|
33095
|
-
const notification =
|
|
33133
|
+
const notification = parse2(message.params);
|
|
33096
33134
|
return await handler(notification, cx) ?? Handled.yes();
|
|
33097
33135
|
},
|
|
33098
33136
|
describe: () => `${this.connectionName ?? "notification"}:${method}`
|
|
@@ -48317,9 +48355,9 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
|
|
|
48317
48355
|
load() {
|
|
48318
48356
|
try {
|
|
48319
48357
|
const raw = JSON.parse(fs77.readFileSync(file, "utf8"));
|
|
48320
|
-
return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) :
|
|
48358
|
+
return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) : null;
|
|
48321
48359
|
} catch {
|
|
48322
|
-
return
|
|
48360
|
+
return null;
|
|
48323
48361
|
}
|
|
48324
48362
|
},
|
|
48325
48363
|
save(list) {
|
|
@@ -48808,7 +48846,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
48808
48846
|
if (process.env.NODE_ENV === "test") return;
|
|
48809
48847
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48810
48848
|
if (process.env.CI) return;
|
|
48811
|
-
const current2 = true ? "2.75.
|
|
48849
|
+
const current2 = true ? "2.75.39" : null;
|
|
48812
48850
|
if (!current2) return;
|
|
48813
48851
|
const cache = readCache();
|
|
48814
48852
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48825,7 +48863,7 @@ function checkForUpdates() {
|
|
|
48825
48863
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48826
48864
|
if (process.env.CI) return;
|
|
48827
48865
|
if (!process.stdout.isTTY) return;
|
|
48828
|
-
const current2 = true ? "2.75.
|
|
48866
|
+
const current2 = true ? "2.75.39" : null;
|
|
48829
48867
|
if (!current2) return;
|
|
48830
48868
|
const cache = readCache();
|
|
48831
48869
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48848,7 +48886,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
48848
48886
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
48849
48887
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
48850
48888
|
function currentCliVersion() {
|
|
48851
|
-
return true ? "2.75.
|
|
48889
|
+
return true ? "2.75.39" : null;
|
|
48852
48890
|
}
|
|
48853
48891
|
async function installedVersion(deps) {
|
|
48854
48892
|
const ls = await deps.run(
|
|
@@ -50122,11 +50160,12 @@ var HostAgentSupervisor = class {
|
|
|
50122
50160
|
try {
|
|
50123
50161
|
if (this.children.size > 0) return;
|
|
50124
50162
|
const records = this.sessionStore.load();
|
|
50125
|
-
if (records
|
|
50163
|
+
if (records === null) {
|
|
50126
50164
|
const target = this.fallbackResumeTarget();
|
|
50127
50165
|
if (target) this.resumeOne(target);
|
|
50128
50166
|
return;
|
|
50129
50167
|
}
|
|
50168
|
+
if (records.length === 0) return;
|
|
50130
50169
|
const max = resolveMaxResumeSessions();
|
|
50131
50170
|
const { resume, dropped } = planSessionResume(records, max);
|
|
50132
50171
|
for (const rec of dropped) {
|
|
@@ -50174,6 +50213,13 @@ var HostAgentSupervisor = class {
|
|
|
50174
50213
|
const session = getActiveSession();
|
|
50175
50214
|
if (!session || !session.pluginId || !session.pollSecret || !session.agent) return null;
|
|
50176
50215
|
const cwd = session.cwd && fs80.existsSync(session.cwd) ? session.cwd : process.cwd();
|
|
50216
|
+
if (isFilesystemRoot(cwd)) {
|
|
50217
|
+
log.warn(
|
|
50218
|
+
"host-agent",
|
|
50219
|
+
`resume: skipping session ${session.id.slice(0, 8)} \u2014 it has no saved workspace and the fallback is the filesystem root`
|
|
50220
|
+
);
|
|
50221
|
+
return null;
|
|
50222
|
+
}
|
|
50177
50223
|
const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
|
|
50178
50224
|
return { deployId, cwd, session };
|
|
50179
50225
|
}
|
|
@@ -50245,7 +50291,7 @@ var HostAgentSupervisor = class {
|
|
|
50245
50291
|
*/
|
|
50246
50292
|
knownSavedSessions() {
|
|
50247
50293
|
try {
|
|
50248
|
-
const persisted = new Map(this.sessionStore.load().map((r) => [r.deployId, r.agent]));
|
|
50294
|
+
const persisted = new Map((this.sessionStore.load() ?? []).map((r) => [r.deployId, r.agent]));
|
|
50249
50295
|
for (const c2 of this.children.values()) persisted.set(c2.deployId, c2.agent);
|
|
50250
50296
|
return this.listSavedSessions().map((s) => ({ s, deployId: deployIdFromWorkspace(s.cwd) })).filter(
|
|
50251
50297
|
(x) => x.deployId !== null && !!x.s.cwd && fs80.existsSync(x.s.cwd)
|
|
@@ -50816,7 +50862,7 @@ function checkChokidar() {
|
|
|
50816
50862
|
}
|
|
50817
50863
|
async function doctor(args2 = []) {
|
|
50818
50864
|
const json = args2.includes("--json");
|
|
50819
|
-
const cliVersion = true ? "2.75.
|
|
50865
|
+
const cliVersion = true ? "2.75.39" : "0.0.0-dev";
|
|
50820
50866
|
const apiBase2 = resolveApiBaseUrl();
|
|
50821
50867
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
50822
50868
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -51340,7 +51386,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
51340
51386
|
// src/commands/version.ts
|
|
51341
51387
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
51342
51388
|
function version2() {
|
|
51343
|
-
const v = true ? "2.75.
|
|
51389
|
+
const v = true ? "2.75.39" : "unknown";
|
|
51344
51390
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
51345
51391
|
}
|
|
51346
51392
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.39",
|
|
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",
|