codeam-cli 2.46.3 → 2.46.5
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 +111 -23
- 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.46.4] — 2026-06-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Retry + poll dolt sql-server start so it's up before the agent (codeagent-r5k)
|
|
12
|
+
|
|
13
|
+
## [2.46.3] — 2026-06-26
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Detect Cursor plan paywall reply → actionable upgrade-link bubble
|
|
18
|
+
|
|
7
19
|
## [2.46.2] — 2026-06-26
|
|
8
20
|
|
|
9
21
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5397,7 +5397,7 @@ function readAnonId() {
|
|
|
5397
5397
|
}
|
|
5398
5398
|
function superProperties() {
|
|
5399
5399
|
return {
|
|
5400
|
-
cliVersion: true ? "2.46.
|
|
5400
|
+
cliVersion: true ? "2.46.5" : "0.0.0-dev",
|
|
5401
5401
|
nodeVersion: process.version,
|
|
5402
5402
|
platform: process.platform,
|
|
5403
5403
|
arch: process.arch,
|
|
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
|
|
|
5578
5578
|
// package.json
|
|
5579
5579
|
var package_default = {
|
|
5580
5580
|
name: "codeam-cli",
|
|
5581
|
-
version: "2.46.
|
|
5581
|
+
version: "2.46.5",
|
|
5582
5582
|
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.",
|
|
5583
5583
|
type: "commonjs",
|
|
5584
5584
|
main: "dist/index.js",
|
|
@@ -14895,29 +14895,54 @@ var _daemonSeam = {
|
|
|
14895
14895
|
* `Dolt server: running`; down blocks say `Dolt server: not running`.
|
|
14896
14896
|
* Match the affirmative form explicitly so "not running" can't false-positive.
|
|
14897
14897
|
*/
|
|
14898
|
-
isRunning: (statusStdout) => /Dolt server:\s*running/i.test(statusStdout)
|
|
14898
|
+
isRunning: (statusStdout) => /Dolt server:\s*running/i.test(statusStdout),
|
|
14899
|
+
/**
|
|
14900
|
+
* Poll delay behind a seam so tests stub it to a no-op (no real timers).
|
|
14901
|
+
* Production uses a short fixed delay between status re-probes.
|
|
14902
|
+
*/
|
|
14903
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms))
|
|
14899
14904
|
};
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
|
|
14905
|
+
var DEFAULTS = { startAttempts: 2, pollAttempts: 10, pollDelayMs: 500 };
|
|
14906
|
+
async function ensureSharedServer(adapter, options = {}) {
|
|
14907
|
+
const startAttempts = options.startAttempts ?? DEFAULTS.startAttempts;
|
|
14908
|
+
const pollAttempts = options.pollAttempts ?? DEFAULTS.pollAttempts;
|
|
14909
|
+
const pollDelayMs = options.pollDelayMs ?? DEFAULTS.pollDelayMs;
|
|
14910
|
+
const probe = async () => {
|
|
14911
|
+
const status2 = await adapter.run(["dolt", "status"]);
|
|
14912
|
+
return status2.code === 0 && _daemonSeam.isRunning(status2.stdout);
|
|
14913
|
+
};
|
|
14914
|
+
if (await probe()) {
|
|
14903
14915
|
log.trace("beads", "shared dolt sql-server already running \u2014 reusing");
|
|
14904
14916
|
return { up: true, started: false };
|
|
14905
14917
|
}
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14918
|
+
for (let attempt = 1; attempt <= startAttempts; attempt++) {
|
|
14919
|
+
log.info(
|
|
14920
|
+
"beads",
|
|
14921
|
+
`shared dolt sql-server not running \u2014 starting (detached), attempt ${attempt}/${startAttempts}`
|
|
14922
|
+
);
|
|
14923
|
+
const start2 = await adapter.run(["dolt", "start"]);
|
|
14924
|
+
if (start2.code !== 0) {
|
|
14925
|
+
log.warn(
|
|
14926
|
+
"beads",
|
|
14927
|
+
`bd dolt start failed (code=${start2.code}): ${start2.stderr.slice(0, 200)} \u2014 retrying`
|
|
14928
|
+
);
|
|
14929
|
+
if (attempt < startAttempts) await _daemonSeam.sleep(pollDelayMs);
|
|
14930
|
+
continue;
|
|
14931
|
+
}
|
|
14932
|
+
for (let poll = 1; poll <= pollAttempts; poll++) {
|
|
14933
|
+
if (await probe()) {
|
|
14934
|
+
log.info("beads", `shared dolt sql-server up after ${poll} status poll(s)`);
|
|
14935
|
+
return { up: true, started: true };
|
|
14936
|
+
}
|
|
14937
|
+
if (poll < pollAttempts) await _daemonSeam.sleep(pollDelayMs);
|
|
14938
|
+
}
|
|
14909
14939
|
log.warn(
|
|
14910
14940
|
"beads",
|
|
14911
|
-
`
|
|
14941
|
+
`shared dolt sql-server not listening after ${pollAttempts} polls (start attempt ${attempt}/${startAttempts})`
|
|
14912
14942
|
);
|
|
14913
|
-
return { up: false, started: false };
|
|
14914
|
-
}
|
|
14915
|
-
const recheck = await adapter.run(["dolt", "status"]);
|
|
14916
|
-
const up = recheck.code === 0 && _daemonSeam.isRunning(recheck.stdout);
|
|
14917
|
-
if (!up) {
|
|
14918
|
-
log.warn("beads", "shared dolt sql-server still not reachable after start \u2014 non-fatal");
|
|
14919
14943
|
}
|
|
14920
|
-
|
|
14944
|
+
log.warn("beads", "shared dolt sql-server still not reachable after all retries \u2014 non-fatal");
|
|
14945
|
+
return { up: false, started: false };
|
|
14921
14946
|
}
|
|
14922
14947
|
|
|
14923
14948
|
// src/beads/project-key.ts
|
|
@@ -15214,6 +15239,34 @@ async function provisionBeads(opts = {}) {
|
|
|
15214
15239
|
log.warn("beads", "shared dolt sql-server not up \u2014 beads disabled this run");
|
|
15215
15240
|
return result;
|
|
15216
15241
|
}
|
|
15242
|
+
try {
|
|
15243
|
+
if (!await projectDbReachable(bd)) {
|
|
15244
|
+
log.info(
|
|
15245
|
+
"beads",
|
|
15246
|
+
`prefix DB '${prefix}' not reachable on shared server \u2014 self-healing via bd bootstrap`
|
|
15247
|
+
);
|
|
15248
|
+
const boot = await bd.run(["bootstrap", "--non-interactive"]);
|
|
15249
|
+
if (boot.code !== 0) {
|
|
15250
|
+
log.warn(
|
|
15251
|
+
"beads",
|
|
15252
|
+
`bd bootstrap failed (code=${boot.code}): ${boot.stderr.slice(0, 200)} \u2014 prefix DB may be absent`
|
|
15253
|
+
);
|
|
15254
|
+
}
|
|
15255
|
+
const reachable = await projectDbReachable(bd);
|
|
15256
|
+
result.serverUp = reachable;
|
|
15257
|
+
result.initialized = reachable;
|
|
15258
|
+
if (!reachable) {
|
|
15259
|
+
log.warn(
|
|
15260
|
+
"beads",
|
|
15261
|
+
`prefix DB '${prefix}' still unreachable after bootstrap \u2014 beads disabled this run`
|
|
15262
|
+
);
|
|
15263
|
+
return result;
|
|
15264
|
+
}
|
|
15265
|
+
log.info("beads", `prefix DB '${prefix}' materialized on shared server`);
|
|
15266
|
+
}
|
|
15267
|
+
} catch (err) {
|
|
15268
|
+
log.warn("beads", "verifying/creating the prefix DB threw (non-fatal)", err);
|
|
15269
|
+
}
|
|
15217
15270
|
const exp = await bd.run(["config", "set", "export.auto", "true"]);
|
|
15218
15271
|
result.exportEnabled = exp.code === 0;
|
|
15219
15272
|
result.agentsWired = await setupAgents(bd, opts.agents ?? []);
|
|
@@ -15223,6 +15276,10 @@ async function provisionBeads(opts = {}) {
|
|
|
15223
15276
|
);
|
|
15224
15277
|
return result;
|
|
15225
15278
|
}
|
|
15279
|
+
async function projectDbReachable(bd) {
|
|
15280
|
+
const ping = await bd.run(["ping"]);
|
|
15281
|
+
return ping.code === 0;
|
|
15282
|
+
}
|
|
15226
15283
|
async function setupAgents(bd, agents) {
|
|
15227
15284
|
const wired = [];
|
|
15228
15285
|
for (const recipe of dedupeRecipes(agents)) {
|
|
@@ -17943,7 +18000,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17943
18000
|
if (process.env.NODE_ENV === "test") return;
|
|
17944
18001
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17945
18002
|
if (process.env.CI) return;
|
|
17946
|
-
const current = true ? "2.46.
|
|
18003
|
+
const current = true ? "2.46.5" : null;
|
|
17947
18004
|
if (!current) return;
|
|
17948
18005
|
const cache = readCache();
|
|
17949
18006
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17960,7 +18017,7 @@ function checkForUpdates() {
|
|
|
17960
18017
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17961
18018
|
if (process.env.CI) return;
|
|
17962
18019
|
if (!process.stdout.isTTY) return;
|
|
17963
|
-
const current = true ? "2.46.
|
|
18020
|
+
const current = true ? "2.46.5" : null;
|
|
17964
18021
|
if (!current) return;
|
|
17965
18022
|
const cache = readCache();
|
|
17966
18023
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18402,7 +18459,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.s
|
|
|
18402
18459
|
detached: false
|
|
18403
18460
|
});
|
|
18404
18461
|
function currentCliVersion() {
|
|
18405
|
-
return true ? "2.46.
|
|
18462
|
+
return true ? "2.46.5" : null;
|
|
18406
18463
|
}
|
|
18407
18464
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18408
18465
|
return new Promise((resolve7) => {
|
|
@@ -23726,8 +23783,18 @@ function reconcileCumulative(existing, incoming) {
|
|
|
23726
23783
|
if (incoming.length === 0) return existing;
|
|
23727
23784
|
if (incoming.startsWith(existing)) return incoming;
|
|
23728
23785
|
if (existing.startsWith(incoming)) return existing;
|
|
23786
|
+
const shared = commonPrefixLength(existing, incoming);
|
|
23787
|
+
if (shared > 0 && shared >= existing.length / 2) {
|
|
23788
|
+
return existing.slice(0, shared) + incoming.slice(shared);
|
|
23789
|
+
}
|
|
23729
23790
|
return existing + incoming;
|
|
23730
23791
|
}
|
|
23792
|
+
function commonPrefixLength(a, b) {
|
|
23793
|
+
const max = Math.min(a.length, b.length);
|
|
23794
|
+
let i = 0;
|
|
23795
|
+
while (i < max && a.charCodeAt(i) === b.charCodeAt(i)) i += 1;
|
|
23796
|
+
return i;
|
|
23797
|
+
}
|
|
23731
23798
|
|
|
23732
23799
|
// src/agents/acp/onboarding.ts
|
|
23733
23800
|
var import_child_process22 = require("child_process");
|
|
@@ -24653,6 +24720,26 @@ var StreamingState = class {
|
|
|
24653
24720
|
* no matter how many message ids the adapter spreads it across.
|
|
24654
24721
|
*/
|
|
24655
24722
|
turnTextChunkId = null;
|
|
24723
|
+
/**
|
|
24724
|
+
* Stable chunkId that ALL `thinking` segments of the current turn collapse
|
|
24725
|
+
* onto (set to the first thought chunk's id, reset each {@link beginTurn}) —
|
|
24726
|
+
* the thinking twin of {@link turnTextChunkId}.
|
|
24727
|
+
*
|
|
24728
|
+
* Why: `claude-agent-acp` (≥0.47) re-emits the CONSOLIDATED thought under a
|
|
24729
|
+
* DIFFERENT message id (the same dedupe misfire that doubles text). The
|
|
24730
|
+
* mapper derives the thinking chunkId from that message id
|
|
24731
|
+
* (`<messageId>::thought`), so the consolidated re-emit lands in a SECOND
|
|
24732
|
+
* `::thought` buffer, BOTH get flushed `isFinal:true`, and the mobile
|
|
24733
|
+
* activity card (which coalesces by chunkId) stacks the two copies → the
|
|
24734
|
+
* thinking doubles ("TheThe user said …briefly.The user said …briefly.").
|
|
24735
|
+
* Text was protected by {@link turnTextChunkId}; thinking was not. Collapsing
|
|
24736
|
+
* every thought segment of a turn onto one reconcile buffer makes the re-emit
|
|
24737
|
+
* a `reconcileCumulative` REPLACE (identical snapshot) instead of a second
|
|
24738
|
+
* buffer. tool_use / tool_result keep their own id within the turn (distinct
|
|
24739
|
+
* bubbles; the adapter does NOT re-emit a consolidated tool snapshot under a
|
|
24740
|
+
* fresh id, so they don't share this bug).
|
|
24741
|
+
*/
|
|
24742
|
+
turnThoughtChunkId = null;
|
|
24656
24743
|
/**
|
|
24657
24744
|
* Monotonic turn counter, bumped each {@link beginTurn}. Used to NAMESPACE
|
|
24658
24745
|
* every streaming-chunk id so an id the ACP adapter REUSES across turns can't
|
|
@@ -24759,6 +24846,7 @@ var StreamingState = class {
|
|
|
24759
24846
|
this.text = "";
|
|
24760
24847
|
this.streamingChunks.clear();
|
|
24761
24848
|
this.turnTextChunkId = null;
|
|
24849
|
+
this.turnThoughtChunkId = null;
|
|
24762
24850
|
this.turnSeq += 1;
|
|
24763
24851
|
if (this.pending?.kind === "permission") {
|
|
24764
24852
|
clearTimeout(this.pending.timeoutTimer);
|
|
@@ -24770,7 +24858,7 @@ var StreamingState = class {
|
|
|
24770
24858
|
await this.publisher.publishOutput({ type: "new_turn", done: false });
|
|
24771
24859
|
}
|
|
24772
24860
|
append(delta) {
|
|
24773
|
-
const baseId = delta.kind === "text" ? this.turnTextChunkId ??= delta.chunkId : delta.chunkId;
|
|
24861
|
+
const baseId = delta.kind === "text" ? this.turnTextChunkId ??= delta.chunkId : delta.kind === "thinking" ? this.turnThoughtChunkId ??= delta.chunkId : delta.chunkId;
|
|
24774
24862
|
const chunkId = `t${this.turnSeq}:${baseId}`;
|
|
24775
24863
|
const existing = this.streamingChunks.get(chunkId);
|
|
24776
24864
|
if (existing && existing.kind !== delta.kind) {
|
|
@@ -29739,7 +29827,7 @@ function checkChokidar() {
|
|
|
29739
29827
|
}
|
|
29740
29828
|
async function doctor(args2 = []) {
|
|
29741
29829
|
const json = args2.includes("--json");
|
|
29742
|
-
const cliVersion = true ? "2.46.
|
|
29830
|
+
const cliVersion = true ? "2.46.5" : "0.0.0-dev";
|
|
29743
29831
|
const apiBase2 = resolveApiBaseUrl();
|
|
29744
29832
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
29745
29833
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -29938,7 +30026,7 @@ async function completion(args2) {
|
|
|
29938
30026
|
// src/commands/version.ts
|
|
29939
30027
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
29940
30028
|
function version2() {
|
|
29941
|
-
const v = true ? "2.46.
|
|
30029
|
+
const v = true ? "2.46.5" : "unknown";
|
|
29942
30030
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
29943
30031
|
}
|
|
29944
30032
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.46.
|
|
3
|
+
"version": "2.46.5",
|
|
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",
|