codeam-cli 2.75.9 → 2.75.11
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 +139 -39
- 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.10] — 2026-09-23
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Guardrails judge a write by its target; pack stage shows a mid-turn permission as awaiting
|
|
12
|
+
|
|
13
|
+
## [2.75.9] — 2026-09-23
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Agent packs — structured Reviewer findings, in-place resume, rehydration after restart
|
|
18
|
+
|
|
7
19
|
## [2.75.8] — 2026-09-23
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -10509,7 +10509,7 @@ function readAnonId() {
|
|
|
10509
10509
|
}
|
|
10510
10510
|
function superProperties() {
|
|
10511
10511
|
return {
|
|
10512
|
-
cliVersion: true ? "2.75.
|
|
10512
|
+
cliVersion: true ? "2.75.11" : "0.0.0-dev",
|
|
10513
10513
|
nodeVersion: process.version,
|
|
10514
10514
|
platform: process.platform,
|
|
10515
10515
|
arch: process.arch,
|
|
@@ -10751,7 +10751,7 @@ var http = __toESM(require("http"));
|
|
|
10751
10751
|
// package.json
|
|
10752
10752
|
var package_default = {
|
|
10753
10753
|
name: "codeam-cli",
|
|
10754
|
-
version: "2.75.
|
|
10754
|
+
version: "2.75.11",
|
|
10755
10755
|
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.",
|
|
10756
10756
|
type: "commonjs",
|
|
10757
10757
|
main: "dist/index.js",
|
|
@@ -12081,7 +12081,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12081
12081
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12082
12082
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12083
12083
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12084
|
-
..."2.75.
|
|
12084
|
+
..."2.75.11" ? { ideVersion: "2.75.11" } : {}
|
|
12085
12085
|
};
|
|
12086
12086
|
try {
|
|
12087
12087
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -33795,7 +33795,7 @@ function internalPathPermissionOutcome(request2, homeDir2) {
|
|
|
33795
33795
|
var INTERNAL_BLOCK_REASON = "This path is a CodeAgent platform internal (CodeAgent's own runtime plumbing, not part of the user's project) and is off-limits. Continue with the user's own project files.";
|
|
33796
33796
|
|
|
33797
33797
|
// src/agents/acp/guardrails.ts
|
|
33798
|
-
var SECRET_RE = /(^|[\s"'`=(/\\])(\.env(\.[\w.-]+)?|[\w.-]+\.(pem|key|pfx|p12|jks|keystore)|id_rsa|id_ed25519|\.npmrc|\.pgpass|\.netrc|\.git-credentials|kubeconfig
|
|
33798
|
+
var SECRET_RE = /(^|[\s"'`=(/\\])(\.env(\.[\w.-]+)?|[\w.-]+\.(pem|key|pfx|p12|jks|keystore)|id_rsa|id_ed25519|\.npmrc|\.pgpass|\.netrc|\.git-credentials|kubeconfig|\.credentials(\.[\w-]+)?)\b|[/\\]credentials(\.[\w-]+)?\b/i;
|
|
33799
33799
|
var DESTRUCTIVE_RES = [
|
|
33800
33800
|
/\brm\s+-[a-z]*f/i,
|
|
33801
33801
|
// rm -rf / -fr / -f
|
|
@@ -33821,6 +33821,15 @@ var OUTWARD_RES = [
|
|
|
33821
33821
|
/\bnetlify\s+deploy\b/i,
|
|
33822
33822
|
/\beas\s+(submit|build)\b/i
|
|
33823
33823
|
];
|
|
33824
|
+
function editTargetHaystack(call) {
|
|
33825
|
+
const parts = [typeof call.title === "string" ? call.title : ""];
|
|
33826
|
+
if (call.rawInput && typeof call.rawInput === "object" && !Array.isArray(call.rawInput)) {
|
|
33827
|
+
for (const [key, value] of Object.entries(call.rawInput)) {
|
|
33828
|
+
if (typeof value === "string" && /path|file|dest|target/i.test(key)) parts.push(value);
|
|
33829
|
+
}
|
|
33830
|
+
}
|
|
33831
|
+
return parts.join("\n");
|
|
33832
|
+
}
|
|
33824
33833
|
function haystack(call) {
|
|
33825
33834
|
let s = typeof call.title === "string" ? call.title : "";
|
|
33826
33835
|
if (call.rawInput != null) {
|
|
@@ -33849,7 +33858,7 @@ function toolPathIsSecret(p2) {
|
|
|
33849
33858
|
var GUARDRAIL_SECRET_READ_BLOCK_REASON = "Reading this secret file is blocked by this session's guardrails (Reading secrets = Deny). Adjust it in the session Guardrails settings if intended.";
|
|
33850
33859
|
function guardrailDecision(request2, policy) {
|
|
33851
33860
|
if (isProseOnlyToolKind(request2.toolCall.kind)) return null;
|
|
33852
|
-
const hay = haystack(request2.toolCall);
|
|
33861
|
+
const hay = request2.toolCall.kind === "edit" ? editTargetHaystack(request2.toolCall) : haystack(request2.toolCall);
|
|
33853
33862
|
if (!hay) return null;
|
|
33854
33863
|
const matched = matchedCategories(hay);
|
|
33855
33864
|
if (matched.size === 0) return null;
|
|
@@ -33873,7 +33882,11 @@ function guardrailDecision(request2, policy) {
|
|
|
33873
33882
|
};
|
|
33874
33883
|
}
|
|
33875
33884
|
if (confirmCat) {
|
|
33876
|
-
return {
|
|
33885
|
+
return {
|
|
33886
|
+
kind: "confirm",
|
|
33887
|
+
category: confirmCat,
|
|
33888
|
+
reason: GUARDRAIL_CATEGORY_META[confirmCat].description
|
|
33889
|
+
};
|
|
33877
33890
|
}
|
|
33878
33891
|
return null;
|
|
33879
33892
|
}
|
|
@@ -35563,6 +35576,18 @@ function _get(url2, headers) {
|
|
|
35563
35576
|
}
|
|
35564
35577
|
|
|
35565
35578
|
// src/agents/acp/publisher.ts
|
|
35579
|
+
var STREAMING_CHUNK_SNAPSHOT_MAX_CHARS = 56 * 1024;
|
|
35580
|
+
var STREAMING_CHUNK_COALESCE_MIN_CHARS = 8 * 1024;
|
|
35581
|
+
var STREAMING_CHUNK_COALESCE_WINDOW_MS = 300;
|
|
35582
|
+
function boundStreamingChunkContent(content, max = STREAMING_CHUNK_SNAPSHOT_MAX_CHARS) {
|
|
35583
|
+
if (content.length <= max) return { content, truncated: false };
|
|
35584
|
+
const dropped = content.length - max;
|
|
35585
|
+
return {
|
|
35586
|
+
content: `${content.slice(0, max)}
|
|
35587
|
+
\u2026 [output truncated: ${dropped} more characters \u2014 the full text is in the conversation transcript]`,
|
|
35588
|
+
truncated: true
|
|
35589
|
+
};
|
|
35590
|
+
}
|
|
35566
35591
|
var AcpPublisher = class {
|
|
35567
35592
|
constructor(opts) {
|
|
35568
35593
|
this.opts = opts;
|
|
@@ -35572,6 +35597,11 @@ var AcpPublisher = class {
|
|
|
35572
35597
|
opts;
|
|
35573
35598
|
apiBase;
|
|
35574
35599
|
token;
|
|
35600
|
+
/** chunkIds whose truncated snapshot already went out — nothing new to show
|
|
35601
|
+
* until the terminal frame. */
|
|
35602
|
+
truncatedChunks = /* @__PURE__ */ new Set();
|
|
35603
|
+
lastChunkPostAt = /* @__PURE__ */ new Map();
|
|
35604
|
+
pendingChunkPosts = /* @__PURE__ */ new Map();
|
|
35575
35605
|
/** Latched on an unrecoverable 401/403 — every surface stops posting
|
|
35576
35606
|
* (2026-06-28 incident: a dead-token publisher spammed 401 ×34 while
|
|
35577
35607
|
* the agent's replies silently never reached the phone). */
|
|
@@ -35600,7 +35630,10 @@ var AcpPublisher = class {
|
|
|
35600
35630
|
const fresh = await this.opts.refreshAuthToken();
|
|
35601
35631
|
if (fresh) {
|
|
35602
35632
|
this.token = fresh;
|
|
35603
|
-
log.info(
|
|
35633
|
+
log.info(
|
|
35634
|
+
"acpPublisher",
|
|
35635
|
+
`plugin-auth token refreshed after ${first.statusCode}; retrying POST`
|
|
35636
|
+
);
|
|
35604
35637
|
const second = await _transport4.post(url2, this.authHeaders(), payload);
|
|
35605
35638
|
if (second.statusCode !== 401 && second.statusCode !== 403) return second;
|
|
35606
35639
|
this.markPairingInvalid(second.statusCode);
|
|
@@ -35709,17 +35742,51 @@ var AcpPublisher = class {
|
|
|
35709
35742
|
* richer SessionDetail surface.
|
|
35710
35743
|
*/
|
|
35711
35744
|
async publishStreamingChunk(event) {
|
|
35745
|
+
const { chunkId, isFinal } = event;
|
|
35746
|
+
const pending = this.pendingChunkPosts.get(chunkId);
|
|
35747
|
+
if (pending) {
|
|
35748
|
+
clearTimeout(pending.timer);
|
|
35749
|
+
this.pendingChunkPosts.delete(chunkId);
|
|
35750
|
+
}
|
|
35751
|
+
const bounded = boundStreamingChunkContent(event.content);
|
|
35752
|
+
if (bounded.truncated) {
|
|
35753
|
+
if (!isFinal && this.truncatedChunks.has(chunkId)) return;
|
|
35754
|
+
if (!this.truncatedChunks.has(chunkId)) {
|
|
35755
|
+
log.warn(
|
|
35756
|
+
"acpPublisher",
|
|
35757
|
+
`streaming-chunk ${chunkId.slice(0, 12)} (${event.kind}) exceeds ${STREAMING_CHUNK_SNAPSHOT_MAX_CHARS} chars \u2014 sending a truncated snapshot once`
|
|
35758
|
+
);
|
|
35759
|
+
}
|
|
35760
|
+
this.truncatedChunks.add(chunkId);
|
|
35761
|
+
}
|
|
35762
|
+
if (isFinal) {
|
|
35763
|
+
this.truncatedChunks.delete(chunkId);
|
|
35764
|
+
this.lastChunkPostAt.delete(chunkId);
|
|
35765
|
+
} else if (!bounded.truncated && bounded.content.length >= STREAMING_CHUNK_COALESCE_MIN_CHARS) {
|
|
35766
|
+
const last = this.lastChunkPostAt.get(chunkId) ?? 0;
|
|
35767
|
+
const wait = STREAMING_CHUNK_COALESCE_WINDOW_MS - (Date.now() - last);
|
|
35768
|
+
if (wait > 0) {
|
|
35769
|
+
const timer = setTimeout(() => {
|
|
35770
|
+
const latest = this.pendingChunkPosts.get(chunkId);
|
|
35771
|
+
this.pendingChunkPosts.delete(chunkId);
|
|
35772
|
+
if (latest) void this.postStreamingChunk(latest.event);
|
|
35773
|
+
}, wait);
|
|
35774
|
+
this.pendingChunkPosts.set(chunkId, { timer, event });
|
|
35775
|
+
return;
|
|
35776
|
+
}
|
|
35777
|
+
}
|
|
35778
|
+
await this.postStreamingChunk({ ...event, content: bounded.content });
|
|
35779
|
+
}
|
|
35780
|
+
async postStreamingChunk(event) {
|
|
35712
35781
|
const url2 = `${this.apiBase}/api/sessions/${encodeURIComponent(this.opts.sessionId)}/streaming-chunk`;
|
|
35782
|
+
if (!event.isFinal) this.lastChunkPostAt.set(event.chunkId, Date.now());
|
|
35713
35783
|
try {
|
|
35714
35784
|
const { statusCode, body } = await this.postWithReauth(
|
|
35715
35785
|
url2,
|
|
35716
35786
|
this.envelope(event)
|
|
35717
35787
|
);
|
|
35718
35788
|
if (statusCode < 200 || statusCode >= 300) {
|
|
35719
|
-
log.warn(
|
|
35720
|
-
"acpPublisher",
|
|
35721
|
-
`streaming-chunk status=${statusCode} body=${body.slice(0, 200)}`
|
|
35722
|
-
);
|
|
35789
|
+
log.warn("acpPublisher", `streaming-chunk status=${statusCode} body=${body.slice(0, 200)}`);
|
|
35723
35790
|
}
|
|
35724
35791
|
} catch (err) {
|
|
35725
35792
|
log.trace("acpPublisher", "streaming-chunk post failed", err);
|
|
@@ -38054,7 +38121,7 @@ var PackRunner = class _PackRunner {
|
|
|
38054
38121
|
previousAttemptError
|
|
38055
38122
|
});
|
|
38056
38123
|
const displayLine = `\u25B6 ${this.pack.name} \u2014 stage ${index + 1}/${this.pack.stages.length}: ${stageDef.name}`;
|
|
38057
|
-
turn = await this.drive(prompt, displayLine);
|
|
38124
|
+
turn = await this.drive(prompt, displayLine, index);
|
|
38058
38125
|
}
|
|
38059
38126
|
if (this.aborted()) {
|
|
38060
38127
|
await this.settle("aborted");
|
|
@@ -38069,7 +38136,7 @@ var PackRunner = class _PackRunner {
|
|
|
38069
38136
|
return this.recordHandoff(
|
|
38070
38137
|
index,
|
|
38071
38138
|
stageDef,
|
|
38072
|
-
await this.noChangeHandoff(startSha, text, startedMs)
|
|
38139
|
+
await this.noChangeHandoff(stageDef, startSha, text, startedMs)
|
|
38073
38140
|
);
|
|
38074
38141
|
}
|
|
38075
38142
|
if (!this.state.stages[index].conversationId) {
|
|
@@ -38078,7 +38145,7 @@ var PackRunner = class _PackRunner {
|
|
|
38078
38145
|
"stage produced no commit \u2014 Retry stage to run it again in a fresh conversation"
|
|
38079
38146
|
);
|
|
38080
38147
|
}
|
|
38081
|
-
const nudged = await this.drive(NUDGE_PROMPT, "\u25B6 Waiting for the stage commit\u2026");
|
|
38148
|
+
const nudged = await this.drive(NUDGE_PROMPT, "\u25B6 Waiting for the stage commit\u2026", index);
|
|
38082
38149
|
if (this.aborted()) {
|
|
38083
38150
|
await this.settle("aborted");
|
|
38084
38151
|
return false;
|
|
@@ -38091,7 +38158,7 @@ var PackRunner = class _PackRunner {
|
|
|
38091
38158
|
return this.recordHandoff(
|
|
38092
38159
|
index,
|
|
38093
38160
|
stageDef,
|
|
38094
|
-
await this.noChangeHandoff(startSha, text, startedMs)
|
|
38161
|
+
await this.noChangeHandoff(stageDef, startSha, text, startedMs)
|
|
38095
38162
|
);
|
|
38096
38163
|
}
|
|
38097
38164
|
return this.stall(index, "stage produced no commit", text);
|
|
@@ -38123,10 +38190,13 @@ var PackRunner = class _PackRunner {
|
|
|
38123
38190
|
aborted() {
|
|
38124
38191
|
return this.control === "abort";
|
|
38125
38192
|
}
|
|
38126
|
-
async drive(prompt, displayLine) {
|
|
38193
|
+
async drive(prompt, displayLine, index) {
|
|
38127
38194
|
this.inTurn = true;
|
|
38128
38195
|
try {
|
|
38129
|
-
return await this.deps.driver.runTurn(prompt, displayLine)
|
|
38196
|
+
return await this.deps.driver.runTurn(prompt, displayLine, (pending) => {
|
|
38197
|
+
this.patchStage(index, { awaitingUser: pending ? true : void 0 });
|
|
38198
|
+
void this.publish();
|
|
38199
|
+
});
|
|
38130
38200
|
} finally {
|
|
38131
38201
|
this.inTurn = false;
|
|
38132
38202
|
}
|
|
@@ -38138,13 +38208,19 @@ var PackRunner = class _PackRunner {
|
|
|
38138
38208
|
if (fresh.length > 0) this.deps.driver.mountSkills(fresh);
|
|
38139
38209
|
this.mountedSkills = next.slice();
|
|
38140
38210
|
}
|
|
38141
|
-
async noChangeHandoff(startSha, text, startedMs) {
|
|
38211
|
+
async noChangeHandoff(stageDef, startSha, text, startedMs) {
|
|
38142
38212
|
const reviewedCommit = startSha ? await this.deps.gates.canonicalCommit(startSha) : null;
|
|
38143
38213
|
return {
|
|
38144
38214
|
commit: reviewedCommit ?? "(no changes)",
|
|
38145
38215
|
summary: summarizeReply(text),
|
|
38146
38216
|
diffStat: "reviewed \u2014 no changes needed",
|
|
38147
|
-
durationMs: Date.now() - startedMs
|
|
38217
|
+
durationMs: Date.now() - startedMs,
|
|
38218
|
+
// A findings-producing stage that hands off without a commit never
|
|
38219
|
+
// wrote its findings file (its contract says: commit it even when
|
|
38220
|
+
// empty). Say so — the next stage must not assume a clean bill.
|
|
38221
|
+
...stageDef.producesFindings ? {
|
|
38222
|
+
findingsNote: `no ${PACK_FINDINGS_FILE} committed \u2014 the stage handed off without structured findings`
|
|
38223
|
+
} : {}
|
|
38148
38224
|
};
|
|
38149
38225
|
}
|
|
38150
38226
|
/**
|
|
@@ -38253,15 +38329,20 @@ function buildPackRunnerDeps(ctx) {
|
|
|
38253
38329
|
ctx.onActiveSessionChanged?.(id);
|
|
38254
38330
|
return id;
|
|
38255
38331
|
},
|
|
38256
|
-
runTurn: async (prompt, displayLine) => {
|
|
38332
|
+
runTurn: async (prompt, displayLine, onAwaiting) => {
|
|
38257
38333
|
await ctx.streaming.beginTurn();
|
|
38258
38334
|
ctx.history.appendUserPrompt(displayLine);
|
|
38259
|
-
|
|
38260
|
-
|
|
38261
|
-
|
|
38262
|
-
|
|
38263
|
-
|
|
38264
|
-
|
|
38335
|
+
ctx.streaming.setPendingListener(onAwaiting ?? null);
|
|
38336
|
+
try {
|
|
38337
|
+
await ctx.client.prompt(prompt);
|
|
38338
|
+
const text = ctx.streaming.getCurrentText();
|
|
38339
|
+
const awaitingUser = await ctx.streaming.closeTurnWithInteractiveDetection();
|
|
38340
|
+
ctx.history.appendAgentReply(text);
|
|
38341
|
+
await ctx.history.flush();
|
|
38342
|
+
return { text, awaitingUser };
|
|
38343
|
+
} finally {
|
|
38344
|
+
ctx.streaming.setPendingListener(null);
|
|
38345
|
+
}
|
|
38265
38346
|
},
|
|
38266
38347
|
cancel: () => ctx.client.cancel(),
|
|
38267
38348
|
mountSkills: (skillIds) => {
|
|
@@ -40064,6 +40145,25 @@ var StreamingState = class {
|
|
|
40064
40145
|
*/
|
|
40065
40146
|
text = "";
|
|
40066
40147
|
pending = null;
|
|
40148
|
+
/** Observer for "is a question pending?" flips. The Agent Packs runner marks
|
|
40149
|
+
* its stage `awaitingUser` while a permission prompt waits on the user
|
|
40150
|
+
* MID-turn, instead of a stage that looks silently "working" for the 5-min
|
|
40151
|
+
* permission TTL (live run 2026-09-23). Never throws into the turn. */
|
|
40152
|
+
pendingListener = null;
|
|
40153
|
+
setPendingListener(listener) {
|
|
40154
|
+
this.pendingListener = listener;
|
|
40155
|
+
}
|
|
40156
|
+
setPending(next) {
|
|
40157
|
+
const was = this.pending !== null;
|
|
40158
|
+
this.pending = next;
|
|
40159
|
+
const is = next !== null;
|
|
40160
|
+
if (was !== is) {
|
|
40161
|
+
try {
|
|
40162
|
+
this.pendingListener?.(is);
|
|
40163
|
+
} catch {
|
|
40164
|
+
}
|
|
40165
|
+
}
|
|
40166
|
+
}
|
|
40067
40167
|
/**
|
|
40068
40168
|
* While true, {@link append} drops incoming session/update deltas instead of
|
|
40069
40169
|
* publishing them. Used by the baton {@link AcpDriver} to swallow the
|
|
@@ -40166,7 +40266,7 @@ var StreamingState = class {
|
|
|
40166
40266
|
"acpRunner",
|
|
40167
40267
|
`permission ${args2.questionId.slice(0, 8)} TTL expired \u2014 auto-cancel`
|
|
40168
40268
|
);
|
|
40169
|
-
this.
|
|
40269
|
+
this.setPending(null);
|
|
40170
40270
|
void this.publisher.publishOutput({
|
|
40171
40271
|
type: "text",
|
|
40172
40272
|
content: permissionExpiredNotice(),
|
|
@@ -40175,13 +40275,13 @@ var StreamingState = class {
|
|
|
40175
40275
|
resolve11({ outcome: { outcome: "cancelled" } });
|
|
40176
40276
|
}
|
|
40177
40277
|
}, PERMISSION_TIMEOUT_MS);
|
|
40178
|
-
this.
|
|
40278
|
+
this.setPending({
|
|
40179
40279
|
kind: "permission",
|
|
40180
40280
|
questionId: args2.questionId,
|
|
40181
40281
|
options: args2.options,
|
|
40182
40282
|
resolve: resolve11,
|
|
40183
40283
|
timeoutTimer
|
|
40184
|
-
};
|
|
40284
|
+
});
|
|
40185
40285
|
});
|
|
40186
40286
|
}
|
|
40187
40287
|
/**
|
|
@@ -40190,7 +40290,7 @@ var StreamingState = class {
|
|
|
40190
40290
|
* `resolveSelection()` (user picked).
|
|
40191
40291
|
*/
|
|
40192
40292
|
registerFreeformOptions(options) {
|
|
40193
|
-
this.
|
|
40293
|
+
this.setPending({ kind: "free-form", options });
|
|
40194
40294
|
}
|
|
40195
40295
|
/**
|
|
40196
40296
|
* Apply a `select_option` command (delivered via the CLI's SSE
|
|
@@ -40217,7 +40317,7 @@ var StreamingState = class {
|
|
|
40217
40317
|
const picked = byId ?? this.pending.options[index];
|
|
40218
40318
|
clearTimeout(this.pending.timeoutTimer);
|
|
40219
40319
|
const resolve11 = this.pending.resolve;
|
|
40220
|
-
this.
|
|
40320
|
+
this.setPending(null);
|
|
40221
40321
|
if (!picked) {
|
|
40222
40322
|
log.warn("acpRunner", `select_option index=${index} out of bounds \u2014 cancel`);
|
|
40223
40323
|
resolve11({ outcome: { outcome: "cancelled" } });
|
|
@@ -40227,7 +40327,7 @@ var StreamingState = class {
|
|
|
40227
40327
|
return { kind: "resolved", optionId: picked.optionId };
|
|
40228
40328
|
}
|
|
40229
40329
|
const text = this.pending.options[index];
|
|
40230
|
-
this.
|
|
40330
|
+
this.setPending(null);
|
|
40231
40331
|
if (!text) {
|
|
40232
40332
|
log.warn("acpRunner", `select_option index=${index} out of bounds (free-form) \u2014 drop`);
|
|
40233
40333
|
return { kind: "none" };
|
|
@@ -40283,7 +40383,7 @@ var StreamingState = class {
|
|
|
40283
40383
|
if (this.pending?.kind === "permission") {
|
|
40284
40384
|
clearTimeout(this.pending.timeoutTimer);
|
|
40285
40385
|
}
|
|
40286
|
-
this.
|
|
40386
|
+
this.setPending(null);
|
|
40287
40387
|
if (opts?.clear !== false) {
|
|
40288
40388
|
await this.publisher.publishOutput({ type: "clear" });
|
|
40289
40389
|
}
|
|
@@ -40470,7 +40570,7 @@ var StreamingState = class {
|
|
|
40470
40570
|
done: true
|
|
40471
40571
|
});
|
|
40472
40572
|
}
|
|
40473
|
-
this.
|
|
40573
|
+
this.setPending({ kind: "free-form", options: extracted.options });
|
|
40474
40574
|
await this.publisher.publishOutput({
|
|
40475
40575
|
type: "select_prompt",
|
|
40476
40576
|
content: extracted.question ?? "Pick an option",
|
|
@@ -47014,7 +47114,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
47014
47114
|
if (process.env.NODE_ENV === "test") return;
|
|
47015
47115
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47016
47116
|
if (process.env.CI) return;
|
|
47017
|
-
const current2 = true ? "2.75.
|
|
47117
|
+
const current2 = true ? "2.75.11" : null;
|
|
47018
47118
|
if (!current2) return;
|
|
47019
47119
|
const cache = readCache();
|
|
47020
47120
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47031,7 +47131,7 @@ function checkForUpdates() {
|
|
|
47031
47131
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47032
47132
|
if (process.env.CI) return;
|
|
47033
47133
|
if (!process.stdout.isTTY) return;
|
|
47034
|
-
const current2 = true ? "2.75.
|
|
47134
|
+
const current2 = true ? "2.75.11" : null;
|
|
47035
47135
|
if (!current2) return;
|
|
47036
47136
|
const cache = readCache();
|
|
47037
47137
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47054,7 +47154,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
47054
47154
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
47055
47155
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
47056
47156
|
function currentCliVersion() {
|
|
47057
|
-
return true ? "2.75.
|
|
47157
|
+
return true ? "2.75.11" : null;
|
|
47058
47158
|
}
|
|
47059
47159
|
async function installedVersion(deps) {
|
|
47060
47160
|
const ls = await deps.run(
|
|
@@ -48794,7 +48894,7 @@ function checkChokidar() {
|
|
|
48794
48894
|
}
|
|
48795
48895
|
async function doctor(args2 = []) {
|
|
48796
48896
|
const json = args2.includes("--json");
|
|
48797
|
-
const cliVersion = true ? "2.75.
|
|
48897
|
+
const cliVersion = true ? "2.75.11" : "0.0.0-dev";
|
|
48798
48898
|
const apiBase2 = resolveApiBaseUrl();
|
|
48799
48899
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
48800
48900
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -49318,7 +49418,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
49318
49418
|
// src/commands/version.ts
|
|
49319
49419
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
49320
49420
|
function version2() {
|
|
49321
|
-
const v = true ? "2.75.
|
|
49421
|
+
const v = true ? "2.75.11" : "unknown";
|
|
49322
49422
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
49323
49423
|
}
|
|
49324
49424
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.11",
|
|
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",
|