codeam-cli 2.76.32 → 2.76.34
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 +26 -0
- package/dist/index.js +201 -45
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ 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.76.33] — 2026-10-14
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **box:** Bake PHP CLI + Composer into the Box image
|
|
12
|
+
- **cli:** Composer pre-flight + PHP guidance for in-app Preview
|
|
13
|
+
|
|
14
|
+
## [2.76.32] — 2026-10-14
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **cli:** Don't resume a session that was deleted from the app while the host slept (codeagent-xwoy)
|
|
19
|
+
|
|
20
|
+
## [2.76.31] — 2026-10-14
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **cli:** Cap the chat-pipe text frame and never loop on a 413
|
|
25
|
+
- **cli:** Make a python static-site preview ready instead of timing out
|
|
26
|
+
- **cli:** Let codex one-shots run outside a git repo
|
|
27
|
+
- **cli:** A failed agent preview hands the agent the dev server's output
|
|
28
|
+
|
|
29
|
+
### Tests
|
|
30
|
+
|
|
31
|
+
- **cli:** Skip the POSIX-only preview subdir spawn test on Windows
|
|
32
|
+
|
|
7
33
|
## [2.76.30] — 2026-10-14
|
|
8
34
|
|
|
9
35
|
### CI
|
package/dist/index.js
CHANGED
|
@@ -3428,14 +3428,23 @@ Rules:
|
|
|
3428
3428
|
otherwise "python3".
|
|
3429
3429
|
- Prefer binding to 0.0.0.0 \u2014 most frameworks default to localhost which the tunnel cannot reach.
|
|
3430
3430
|
- For Expo: framework="Expo", command="npx", args=["expo","start","--tunnel"], port=8081, notes="Scan QR with Expo Go".
|
|
3431
|
+
- For PHP (composer.json / index.php): use PHP's built-in server bound to 0.0.0.0 with the
|
|
3432
|
+
web root as docroot \u2014 command="php", args=["-S","0.0.0.0:8080","-t","public"] (Yii3,
|
|
3433
|
+
Symfony, Slim, Mezzio; use the real docroot, e.g. "web" for Yii2, "." for plain PHP),
|
|
3434
|
+
port=8080, ready_pattern="Development Server". Laravel: command="php",
|
|
3435
|
+
args=["artisan","serve","--host=0.0.0.0","--port=8000"], port=8000,
|
|
3436
|
+
ready_pattern="Server running". Do NOT use "composer serve", "symfony serve" or a
|
|
3437
|
+
"./yii serve" wrapper \u2014 call php directly.
|
|
3431
3438
|
- If no dev server applies (CLI library, lambda, batch script): {"framework":"unsupported","notes":"<reason>"}.
|
|
3432
3439
|
|
|
3433
3440
|
CRITICAL \u2014 setup_commands:
|
|
3434
3441
|
- DO NOT include an install command (npm install, pnpm install, yarn install,
|
|
3435
|
-
yarn, bun install) in setup_commands.
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3442
|
+
yarn, bun install, composer install) in setup_commands. Pre-flight installers
|
|
3443
|
+
run BEFORE setup_commands: composer install whenever composer.json exists and
|
|
3444
|
+
vendor/ is missing, and a lockfile-aware Node installer that picks the
|
|
3445
|
+
correct package manager from the lockfile present (pnpm-lock.yaml -> pnpm,
|
|
3446
|
+
yarn.lock -> yarn, bun.lockb -> bun, else npm). Emitting an install here
|
|
3447
|
+
either duplicates that work or, worse,
|
|
3439
3448
|
uses the WRONG package manager on top of node_modules just populated by the
|
|
3440
3449
|
pre-flight, which crashes (e.g. npm errors with "Cannot read properties of
|
|
3441
3450
|
null (reading 'matches')" when run over pnpm's .pnpm/ layout).
|
|
@@ -10627,7 +10636,7 @@ function readAnonId() {
|
|
|
10627
10636
|
}
|
|
10628
10637
|
function superProperties() {
|
|
10629
10638
|
return {
|
|
10630
|
-
cliVersion: true ? "2.76.
|
|
10639
|
+
cliVersion: true ? "2.76.34" : "0.0.0-dev",
|
|
10631
10640
|
nodeVersion: process.version,
|
|
10632
10641
|
platform: process.platform,
|
|
10633
10642
|
arch: process.arch,
|
|
@@ -10876,7 +10885,7 @@ var http = __toESM(require("http"));
|
|
|
10876
10885
|
// package.json
|
|
10877
10886
|
var package_default = {
|
|
10878
10887
|
name: "codeam-cli",
|
|
10879
|
-
version: "2.76.
|
|
10888
|
+
version: "2.76.34",
|
|
10880
10889
|
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.",
|
|
10881
10890
|
type: "commonjs",
|
|
10882
10891
|
main: "dist/index.js",
|
|
@@ -10964,7 +10973,7 @@ var package_default = {
|
|
|
10964
10973
|
zod: "^4.3.6"
|
|
10965
10974
|
},
|
|
10966
10975
|
optionalDependencies: {
|
|
10967
|
-
"@beads/bd": "1.
|
|
10976
|
+
"@beads/bd": "1.3.1"
|
|
10968
10977
|
},
|
|
10969
10978
|
devDependencies: {
|
|
10970
10979
|
"@codeam/shared": "*",
|
|
@@ -12252,7 +12261,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12252
12261
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12253
12262
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12254
12263
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12255
|
-
..."2.76.
|
|
12264
|
+
..."2.76.34" ? { ideVersion: "2.76.34" } : {}
|
|
12256
12265
|
};
|
|
12257
12266
|
try {
|
|
12258
12267
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body, this.pollSecretHeader());
|
|
@@ -24657,6 +24666,24 @@ function isJsInstallCommand(cmd, args2) {
|
|
|
24657
24666
|
const verb = args2[0];
|
|
24658
24667
|
return verb === "install" || verb === "i" || verb === "ci";
|
|
24659
24668
|
}
|
|
24669
|
+
function detectMissingPhpDeps(cwd) {
|
|
24670
|
+
if (!import_fs5.default.existsSync(import_path8.default.join(cwd, "composer.json"))) return null;
|
|
24671
|
+
if (import_fs5.default.existsSync(import_path8.default.join(cwd, "vendor"))) return null;
|
|
24672
|
+
return {
|
|
24673
|
+
cmd: "composer",
|
|
24674
|
+
args: [
|
|
24675
|
+
"install",
|
|
24676
|
+
"--no-interaction",
|
|
24677
|
+
"--no-progress",
|
|
24678
|
+
"--prefer-dist",
|
|
24679
|
+
"--ignore-platform-req=ext-*"
|
|
24680
|
+
]
|
|
24681
|
+
};
|
|
24682
|
+
}
|
|
24683
|
+
function isComposerInstallCommand(cmd, args2) {
|
|
24684
|
+
if (cmd !== "composer") return false;
|
|
24685
|
+
return args2[0] === "install" || args2[0] === "i";
|
|
24686
|
+
}
|
|
24660
24687
|
|
|
24661
24688
|
// src/services/preview/script-candidates.ts
|
|
24662
24689
|
var fs47 = __toESM(require("fs"));
|
|
@@ -27119,6 +27146,29 @@ function announceReady(ctx, dev, tun) {
|
|
|
27119
27146
|
port: detection.port
|
|
27120
27147
|
});
|
|
27121
27148
|
}
|
|
27149
|
+
async function runPreflightInstall(ctx, install, why) {
|
|
27150
|
+
const { detection, cwd, emit: emit2, emitProgress } = ctx;
|
|
27151
|
+
const label = `${install.cmd} ${install.args.join(" ")}`;
|
|
27152
|
+
emitProgress("SETUP_RUN", `${label} (pre-flight \u2014 ${why})`);
|
|
27153
|
+
const result = await runSetupCommand(install.cmd, install.args, cwd, detection.env, {
|
|
27154
|
+
timeoutMs: INSTALL_TIMEOUT_MS2
|
|
27155
|
+
});
|
|
27156
|
+
if (result.status === "timeout") {
|
|
27157
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27158
|
+
stage: "ready_timeout",
|
|
27159
|
+
message: `Dependency install (${label}) didn't finish within ${Math.round(INSTALL_TIMEOUT_MS2 / 1e3)}s and was stopped. Run it manually in this project, then try the preview again.`
|
|
27160
|
+
});
|
|
27161
|
+
return false;
|
|
27162
|
+
}
|
|
27163
|
+
if (result.status === "failed") {
|
|
27164
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27165
|
+
stage: "spawn",
|
|
27166
|
+
message: `Dependency install failed (${label}, exit ${result.code}). Run it manually in this project and try again.`
|
|
27167
|
+
});
|
|
27168
|
+
return false;
|
|
27169
|
+
}
|
|
27170
|
+
return true;
|
|
27171
|
+
}
|
|
27122
27172
|
async function provisionDeps(ctx) {
|
|
27123
27173
|
const { detection, cwd, emit: emit2, emitProgress } = ctx;
|
|
27124
27174
|
if (ctx.projectEnvAuth?.pluginAuthToken) {
|
|
@@ -27155,32 +27205,21 @@ async function provisionDeps(ctx) {
|
|
|
27155
27205
|
return false;
|
|
27156
27206
|
}
|
|
27157
27207
|
}
|
|
27158
|
-
|
|
27159
|
-
|
|
27160
|
-
|
|
27161
|
-
|
|
27162
|
-
|
|
27163
|
-
|
|
27164
|
-
|
|
27165
|
-
cwd,
|
|
27166
|
-
detection.env,
|
|
27167
|
-
{ timeoutMs: INSTALL_TIMEOUT_MS2 }
|
|
27168
|
-
);
|
|
27169
|
-
if (result.status === "timeout") {
|
|
27170
|
-
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27171
|
-
stage: "ready_timeout",
|
|
27172
|
-
message: `Dependency install (${missingDeps.cmd} ${missingDeps.args.join(" ")}) didn't finish within ${Math.round(INSTALL_TIMEOUT_MS2 / 1e3)}s and was stopped. Run it manually in this project, then try the preview again.`
|
|
27173
|
-
});
|
|
27174
|
-
return false;
|
|
27175
|
-
}
|
|
27176
|
-
if (result.status === "failed") {
|
|
27208
|
+
if (!await runPreflightInstall(ctx, missingDeps, "node_modules missing")) return false;
|
|
27209
|
+
preflightRan = true;
|
|
27210
|
+
}
|
|
27211
|
+
const missingPhpDeps = detectMissingPhpDeps(cwd);
|
|
27212
|
+
let composerPreflightRan = false;
|
|
27213
|
+
if (missingPhpDeps) {
|
|
27214
|
+
if (!await (0, import_which3.default)("composer", { nothrow: true })) {
|
|
27177
27215
|
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27178
27216
|
stage: "spawn",
|
|
27179
|
-
message:
|
|
27217
|
+
message: "This is a PHP project (composer.json) but Composer isn't installed in this environment, so its dependencies (vendor/) can't be installed. Install PHP and Composer, then try the preview again."
|
|
27180
27218
|
});
|
|
27181
27219
|
return false;
|
|
27182
27220
|
}
|
|
27183
|
-
|
|
27221
|
+
if (!await runPreflightInstall(ctx, missingPhpDeps, "vendor/ missing")) return false;
|
|
27222
|
+
composerPreflightRan = true;
|
|
27184
27223
|
}
|
|
27185
27224
|
const normalizedSetup = (detection.setup_commands ?? []).map((entry) => {
|
|
27186
27225
|
if (typeof entry === "string") {
|
|
@@ -27193,10 +27232,12 @@ async function provisionDeps(ctx) {
|
|
|
27193
27232
|
args: Array.isArray(o.args) ? o.args.filter((a) => typeof a === "string") : []
|
|
27194
27233
|
};
|
|
27195
27234
|
}).filter((s) => s.cmd.length > 0);
|
|
27196
|
-
const agentSetupCommands =
|
|
27235
|
+
const agentSetupCommands = normalizedSetup.filter(
|
|
27236
|
+
(s) => !(preflightRan && isJsInstallCommand(s.cmd, s.args)) && !(composerPreflightRan && isComposerInstallCommand(s.cmd, s.args))
|
|
27237
|
+
);
|
|
27197
27238
|
for (const setup of agentSetupCommands) {
|
|
27198
27239
|
emitProgress("SETUP_RUN", `${setup.cmd} ${setup.args.join(" ")}`);
|
|
27199
|
-
const timeoutMs = isJsInstallCommand(setup.cmd, setup.args) ? INSTALL_TIMEOUT_MS2 : SETUP_TIMEOUT_MS;
|
|
27240
|
+
const timeoutMs = isJsInstallCommand(setup.cmd, setup.args) || isComposerInstallCommand(setup.cmd, setup.args) ? INSTALL_TIMEOUT_MS2 : SETUP_TIMEOUT_MS;
|
|
27200
27241
|
const result = await runSetupCommand(setup.cmd, setup.args, cwd, detection.env, {
|
|
27201
27242
|
timeoutMs
|
|
27202
27243
|
});
|
|
@@ -27468,6 +27509,43 @@ var import_child_process21 = require("child_process");
|
|
|
27468
27509
|
var fs59 = __toESM(require("fs"));
|
|
27469
27510
|
var os40 = __toESM(require("os"));
|
|
27470
27511
|
var path67 = __toESM(require("path"));
|
|
27512
|
+
|
|
27513
|
+
// src/beads/schema-migrate.ts
|
|
27514
|
+
var SCHEMA_SKEW_RE = /Error 1146|table not found|refusing to auto-apply \d+ pending schema migration/i;
|
|
27515
|
+
function isSchemaSkew(text) {
|
|
27516
|
+
return SCHEMA_SKEW_RE.test(text);
|
|
27517
|
+
}
|
|
27518
|
+
var APPLIED_RE = /applying (\d+) pending schema migration/i;
|
|
27519
|
+
var REMOTE_GATE_RE = /remote-backed database/i;
|
|
27520
|
+
async function migrateSchema(bd) {
|
|
27521
|
+
let forced = false;
|
|
27522
|
+
let res = await bd.run(["migrate", "schema"]);
|
|
27523
|
+
if (res.code !== 0 && REMOTE_GATE_RE.test(res.stderr + res.stdout)) {
|
|
27524
|
+
log.info("beads", "schema migrate refused for a remote-backed DB \u2014 migrating with --force");
|
|
27525
|
+
forced = true;
|
|
27526
|
+
res = await bd.run(["migrate", "schema", "--force"]);
|
|
27527
|
+
}
|
|
27528
|
+
const text = `${res.stderr}
|
|
27529
|
+
${res.stdout}`;
|
|
27530
|
+
if (res.code !== 0) {
|
|
27531
|
+
const detail = (res.stderr || res.stdout).trim().slice(0, 200);
|
|
27532
|
+
log.warn("beads", `bd migrate schema failed (code=${res.code}): ${detail}`);
|
|
27533
|
+
return { status: "failed", detail };
|
|
27534
|
+
}
|
|
27535
|
+
const applied = APPLIED_RE.exec(text);
|
|
27536
|
+
if (applied) {
|
|
27537
|
+
const count = Number(applied[1]);
|
|
27538
|
+
log.info(
|
|
27539
|
+
"beads",
|
|
27540
|
+
`bd migrate schema applied ${count} migration(s)${forced ? " (--force)" : ""}`
|
|
27541
|
+
);
|
|
27542
|
+
return { status: "applied", count, forced };
|
|
27543
|
+
}
|
|
27544
|
+
log.trace("beads", "bd migrate schema: already current");
|
|
27545
|
+
return { status: "current" };
|
|
27546
|
+
}
|
|
27547
|
+
|
|
27548
|
+
// src/beads/bd-adapter.ts
|
|
27471
27549
|
var BD_PACKAGE = "@beads/bd";
|
|
27472
27550
|
function resolveBundledBdBinary() {
|
|
27473
27551
|
return _resolveSeam.resolveBundled();
|
|
@@ -27545,6 +27623,8 @@ var BdAdapter = class {
|
|
|
27545
27623
|
}
|
|
27546
27624
|
opts;
|
|
27547
27625
|
resolved;
|
|
27626
|
+
/** Set when a bd call failed on schema skew; read + cleared by `takeSchemaSkew`. */
|
|
27627
|
+
schemaSkewSeen = false;
|
|
27548
27628
|
/**
|
|
27549
27629
|
* Resolve the bd binary lazily, caching the result. Order:
|
|
27550
27630
|
* bundled @beads/bd → PATH. Returns null when neither is available — the
|
|
@@ -27600,8 +27680,20 @@ var BdAdapter = class {
|
|
|
27600
27680
|
await _adapterSeam.sleep(750 * attempt);
|
|
27601
27681
|
res = await _spawnSeam.run(binary, args2, { cwd, env });
|
|
27602
27682
|
}
|
|
27683
|
+
if (res.code !== 0 && isSchemaSkew(res.stderr + res.stdout)) this.schemaSkewSeen = true;
|
|
27603
27684
|
return res;
|
|
27604
27685
|
}
|
|
27686
|
+
/**
|
|
27687
|
+
* Whether a bd call since the last check failed because the project DB is
|
|
27688
|
+
* behind this bd's schema (see `schema-migrate.ts`). `listIssues` /
|
|
27689
|
+
* `statusSummary` swallow failures into []/null, so this is how the watcher
|
|
27690
|
+
* learns the cause. Clears the flag.
|
|
27691
|
+
*/
|
|
27692
|
+
takeSchemaSkew() {
|
|
27693
|
+
const seen2 = this.schemaSkewSeen;
|
|
27694
|
+
this.schemaSkewSeen = false;
|
|
27695
|
+
return seen2;
|
|
27696
|
+
}
|
|
27605
27697
|
/**
|
|
27606
27698
|
* `bd ready --json` → typed issue array. `bd list --json` shares the shape,
|
|
27607
27699
|
* so `listIssues` reuses the same parser. Bad JSON / non-zero exit → [].
|
|
@@ -28167,7 +28259,8 @@ async function provisionBeads(opts = {}) {
|
|
|
28167
28259
|
prefix: null,
|
|
28168
28260
|
initialized: false,
|
|
28169
28261
|
exportEnabled: false,
|
|
28170
|
-
agentsWired: []
|
|
28262
|
+
agentsWired: [],
|
|
28263
|
+
schemaMigrate: null
|
|
28171
28264
|
};
|
|
28172
28265
|
if (!bd.isAvailable()) {
|
|
28173
28266
|
log.info("beads", "bd binary missing \u2014 running OS installer fallback");
|
|
@@ -28249,6 +28342,7 @@ async function provisionBeads(opts = {}) {
|
|
|
28249
28342
|
log.warn("beads", "shared dolt sql-server not up \u2014 beads disabled this run");
|
|
28250
28343
|
return result;
|
|
28251
28344
|
}
|
|
28345
|
+
result.schemaMigrate = await migrateSchemaSafely(bd);
|
|
28252
28346
|
try {
|
|
28253
28347
|
if (!await projectDbReachable(bd)) {
|
|
28254
28348
|
log.info(
|
|
@@ -28264,6 +28358,8 @@ async function provisionBeads(opts = {}) {
|
|
|
28264
28358
|
"beads",
|
|
28265
28359
|
`bd bootstrap failed (code=${boot.code}): ${boot.stderr.slice(0, 200)} \u2014 prefix DB may be absent`
|
|
28266
28360
|
);
|
|
28361
|
+
} else {
|
|
28362
|
+
result.schemaMigrate = await migrateSchemaSafely(bd);
|
|
28267
28363
|
}
|
|
28268
28364
|
}
|
|
28269
28365
|
if (!await projectDbReachable(bd)) {
|
|
@@ -28315,10 +28411,25 @@ async function provisionBeads(opts = {}) {
|
|
|
28315
28411
|
result.agentsWired = await setupAgents(bd, opts.agents ?? []);
|
|
28316
28412
|
log.info(
|
|
28317
28413
|
"beads",
|
|
28318
|
-
`provision done dolt=${result.doltAvailable} server=${result.serverUp} prefix=${result.prefix} initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
|
|
28414
|
+
`provision done dolt=${result.doltAvailable} server=${result.serverUp} prefix=${result.prefix} initialized=${result.initialized} schema=${describeSchemaMigrate(result.schemaMigrate)} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
|
|
28319
28415
|
);
|
|
28320
28416
|
return result;
|
|
28321
28417
|
}
|
|
28418
|
+
async function migrateSchemaSafely(bd) {
|
|
28419
|
+
try {
|
|
28420
|
+
return await migrateSchema(bd);
|
|
28421
|
+
} catch (err) {
|
|
28422
|
+
log.warn("beads", "bd migrate schema threw (non-fatal)", err);
|
|
28423
|
+
return { status: "failed", detail: err.message };
|
|
28424
|
+
}
|
|
28425
|
+
}
|
|
28426
|
+
function describeSchemaMigrate(outcome) {
|
|
28427
|
+
if (!outcome) return "skipped";
|
|
28428
|
+
if (outcome.status === "applied") {
|
|
28429
|
+
return `applied:${outcome.count}${outcome.forced ? ":forced" : ""}`;
|
|
28430
|
+
}
|
|
28431
|
+
return outcome.status;
|
|
28432
|
+
}
|
|
28322
28433
|
async function projectDbReachable(bd) {
|
|
28323
28434
|
const ping = await bd.run(["ping"]);
|
|
28324
28435
|
return ping.code === 0;
|
|
@@ -28414,6 +28525,8 @@ var BeadsWatcher = class {
|
|
|
28414
28525
|
debounceTimer = null;
|
|
28415
28526
|
stopped = false;
|
|
28416
28527
|
lastPushedHash = null;
|
|
28528
|
+
/** One schema-heal attempt per watcher — a failing migrate must not loop. */
|
|
28529
|
+
schemaHealTried = false;
|
|
28417
28530
|
bd;
|
|
28418
28531
|
feedPath;
|
|
28419
28532
|
apiBase;
|
|
@@ -28482,10 +28595,15 @@ var BeadsWatcher = class {
|
|
|
28482
28595
|
async syncNow() {
|
|
28483
28596
|
if (this.stopped) return;
|
|
28484
28597
|
const { projectKey, projectLabel } = deriveProjectIdentity(this.opts.cwd);
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
this.
|
|
28488
|
-
|
|
28598
|
+
let [issues, summary] = await this.readSnapshot(projectKey);
|
|
28599
|
+
if (!this.schemaHealTried && this.bd.takeSchemaSkew()) {
|
|
28600
|
+
this.schemaHealTried = true;
|
|
28601
|
+
log.info("beads", "snapshot hit schema skew \u2014 running bd migrate schema once");
|
|
28602
|
+
const outcome = await migrateSchema(this.bd);
|
|
28603
|
+
if (outcome.status !== "failed") {
|
|
28604
|
+
[issues, summary] = await this.readSnapshot(projectKey);
|
|
28605
|
+
}
|
|
28606
|
+
}
|
|
28489
28607
|
const payload = {
|
|
28490
28608
|
sessionId: this.opts.sessionId,
|
|
28491
28609
|
pluginId: this.opts.pluginId,
|
|
@@ -28524,6 +28642,9 @@ var BeadsWatcher = class {
|
|
|
28524
28642
|
log.warn("beads", "ingest POST error", err);
|
|
28525
28643
|
}
|
|
28526
28644
|
}
|
|
28645
|
+
readSnapshot(projectKey) {
|
|
28646
|
+
return Promise.all([this.bd.listIssues(projectKey), this.bd.statusSummary()]);
|
|
28647
|
+
}
|
|
28527
28648
|
headers() {
|
|
28528
28649
|
return {
|
|
28529
28650
|
"Content-Type": "application/json",
|
|
@@ -51501,7 +51622,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
51501
51622
|
if (process.env.NODE_ENV === "test") return;
|
|
51502
51623
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51503
51624
|
if (process.env.CI) return;
|
|
51504
|
-
const current2 = true ? "2.76.
|
|
51625
|
+
const current2 = true ? "2.76.34" : null;
|
|
51505
51626
|
if (!current2) return;
|
|
51506
51627
|
const cache = readCache();
|
|
51507
51628
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51518,7 +51639,7 @@ function checkForUpdates() {
|
|
|
51518
51639
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51519
51640
|
if (process.env.CI) return;
|
|
51520
51641
|
if (!process.stdout.isTTY) return;
|
|
51521
|
-
const current2 = true ? "2.76.
|
|
51642
|
+
const current2 = true ? "2.76.34" : null;
|
|
51522
51643
|
if (!current2) return;
|
|
51523
51644
|
const cache = readCache();
|
|
51524
51645
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51694,14 +51815,37 @@ function pidAlive3(pid) {
|
|
|
51694
51815
|
return err.code === "EPERM";
|
|
51695
51816
|
}
|
|
51696
51817
|
}
|
|
51818
|
+
var CLK_TCK = 100;
|
|
51819
|
+
function processStartMs(pid) {
|
|
51820
|
+
try {
|
|
51821
|
+
const stat3 = fs96.readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
51822
|
+
const ticks = Number(stat3.slice(stat3.lastIndexOf(")") + 2).split(" ")[19]);
|
|
51823
|
+
const btime = /^btime (\d+)$/m.exec(fs96.readFileSync("/proc/stat", "utf8"))?.[1];
|
|
51824
|
+
if (!Number.isFinite(ticks) || !btime) return null;
|
|
51825
|
+
return Number(btime) * 1e3 + ticks * 1e3 / CLK_TCK;
|
|
51826
|
+
} catch {
|
|
51827
|
+
return null;
|
|
51828
|
+
}
|
|
51829
|
+
}
|
|
51830
|
+
var PID_REUSE_SLACK_MS = 2e3;
|
|
51697
51831
|
function livePids(versionDir) {
|
|
51832
|
+
const dir = path109.join(versionDir, ".pids");
|
|
51698
51833
|
let names;
|
|
51699
51834
|
try {
|
|
51700
|
-
names = fs96.readdirSync(
|
|
51835
|
+
names = fs96.readdirSync(dir);
|
|
51701
51836
|
} catch {
|
|
51702
51837
|
return [];
|
|
51703
51838
|
}
|
|
51704
|
-
return names.map(Number).filter((pid) =>
|
|
51839
|
+
return names.map(Number).filter((pid) => {
|
|
51840
|
+
if (!Number.isInteger(pid) || pid <= 0 || !pidAlive3(pid)) return false;
|
|
51841
|
+
const started = processStartMs(pid);
|
|
51842
|
+
if (started === null) return true;
|
|
51843
|
+
try {
|
|
51844
|
+
return started <= fs96.statSync(path109.join(dir, String(pid))).mtimeMs + PID_REUSE_SLACK_MS;
|
|
51845
|
+
} catch {
|
|
51846
|
+
return true;
|
|
51847
|
+
}
|
|
51848
|
+
});
|
|
51705
51849
|
}
|
|
51706
51850
|
function registerRunningVersion(root = cliVersionsRoot(), entry = process.argv[1]) {
|
|
51707
51851
|
const dir = versionDirContaining(root, entry);
|
|
@@ -51801,7 +51945,7 @@ var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
|
51801
51945
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
51802
51946
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
51803
51947
|
function currentCliVersion() {
|
|
51804
|
-
return true ? "2.76.
|
|
51948
|
+
return true ? "2.76.34" : null;
|
|
51805
51949
|
}
|
|
51806
51950
|
async function installedVersion(deps) {
|
|
51807
51951
|
const ls = await deps.run(
|
|
@@ -51886,6 +52030,7 @@ async function runSelfUpdateWith(deps) {
|
|
|
51886
52030
|
}
|
|
51887
52031
|
if (compareSemver(latest, current2) <= 0) {
|
|
51888
52032
|
log.info("host-agent", `self-update: running ${current2}, npm latest ${latest} \u2014 up to date`);
|
|
52033
|
+
if (versionedModeSupported(deps.platform)) collectOldVersions(root);
|
|
51889
52034
|
return { status: "current" };
|
|
51890
52035
|
}
|
|
51891
52036
|
if (!versionedModeSupported(deps.platform)) {
|
|
@@ -51902,6 +52047,17 @@ async function runSelfUpdateWith(deps) {
|
|
|
51902
52047
|
return { status: "skipped" };
|
|
51903
52048
|
}
|
|
51904
52049
|
}
|
|
52050
|
+
function collectOldVersions(root) {
|
|
52051
|
+
const release3 = acquireInstallLock(root);
|
|
52052
|
+
if (!release3) return [];
|
|
52053
|
+
try {
|
|
52054
|
+
const removed = gcVersions(root);
|
|
52055
|
+
if (removed.length) log.info("host-agent", `self-update: gc removed ${removed.join(", ")}`);
|
|
52056
|
+
return removed;
|
|
52057
|
+
} finally {
|
|
52058
|
+
release3();
|
|
52059
|
+
}
|
|
52060
|
+
}
|
|
51905
52061
|
var VERIFY_TIMEOUT_MS = 3e4;
|
|
51906
52062
|
async function installVersioned(deps, root, latest, running2) {
|
|
51907
52063
|
const node = deps.nodePath ?? process.execPath;
|
|
@@ -52012,7 +52168,7 @@ function signalHostReady(send = process.send?.bind(process)) {
|
|
|
52012
52168
|
}
|
|
52013
52169
|
function defaultDeps() {
|
|
52014
52170
|
return {
|
|
52015
|
-
ownVersion: true ? "2.76.
|
|
52171
|
+
ownVersion: true ? "2.76.34" : null,
|
|
52016
52172
|
root: cliVersionsRoot(),
|
|
52017
52173
|
args: process.argv.slice(3),
|
|
52018
52174
|
execPath: process.execPath,
|
|
@@ -54550,7 +54706,7 @@ function checkChokidar() {
|
|
|
54550
54706
|
}
|
|
54551
54707
|
async function doctor(args2 = []) {
|
|
54552
54708
|
const json = args2.includes("--json");
|
|
54553
|
-
const cliVersion = true ? "2.76.
|
|
54709
|
+
const cliVersion = true ? "2.76.34" : "0.0.0-dev";
|
|
54554
54710
|
const apiBase2 = resolveApiBaseUrl();
|
|
54555
54711
|
const diagnosticId = (0, import_node_crypto17.randomUUID)();
|
|
54556
54712
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -55086,7 +55242,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
55086
55242
|
// src/commands/version.ts
|
|
55087
55243
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
55088
55244
|
function version2() {
|
|
55089
|
-
const v = true ? "2.76.
|
|
55245
|
+
const v = true ? "2.76.34" : "unknown";
|
|
55090
55246
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
55091
55247
|
}
|
|
55092
55248
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.76.
|
|
3
|
+
"version": "2.76.34",
|
|
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",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"zod": "^4.3.6"
|
|
89
89
|
},
|
|
90
90
|
"optionalDependencies": {
|
|
91
|
-
"@beads/bd": "1.
|
|
91
|
+
"@beads/bd": "1.3.1"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@codeam/shared": "*",
|