codeam-cli 2.60.19 → 2.60.20
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 +20 -0
- package/dist/index.js +111 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ 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.19] — 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Baton — pre-mint Cursor session id via `create-chat`
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
|
|
15
|
+
- **cli:** De-flake adapter module-graph gate — crash synchronously in settling fixture
|
|
16
|
+
|
|
17
|
+
## [2.60.18] — 2026-07-09
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **cli:** Auto-install Kimi on local pair when the binary is missing
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **cli:** Baton — discover Kimi's self-minted session id after spawn
|
|
26
|
+
|
|
7
27
|
## [2.60.17] — 2026-07-09
|
|
8
28
|
|
|
9
29
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5680,7 +5680,7 @@ function readAnonId() {
|
|
|
5680
5680
|
}
|
|
5681
5681
|
function superProperties() {
|
|
5682
5682
|
return {
|
|
5683
|
-
cliVersion: true ? "2.60.
|
|
5683
|
+
cliVersion: true ? "2.60.20" : "0.0.0-dev",
|
|
5684
5684
|
nodeVersion: process.version,
|
|
5685
5685
|
platform: process.platform,
|
|
5686
5686
|
arch: process.arch,
|
|
@@ -5861,7 +5861,7 @@ var os4 = __toESM(require("os"));
|
|
|
5861
5861
|
// package.json
|
|
5862
5862
|
var package_default = {
|
|
5863
5863
|
name: "codeam-cli",
|
|
5864
|
-
version: "2.60.
|
|
5864
|
+
version: "2.60.20",
|
|
5865
5865
|
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.",
|
|
5866
5866
|
type: "commonjs",
|
|
5867
5867
|
main: "dist/index.js",
|
|
@@ -6932,7 +6932,7 @@ var CommandRelayService = class {
|
|
|
6932
6932
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6933
6933
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6934
6934
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6935
|
-
..."2.60.
|
|
6935
|
+
..."2.60.20" ? { ideVersion: "2.60.20" } : {}
|
|
6936
6936
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6937
6937
|
}
|
|
6938
6938
|
/**
|
|
@@ -9089,7 +9089,7 @@ function findGitRoot2(startDir) {
|
|
|
9089
9089
|
}
|
|
9090
9090
|
|
|
9091
9091
|
// src/commands/link.ts
|
|
9092
|
-
var
|
|
9092
|
+
var import_node_crypto8 = require("crypto");
|
|
9093
9093
|
var fs30 = __toESM(require("fs"));
|
|
9094
9094
|
var path34 = __toESM(require("path"));
|
|
9095
9095
|
var import_chokidar = __toESM(require("chokidar"));
|
|
@@ -13444,7 +13444,70 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13444
13444
|
var fs23 = __toESM(require("fs"));
|
|
13445
13445
|
var os21 = __toESM(require("os"));
|
|
13446
13446
|
var path27 = __toESM(require("path"));
|
|
13447
|
+
var import_node_crypto5 = require("crypto");
|
|
13447
13448
|
var HISTORY_ROOT = path27.join(os21.homedir(), ".cursor", "projects");
|
|
13449
|
+
var CURSOR_HOME = path27.join(os21.homedir(), ".cursor");
|
|
13450
|
+
var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
|
|
13451
|
+
function acpSessionDir(sessionId) {
|
|
13452
|
+
return path27.join(CURSOR_HOME, "acp-sessions", sessionId);
|
|
13453
|
+
}
|
|
13454
|
+
function nativeStoreDir(cwd, sessionId) {
|
|
13455
|
+
const chatsRoot = path27.join(CURSOR_HOME, "chats");
|
|
13456
|
+
let buckets = [];
|
|
13457
|
+
try {
|
|
13458
|
+
buckets = fs23.readdirSync(chatsRoot);
|
|
13459
|
+
} catch {
|
|
13460
|
+
}
|
|
13461
|
+
for (const b of buckets) {
|
|
13462
|
+
const candidate = path27.join(chatsRoot, b, sessionId);
|
|
13463
|
+
if (fs23.existsSync(path27.join(candidate, "store.db"))) return candidate;
|
|
13464
|
+
}
|
|
13465
|
+
const computed = path27.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
13466
|
+
return fs23.existsSync(computed) ? computed : null;
|
|
13467
|
+
}
|
|
13468
|
+
function copyStoreFiles(srcDir, dstDir) {
|
|
13469
|
+
fs23.mkdirSync(dstDir, { recursive: true });
|
|
13470
|
+
for (const f of STORE_FILES) {
|
|
13471
|
+
const dst = path27.join(dstDir, f);
|
|
13472
|
+
if (fs23.existsSync(dst)) fs23.rmSync(dst, { force: true });
|
|
13473
|
+
}
|
|
13474
|
+
for (const f of STORE_FILES) {
|
|
13475
|
+
const src = path27.join(srcDir, f);
|
|
13476
|
+
if (fs23.existsSync(src)) fs23.copyFileSync(src, path27.join(dstDir, f));
|
|
13477
|
+
}
|
|
13478
|
+
}
|
|
13479
|
+
function bridgeNativeToAcp(cwd, sessionId) {
|
|
13480
|
+
try {
|
|
13481
|
+
const src = nativeStoreDir(cwd, sessionId);
|
|
13482
|
+
if (!src) {
|
|
13483
|
+
log.warn("cursor", `baton bridge: no native store for ${sessionId.slice(0, 8)} \u2014 skip`);
|
|
13484
|
+
return;
|
|
13485
|
+
}
|
|
13486
|
+
const dst = acpSessionDir(sessionId);
|
|
13487
|
+
copyStoreFiles(src, dst);
|
|
13488
|
+
fs23.writeFileSync(
|
|
13489
|
+
path27.join(dst, "meta.json"),
|
|
13490
|
+
JSON.stringify({ schemaVersion: 1, cwd })
|
|
13491
|
+
);
|
|
13492
|
+
log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
|
|
13493
|
+
} catch (err) {
|
|
13494
|
+
log.warn("cursor", `baton bridge native\u2192acp failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13495
|
+
}
|
|
13496
|
+
}
|
|
13497
|
+
function bridgeAcpToNative(cwd, sessionId) {
|
|
13498
|
+
try {
|
|
13499
|
+
const src = acpSessionDir(sessionId);
|
|
13500
|
+
if (!fs23.existsSync(path27.join(src, "store.db"))) {
|
|
13501
|
+
log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
|
|
13502
|
+
return;
|
|
13503
|
+
}
|
|
13504
|
+
const dst = nativeStoreDir(cwd, sessionId) ?? path27.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
13505
|
+
copyStoreFiles(src, dst);
|
|
13506
|
+
log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
|
|
13507
|
+
} catch (err) {
|
|
13508
|
+
log.warn("cursor", `baton bridge acp\u2192native failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13509
|
+
}
|
|
13510
|
+
}
|
|
13448
13511
|
function encodeCursorCwd(cwd) {
|
|
13449
13512
|
return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
|
|
13450
13513
|
}
|
|
@@ -13685,6 +13748,25 @@ var CursorRuntimeStrategy = class {
|
|
|
13685
13748
|
parseHistoryFile(filePath) {
|
|
13686
13749
|
return parseHistoryFile3(filePath);
|
|
13687
13750
|
}
|
|
13751
|
+
/**
|
|
13752
|
+
* Baton Take Control (native TUI → mobile ACP). Cursor keeps native-TUI
|
|
13753
|
+
* conversations in `~/.cursor/chats/<md5(cwd)>/<id>` but ACP `session/load`
|
|
13754
|
+
* only reads `~/.cursor/acp-sessions/<id>` — so without this, loading the
|
|
13755
|
+
* native session id fails "not found". Bridge the native store into the ACP
|
|
13756
|
+
* store just before the load. Best-effort; verified live (identical
|
|
13757
|
+
* `blobs`+`meta` SQLite schema, raw file copy replays the conversation).
|
|
13758
|
+
*/
|
|
13759
|
+
async syncTranscriptForAcpResume(cwd, sessionId) {
|
|
13760
|
+
bridgeNativeToAcp(cwd, sessionId);
|
|
13761
|
+
}
|
|
13762
|
+
/**
|
|
13763
|
+
* Baton hand-back (mobile ACP → native TUI). Copy the ACP conversation store
|
|
13764
|
+
* back into the native `~/.cursor/chats` store so `cursor-agent --resume <id>`
|
|
13765
|
+
* in the terminal picks up whatever mobile did. Best-effort.
|
|
13766
|
+
*/
|
|
13767
|
+
async syncTranscriptForNativeResume(cwd, sessionId) {
|
|
13768
|
+
bridgeAcpToNative(cwd, sessionId);
|
|
13769
|
+
}
|
|
13688
13770
|
getCurrentUsage(historyDir) {
|
|
13689
13771
|
return getCurrentUsage3(historyDir);
|
|
13690
13772
|
}
|
|
@@ -13957,7 +14039,7 @@ var AiderRuntimeStrategy = class {
|
|
|
13957
14039
|
};
|
|
13958
14040
|
|
|
13959
14041
|
// src/agents/gemini/runtime.ts
|
|
13960
|
-
var
|
|
14042
|
+
var import_node_crypto6 = require("crypto");
|
|
13961
14043
|
|
|
13962
14044
|
// src/agents/gemini/link.ts
|
|
13963
14045
|
var import_node_child_process12 = require("child_process");
|
|
@@ -14222,7 +14304,7 @@ var GeminiRuntimeStrategy = class {
|
|
|
14222
14304
|
"Gemini CLI is not on PATH. Install it with:\n npm install -g @google/gemini-cli\n Then run `codeam pair` again."
|
|
14223
14305
|
);
|
|
14224
14306
|
}
|
|
14225
|
-
const sessionId = (0,
|
|
14307
|
+
const sessionId = (0, import_node_crypto6.randomUUID)();
|
|
14226
14308
|
const launch = this.os.buildLaunch(binary, ["--session-id", sessionId]);
|
|
14227
14309
|
log.info(
|
|
14228
14310
|
"gemini",
|
|
@@ -14329,12 +14411,12 @@ var import_node_path4 = require("path");
|
|
|
14329
14411
|
var fs29 = __toESM(require("fs"));
|
|
14330
14412
|
var os26 = __toESM(require("os"));
|
|
14331
14413
|
var path33 = __toESM(require("path"));
|
|
14332
|
-
var
|
|
14414
|
+
var import_node_crypto7 = require("crypto");
|
|
14333
14415
|
function kimiHome() {
|
|
14334
14416
|
return process.env.KIMI_CODE_HOME || path33.join(os26.homedir(), ".kimi-code");
|
|
14335
14417
|
}
|
|
14336
14418
|
function workDirKey(cwd) {
|
|
14337
|
-
const hash = (0,
|
|
14419
|
+
const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
|
|
14338
14420
|
return `wd_${path33.basename(cwd)}_${hash}`;
|
|
14339
14421
|
}
|
|
14340
14422
|
function resolveHistoryDir6(cwd) {
|
|
@@ -14727,9 +14809,9 @@ async function link(args2 = []) {
|
|
|
14727
14809
|
await linkDryRunPreflight(ctx);
|
|
14728
14810
|
return;
|
|
14729
14811
|
}
|
|
14730
|
-
const pluginId = (0,
|
|
14731
|
-
const pollSecret = (0,
|
|
14732
|
-
const pluginSecretHash = (0,
|
|
14812
|
+
const pluginId = (0, import_node_crypto8.randomUUID)();
|
|
14813
|
+
const pollSecret = (0, import_node_crypto8.randomBytes)(32).toString("base64url");
|
|
14814
|
+
const pluginSecretHash = (0, import_node_crypto8.createHash)("sha256").update(pollSecret).digest("hex");
|
|
14733
14815
|
const spin = dist_exports.spinner();
|
|
14734
14816
|
spin.start("Requesting pairing code...");
|
|
14735
14817
|
const pairing = await requestCode(pluginId, pluginSecretHash);
|
|
@@ -16560,7 +16642,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16560
16642
|
if (process.env.NODE_ENV === "test") return;
|
|
16561
16643
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16562
16644
|
if (process.env.CI) return;
|
|
16563
|
-
const current = true ? "2.60.
|
|
16645
|
+
const current = true ? "2.60.20" : null;
|
|
16564
16646
|
if (!current) return;
|
|
16565
16647
|
const cache = readCache();
|
|
16566
16648
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16577,7 +16659,7 @@ function checkForUpdates() {
|
|
|
16577
16659
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16578
16660
|
if (process.env.CI) return;
|
|
16579
16661
|
if (!process.stdout.isTTY) return;
|
|
16580
|
-
const current = true ? "2.60.
|
|
16662
|
+
const current = true ? "2.60.20" : null;
|
|
16581
16663
|
if (!current) return;
|
|
16582
16664
|
const cache = readCache();
|
|
16583
16665
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16597,7 +16679,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16597
16679
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16598
16680
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16599
16681
|
function currentCliVersion() {
|
|
16600
|
-
return true ? "2.60.
|
|
16682
|
+
return true ? "2.60.20" : null;
|
|
16601
16683
|
}
|
|
16602
16684
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16603
16685
|
return new Promise((resolve7) => {
|
|
@@ -22431,7 +22513,7 @@ function requiresAcp(agent) {
|
|
|
22431
22513
|
}
|
|
22432
22514
|
|
|
22433
22515
|
// src/agents/acp/runner.ts
|
|
22434
|
-
var
|
|
22516
|
+
var import_node_crypto10 = require("crypto");
|
|
22435
22517
|
|
|
22436
22518
|
// src/services/history.service.ts
|
|
22437
22519
|
var fs55 = __toESM(require("fs"));
|
|
@@ -26632,7 +26714,7 @@ async function runOnboardingTurn(opts) {
|
|
|
26632
26714
|
}
|
|
26633
26715
|
|
|
26634
26716
|
// src/agents/acp/mappers.ts
|
|
26635
|
-
var
|
|
26717
|
+
var import_node_crypto9 = require("crypto");
|
|
26636
26718
|
function mapSessionUpdate(notification) {
|
|
26637
26719
|
const update = notification.update;
|
|
26638
26720
|
switch (update.sessionUpdate) {
|
|
@@ -26695,7 +26777,7 @@ function mapPermissionRequest(request) {
|
|
|
26695
26777
|
}
|
|
26696
26778
|
return {
|
|
26697
26779
|
event: {
|
|
26698
|
-
questionId: (0,
|
|
26780
|
+
questionId: (0, import_node_crypto9.randomUUID)(),
|
|
26699
26781
|
prompt,
|
|
26700
26782
|
options: labels.length > 0 ? labels : void 0
|
|
26701
26783
|
},
|
|
@@ -26705,7 +26787,7 @@ function mapPermissionRequest(request) {
|
|
|
26705
26787
|
}
|
|
26706
26788
|
function messageChunkId(messageId) {
|
|
26707
26789
|
if (typeof messageId === "string" && messageId.length > 0) return messageId;
|
|
26708
|
-
return (0,
|
|
26790
|
+
return (0, import_node_crypto9.randomUUID)();
|
|
26709
26791
|
}
|
|
26710
26792
|
function extractText4(content) {
|
|
26711
26793
|
if (!content || typeof content !== "object") return null;
|
|
@@ -28518,7 +28600,7 @@ var AcpHistory = class {
|
|
|
28518
28600
|
this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
|
|
28519
28601
|
}
|
|
28520
28602
|
this.messages.push({
|
|
28521
|
-
id: (0,
|
|
28603
|
+
id: (0, import_node_crypto10.randomUUID)(),
|
|
28522
28604
|
role: "user",
|
|
28523
28605
|
text,
|
|
28524
28606
|
timestamp: Date.now()
|
|
@@ -28527,7 +28609,7 @@ var AcpHistory = class {
|
|
|
28527
28609
|
appendAgentReply(text) {
|
|
28528
28610
|
if (text.length === 0) return;
|
|
28529
28611
|
this.messages.push({
|
|
28530
|
-
id: (0,
|
|
28612
|
+
id: (0, import_node_crypto10.randomUUID)(),
|
|
28531
28613
|
role: "agent",
|
|
28532
28614
|
text,
|
|
28533
28615
|
timestamp: Date.now()
|
|
@@ -28733,7 +28815,7 @@ async function runAcpSession(opts) {
|
|
|
28733
28815
|
currentIndex: 0,
|
|
28734
28816
|
done: true
|
|
28735
28817
|
}),
|
|
28736
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
28818
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto10.randomUUID)(), prompt, options }),
|
|
28737
28819
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
28738
28820
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
28739
28821
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -30041,6 +30123,7 @@ var NativeTuiDriver = class {
|
|
|
30041
30123
|
keepAliveCtx;
|
|
30042
30124
|
async start(resumeId) {
|
|
30043
30125
|
if (resumeId !== void 0) {
|
|
30126
|
+
await this.deps.runtime.syncTranscriptForNativeResume?.(this.deps.opts.cwd, resumeId);
|
|
30044
30127
|
await this.agent.restart(resumeId, false);
|
|
30045
30128
|
return resumeId;
|
|
30046
30129
|
}
|
|
@@ -30099,7 +30182,7 @@ var NativeTuiDriver = class {
|
|
|
30099
30182
|
};
|
|
30100
30183
|
|
|
30101
30184
|
// src/baton/acp-driver.ts
|
|
30102
|
-
var
|
|
30185
|
+
var import_node_crypto11 = require("crypto");
|
|
30103
30186
|
var AcpDriver = class {
|
|
30104
30187
|
constructor(deps) {
|
|
30105
30188
|
this.deps = deps;
|
|
@@ -30121,6 +30204,7 @@ var AcpDriver = class {
|
|
|
30121
30204
|
try {
|
|
30122
30205
|
started = await this.deps.client.start();
|
|
30123
30206
|
if (resumeId !== void 0) {
|
|
30207
|
+
await this.deps.runtime.syncTranscriptForAcpResume?.(this.deps.opts.cwd, resumeId);
|
|
30124
30208
|
this.deps.streaming.beginLoadReplay();
|
|
30125
30209
|
try {
|
|
30126
30210
|
await this.deps.client.loadSession(resumeId);
|
|
@@ -30192,7 +30276,7 @@ var AcpDriver = class {
|
|
|
30192
30276
|
currentIndex: 0,
|
|
30193
30277
|
done: true
|
|
30194
30278
|
}),
|
|
30195
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
30279
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto11.randomUUID)(), prompt, options }),
|
|
30196
30280
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
30197
30281
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
30198
30282
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -33287,7 +33371,7 @@ async function invite() {
|
|
|
33287
33371
|
// src/commands/doctor.ts
|
|
33288
33372
|
var import_node_dns = require("dns");
|
|
33289
33373
|
var import_node_util5 = require("util");
|
|
33290
|
-
var
|
|
33374
|
+
var import_node_crypto12 = require("crypto");
|
|
33291
33375
|
var fs62 = __toESM(require("fs"));
|
|
33292
33376
|
var path69 = __toESM(require("path"));
|
|
33293
33377
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
@@ -33457,9 +33541,9 @@ function checkChokidar() {
|
|
|
33457
33541
|
}
|
|
33458
33542
|
async function doctor(args2 = []) {
|
|
33459
33543
|
const json = args2.includes("--json");
|
|
33460
|
-
const cliVersion = true ? "2.60.
|
|
33544
|
+
const cliVersion = true ? "2.60.20" : "0.0.0-dev";
|
|
33461
33545
|
const apiBase2 = resolveApiBaseUrl();
|
|
33462
|
-
const diagnosticId = (0,
|
|
33546
|
+
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
33463
33547
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
33464
33548
|
const [dns, health] = await Promise.all([
|
|
33465
33549
|
checkDns(apiBase2),
|
|
@@ -33656,7 +33740,7 @@ async function completion(args2) {
|
|
|
33656
33740
|
// src/commands/version.ts
|
|
33657
33741
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33658
33742
|
function version2() {
|
|
33659
|
-
const v = true ? "2.60.
|
|
33743
|
+
const v = true ? "2.60.20" : "unknown";
|
|
33660
33744
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33661
33745
|
}
|
|
33662
33746
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.20",
|
|
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",
|