codeam-cli 2.60.17 → 2.60.19
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 +157 -57
- 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.60.17] — 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Auto-install Kimi on local pair when the binary is missing
|
|
12
|
+
|
|
13
|
+
## [2.60.16] — 2026-07-09
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Session Baton support for Kimi Code (local Take Control)
|
|
18
|
+
|
|
7
19
|
## [2.60.15] — 2026-07-09
|
|
8
20
|
|
|
9
21
|
### Fixed
|
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.19" : "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.19",
|
|
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.19" ? { ideVersion: "2.60.19" } : {}
|
|
6936
6936
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6937
6937
|
}
|
|
6938
6938
|
/**
|
|
@@ -13601,6 +13601,8 @@ function detectCursorSelector(lines) {
|
|
|
13601
13601
|
}
|
|
13602
13602
|
|
|
13603
13603
|
// src/agents/cursor/runtime.ts
|
|
13604
|
+
var import_node_child_process10 = require("child_process");
|
|
13605
|
+
var UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
13604
13606
|
var CURSOR_CONTEXT_WINDOW = 2e5;
|
|
13605
13607
|
var CURSOR_MODELS = [
|
|
13606
13608
|
{ id: "cursor-default", label: "Cursor (auto)", contextWindow: CURSOR_CONTEXT_WINDOW },
|
|
@@ -13622,12 +13624,54 @@ var CursorRuntimeStrategy = class {
|
|
|
13622
13624
|
'Cursor Agent CLI ("cursor-agent") is not on PATH.\n Install Cursor (https://cursor.com/), enable its CLI plugin,\n then run `codeam pair` again.'
|
|
13623
13625
|
);
|
|
13624
13626
|
}
|
|
13625
|
-
|
|
13627
|
+
const sessionId = this.mintChatId(binary);
|
|
13628
|
+
if (sessionId) {
|
|
13629
|
+
const launch2 = this.os.buildLaunch(binary, ["--resume", sessionId]);
|
|
13630
|
+
return { cmd: launch2.cmd, args: launch2.args, sessionId };
|
|
13631
|
+
}
|
|
13632
|
+
const launch = this.os.buildLaunch(binary);
|
|
13633
|
+
return { cmd: launch.cmd, args: launch.args };
|
|
13634
|
+
}
|
|
13635
|
+
/**
|
|
13636
|
+
* Pre-create an empty, resumable Cursor chat and return its id, or null on any
|
|
13637
|
+
* failure. `cursor-agent create-chat` prints a bare UUID and exits 0 (verified
|
|
13638
|
+
* on cursor-agent 2026.06.24). Synchronous + bounded so prepareLaunch stays a
|
|
13639
|
+
* single deterministic step; a timeout/parse failure just disables pre-mint.
|
|
13640
|
+
*/
|
|
13641
|
+
mintChatId(binary) {
|
|
13642
|
+
try {
|
|
13643
|
+
const r = (0, import_node_child_process10.spawnSync)(binary, ["create-chat"], {
|
|
13644
|
+
encoding: "utf8",
|
|
13645
|
+
timeout: 2e4,
|
|
13646
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
13647
|
+
});
|
|
13648
|
+
if (r.status !== 0 || r.error) {
|
|
13649
|
+
log.warn("cursor", `create-chat failed (status=${r.status}) \u2014 baton id pre-mint skipped`);
|
|
13650
|
+
return null;
|
|
13651
|
+
}
|
|
13652
|
+
const id = (r.stdout ?? "").match(UUID_RE)?.[0] ?? null;
|
|
13653
|
+
if (!id) log.warn("cursor", "create-chat produced no chat id \u2014 baton id pre-mint skipped");
|
|
13654
|
+
return id;
|
|
13655
|
+
} catch (err) {
|
|
13656
|
+
log.warn("cursor", `create-chat threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
13657
|
+
return null;
|
|
13658
|
+
}
|
|
13626
13659
|
}
|
|
13627
13660
|
/** Cursor mirrors Claude's `--resume <id>` flag for session resume. */
|
|
13628
13661
|
resumeLaunchArgs(sessionId, _opts) {
|
|
13629
13662
|
return ["--resume", sessionId];
|
|
13630
13663
|
}
|
|
13664
|
+
/**
|
|
13665
|
+
* Resume as a COMPLETE relaunch (mirrors Claude). The initial spawn already
|
|
13666
|
+
* carries `--resume <preMintedId>` from {@link prepareLaunch}, so appending
|
|
13667
|
+
* `resumeLaunchArgs` onto `initialLaunch.args` would emit a duplicate
|
|
13668
|
+
* `--resume … --resume …`. Rebuild a clean `--resume <id>` launch instead.
|
|
13669
|
+
*/
|
|
13670
|
+
prepareResumeLaunch(sessionId, opts) {
|
|
13671
|
+
const binary = this.os.findInPath("cursor-agent") ?? this.meta.binaryName;
|
|
13672
|
+
const launch = this.os.buildLaunch(binary, this.resumeLaunchArgs(sessionId, opts));
|
|
13673
|
+
return { cmd: launch.cmd, args: launch.args };
|
|
13674
|
+
}
|
|
13631
13675
|
resolveHistoryDir(cwd) {
|
|
13632
13676
|
return resolveHistoryDir3(cwd);
|
|
13633
13677
|
}
|
|
@@ -13714,7 +13758,7 @@ function getCurrentUsage4(_historyDir) {
|
|
|
13714
13758
|
}
|
|
13715
13759
|
|
|
13716
13760
|
// src/agents/aider/link.ts
|
|
13717
|
-
var
|
|
13761
|
+
var import_node_child_process11 = require("child_process");
|
|
13718
13762
|
|
|
13719
13763
|
// src/agents/aider/local-token.ts
|
|
13720
13764
|
var fs26 = __toESM(require("fs"));
|
|
@@ -13772,7 +13816,7 @@ function aiderLoginLauncher(os49) {
|
|
|
13772
13816
|
console.error(
|
|
13773
13817
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
13774
13818
|
);
|
|
13775
|
-
return (0,
|
|
13819
|
+
return (0, import_node_child_process11.spawn)(os49.id === "win32" ? "cmd.exe" : "sh", os49.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
13776
13820
|
stdio: "ignore"
|
|
13777
13821
|
});
|
|
13778
13822
|
}
|
|
@@ -13916,7 +13960,7 @@ var AiderRuntimeStrategy = class {
|
|
|
13916
13960
|
var import_node_crypto5 = require("crypto");
|
|
13917
13961
|
|
|
13918
13962
|
// src/agents/gemini/link.ts
|
|
13919
|
-
var
|
|
13963
|
+
var import_node_child_process12 = require("child_process");
|
|
13920
13964
|
|
|
13921
13965
|
// src/agents/gemini/local-token.ts
|
|
13922
13966
|
var fs27 = __toESM(require("fs"));
|
|
@@ -13981,7 +14025,7 @@ function geminiLoginLauncher() {
|
|
|
13981
14025
|
return os49.findInPath("gemini") !== null;
|
|
13982
14026
|
},
|
|
13983
14027
|
launch() {
|
|
13984
|
-
return (0,
|
|
14028
|
+
return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
13985
14029
|
}
|
|
13986
14030
|
};
|
|
13987
14031
|
}
|
|
@@ -14277,7 +14321,7 @@ var GeminiRuntimeStrategy = class {
|
|
|
14277
14321
|
};
|
|
14278
14322
|
|
|
14279
14323
|
// src/agents/kimi/runtime.ts
|
|
14280
|
-
var
|
|
14324
|
+
var import_node_child_process13 = require("child_process");
|
|
14281
14325
|
var import_node_os3 = require("os");
|
|
14282
14326
|
var import_node_path4 = require("path");
|
|
14283
14327
|
|
|
@@ -14347,6 +14391,44 @@ function scanBucketsForSession(sessionId) {
|
|
|
14347
14391
|
}
|
|
14348
14392
|
return null;
|
|
14349
14393
|
}
|
|
14394
|
+
async function discoverSessionId(cwd, opts) {
|
|
14395
|
+
const bucket = path33.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
14396
|
+
const floor = opts.sinceMs - 2e3;
|
|
14397
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
|
|
14398
|
+
for (; ; ) {
|
|
14399
|
+
const id = newestSessionSince(bucket, floor);
|
|
14400
|
+
if (id) return id;
|
|
14401
|
+
if (Date.now() >= deadline) return null;
|
|
14402
|
+
await sleep2(250);
|
|
14403
|
+
}
|
|
14404
|
+
}
|
|
14405
|
+
function newestSessionSince(bucket, floorMs) {
|
|
14406
|
+
let entries;
|
|
14407
|
+
try {
|
|
14408
|
+
entries = fs29.readdirSync(bucket, { withFileTypes: true });
|
|
14409
|
+
} catch {
|
|
14410
|
+
return null;
|
|
14411
|
+
}
|
|
14412
|
+
let bestId = null;
|
|
14413
|
+
let bestMtime = -1;
|
|
14414
|
+
for (const e of entries) {
|
|
14415
|
+
if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
|
|
14416
|
+
let mtime;
|
|
14417
|
+
try {
|
|
14418
|
+
mtime = fs29.statSync(path33.join(bucket, e.name)).mtimeMs;
|
|
14419
|
+
} catch {
|
|
14420
|
+
continue;
|
|
14421
|
+
}
|
|
14422
|
+
if (mtime >= floorMs && mtime > bestMtime) {
|
|
14423
|
+
bestMtime = mtime;
|
|
14424
|
+
bestId = e.name;
|
|
14425
|
+
}
|
|
14426
|
+
}
|
|
14427
|
+
return bestId;
|
|
14428
|
+
}
|
|
14429
|
+
function sleep2(ms) {
|
|
14430
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
14431
|
+
}
|
|
14350
14432
|
function joinTextParts(parts) {
|
|
14351
14433
|
if (!Array.isArray(parts)) return "";
|
|
14352
14434
|
return parts.filter((p2) => p2 && p2.type === "text" && typeof p2.text === "string").map((p2) => p2.text).join("").trim();
|
|
@@ -14456,6 +14538,19 @@ var KimiRuntimeStrategy = class {
|
|
|
14456
14538
|
parseHistoryFile(filePath) {
|
|
14457
14539
|
return parseHistoryFile6(filePath);
|
|
14458
14540
|
}
|
|
14541
|
+
/**
|
|
14542
|
+
* Kimi neither accepts a pre-set session id (`kimi -S <newid>` fails
|
|
14543
|
+
* "Session not found") NOR prints its id on stdout — it MINTS one itself and
|
|
14544
|
+
* writes it to `<KIMI_CODE_HOME>/sessions/wd_<key>/<sessionId>/` when the
|
|
14545
|
+
* native TUI boots. So `prepareLaunch` can't return a `sessionId` and the
|
|
14546
|
+
* baton's NativeTuiDriver has nothing to bind. This hook bounded-polls that
|
|
14547
|
+
* store for the dir kimi just created (mtime ≥ spawn time) and returns its id.
|
|
14548
|
+
* Kimi-specific — no other agent implements this (claude pre-mints; the rest
|
|
14549
|
+
* have no baton), so the driver's optional call is inert for them.
|
|
14550
|
+
*/
|
|
14551
|
+
discoverSessionId(cwd, opts) {
|
|
14552
|
+
return discoverSessionId(cwd, opts);
|
|
14553
|
+
}
|
|
14459
14554
|
getCurrentUsage(historyDir) {
|
|
14460
14555
|
return getCurrentUsage5(historyDir);
|
|
14461
14556
|
}
|
|
@@ -14516,7 +14611,7 @@ var KimiRuntimeStrategy = class {
|
|
|
14516
14611
|
return createOsStrategy().findInPath("kimi") !== null;
|
|
14517
14612
|
},
|
|
14518
14613
|
launch() {
|
|
14519
|
-
return (0,
|
|
14614
|
+
return (0, import_node_child_process13.spawn)("kimi", [], { stdio: "inherit" });
|
|
14520
14615
|
}
|
|
14521
14616
|
};
|
|
14522
14617
|
}
|
|
@@ -14949,7 +15044,7 @@ async function linkDryRunPreflight(ctx) {
|
|
|
14949
15044
|
}
|
|
14950
15045
|
|
|
14951
15046
|
// src/commands/host-agent.ts
|
|
14952
|
-
var
|
|
15047
|
+
var import_node_child_process21 = require("child_process");
|
|
14953
15048
|
var os34 = __toESM(require("os"));
|
|
14954
15049
|
var fs40 = __toESM(require("fs"));
|
|
14955
15050
|
var path42 = __toESM(require("path"));
|
|
@@ -14962,7 +15057,7 @@ var path35 = __toESM(require("path"));
|
|
|
14962
15057
|
// src/lib/restrict-to-owner.ts
|
|
14963
15058
|
var import_node_fs5 = __toESM(require("fs"));
|
|
14964
15059
|
var import_node_os4 = __toESM(require("os"));
|
|
14965
|
-
var
|
|
15060
|
+
var import_node_child_process14 = require("child_process");
|
|
14966
15061
|
var BROAD_WINDOWS_SIDS = [
|
|
14967
15062
|
"*S-1-1-0",
|
|
14968
15063
|
"*S-1-5-11",
|
|
@@ -14974,7 +15069,7 @@ function restrictToOwner(filePath) {
|
|
|
14974
15069
|
try {
|
|
14975
15070
|
if (process.platform === "win32") {
|
|
14976
15071
|
const username = import_node_os4.default.userInfo().username;
|
|
14977
|
-
(0,
|
|
15072
|
+
(0, import_node_child_process14.execFileSync)(
|
|
14978
15073
|
"icacls",
|
|
14979
15074
|
[
|
|
14980
15075
|
filePath,
|
|
@@ -15236,9 +15331,9 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
15236
15331
|
var fs33 = __toESM(require("fs"));
|
|
15237
15332
|
var os29 = __toESM(require("os"));
|
|
15238
15333
|
var path36 = __toESM(require("path"));
|
|
15239
|
-
var
|
|
15334
|
+
var import_node_child_process15 = require("child_process");
|
|
15240
15335
|
var import_node_util4 = require("util");
|
|
15241
|
-
var execFileP4 = (0, import_node_util4.promisify)(
|
|
15336
|
+
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process15.execFile);
|
|
15242
15337
|
function isAbsolutePathTarget(target) {
|
|
15243
15338
|
return path36.isAbsolute(target);
|
|
15244
15339
|
}
|
|
@@ -15508,7 +15603,7 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
|
|
|
15508
15603
|
}
|
|
15509
15604
|
|
|
15510
15605
|
// src/commands/host/git-tooling.ts
|
|
15511
|
-
var
|
|
15606
|
+
var import_node_child_process16 = require("child_process");
|
|
15512
15607
|
var fs35 = __toESM(require("fs"));
|
|
15513
15608
|
var os31 = __toESM(require("os"));
|
|
15514
15609
|
var path38 = __toESM(require("path"));
|
|
@@ -15622,7 +15717,7 @@ var defaultGitToolingRunner = {
|
|
|
15622
15717
|
which(cmd) {
|
|
15623
15718
|
try {
|
|
15624
15719
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
15625
|
-
(0,
|
|
15720
|
+
(0, import_node_child_process16.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
15626
15721
|
return true;
|
|
15627
15722
|
} catch {
|
|
15628
15723
|
return false;
|
|
@@ -15630,7 +15725,7 @@ var defaultGitToolingRunner = {
|
|
|
15630
15725
|
},
|
|
15631
15726
|
run(cmd, args2, opts = {}) {
|
|
15632
15727
|
return new Promise((resolve7) => {
|
|
15633
|
-
const child = (0,
|
|
15728
|
+
const child = (0, import_node_child_process16.spawn)(cmd, args2, {
|
|
15634
15729
|
stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
|
|
15635
15730
|
});
|
|
15636
15731
|
let stderr = "";
|
|
@@ -15784,12 +15879,12 @@ var HeadroomStatsReporter = class {
|
|
|
15784
15879
|
};
|
|
15785
15880
|
|
|
15786
15881
|
// src/commands/host/os-packages.ts
|
|
15787
|
-
var
|
|
15882
|
+
var import_node_child_process17 = require("child_process");
|
|
15788
15883
|
var PM_INSTALL_TIMEOUT_MS = 18e4;
|
|
15789
15884
|
var defaultHeadroomRunner = {
|
|
15790
15885
|
which(cmd) {
|
|
15791
15886
|
try {
|
|
15792
|
-
(0,
|
|
15887
|
+
(0, import_node_child_process17.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
15793
15888
|
return true;
|
|
15794
15889
|
} catch {
|
|
15795
15890
|
return false;
|
|
@@ -15798,7 +15893,7 @@ var defaultHeadroomRunner = {
|
|
|
15798
15893
|
run(cmd, args2, opts = {}) {
|
|
15799
15894
|
return new Promise((resolve7) => {
|
|
15800
15895
|
const spawnEnv = opts.env ?? process.env;
|
|
15801
|
-
const child = (0,
|
|
15896
|
+
const child = (0, import_node_child_process17.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
|
|
15802
15897
|
let stderrBuf = "";
|
|
15803
15898
|
let stdoutBuf = "";
|
|
15804
15899
|
let settled = false;
|
|
@@ -16305,14 +16400,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
16305
16400
|
}
|
|
16306
16401
|
|
|
16307
16402
|
// src/commands/host/self-update.ts
|
|
16308
|
-
var
|
|
16403
|
+
var import_node_child_process19 = require("child_process");
|
|
16309
16404
|
|
|
16310
16405
|
// src/lib/updateNotifier.ts
|
|
16311
16406
|
var fs38 = __toESM(require("fs"));
|
|
16312
16407
|
var os33 = __toESM(require("os"));
|
|
16313
16408
|
var path41 = __toESM(require("path"));
|
|
16314
16409
|
var https6 = __toESM(require("https"));
|
|
16315
|
-
var
|
|
16410
|
+
var import_node_child_process18 = require("child_process");
|
|
16316
16411
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
16317
16412
|
var PKG_NAME = "codeam-cli";
|
|
16318
16413
|
var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
@@ -16406,7 +16501,7 @@ function notifyIfStale(currentVersion, latest) {
|
|
|
16406
16501
|
}
|
|
16407
16502
|
function isLinkedInstall() {
|
|
16408
16503
|
try {
|
|
16409
|
-
const root = (0,
|
|
16504
|
+
const root = (0, import_node_child_process18.execSync)("npm root -g", {
|
|
16410
16505
|
encoding: "utf8",
|
|
16411
16506
|
stdio: ["ignore", "pipe", "ignore"],
|
|
16412
16507
|
timeout: 2e3
|
|
@@ -16434,7 +16529,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16434
16529
|
|
|
16435
16530
|
`
|
|
16436
16531
|
);
|
|
16437
|
-
const install = (0,
|
|
16532
|
+
const install = (0, import_node_child_process18.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
|
|
16438
16533
|
stdio: "inherit",
|
|
16439
16534
|
env: process.env
|
|
16440
16535
|
});
|
|
@@ -16455,7 +16550,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16455
16550
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
16456
16551
|
|
|
16457
16552
|
`);
|
|
16458
|
-
const child = (0,
|
|
16553
|
+
const child = (0, import_node_child_process18.spawnSync)("codeam", process.argv.slice(2), {
|
|
16459
16554
|
stdio: "inherit",
|
|
16460
16555
|
env: process.env
|
|
16461
16556
|
});
|
|
@@ -16465,7 +16560,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16465
16560
|
if (process.env.NODE_ENV === "test") return;
|
|
16466
16561
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16467
16562
|
if (process.env.CI) return;
|
|
16468
|
-
const current = true ? "2.60.
|
|
16563
|
+
const current = true ? "2.60.19" : null;
|
|
16469
16564
|
if (!current) return;
|
|
16470
16565
|
const cache = readCache();
|
|
16471
16566
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16482,7 +16577,7 @@ function checkForUpdates() {
|
|
|
16482
16577
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16483
16578
|
if (process.env.CI) return;
|
|
16484
16579
|
if (!process.stdout.isTTY) return;
|
|
16485
|
-
const current = true ? "2.60.
|
|
16580
|
+
const current = true ? "2.60.19" : null;
|
|
16486
16581
|
if (!current) return;
|
|
16487
16582
|
const cache = readCache();
|
|
16488
16583
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16502,11 +16597,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16502
16597
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16503
16598
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16504
16599
|
function currentCliVersion() {
|
|
16505
|
-
return true ? "2.60.
|
|
16600
|
+
return true ? "2.60.19" : null;
|
|
16506
16601
|
}
|
|
16507
16602
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16508
16603
|
return new Promise((resolve7) => {
|
|
16509
|
-
(0,
|
|
16604
|
+
(0, import_node_child_process19.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
16510
16605
|
const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
|
|
16511
16606
|
resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
16512
16607
|
});
|
|
@@ -16568,11 +16663,11 @@ async function runSelfUpdate() {
|
|
|
16568
16663
|
}
|
|
16569
16664
|
|
|
16570
16665
|
// src/commands/host/teardown.ts
|
|
16571
|
-
var
|
|
16666
|
+
var import_node_child_process20 = require("child_process");
|
|
16572
16667
|
var fs39 = __toESM(require("fs"));
|
|
16573
16668
|
var defaultDisableService = () => {
|
|
16574
16669
|
try {
|
|
16575
|
-
(0,
|
|
16670
|
+
(0, import_node_child_process20.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
16576
16671
|
} catch {
|
|
16577
16672
|
}
|
|
16578
16673
|
};
|
|
@@ -16580,7 +16675,7 @@ var defaultTeardownHeadroom = () => {
|
|
|
16580
16675
|
try {
|
|
16581
16676
|
const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
16582
16677
|
if (kind) {
|
|
16583
|
-
(0,
|
|
16678
|
+
(0, import_node_child_process20.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
16584
16679
|
}
|
|
16585
16680
|
} catch {
|
|
16586
16681
|
}
|
|
@@ -16738,7 +16833,7 @@ var CONTROL_AGENT_META = {
|
|
|
16738
16833
|
headroomWrappable: false,
|
|
16739
16834
|
acp: false
|
|
16740
16835
|
};
|
|
16741
|
-
var defaultSpawner = (env, cwd, args2 = []) => (0,
|
|
16836
|
+
var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process21.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
|
|
16742
16837
|
cwd,
|
|
16743
16838
|
env: { ...process.env, ...env },
|
|
16744
16839
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -17218,7 +17313,7 @@ var HostAgentSupervisor = class {
|
|
|
17218
17313
|
runAgentInstall(script) {
|
|
17219
17314
|
return new Promise((resolve7) => {
|
|
17220
17315
|
const home = process.env.HOME || os34.homedir();
|
|
17221
|
-
const child = (0,
|
|
17316
|
+
const child = (0, import_node_child_process21.spawn)("sh", ["-c", script], {
|
|
17222
17317
|
env: { ...process.env, HOME: home },
|
|
17223
17318
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17224
17319
|
});
|
|
@@ -21624,7 +21719,7 @@ async function pairAuto(args2) {
|
|
|
21624
21719
|
}
|
|
21625
21720
|
|
|
21626
21721
|
// src/services/headroom/wrap-launch.ts
|
|
21627
|
-
var
|
|
21722
|
+
var import_node_child_process22 = require("child_process");
|
|
21628
21723
|
function wrapWithHeadroom(launch, opts) {
|
|
21629
21724
|
if (!opts.enabled || !opts.headroomPresent) return launch;
|
|
21630
21725
|
return {
|
|
@@ -21637,7 +21732,7 @@ var _present;
|
|
|
21637
21732
|
function headroomPresent() {
|
|
21638
21733
|
if (_present !== void 0) return Promise.resolve(_present);
|
|
21639
21734
|
return new Promise((resolve7) => {
|
|
21640
|
-
(0,
|
|
21735
|
+
(0, import_node_child_process22.execFile)("headroom", ["--version"], (err) => {
|
|
21641
21736
|
_present = !err;
|
|
21642
21737
|
resolve7(_present);
|
|
21643
21738
|
});
|
|
@@ -22034,7 +22129,7 @@ async function waitForClaudeNativeBinary(opts = {}) {
|
|
|
22034
22129
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22035
22130
|
const pollMs = opts.pollMs ?? 500;
|
|
22036
22131
|
const now = opts.now ?? Date.now;
|
|
22037
|
-
const
|
|
22132
|
+
const sleep4 = opts.sleep ?? realSleep;
|
|
22038
22133
|
const deps = {
|
|
22039
22134
|
sdkDir: opts.sdkDir,
|
|
22040
22135
|
platformKey: opts.platformKey,
|
|
@@ -22044,7 +22139,7 @@ async function waitForClaudeNativeBinary(opts = {}) {
|
|
|
22044
22139
|
let found = resolveClaudeNativeBinary(deps);
|
|
22045
22140
|
if (found) return found;
|
|
22046
22141
|
while (now() < deadline) {
|
|
22047
|
-
await
|
|
22142
|
+
await sleep4(pollMs);
|
|
22048
22143
|
found = resolveClaudeNativeBinary(deps);
|
|
22049
22144
|
if (found) return found;
|
|
22050
22145
|
}
|
|
@@ -22066,13 +22161,13 @@ async function waitForCommandOnPath(cmd, opts = {}) {
|
|
|
22066
22161
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22067
22162
|
const pollMs = opts.pollMs ?? 500;
|
|
22068
22163
|
const now = opts.now ?? Date.now;
|
|
22069
|
-
const
|
|
22164
|
+
const sleep4 = opts.sleep ?? realSleep;
|
|
22070
22165
|
const probe = opts.probe;
|
|
22071
22166
|
const check = () => isCommandOnPath(cmd, probe);
|
|
22072
22167
|
const deadline = now() + timeoutMs;
|
|
22073
22168
|
if (check()) return true;
|
|
22074
22169
|
while (now() < deadline) {
|
|
22075
|
-
await
|
|
22170
|
+
await sleep4(pollMs);
|
|
22076
22171
|
if (check()) return true;
|
|
22077
22172
|
}
|
|
22078
22173
|
return check();
|
|
@@ -22095,12 +22190,12 @@ async function waitForCursorAgent(opts = {}) {
|
|
|
22095
22190
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22096
22191
|
const pollMs = opts.pollMs ?? 500;
|
|
22097
22192
|
const now = opts.now ?? Date.now;
|
|
22098
|
-
const
|
|
22193
|
+
const sleep4 = opts.sleep ?? realSleep;
|
|
22099
22194
|
const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
|
|
22100
22195
|
const deadline = now() + timeoutMs;
|
|
22101
22196
|
if (check()) return true;
|
|
22102
22197
|
while (now() < deadline) {
|
|
22103
|
-
await
|
|
22198
|
+
await sleep4(pollMs);
|
|
22104
22199
|
if (check()) return true;
|
|
22105
22200
|
}
|
|
22106
22201
|
return check();
|
|
@@ -22149,19 +22244,19 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
22149
22244
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22150
22245
|
const pollMs = opts.pollMs ?? 500;
|
|
22151
22246
|
const now = opts.now ?? Date.now;
|
|
22152
|
-
const
|
|
22247
|
+
const sleep4 = opts.sleep ?? realSleep;
|
|
22153
22248
|
const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
|
|
22154
22249
|
const deadline = now() + timeoutMs;
|
|
22155
22250
|
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
22156
22251
|
while (now() < deadline) {
|
|
22157
|
-
await
|
|
22252
|
+
await sleep4(pollMs);
|
|
22158
22253
|
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
22159
22254
|
}
|
|
22160
22255
|
return false;
|
|
22161
22256
|
}
|
|
22162
22257
|
|
|
22163
22258
|
// src/agents/kimi/installer.ts
|
|
22164
|
-
var
|
|
22259
|
+
var import_node_child_process23 = require("child_process");
|
|
22165
22260
|
var import_node_os6 = require("os");
|
|
22166
22261
|
var import_node_path6 = require("path");
|
|
22167
22262
|
var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
|
|
@@ -22169,7 +22264,7 @@ function kimiBinDir() {
|
|
|
22169
22264
|
return (0, import_node_path6.join)(process.env.KIMI_CODE_HOME || (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".kimi-code"), "bin");
|
|
22170
22265
|
}
|
|
22171
22266
|
function kimiRuns() {
|
|
22172
|
-
const r = (0,
|
|
22267
|
+
const r = (0, import_node_child_process23.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
|
|
22173
22268
|
return !r.error && r.status === 0;
|
|
22174
22269
|
}
|
|
22175
22270
|
function augmentPath2() {
|
|
@@ -22179,7 +22274,7 @@ function augmentPath2() {
|
|
|
22179
22274
|
}
|
|
22180
22275
|
async function runInstaller2() {
|
|
22181
22276
|
return new Promise((resolve7) => {
|
|
22182
|
-
const proc = (0,
|
|
22277
|
+
const proc = (0, import_node_child_process23.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
|
|
22183
22278
|
proc.on("close", (code) => resolve7(code === 0));
|
|
22184
22279
|
proc.on("error", () => resolve7(false));
|
|
22185
22280
|
});
|
|
@@ -22916,7 +23011,7 @@ var HistoryService = class _HistoryService {
|
|
|
22916
23011
|
};
|
|
22917
23012
|
|
|
22918
23013
|
// src/agents/acp/client.ts
|
|
22919
|
-
var
|
|
23014
|
+
var import_node_child_process24 = require("child_process");
|
|
22920
23015
|
var fs56 = __toESM(require("fs/promises"));
|
|
22921
23016
|
var fsSync = __toESM(require("fs"));
|
|
22922
23017
|
var os45 = __toESM(require("os"));
|
|
@@ -25520,7 +25615,7 @@ var AcpClient = class {
|
|
|
25520
25615
|
"acpClient",
|
|
25521
25616
|
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
25522
25617
|
);
|
|
25523
|
-
const child = (0,
|
|
25618
|
+
const child = (0, import_node_child_process24.spawn)(adapter.command, adapter.args, {
|
|
25524
25619
|
cwd,
|
|
25525
25620
|
// extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
|
|
25526
25621
|
// re-spawn) layers over process.env; PATH stays last so the augmented
|
|
@@ -29762,12 +29857,12 @@ var StreamingEmitterService = class {
|
|
|
29762
29857
|
log.warn("streamingEmitter", `post error url=${url} attempt=${attempt + 1}`, err);
|
|
29763
29858
|
}
|
|
29764
29859
|
if (attempt < MAX_RETRIES2) {
|
|
29765
|
-
await
|
|
29860
|
+
await sleep3(RETRY_BACKOFF_MS3 * (attempt + 1));
|
|
29766
29861
|
}
|
|
29767
29862
|
}
|
|
29768
29863
|
}
|
|
29769
29864
|
};
|
|
29770
|
-
function
|
|
29865
|
+
function sleep3(ms) {
|
|
29771
29866
|
return new Promise((r) => setTimeout(r, ms));
|
|
29772
29867
|
}
|
|
29773
29868
|
var TREE_CONTINUATION_RE = /^\s*└/;
|
|
@@ -29949,10 +30044,15 @@ var NativeTuiDriver = class {
|
|
|
29949
30044
|
await this.agent.restart(resumeId, false);
|
|
29950
30045
|
return resumeId;
|
|
29951
30046
|
}
|
|
30047
|
+
const spawnedAt = this.now();
|
|
29952
30048
|
await this.agent.spawn();
|
|
29953
|
-
const
|
|
29954
|
-
if (
|
|
29955
|
-
|
|
30049
|
+
const preMinted = this.agent.spawnedSessionId;
|
|
30050
|
+
if (preMinted) return preMinted;
|
|
30051
|
+
const discovered = await this.deps.runtime.discoverSessionId?.(this.deps.opts.cwd, {
|
|
30052
|
+
sinceMs: spawnedAt
|
|
30053
|
+
});
|
|
30054
|
+
if (discovered) return discovered;
|
|
30055
|
+
throw new Error("NativeTuiDriver: agent did not expose a session id after spawn");
|
|
29956
30056
|
}
|
|
29957
30057
|
async stop() {
|
|
29958
30058
|
this.agent.kill();
|
|
@@ -33357,7 +33457,7 @@ function checkChokidar() {
|
|
|
33357
33457
|
}
|
|
33358
33458
|
async function doctor(args2 = []) {
|
|
33359
33459
|
const json = args2.includes("--json");
|
|
33360
|
-
const cliVersion = true ? "2.60.
|
|
33460
|
+
const cliVersion = true ? "2.60.19" : "0.0.0-dev";
|
|
33361
33461
|
const apiBase2 = resolveApiBaseUrl();
|
|
33362
33462
|
const diagnosticId = (0, import_node_crypto11.randomUUID)();
|
|
33363
33463
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -33556,7 +33656,7 @@ async function completion(args2) {
|
|
|
33556
33656
|
// src/commands/version.ts
|
|
33557
33657
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33558
33658
|
function version2() {
|
|
33559
|
-
const v = true ? "2.60.
|
|
33659
|
+
const v = true ? "2.60.19" : "unknown";
|
|
33560
33660
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33561
33661
|
}
|
|
33562
33662
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.19",
|
|
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",
|