codeam-cli 2.60.64 → 2.60.65
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 +10 -0
- package/dist/index.js +45 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ 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.60.64] — 2026-07-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Add Slack search:read scope (agent can search the user's messages)
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- **shared:** Clarify Slack uses a USER token (agent acts as the user)
|
|
16
|
+
|
|
7
17
|
## [2.60.63] — 2026-07-15
|
|
8
18
|
|
|
9
19
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5891,7 +5891,7 @@ function readAnonId() {
|
|
|
5891
5891
|
}
|
|
5892
5892
|
function superProperties() {
|
|
5893
5893
|
return {
|
|
5894
|
-
cliVersion: true ? "2.60.
|
|
5894
|
+
cliVersion: true ? "2.60.65" : "0.0.0-dev",
|
|
5895
5895
|
nodeVersion: process.version,
|
|
5896
5896
|
platform: process.platform,
|
|
5897
5897
|
arch: process.arch,
|
|
@@ -6072,7 +6072,7 @@ var os4 = __toESM(require("os"));
|
|
|
6072
6072
|
// package.json
|
|
6073
6073
|
var package_default = {
|
|
6074
6074
|
name: "codeam-cli",
|
|
6075
|
-
version: "2.60.
|
|
6075
|
+
version: "2.60.65",
|
|
6076
6076
|
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.",
|
|
6077
6077
|
type: "commonjs",
|
|
6078
6078
|
main: "dist/index.js",
|
|
@@ -6840,7 +6840,7 @@ function httpStatusOf(err) {
|
|
|
6840
6840
|
var API_BASE2 = resolveApiBaseUrl();
|
|
6841
6841
|
var SSE_LIVENESS_TIMEOUT_MS = 45e3;
|
|
6842
6842
|
var SSE_WATCHDOG_INTERVAL_MS = 1e4;
|
|
6843
|
-
var CommandRelayService = class {
|
|
6843
|
+
var CommandRelayService = class _CommandRelayService {
|
|
6844
6844
|
constructor(pluginId, onCommand, agentMeta, agentsOverride) {
|
|
6845
6845
|
this.pluginId = pluginId;
|
|
6846
6846
|
this.onCommand = onCommand;
|
|
@@ -6862,6 +6862,16 @@ var CommandRelayService = class {
|
|
|
6862
6862
|
agentsRegistered = false;
|
|
6863
6863
|
/** SSE connection (null when on the polling fallback or stopped). */
|
|
6864
6864
|
sseRequest = null;
|
|
6865
|
+
// At-least-once delivery: the backend now delivers commands NON-DESTRUCTIVELY
|
|
6866
|
+
// (peek) when we advertise `X-Codeam-Cmd-Ack: 1`, and drains the queue only
|
|
6867
|
+
// when we ack the ids. So a command can never be lost to a ghost/racing SSE
|
|
6868
|
+
// subscriber during codespace boot (the 2026-07-15 first-prompt loss). The
|
|
6869
|
+
// trade-off is possible REDELIVERY (reconnect, publish re-fire, ghost race),
|
|
6870
|
+
// so we dedupe by id here — a bounded FIFO set of ids we've already
|
|
6871
|
+
// dispatched. Cap keeps memory flat over a long session; the oldest ids are
|
|
6872
|
+
// evicted (a command that old is long gone from the server queue anyway).
|
|
6873
|
+
processedIds = /* @__PURE__ */ new Set();
|
|
6874
|
+
static PROCESSED_ID_CAP = 1e3;
|
|
6865
6875
|
/** Polling backoff state (only used on the fallback). */
|
|
6866
6876
|
pollTimer = null;
|
|
6867
6877
|
pollFailures = 0;
|
|
@@ -7131,14 +7141,15 @@ var CommandRelayService = class {
|
|
|
7131
7141
|
// as X-Plugin-Poll-Secret. Empty {} for legacy sessions / older
|
|
7132
7142
|
// backends (which ignore it).
|
|
7133
7143
|
pollSecretHeader() {
|
|
7144
|
+
const headers = { "X-Codeam-Cmd-Ack": "1" };
|
|
7134
7145
|
try {
|
|
7135
7146
|
const secret = loadCliConfig().sessions.find(
|
|
7136
7147
|
(s) => s.pluginId === this.pluginId
|
|
7137
7148
|
)?.pollSecret;
|
|
7138
|
-
|
|
7149
|
+
if (secret) headers["X-Plugin-Poll-Secret"] = secret;
|
|
7139
7150
|
} catch {
|
|
7140
|
-
return {};
|
|
7141
7151
|
}
|
|
7152
|
+
return headers;
|
|
7142
7153
|
}
|
|
7143
7154
|
async pollOnce() {
|
|
7144
7155
|
try {
|
|
@@ -7161,7 +7172,13 @@ var CommandRelayService = class {
|
|
|
7161
7172
|
}
|
|
7162
7173
|
}
|
|
7163
7174
|
async dispatchCommands(commands) {
|
|
7175
|
+
this.ackCommands(commands.map((c2) => c2.id));
|
|
7164
7176
|
for (const cmd of commands) {
|
|
7177
|
+
if (cmd.id && this.processedIds.has(cmd.id)) {
|
|
7178
|
+
log.trace("relay", `dedupe skip already-dispatched id=${cmd.id}`);
|
|
7179
|
+
continue;
|
|
7180
|
+
}
|
|
7181
|
+
if (cmd.id) this.rememberProcessed(cmd.id);
|
|
7165
7182
|
try {
|
|
7166
7183
|
log.trace("relay", `dispatch type=${cmd.type} id=${cmd.id}`);
|
|
7167
7184
|
await this.onCommand(cmd);
|
|
@@ -7170,6 +7187,23 @@ var CommandRelayService = class {
|
|
|
7170
7187
|
}
|
|
7171
7188
|
}
|
|
7172
7189
|
}
|
|
7190
|
+
/** Record a dispatched id, evicting the oldest when over the cap (FIFO). */
|
|
7191
|
+
rememberProcessed(id) {
|
|
7192
|
+
this.processedIds.add(id);
|
|
7193
|
+
if (this.processedIds.size > _CommandRelayService.PROCESSED_ID_CAP) {
|
|
7194
|
+
const oldest = this.processedIds.values().next().value;
|
|
7195
|
+
if (oldest !== void 0) this.processedIds.delete(oldest);
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
/** Confirm receipt of command ids so the backend removes them from the queue
|
|
7199
|
+
* (the at-least-once delivery guarantee). Best-effort — never throws. */
|
|
7200
|
+
ackCommands(ids) {
|
|
7201
|
+
const commandIds = ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
7202
|
+
if (commandIds.length === 0) return;
|
|
7203
|
+
void _postJson(`${API_BASE2}/api/commands/ack`, { pluginId: this.pluginId, commandIds }, {
|
|
7204
|
+
...this.pollSecretHeader()
|
|
7205
|
+
}).catch((err) => log.trace("relay", "ack post failed (will redeliver+dedupe)", err));
|
|
7206
|
+
}
|
|
7173
7207
|
// ─── Heartbeat + agents ──────────────────────────────────────────
|
|
7174
7208
|
async sendHeartbeat(online) {
|
|
7175
7209
|
await _postJson(`${API_BASE2}/api/plugin/heartbeat`, {
|
|
@@ -7181,7 +7215,7 @@ var CommandRelayService = class {
|
|
|
7181
7215
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7182
7216
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7183
7217
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7184
|
-
..."2.60.
|
|
7218
|
+
..."2.60.65" ? { ideVersion: "2.60.65" } : {}
|
|
7185
7219
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7186
7220
|
}
|
|
7187
7221
|
/**
|
|
@@ -17758,7 +17792,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17758
17792
|
if (process.env.NODE_ENV === "test") return;
|
|
17759
17793
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17760
17794
|
if (process.env.CI) return;
|
|
17761
|
-
const current = true ? "2.60.
|
|
17795
|
+
const current = true ? "2.60.65" : null;
|
|
17762
17796
|
if (!current) return;
|
|
17763
17797
|
const cache = readCache();
|
|
17764
17798
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17775,7 +17809,7 @@ function checkForUpdates() {
|
|
|
17775
17809
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17776
17810
|
if (process.env.CI) return;
|
|
17777
17811
|
if (!process.stdout.isTTY) return;
|
|
17778
|
-
const current = true ? "2.60.
|
|
17812
|
+
const current = true ? "2.60.65" : null;
|
|
17779
17813
|
if (!current) return;
|
|
17780
17814
|
const cache = readCache();
|
|
17781
17815
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17795,7 +17829,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17795
17829
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17796
17830
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17797
17831
|
function currentCliVersion() {
|
|
17798
|
-
return true ? "2.60.
|
|
17832
|
+
return true ? "2.60.65" : null;
|
|
17799
17833
|
}
|
|
17800
17834
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17801
17835
|
return new Promise((resolve7) => {
|
|
@@ -35224,7 +35258,7 @@ function checkChokidar() {
|
|
|
35224
35258
|
}
|
|
35225
35259
|
async function doctor(args2 = []) {
|
|
35226
35260
|
const json = args2.includes("--json");
|
|
35227
|
-
const cliVersion = true ? "2.60.
|
|
35261
|
+
const cliVersion = true ? "2.60.65" : "0.0.0-dev";
|
|
35228
35262
|
const apiBase2 = resolveApiBaseUrl();
|
|
35229
35263
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
35230
35264
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -35701,7 +35735,7 @@ async function mcpRun(args2) {
|
|
|
35701
35735
|
// src/commands/version.ts
|
|
35702
35736
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
35703
35737
|
function version2() {
|
|
35704
|
-
const v = true ? "2.60.
|
|
35738
|
+
const v = true ? "2.60.65" : "unknown";
|
|
35705
35739
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
35706
35740
|
}
|
|
35707
35741
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.65",
|
|
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",
|