codeam-cli 2.60.13 → 2.60.15
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 +209 -53
- 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.14] — 2026-07-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Add Kimi Code (Moonshot) as a native ACP agent
|
|
12
|
+
|
|
13
|
+
## [2.60.13] — 2026-07-08
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Pair-auto must never be a local/baton session (agent_banner regression)
|
|
18
|
+
|
|
7
19
|
## [2.60.12] — 2026-07-08
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -389,6 +389,23 @@ var AGENT_REGISTRY = {
|
|
|
389
389
|
headroomWrappable: false,
|
|
390
390
|
// Native ACP server: `gemini --skip-trust --acp`.
|
|
391
391
|
acp: true
|
|
392
|
+
},
|
|
393
|
+
kimi: {
|
|
394
|
+
id: "kimi",
|
|
395
|
+
displayName: "Kimi Code",
|
|
396
|
+
binaryName: "kimi",
|
|
397
|
+
enabled: true,
|
|
398
|
+
// API key (KIMI_API_KEY, + optional KIMI_BASE_URL) is the shipping auth —
|
|
399
|
+
// fully documented, no reverse-engineering. OAuth `/login` (login-state at
|
|
400
|
+
// ~/.kimi-code/credentials/<name>.json, base https://api.kimi.com/coding/)
|
|
401
|
+
// is declared so it can land later without a wire change, but capturing
|
|
402
|
+
// that blob server-side is a separate reverse-engineering spike (phase 2).
|
|
403
|
+
supportedAuthKinds: ["api_key", "oauth_token"],
|
|
404
|
+
preferredAuthKind: "api_key",
|
|
405
|
+
// Moonshot's `kimi` is not listed by `headroom wrap --help` — runs native.
|
|
406
|
+
headroomWrappable: false,
|
|
407
|
+
// Native ACP server: `kimi acp` (stdio JSON-RPC, answers `initialize`).
|
|
408
|
+
acp: true
|
|
392
409
|
}
|
|
393
410
|
};
|
|
394
411
|
function getEnabledAgents() {
|
|
@@ -417,6 +434,7 @@ var PUBLIC_TO_INTERNAL = {
|
|
|
417
434
|
aider: "aider",
|
|
418
435
|
coderabbit: "coderabbit",
|
|
419
436
|
gemini: "gemini",
|
|
437
|
+
kimi: "kimi",
|
|
420
438
|
// The house agent runs Claude Code under the hood (pointed at the
|
|
421
439
|
// MiniMax proxy). Its internal runtime is therefore `claude`.
|
|
422
440
|
[HOUSE_AGENT_ID]: "claude"
|
|
@@ -5662,7 +5680,7 @@ function readAnonId() {
|
|
|
5662
5680
|
}
|
|
5663
5681
|
function superProperties() {
|
|
5664
5682
|
return {
|
|
5665
|
-
cliVersion: true ? "2.60.
|
|
5683
|
+
cliVersion: true ? "2.60.15" : "0.0.0-dev",
|
|
5666
5684
|
nodeVersion: process.version,
|
|
5667
5685
|
platform: process.platform,
|
|
5668
5686
|
arch: process.arch,
|
|
@@ -5843,7 +5861,7 @@ var os4 = __toESM(require("os"));
|
|
|
5843
5861
|
// package.json
|
|
5844
5862
|
var package_default = {
|
|
5845
5863
|
name: "codeam-cli",
|
|
5846
|
-
version: "2.60.
|
|
5864
|
+
version: "2.60.15",
|
|
5847
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.",
|
|
5848
5866
|
type: "commonjs",
|
|
5849
5867
|
main: "dist/index.js",
|
|
@@ -6914,7 +6932,7 @@ var CommandRelayService = class {
|
|
|
6914
6932
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6915
6933
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6916
6934
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6917
|
-
..."2.60.
|
|
6935
|
+
..."2.60.15" ? { ideVersion: "2.60.15" } : {}
|
|
6918
6936
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6919
6937
|
}
|
|
6920
6938
|
/**
|
|
@@ -7141,10 +7159,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
7141
7159
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
7142
7160
|
/[\\/]Templates([\\/]|$)/i
|
|
7143
7161
|
];
|
|
7144
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
7162
|
+
function isUnsafeWindowsWatchRoot(dir, homedir39) {
|
|
7145
7163
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
7146
7164
|
const cwd = norm(dir);
|
|
7147
|
-
const home = norm(
|
|
7165
|
+
const home = norm(homedir39);
|
|
7148
7166
|
if (cwd === home) return true;
|
|
7149
7167
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
7150
7168
|
const sysRoots = [
|
|
@@ -14258,6 +14276,111 @@ var GeminiRuntimeStrategy = class {
|
|
|
14258
14276
|
}
|
|
14259
14277
|
};
|
|
14260
14278
|
|
|
14279
|
+
// src/agents/kimi/runtime.ts
|
|
14280
|
+
var import_node_child_process12 = require("child_process");
|
|
14281
|
+
var import_node_os3 = require("os");
|
|
14282
|
+
var import_node_path4 = require("path");
|
|
14283
|
+
var KIMI_CONTEXT_WINDOW = 262144;
|
|
14284
|
+
var KIMI_MODELS = [
|
|
14285
|
+
{ id: "kimi-for-coding", label: "Kimi for Coding", contextWindow: KIMI_CONTEXT_WINDOW }
|
|
14286
|
+
];
|
|
14287
|
+
function kimiCredentialsDir() {
|
|
14288
|
+
const root = process.env.KIMI_CODE_HOME || (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".kimi-code");
|
|
14289
|
+
return (0, import_node_path4.join)(root, "credentials");
|
|
14290
|
+
}
|
|
14291
|
+
var KimiRuntimeStrategy = class {
|
|
14292
|
+
id = "kimi";
|
|
14293
|
+
meta = getAgent("kimi");
|
|
14294
|
+
mode = "interactive";
|
|
14295
|
+
os;
|
|
14296
|
+
constructor(os48) {
|
|
14297
|
+
this.os = os48;
|
|
14298
|
+
}
|
|
14299
|
+
async prepareLaunch() {
|
|
14300
|
+
const binary = this.os.findInPath("kimi");
|
|
14301
|
+
if (!binary) {
|
|
14302
|
+
throw new Error(
|
|
14303
|
+
"Kimi Code CLI is not on PATH. Install it with:\n curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash\n Then run `codeam pair` again."
|
|
14304
|
+
);
|
|
14305
|
+
}
|
|
14306
|
+
const launch = this.os.buildLaunch(binary, []);
|
|
14307
|
+
return { cmd: launch.cmd, args: launch.args };
|
|
14308
|
+
}
|
|
14309
|
+
resumeLaunchArgs(_sessionId, _opts) {
|
|
14310
|
+
return [];
|
|
14311
|
+
}
|
|
14312
|
+
resolveHistoryDir(_cwd) {
|
|
14313
|
+
return null;
|
|
14314
|
+
}
|
|
14315
|
+
parseHistoryFile(_filePath) {
|
|
14316
|
+
return [];
|
|
14317
|
+
}
|
|
14318
|
+
getCurrentUsage(_historyDir) {
|
|
14319
|
+
return null;
|
|
14320
|
+
}
|
|
14321
|
+
async fetchWeeklyUsage() {
|
|
14322
|
+
return null;
|
|
14323
|
+
}
|
|
14324
|
+
async listModels() {
|
|
14325
|
+
return KIMI_MODELS;
|
|
14326
|
+
}
|
|
14327
|
+
changeModelInstruction(modelId) {
|
|
14328
|
+
return { type: "pty", ptyInput: `/model ${modelId}\r` };
|
|
14329
|
+
}
|
|
14330
|
+
summarizeInstruction(_mode) {
|
|
14331
|
+
return { ptyInput: "/compact\r" };
|
|
14332
|
+
}
|
|
14333
|
+
filterTuiOutput(lines) {
|
|
14334
|
+
return lines;
|
|
14335
|
+
}
|
|
14336
|
+
detectInteractivePrompt(_lines) {
|
|
14337
|
+
return null;
|
|
14338
|
+
}
|
|
14339
|
+
/**
|
|
14340
|
+
* Headless single-prompt invocation — powers `request_ai_summary` /
|
|
14341
|
+
* `request_ai_insight` (Files review) AND Preview detection, same as
|
|
14342
|
+
* claude/codex/gemini. Kimi's non-interactive print mode is
|
|
14343
|
+
* `kimi -p "<prompt>" --output-format text`: it streams the assistant reply
|
|
14344
|
+
* to stdout under the `auto` permission policy (no approval prompt) and exits.
|
|
14345
|
+
* Returns `null` on spawn failure / timeout / empty output so callers skip
|
|
14346
|
+
* silently instead of bubbling a partial reply.
|
|
14347
|
+
*/
|
|
14348
|
+
async generateOneShot(prompt, opts) {
|
|
14349
|
+
const binary = this.os.findInPath("kimi");
|
|
14350
|
+
if (!binary) return null;
|
|
14351
|
+
const launch = this.os.buildLaunch(binary, ["-p", prompt, "--output-format", "text"]);
|
|
14352
|
+
return spawnAndCapture(launch.cmd, launch.args, {
|
|
14353
|
+
cwd: opts?.cwd,
|
|
14354
|
+
timeoutMs: opts?.timeoutMs
|
|
14355
|
+
});
|
|
14356
|
+
}
|
|
14357
|
+
credentialLocator() {
|
|
14358
|
+
return {
|
|
14359
|
+
publicId: "kimi",
|
|
14360
|
+
vendor: "Moonshot",
|
|
14361
|
+
hint: "~/.kimi-code/credentials/",
|
|
14362
|
+
watchPaths: () => [kimiCredentialsDir()],
|
|
14363
|
+
// Phase-2 OAuth capture: the `kimi` toolchain writes per-provider OAuth
|
|
14364
|
+
// JSON under this dir after `/login`. Until that flow is reverse-engineered
|
|
14365
|
+
// (blob format + refresh), file capture is a no-op — the shipping auth is
|
|
14366
|
+
// the API key (KIMI_API_KEY), delivered by the provisioner, not this
|
|
14367
|
+
// watcher. Returning null means "nothing captured here yet".
|
|
14368
|
+
extract: async () => null,
|
|
14369
|
+
validate: validateNonEmptyCredential
|
|
14370
|
+
};
|
|
14371
|
+
}
|
|
14372
|
+
loginLauncher() {
|
|
14373
|
+
return {
|
|
14374
|
+
async ensureInstalled() {
|
|
14375
|
+
return createOsStrategy().findInPath("kimi") !== null;
|
|
14376
|
+
},
|
|
14377
|
+
launch() {
|
|
14378
|
+
return (0, import_node_child_process12.spawn)("kimi", [], { stdio: "inherit" });
|
|
14379
|
+
}
|
|
14380
|
+
};
|
|
14381
|
+
}
|
|
14382
|
+
};
|
|
14383
|
+
|
|
14261
14384
|
// src/agents/registry.ts
|
|
14262
14385
|
var runtimeBuilders = {
|
|
14263
14386
|
claude: (os48) => new ClaudeRuntimeStrategy(os48),
|
|
@@ -14265,7 +14388,8 @@ var runtimeBuilders = {
|
|
|
14265
14388
|
coderabbit: (os48) => new CoderabbitRuntimeStrategy(os48),
|
|
14266
14389
|
cursor: (os48) => new CursorRuntimeStrategy(os48),
|
|
14267
14390
|
aider: (os48) => new AiderRuntimeStrategy(os48),
|
|
14268
|
-
gemini: (os48) => new GeminiRuntimeStrategy(os48)
|
|
14391
|
+
gemini: (os48) => new GeminiRuntimeStrategy(os48),
|
|
14392
|
+
kimi: (os48) => new KimiRuntimeStrategy(os48)
|
|
14269
14393
|
};
|
|
14270
14394
|
var deployBuilders = {
|
|
14271
14395
|
claude: () => new ClaudeDeployStrategy(),
|
|
@@ -14684,7 +14808,7 @@ async function linkDryRunPreflight(ctx) {
|
|
|
14684
14808
|
}
|
|
14685
14809
|
|
|
14686
14810
|
// src/commands/host-agent.ts
|
|
14687
|
-
var
|
|
14811
|
+
var import_node_child_process20 = require("child_process");
|
|
14688
14812
|
var os33 = __toESM(require("os"));
|
|
14689
14813
|
var fs39 = __toESM(require("fs"));
|
|
14690
14814
|
var path41 = __toESM(require("path"));
|
|
@@ -14696,8 +14820,8 @@ var path34 = __toESM(require("path"));
|
|
|
14696
14820
|
|
|
14697
14821
|
// src/lib/restrict-to-owner.ts
|
|
14698
14822
|
var import_node_fs5 = __toESM(require("fs"));
|
|
14699
|
-
var
|
|
14700
|
-
var
|
|
14823
|
+
var import_node_os4 = __toESM(require("os"));
|
|
14824
|
+
var import_node_child_process13 = require("child_process");
|
|
14701
14825
|
var BROAD_WINDOWS_SIDS = [
|
|
14702
14826
|
"*S-1-1-0",
|
|
14703
14827
|
"*S-1-5-11",
|
|
@@ -14708,8 +14832,8 @@ var BROAD_WINDOWS_SIDS = [
|
|
|
14708
14832
|
function restrictToOwner(filePath) {
|
|
14709
14833
|
try {
|
|
14710
14834
|
if (process.platform === "win32") {
|
|
14711
|
-
const username =
|
|
14712
|
-
(0,
|
|
14835
|
+
const username = import_node_os4.default.userInfo().username;
|
|
14836
|
+
(0, import_node_child_process13.execFileSync)(
|
|
14713
14837
|
"icacls",
|
|
14714
14838
|
[
|
|
14715
14839
|
filePath,
|
|
@@ -14971,9 +15095,9 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
14971
15095
|
var fs32 = __toESM(require("fs"));
|
|
14972
15096
|
var os28 = __toESM(require("os"));
|
|
14973
15097
|
var path35 = __toESM(require("path"));
|
|
14974
|
-
var
|
|
15098
|
+
var import_node_child_process14 = require("child_process");
|
|
14975
15099
|
var import_node_util4 = require("util");
|
|
14976
|
-
var execFileP4 = (0, import_node_util4.promisify)(
|
|
15100
|
+
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process14.execFile);
|
|
14977
15101
|
function isAbsolutePathTarget(target) {
|
|
14978
15102
|
return path35.isAbsolute(target);
|
|
14979
15103
|
}
|
|
@@ -15111,7 +15235,8 @@ var PUBLIC_TO_INTERNAL_AGENT = {
|
|
|
15111
15235
|
cursor: "cursor",
|
|
15112
15236
|
aider: "aider",
|
|
15113
15237
|
coderabbit: "coderabbit",
|
|
15114
|
-
gemini: "gemini"
|
|
15238
|
+
gemini: "gemini",
|
|
15239
|
+
kimi: "kimi"
|
|
15115
15240
|
};
|
|
15116
15241
|
function toInternalAgentId(publicAgentId) {
|
|
15117
15242
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
@@ -15204,8 +15329,23 @@ var cursorProvisioner = {
|
|
|
15204
15329
|
return {};
|
|
15205
15330
|
}
|
|
15206
15331
|
};
|
|
15332
|
+
var kimiProvisioner = {
|
|
15333
|
+
write(auth, home) {
|
|
15334
|
+
const credentialsFiles = [
|
|
15335
|
+
path36.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
15336
|
+
path36.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
15337
|
+
];
|
|
15338
|
+
if (auth.kind === "api_key") {
|
|
15339
|
+
credentialsFiles.forEach(rmIfExists);
|
|
15340
|
+
return { KIMI_API_KEY: auth.value };
|
|
15341
|
+
}
|
|
15342
|
+
credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
|
|
15343
|
+
return {};
|
|
15344
|
+
}
|
|
15345
|
+
};
|
|
15207
15346
|
var PROVISIONERS = {
|
|
15208
15347
|
claude: claudeProvisioner,
|
|
15348
|
+
kimi: kimiProvisioner,
|
|
15209
15349
|
codex: codexProvisioner,
|
|
15210
15350
|
gemini: geminiProvisioner,
|
|
15211
15351
|
cursor: cursorProvisioner
|
|
@@ -15227,7 +15367,7 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os29.homedir(
|
|
|
15227
15367
|
}
|
|
15228
15368
|
|
|
15229
15369
|
// src/commands/host/git-tooling.ts
|
|
15230
|
-
var
|
|
15370
|
+
var import_node_child_process15 = require("child_process");
|
|
15231
15371
|
var fs34 = __toESM(require("fs"));
|
|
15232
15372
|
var os30 = __toESM(require("os"));
|
|
15233
15373
|
var path37 = __toESM(require("path"));
|
|
@@ -15341,7 +15481,7 @@ var defaultGitToolingRunner = {
|
|
|
15341
15481
|
which(cmd) {
|
|
15342
15482
|
try {
|
|
15343
15483
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
15344
|
-
(0,
|
|
15484
|
+
(0, import_node_child_process15.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
15345
15485
|
return true;
|
|
15346
15486
|
} catch {
|
|
15347
15487
|
return false;
|
|
@@ -15349,7 +15489,7 @@ var defaultGitToolingRunner = {
|
|
|
15349
15489
|
},
|
|
15350
15490
|
run(cmd, args2, opts = {}) {
|
|
15351
15491
|
return new Promise((resolve7) => {
|
|
15352
|
-
const child = (0,
|
|
15492
|
+
const child = (0, import_node_child_process15.spawn)(cmd, args2, {
|
|
15353
15493
|
stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
|
|
15354
15494
|
});
|
|
15355
15495
|
let stderr = "";
|
|
@@ -15503,12 +15643,12 @@ var HeadroomStatsReporter = class {
|
|
|
15503
15643
|
};
|
|
15504
15644
|
|
|
15505
15645
|
// src/commands/host/os-packages.ts
|
|
15506
|
-
var
|
|
15646
|
+
var import_node_child_process16 = require("child_process");
|
|
15507
15647
|
var PM_INSTALL_TIMEOUT_MS = 18e4;
|
|
15508
15648
|
var defaultHeadroomRunner = {
|
|
15509
15649
|
which(cmd) {
|
|
15510
15650
|
try {
|
|
15511
|
-
(0,
|
|
15651
|
+
(0, import_node_child_process16.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
15512
15652
|
return true;
|
|
15513
15653
|
} catch {
|
|
15514
15654
|
return false;
|
|
@@ -15517,7 +15657,7 @@ var defaultHeadroomRunner = {
|
|
|
15517
15657
|
run(cmd, args2, opts = {}) {
|
|
15518
15658
|
return new Promise((resolve7) => {
|
|
15519
15659
|
const spawnEnv = opts.env ?? process.env;
|
|
15520
|
-
const child = (0,
|
|
15660
|
+
const child = (0, import_node_child_process16.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
|
|
15521
15661
|
let stderrBuf = "";
|
|
15522
15662
|
let stdoutBuf = "";
|
|
15523
15663
|
let settled = false;
|
|
@@ -16024,14 +16164,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
16024
16164
|
}
|
|
16025
16165
|
|
|
16026
16166
|
// src/commands/host/self-update.ts
|
|
16027
|
-
var
|
|
16167
|
+
var import_node_child_process18 = require("child_process");
|
|
16028
16168
|
|
|
16029
16169
|
// src/lib/updateNotifier.ts
|
|
16030
16170
|
var fs37 = __toESM(require("fs"));
|
|
16031
16171
|
var os32 = __toESM(require("os"));
|
|
16032
16172
|
var path40 = __toESM(require("path"));
|
|
16033
16173
|
var https6 = __toESM(require("https"));
|
|
16034
|
-
var
|
|
16174
|
+
var import_node_child_process17 = require("child_process");
|
|
16035
16175
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
16036
16176
|
var PKG_NAME = "codeam-cli";
|
|
16037
16177
|
var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
@@ -16125,7 +16265,7 @@ function notifyIfStale(currentVersion, latest) {
|
|
|
16125
16265
|
}
|
|
16126
16266
|
function isLinkedInstall() {
|
|
16127
16267
|
try {
|
|
16128
|
-
const root = (0,
|
|
16268
|
+
const root = (0, import_node_child_process17.execSync)("npm root -g", {
|
|
16129
16269
|
encoding: "utf8",
|
|
16130
16270
|
stdio: ["ignore", "pipe", "ignore"],
|
|
16131
16271
|
timeout: 2e3
|
|
@@ -16153,7 +16293,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16153
16293
|
|
|
16154
16294
|
`
|
|
16155
16295
|
);
|
|
16156
|
-
const install = (0,
|
|
16296
|
+
const install = (0, import_node_child_process17.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
|
|
16157
16297
|
stdio: "inherit",
|
|
16158
16298
|
env: process.env
|
|
16159
16299
|
});
|
|
@@ -16174,7 +16314,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16174
16314
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
16175
16315
|
|
|
16176
16316
|
`);
|
|
16177
|
-
const child = (0,
|
|
16317
|
+
const child = (0, import_node_child_process17.spawnSync)("codeam", process.argv.slice(2), {
|
|
16178
16318
|
stdio: "inherit",
|
|
16179
16319
|
env: process.env
|
|
16180
16320
|
});
|
|
@@ -16184,7 +16324,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16184
16324
|
if (process.env.NODE_ENV === "test") return;
|
|
16185
16325
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16186
16326
|
if (process.env.CI) return;
|
|
16187
|
-
const current = true ? "2.60.
|
|
16327
|
+
const current = true ? "2.60.15" : null;
|
|
16188
16328
|
if (!current) return;
|
|
16189
16329
|
const cache = readCache();
|
|
16190
16330
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16201,7 +16341,7 @@ function checkForUpdates() {
|
|
|
16201
16341
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16202
16342
|
if (process.env.CI) return;
|
|
16203
16343
|
if (!process.stdout.isTTY) return;
|
|
16204
|
-
const current = true ? "2.60.
|
|
16344
|
+
const current = true ? "2.60.15" : null;
|
|
16205
16345
|
if (!current) return;
|
|
16206
16346
|
const cache = readCache();
|
|
16207
16347
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16221,11 +16361,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16221
16361
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16222
16362
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16223
16363
|
function currentCliVersion() {
|
|
16224
|
-
return true ? "2.60.
|
|
16364
|
+
return true ? "2.60.15" : null;
|
|
16225
16365
|
}
|
|
16226
16366
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16227
16367
|
return new Promise((resolve7) => {
|
|
16228
|
-
(0,
|
|
16368
|
+
(0, import_node_child_process18.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
16229
16369
|
const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
|
|
16230
16370
|
resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
16231
16371
|
});
|
|
@@ -16287,11 +16427,11 @@ async function runSelfUpdate() {
|
|
|
16287
16427
|
}
|
|
16288
16428
|
|
|
16289
16429
|
// src/commands/host/teardown.ts
|
|
16290
|
-
var
|
|
16430
|
+
var import_node_child_process19 = require("child_process");
|
|
16291
16431
|
var fs38 = __toESM(require("fs"));
|
|
16292
16432
|
var defaultDisableService = () => {
|
|
16293
16433
|
try {
|
|
16294
|
-
(0,
|
|
16434
|
+
(0, import_node_child_process19.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
16295
16435
|
} catch {
|
|
16296
16436
|
}
|
|
16297
16437
|
};
|
|
@@ -16299,7 +16439,7 @@ var defaultTeardownHeadroom = () => {
|
|
|
16299
16439
|
try {
|
|
16300
16440
|
const kind = JSON.parse(fs38.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
16301
16441
|
if (kind) {
|
|
16302
|
-
(0,
|
|
16442
|
+
(0, import_node_child_process19.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
16303
16443
|
}
|
|
16304
16444
|
} catch {
|
|
16305
16445
|
}
|
|
@@ -16457,7 +16597,7 @@ var CONTROL_AGENT_META = {
|
|
|
16457
16597
|
headroomWrappable: false,
|
|
16458
16598
|
acp: false
|
|
16459
16599
|
};
|
|
16460
|
-
var defaultSpawner = (env, cwd, args2 = []) => (0,
|
|
16600
|
+
var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process20.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
|
|
16461
16601
|
cwd,
|
|
16462
16602
|
env: { ...process.env, ...env },
|
|
16463
16603
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -16937,7 +17077,7 @@ var HostAgentSupervisor = class {
|
|
|
16937
17077
|
runAgentInstall(script) {
|
|
16938
17078
|
return new Promise((resolve7) => {
|
|
16939
17079
|
const home = process.env.HOME || os33.homedir();
|
|
16940
|
-
const child = (0,
|
|
17080
|
+
const child = (0, import_node_child_process20.spawn)("sh", ["-c", script], {
|
|
16941
17081
|
env: { ...process.env, HOME: home },
|
|
16942
17082
|
stdio: ["ignore", "pipe", "pipe"]
|
|
16943
17083
|
});
|
|
@@ -17245,11 +17385,11 @@ function makeRealApplyBudgetDeps() {
|
|
|
17245
17385
|
var import_child_process14 = require("child_process");
|
|
17246
17386
|
var import_fs = require("fs");
|
|
17247
17387
|
var import_promises = __toESM(require("fs/promises"));
|
|
17248
|
-
var
|
|
17388
|
+
var import_os7 = __toESM(require("os"));
|
|
17249
17389
|
var import_path4 = __toESM(require("path"));
|
|
17250
17390
|
var import_promises2 = require("stream/promises");
|
|
17251
17391
|
var import_which = __toESM(require("which"));
|
|
17252
|
-
var CACHED_BINARY = import_path4.default.join(
|
|
17392
|
+
var CACHED_BINARY = import_path4.default.join(import_os7.default.homedir(), ".codeam", "bin", "cloudflared");
|
|
17253
17393
|
async function resolveCloudflared(opts = {}) {
|
|
17254
17394
|
try {
|
|
17255
17395
|
return await (0, import_which.default)("cloudflared");
|
|
@@ -17349,7 +17489,7 @@ function decodeTunnelToken(token) {
|
|
|
17349
17489
|
}
|
|
17350
17490
|
async function spawnNamedTunnel(bin, token, port) {
|
|
17351
17491
|
const creds = decodeTunnelToken(token);
|
|
17352
|
-
const credDir = import_path4.default.join(
|
|
17492
|
+
const credDir = import_path4.default.join(import_os7.default.homedir(), ".codeam");
|
|
17353
17493
|
await import_promises.default.mkdir(credDir, { recursive: true });
|
|
17354
17494
|
const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
|
|
17355
17495
|
await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
|
|
@@ -18969,6 +19109,9 @@ var AGENT_SETUP_RECIPE = {
|
|
|
18969
19109
|
cursor: "cursor",
|
|
18970
19110
|
aider: "aider",
|
|
18971
19111
|
gemini: "gemini",
|
|
19112
|
+
// bd 1.0.5 has no Kimi recipe → skip (like coderabbit); beads still works,
|
|
19113
|
+
// the agent just isn't wired natively via `bd setup`.
|
|
19114
|
+
kimi: null,
|
|
18972
19115
|
coderabbit: null
|
|
18973
19116
|
};
|
|
18974
19117
|
var _provisionSeam = {
|
|
@@ -19537,10 +19680,10 @@ async function handleBeadsActionCommand(action, started) {
|
|
|
19537
19680
|
|
|
19538
19681
|
// src/beads/config-store.ts
|
|
19539
19682
|
var import_node_fs6 = __toESM(require("fs"));
|
|
19540
|
-
var
|
|
19541
|
-
var
|
|
19683
|
+
var import_node_os5 = __toESM(require("os"));
|
|
19684
|
+
var import_node_path5 = __toESM(require("path"));
|
|
19542
19685
|
function beadsConfigPath() {
|
|
19543
|
-
return
|
|
19686
|
+
return import_node_path5.default.join(import_node_os5.default.homedir(), ".codeam", "beads-config.json");
|
|
19544
19687
|
}
|
|
19545
19688
|
function readBeadsEnabled() {
|
|
19546
19689
|
try {
|
|
@@ -19553,7 +19696,7 @@ function readBeadsEnabled() {
|
|
|
19553
19696
|
}
|
|
19554
19697
|
function persistBeadsConfig(cfg) {
|
|
19555
19698
|
const file = beadsConfigPath();
|
|
19556
|
-
import_node_fs6.default.mkdirSync(
|
|
19699
|
+
import_node_fs6.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
|
|
19557
19700
|
const tmp = `${file}.tmp`;
|
|
19558
19701
|
import_node_fs6.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
|
|
19559
19702
|
import_node_fs6.default.renameSync(tmp, file);
|
|
@@ -21340,7 +21483,7 @@ async function pairAuto(args2) {
|
|
|
21340
21483
|
}
|
|
21341
21484
|
|
|
21342
21485
|
// src/services/headroom/wrap-launch.ts
|
|
21343
|
-
var
|
|
21486
|
+
var import_node_child_process21 = require("child_process");
|
|
21344
21487
|
function wrapWithHeadroom(launch, opts) {
|
|
21345
21488
|
if (!opts.enabled || !opts.headroomPresent) return launch;
|
|
21346
21489
|
return {
|
|
@@ -21353,7 +21496,7 @@ var _present;
|
|
|
21353
21496
|
function headroomPresent() {
|
|
21354
21497
|
if (_present !== void 0) return Promise.resolve(_present);
|
|
21355
21498
|
return new Promise((resolve7) => {
|
|
21356
|
-
(0,
|
|
21499
|
+
(0, import_node_child_process21.execFile)("headroom", ["--version"], (err) => {
|
|
21357
21500
|
_present = !err;
|
|
21358
21501
|
resolve7(_present);
|
|
21359
21502
|
});
|
|
@@ -21707,7 +21850,7 @@ var path57 = __toESM(require("path"));
|
|
|
21707
21850
|
|
|
21708
21851
|
// src/agents/acp/agent-binary.ts
|
|
21709
21852
|
var import_fs4 = __toESM(require("fs"));
|
|
21710
|
-
var
|
|
21853
|
+
var import_os8 = __toESM(require("os"));
|
|
21711
21854
|
var import_path8 = __toESM(require("path"));
|
|
21712
21855
|
var import_child_process25 = require("child_process");
|
|
21713
21856
|
function currentPlatformKey() {
|
|
@@ -21803,7 +21946,7 @@ function resolveCursorAgentBinary(deps = {}) {
|
|
|
21803
21946
|
const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
|
|
21804
21947
|
return existsSync25(exe) ? exe : null;
|
|
21805
21948
|
}
|
|
21806
|
-
const home = deps.homedir ??
|
|
21949
|
+
const home = deps.homedir ?? import_os8.default.homedir();
|
|
21807
21950
|
const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
|
|
21808
21951
|
return existsSync25(unix) ? unix : null;
|
|
21809
21952
|
}
|
|
@@ -21960,6 +22103,19 @@ var REGISTRY = {
|
|
|
21960
22103
|
args: ["--skip-trust", "--acp"],
|
|
21961
22104
|
requiresAgentBinary: "gemini",
|
|
21962
22105
|
waitForBinary: (o) => waitForCommandOnPath("gemini", o)
|
|
22106
|
+
}),
|
|
22107
|
+
// Kimi Code (Moonshot) speaks ACP natively via `kimi acp` — a stdio
|
|
22108
|
+
// JSON-RPC server that answers `initialize` (agentInfo `Kimi Code CLI`,
|
|
22109
|
+
// capabilities, authMethods) and prints no TUI banner. No npm adapter, just
|
|
22110
|
+
// the user-installed `kimi` binary on PATH. Same {@link AdapterSpec} shape as
|
|
22111
|
+
// gemini/cursor. Auth (KIMI_API_KEY env, or the ~/.kimi-code/credentials
|
|
22112
|
+
// login-state file) reaches kimi because the ACP client spawns the adapter
|
|
22113
|
+
// with `env: { ...process.env, ...extraEnv }`.
|
|
22114
|
+
kimi: () => ({
|
|
22115
|
+
command: "kimi",
|
|
22116
|
+
args: ["acp"],
|
|
22117
|
+
requiresAgentBinary: "kimi",
|
|
22118
|
+
waitForBinary: (o) => waitForCommandOnPath("kimi", o)
|
|
21963
22119
|
})
|
|
21964
22120
|
};
|
|
21965
22121
|
function getAcpAdapter(agent) {
|
|
@@ -22551,7 +22707,7 @@ var HistoryService = class _HistoryService {
|
|
|
22551
22707
|
};
|
|
22552
22708
|
|
|
22553
22709
|
// src/agents/acp/client.ts
|
|
22554
|
-
var
|
|
22710
|
+
var import_node_child_process22 = require("child_process");
|
|
22555
22711
|
var fs55 = __toESM(require("fs/promises"));
|
|
22556
22712
|
var fsSync = __toESM(require("fs"));
|
|
22557
22713
|
var os44 = __toESM(require("os"));
|
|
@@ -25155,7 +25311,7 @@ var AcpClient = class {
|
|
|
25155
25311
|
"acpClient",
|
|
25156
25312
|
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
25157
25313
|
);
|
|
25158
|
-
const child = (0,
|
|
25314
|
+
const child = (0, import_node_child_process22.spawn)(adapter.command, adapter.args, {
|
|
25159
25315
|
cwd,
|
|
25160
25316
|
// extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
|
|
25161
25317
|
// re-spawn) layers over process.env; PATH stays last so the augmented
|
|
@@ -25593,12 +25749,12 @@ function buildRelaunchProxyEnv(baseEnv) {
|
|
|
25593
25749
|
return env;
|
|
25594
25750
|
}
|
|
25595
25751
|
var relaunchProxyWithoutBudget = async () => {
|
|
25596
|
-
const { spawn:
|
|
25752
|
+
const { spawn: spawn39 } = await import("child_process");
|
|
25597
25753
|
killHeadroomProxy();
|
|
25598
25754
|
await new Promise((r) => setTimeout(r, 500));
|
|
25599
25755
|
const proxyEnv = buildRelaunchProxyEnv(process.env);
|
|
25600
25756
|
try {
|
|
25601
|
-
const proxy =
|
|
25757
|
+
const proxy = spawn39(
|
|
25602
25758
|
"headroom",
|
|
25603
25759
|
["proxy", "--port", "8787"],
|
|
25604
25760
|
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
@@ -26539,7 +26695,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
26539
26695
|
// src/services/turn-files/files-outbox.ts
|
|
26540
26696
|
var fs58 = __toESM(require("fs/promises"));
|
|
26541
26697
|
var path62 = __toESM(require("path"));
|
|
26542
|
-
var
|
|
26698
|
+
var import_os9 = require("os");
|
|
26543
26699
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
26544
26700
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
26545
26701
|
var BACKOFF_STEPS_MS = [
|
|
@@ -26706,7 +26862,7 @@ function applyJitter(ms) {
|
|
|
26706
26862
|
return Math.round(ms * factor);
|
|
26707
26863
|
}
|
|
26708
26864
|
function homeDir() {
|
|
26709
|
-
return process.env.HOME ?? process.env.USERPROFILE ?? (0,
|
|
26865
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os9.tmpdir)();
|
|
26710
26866
|
}
|
|
26711
26867
|
|
|
26712
26868
|
// src/services/turn-files/turn-file-aggregator.ts
|
|
@@ -33000,7 +33156,7 @@ function checkChokidar() {
|
|
|
33000
33156
|
}
|
|
33001
33157
|
async function doctor(args2 = []) {
|
|
33002
33158
|
const json = args2.includes("--json");
|
|
33003
|
-
const cliVersion = true ? "2.60.
|
|
33159
|
+
const cliVersion = true ? "2.60.15" : "0.0.0-dev";
|
|
33004
33160
|
const apiBase2 = resolveApiBaseUrl();
|
|
33005
33161
|
const diagnosticId = (0, import_node_crypto10.randomUUID)();
|
|
33006
33162
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -33199,7 +33355,7 @@ async function completion(args2) {
|
|
|
33199
33355
|
// src/commands/version.ts
|
|
33200
33356
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33201
33357
|
function version2() {
|
|
33202
|
-
const v = true ? "2.60.
|
|
33358
|
+
const v = true ? "2.60.15" : "unknown";
|
|
33203
33359
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33204
33360
|
}
|
|
33205
33361
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.15",
|
|
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",
|