codeam-cli 2.23.32 → 2.23.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 +7 -0
- package/dist/index.js +99 -13
- 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.23.32] — 2026-05-31
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Add CommitEntry + BlameLine wire types for git enrichment
|
|
12
|
+
- **cli:** Capture git log + blame per changed file at turn end
|
|
13
|
+
|
|
7
14
|
## [2.23.31] — 2026-05-30
|
|
8
15
|
|
|
9
16
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -441,7 +441,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
441
441
|
// package.json
|
|
442
442
|
var package_default = {
|
|
443
443
|
name: "codeam-cli",
|
|
444
|
-
version: "2.23.
|
|
444
|
+
version: "2.23.34",
|
|
445
445
|
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.",
|
|
446
446
|
type: "commonjs",
|
|
447
447
|
main: "dist/index.js",
|
|
@@ -5774,7 +5774,7 @@ function readAnonId() {
|
|
|
5774
5774
|
}
|
|
5775
5775
|
function superProperties() {
|
|
5776
5776
|
return {
|
|
5777
|
-
cliVersion: true ? "2.23.
|
|
5777
|
+
cliVersion: true ? "2.23.34" : "0.0.0-dev",
|
|
5778
5778
|
nodeVersion: process.version,
|
|
5779
5779
|
platform: process.platform,
|
|
5780
5780
|
arch: process.arch,
|
|
@@ -6305,19 +6305,40 @@ var AgentService = class _AgentService {
|
|
|
6305
6305
|
this.quietTimer = setTimeout(tick, _AgentService.QUIET_MS);
|
|
6306
6306
|
}
|
|
6307
6307
|
/**
|
|
6308
|
-
* Write one prompt to the PTY
|
|
6309
|
-
*
|
|
6310
|
-
*
|
|
6308
|
+
* Write one prompt to the PTY and submit it.
|
|
6309
|
+
*
|
|
6310
|
+
* For multi-line text (or any text > 1 line), Claude Code's TUI
|
|
6311
|
+
* triggers bracketed-paste mode and treats the write as a paste:
|
|
6312
|
+
* a `[Pasted text #N]` marker lands in the input field, and any
|
|
6313
|
+
* `\r` we send while the paste boundary is still open is swallowed
|
|
6314
|
+
* as part of the paste content — never reaching the submit
|
|
6315
|
+
* handler. The result is the prompt sitting in the input forever
|
|
6316
|
+
* (the user reported stacking `[Pasted text #N]` markers with no
|
|
6317
|
+
* agent reply).
|
|
6318
|
+
*
|
|
6319
|
+
* Fix: explicitly bracket the paste ourselves (`ESC[200~ <text>
|
|
6320
|
+
* ESC[201~`) so the end marker closes the paste deterministically.
|
|
6321
|
+
* A short delay later we send `\r` — now OUTSIDE the bracket — so
|
|
6322
|
+
* Claude's input handler treats it as Submit, not paste content.
|
|
6323
|
+
* Single-line text doesn't trigger paste mode, so we keep the
|
|
6324
|
+
* legacy `text + \r` path for that case (cheaper, no markers).
|
|
6325
|
+
*
|
|
6326
|
+
* Marks the agent busy so subsequent `sendCommand` calls queue
|
|
6327
|
+
* instead of stacking pastes.
|
|
6311
6328
|
*/
|
|
6312
6329
|
submitToPty(text) {
|
|
6313
6330
|
if (!this.strategy) return;
|
|
6314
6331
|
const s = this.strategy;
|
|
6315
6332
|
this.agentBusy = true;
|
|
6316
6333
|
log.trace("agent", `submit text=${text.length}B (queued=${this.pendingInputs.length})`);
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6334
|
+
const isMultiline = text.includes("\n");
|
|
6335
|
+
if (isMultiline) {
|
|
6336
|
+
s.write(`\x1B[200~${text}\x1B[201~`);
|
|
6337
|
+
setTimeout(() => s.write("\r"), 80);
|
|
6338
|
+
} else {
|
|
6339
|
+
s.write(text);
|
|
6340
|
+
setTimeout(() => s.write("\r"), 50);
|
|
6341
|
+
}
|
|
6321
6342
|
}
|
|
6322
6343
|
drainPending() {
|
|
6323
6344
|
if (!this.strategy || this.pendingInputs.length === 0) return;
|
|
@@ -12825,6 +12846,8 @@ function _post2(url, headers, payload) {
|
|
|
12825
12846
|
// src/services/file-watcher.service.ts
|
|
12826
12847
|
var API_BASE5 = resolveApiBaseUrl();
|
|
12827
12848
|
var DEBOUNCE_MS = 250;
|
|
12849
|
+
var COALESCE_WINDOW_MS = 250;
|
|
12850
|
+
var COALESCE_MAX_HOLD_MS = 2e3;
|
|
12828
12851
|
var MAX_RETRIES = 2;
|
|
12829
12852
|
var RETRY_BACKOFF_MS = 300;
|
|
12830
12853
|
var HISTORY_MAX_COMMITS = 50;
|
|
@@ -12908,6 +12931,17 @@ var FileWatcherService = class {
|
|
|
12908
12931
|
*/
|
|
12909
12932
|
gitRootByDir = /* @__PURE__ */ new Map();
|
|
12910
12933
|
stopped = false;
|
|
12934
|
+
/**
|
|
12935
|
+
* Cross-file coalescing buffer. Keyed by absPath so multiple
|
|
12936
|
+
* scheduled emits for the same file collapse to the latest
|
|
12937
|
+
* `changeType`. The buffer drains via `coalesceTimer` after
|
|
12938
|
+
* `COALESCE_WINDOW_MS` of quiescence, or forcibly after
|
|
12939
|
+
* `COALESCE_MAX_HOLD_MS` so the UI never starves during a long
|
|
12940
|
+
* continuous edit.
|
|
12941
|
+
*/
|
|
12942
|
+
coalesceBuffer = /* @__PURE__ */ new Map();
|
|
12943
|
+
coalesceTimer = null;
|
|
12944
|
+
coalesceMaxHoldTimer = null;
|
|
12911
12945
|
/**
|
|
12912
12946
|
* Start watching `opts.workingDir`. Idempotent (second call is a
|
|
12913
12947
|
* no-op). Resolves once chokidar's initial scan completes; that
|
|
@@ -13009,6 +13043,15 @@ var FileWatcherService = class {
|
|
|
13009
13043
|
clearTimeout(entry.timer);
|
|
13010
13044
|
}
|
|
13011
13045
|
this.pending.clear();
|
|
13046
|
+
if (this.coalesceTimer) {
|
|
13047
|
+
clearTimeout(this.coalesceTimer);
|
|
13048
|
+
this.coalesceTimer = null;
|
|
13049
|
+
}
|
|
13050
|
+
if (this.coalesceMaxHoldTimer) {
|
|
13051
|
+
clearTimeout(this.coalesceMaxHoldTimer);
|
|
13052
|
+
this.coalesceMaxHoldTimer = null;
|
|
13053
|
+
}
|
|
13054
|
+
this.coalesceBuffer.clear();
|
|
13012
13055
|
if (this.watcher) {
|
|
13013
13056
|
try {
|
|
13014
13057
|
await this.watcher.close();
|
|
@@ -13036,7 +13079,7 @@ var FileWatcherService = class {
|
|
|
13036
13079
|
if (existing) clearTimeout(existing.timer);
|
|
13037
13080
|
const timer = setTimeout(() => {
|
|
13038
13081
|
this.pending.delete(absPath);
|
|
13039
|
-
|
|
13082
|
+
this.enqueueForCoalesce(absPath, changeType);
|
|
13040
13083
|
}, DEBOUNCE_MS);
|
|
13041
13084
|
this.pending.set(absPath, {
|
|
13042
13085
|
lastEventAt: Date.now(),
|
|
@@ -13044,6 +13087,49 @@ var FileWatcherService = class {
|
|
|
13044
13087
|
changeType
|
|
13045
13088
|
});
|
|
13046
13089
|
}
|
|
13090
|
+
/**
|
|
13091
|
+
* Drop the file into the cross-file coalescing buffer. The buffer
|
|
13092
|
+
* flushes after `COALESCE_WINDOW_MS` of quiescence (resets on each
|
|
13093
|
+
* new enqueue) or after `COALESCE_MAX_HOLD_MS` regardless. Same
|
|
13094
|
+
* file enqueued twice in a row keeps only the latest `changeType`
|
|
13095
|
+
* (typically the most recent FS event wins).
|
|
13096
|
+
*/
|
|
13097
|
+
enqueueForCoalesce(absPath, changeType) {
|
|
13098
|
+
if (this.stopped) return;
|
|
13099
|
+
this.coalesceBuffer.set(absPath, { absPath, changeType });
|
|
13100
|
+
if (this.coalesceTimer) clearTimeout(this.coalesceTimer);
|
|
13101
|
+
this.coalesceTimer = setTimeout(() => {
|
|
13102
|
+
void this.flushCoalesceBuffer();
|
|
13103
|
+
}, COALESCE_WINDOW_MS);
|
|
13104
|
+
if (!this.coalesceMaxHoldTimer) {
|
|
13105
|
+
this.coalesceMaxHoldTimer = setTimeout(() => {
|
|
13106
|
+
void this.flushCoalesceBuffer();
|
|
13107
|
+
}, COALESCE_MAX_HOLD_MS);
|
|
13108
|
+
}
|
|
13109
|
+
}
|
|
13110
|
+
/**
|
|
13111
|
+
* Drain the coalesce buffer. Snapshots the entries up-front so any
|
|
13112
|
+
* emissions that arrive mid-flush (chokidar fires again, agent
|
|
13113
|
+
* keeps writing) land in a fresh buffer rather than competing with
|
|
13114
|
+
* the in-flight one.
|
|
13115
|
+
*/
|
|
13116
|
+
async flushCoalesceBuffer() {
|
|
13117
|
+
if (this.coalesceTimer) {
|
|
13118
|
+
clearTimeout(this.coalesceTimer);
|
|
13119
|
+
this.coalesceTimer = null;
|
|
13120
|
+
}
|
|
13121
|
+
if (this.coalesceMaxHoldTimer) {
|
|
13122
|
+
clearTimeout(this.coalesceMaxHoldTimer);
|
|
13123
|
+
this.coalesceMaxHoldTimer = null;
|
|
13124
|
+
}
|
|
13125
|
+
if (this.coalesceBuffer.size === 0) return;
|
|
13126
|
+
const entries = Array.from(this.coalesceBuffer.values());
|
|
13127
|
+
this.coalesceBuffer.clear();
|
|
13128
|
+
for (const entry of entries) {
|
|
13129
|
+
if (this.stopped) return;
|
|
13130
|
+
await this.emitForFile(entry.absPath, entry.changeType);
|
|
13131
|
+
}
|
|
13132
|
+
}
|
|
13047
13133
|
/**
|
|
13048
13134
|
* Visible for tests — lets vitest pump a synthetic file event
|
|
13049
13135
|
* through the debounce + diff + emit pipeline without spinning up
|
|
@@ -19106,7 +19192,7 @@ function checkChokidar() {
|
|
|
19106
19192
|
}
|
|
19107
19193
|
async function doctor(args2 = []) {
|
|
19108
19194
|
const json = args2.includes("--json");
|
|
19109
|
-
const cliVersion = true ? "2.23.
|
|
19195
|
+
const cliVersion = true ? "2.23.34" : "0.0.0-dev";
|
|
19110
19196
|
const apiBase = resolveApiBaseUrl();
|
|
19111
19197
|
const diagnosticId = (0, import_node_crypto6.randomUUID)();
|
|
19112
19198
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -19305,7 +19391,7 @@ async function completion(args2) {
|
|
|
19305
19391
|
// src/commands/version.ts
|
|
19306
19392
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
19307
19393
|
function version2() {
|
|
19308
|
-
const v = true ? "2.23.
|
|
19394
|
+
const v = true ? "2.23.34" : "unknown";
|
|
19309
19395
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
19310
19396
|
}
|
|
19311
19397
|
|
|
@@ -19533,7 +19619,7 @@ function checkForUpdates() {
|
|
|
19533
19619
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
19534
19620
|
if (process.env.CI) return;
|
|
19535
19621
|
if (!process.stdout.isTTY) return;
|
|
19536
|
-
const current = true ? "2.23.
|
|
19622
|
+
const current = true ? "2.23.34" : null;
|
|
19537
19623
|
if (!current) return;
|
|
19538
19624
|
const cache = readCache();
|
|
19539
19625
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.23.
|
|
3
|
+
"version": "2.23.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",
|