codeam-cli 2.39.9 → 2.39.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +177 -122
- 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.39.10] — 2026-06-13
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Pre-complete Claude onboarding + persist on-demand preview detect
|
|
12
|
+
|
|
13
|
+
## [2.39.9] — 2026-06-13
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Auto-provision project deps (docker compose) gated before the agent
|
|
18
|
+
|
|
7
19
|
## [2.39.8] — 2026-06-13
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.39.
|
|
501
|
+
version: "2.39.11",
|
|
502
502
|
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.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -1186,8 +1186,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1186
1186
|
return decodedFile;
|
|
1187
1187
|
};
|
|
1188
1188
|
}
|
|
1189
|
-
function normalizeWindowsPath(
|
|
1190
|
-
return
|
|
1189
|
+
function normalizeWindowsPath(path55) {
|
|
1190
|
+
return path55.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1191
1191
|
}
|
|
1192
1192
|
|
|
1193
1193
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3667,9 +3667,9 @@ async function addSourceContext(frames) {
|
|
|
3667
3667
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3668
3668
|
return frames;
|
|
3669
3669
|
}
|
|
3670
|
-
function getContextLinesFromFile(
|
|
3670
|
+
function getContextLinesFromFile(path55, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path55);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path54, ranges, output) {
|
|
|
3684
3684
|
let rangeStart = range[0];
|
|
3685
3685
|
let rangeEnd = range[1];
|
|
3686
3686
|
function onStreamError() {
|
|
3687
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3687
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path55, 1);
|
|
3688
3688
|
lineReaded.close();
|
|
3689
3689
|
lineReaded.removeAllListeners();
|
|
3690
3690
|
destroyStreamAndResolve();
|
|
@@ -3745,8 +3745,8 @@ function clearLineContext(frame) {
|
|
|
3745
3745
|
delete frame.context_line;
|
|
3746
3746
|
delete frame.post_context;
|
|
3747
3747
|
}
|
|
3748
|
-
function shouldSkipContextLinesForFile(
|
|
3749
|
-
return
|
|
3748
|
+
function shouldSkipContextLinesForFile(path55) {
|
|
3749
|
+
return path55.startsWith("node:") || path55.endsWith(".min.js") || path55.endsWith(".min.cjs") || path55.endsWith(".min.mjs") || path55.startsWith("data:");
|
|
3750
3750
|
}
|
|
3751
3751
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3752
3752
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5900,13 +5900,29 @@ function readAnonId() {
|
|
|
5900
5900
|
}
|
|
5901
5901
|
function superProperties() {
|
|
5902
5902
|
return {
|
|
5903
|
-
cliVersion: true ? "2.39.
|
|
5903
|
+
cliVersion: true ? "2.39.11" : "0.0.0-dev",
|
|
5904
5904
|
nodeVersion: process.version,
|
|
5905
5905
|
platform: process.platform,
|
|
5906
5906
|
arch: process.arch,
|
|
5907
5907
|
osRelease: os4.release()
|
|
5908
5908
|
};
|
|
5909
5909
|
}
|
|
5910
|
+
var resilientFetch = async (url, options) => {
|
|
5911
|
+
try {
|
|
5912
|
+
return await fetch(url, options);
|
|
5913
|
+
} catch (err) {
|
|
5914
|
+
log.trace(
|
|
5915
|
+
"telemetry",
|
|
5916
|
+
`posthog transport failed \u2014 dropping batch (network unreachable): ${err instanceof Error ? err.message : String(err)}`
|
|
5917
|
+
);
|
|
5918
|
+
return {
|
|
5919
|
+
status: 200,
|
|
5920
|
+
text: async () => "",
|
|
5921
|
+
json: async () => ({}),
|
|
5922
|
+
body: null
|
|
5923
|
+
};
|
|
5924
|
+
}
|
|
5925
|
+
};
|
|
5910
5926
|
function initTelemetry() {
|
|
5911
5927
|
if (client) return true;
|
|
5912
5928
|
if (isOptedOut()) {
|
|
@@ -5926,7 +5942,14 @@ function initTelemetry() {
|
|
|
5926
5942
|
// and we shutdown() before exit anyway. Per-batch size caps
|
|
5927
5943
|
// memory growth on long-lived `codeam start` sessions.
|
|
5928
5944
|
flushAt: 20,
|
|
5929
|
-
flushInterval: 1e4
|
|
5945
|
+
flushInterval: 1e4,
|
|
5946
|
+
// Network failures resolve to a synthetic 200 instead of throwing —
|
|
5947
|
+
// keeps a flaky/offline network from crashing the CLI or spamming the
|
|
5948
|
+
// session PTY. See resilientFetch above.
|
|
5949
|
+
fetch: resilientFetch
|
|
5950
|
+
});
|
|
5951
|
+
client.on("error", (err) => {
|
|
5952
|
+
log.trace("telemetry", "posthog error (ignored)", err);
|
|
5930
5953
|
});
|
|
5931
5954
|
client.register(superProperties());
|
|
5932
5955
|
log.trace("telemetry", `posthog client initialised host=${host} distinctId=${distinctId}`);
|
|
@@ -7248,10 +7271,10 @@ function buildForPlatform(platform2) {
|
|
|
7248
7271
|
var import_node_crypto4 = require("crypto");
|
|
7249
7272
|
|
|
7250
7273
|
// src/agents/claude/resolver.ts
|
|
7251
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
7252
|
-
const found =
|
|
7274
|
+
function buildClaudeLaunch(extraArgs = [], os33 = createOsStrategy()) {
|
|
7275
|
+
const found = os33.findInPath("claude") ?? os33.findInPath("claude-code");
|
|
7253
7276
|
if (!found) return null;
|
|
7254
|
-
return
|
|
7277
|
+
return os33.buildLaunch(found, extraArgs);
|
|
7255
7278
|
}
|
|
7256
7279
|
|
|
7257
7280
|
// src/agents/claude/installer.ts
|
|
@@ -9978,13 +10001,13 @@ function detectStartupBanner(lines) {
|
|
|
9978
10001
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9979
10002
|
if (metaIdx - artStart < 2) return null;
|
|
9980
10003
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9981
|
-
const
|
|
10004
|
+
const path55 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
10005
|
return {
|
|
9983
10006
|
title: "",
|
|
9984
10007
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
10008
|
+
path: path55,
|
|
9986
10009
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
10010
|
+
endIdx: metaIdx + (path55 ? 1 : 0)
|
|
9988
10011
|
};
|
|
9989
10012
|
}
|
|
9990
10013
|
|
|
@@ -9994,8 +10017,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9994
10017
|
meta = getAgent("claude");
|
|
9995
10018
|
mode = "interactive";
|
|
9996
10019
|
os;
|
|
9997
|
-
constructor(
|
|
9998
|
-
this.os =
|
|
10020
|
+
constructor(os33) {
|
|
10021
|
+
this.os = os33;
|
|
9999
10022
|
}
|
|
10000
10023
|
/**
|
|
10001
10024
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -11025,8 +11048,8 @@ function codexCredentialLocator() {
|
|
|
11025
11048
|
function codexLoginLauncher() {
|
|
11026
11049
|
return {
|
|
11027
11050
|
async ensureInstalled() {
|
|
11028
|
-
const
|
|
11029
|
-
return
|
|
11051
|
+
const os33 = createOsStrategy();
|
|
11052
|
+
return os33.findInPath("codex") !== null;
|
|
11030
11053
|
},
|
|
11031
11054
|
launch() {
|
|
11032
11055
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -11049,8 +11072,8 @@ var CodexRuntimeStrategy = class {
|
|
|
11049
11072
|
meta = getAgent("codex");
|
|
11050
11073
|
mode = "interactive";
|
|
11051
11074
|
os;
|
|
11052
|
-
constructor(
|
|
11053
|
-
this.os =
|
|
11075
|
+
constructor(os33) {
|
|
11076
|
+
this.os = os33;
|
|
11054
11077
|
}
|
|
11055
11078
|
async prepareLaunch() {
|
|
11056
11079
|
let binary = this.os.findInPath("codex");
|
|
@@ -11156,12 +11179,12 @@ var CodexRuntimeStrategy = class {
|
|
|
11156
11179
|
});
|
|
11157
11180
|
}
|
|
11158
11181
|
};
|
|
11159
|
-
function resolveNpm(
|
|
11160
|
-
return
|
|
11182
|
+
function resolveNpm(os33) {
|
|
11183
|
+
return os33.id === "win32" ? "npm.cmd" : "npm";
|
|
11161
11184
|
}
|
|
11162
|
-
async function installCodexViaNpm(
|
|
11185
|
+
async function installCodexViaNpm(os33) {
|
|
11163
11186
|
return new Promise((resolve7, reject) => {
|
|
11164
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
11187
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os33), ["install", "-g", "@openai/codex"], {
|
|
11165
11188
|
stdio: "inherit"
|
|
11166
11189
|
});
|
|
11167
11190
|
proc.on("close", (code) => {
|
|
@@ -11178,16 +11201,16 @@ async function installCodexViaNpm(os32) {
|
|
|
11178
11201
|
});
|
|
11179
11202
|
});
|
|
11180
11203
|
}
|
|
11181
|
-
function augmentNpmGlobalBin(
|
|
11204
|
+
function augmentNpmGlobalBin(os33) {
|
|
11182
11205
|
try {
|
|
11183
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
11206
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os33), ["prefix", "-g"], {
|
|
11184
11207
|
stdio: ["ignore", "pipe", "ignore"]
|
|
11185
11208
|
});
|
|
11186
11209
|
if (result.status !== 0) return;
|
|
11187
11210
|
const prefix = result.stdout.toString().trim();
|
|
11188
11211
|
if (!prefix) return;
|
|
11189
|
-
const binDir =
|
|
11190
|
-
|
|
11212
|
+
const binDir = os33.id === "win32" ? prefix : path17.join(prefix, "bin");
|
|
11213
|
+
os33.augmentPath([binDir]);
|
|
11191
11214
|
} catch {
|
|
11192
11215
|
}
|
|
11193
11216
|
}
|
|
@@ -11271,9 +11294,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
11271
11294
|
// src/agents/coderabbit/installer.ts
|
|
11272
11295
|
var import_node_child_process5 = require("child_process");
|
|
11273
11296
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
11274
|
-
async function ensureCoderabbitInstalled(
|
|
11275
|
-
if (
|
|
11276
|
-
if (
|
|
11297
|
+
async function ensureCoderabbitInstalled(os33) {
|
|
11298
|
+
if (os33.findInPath("coderabbit")) return true;
|
|
11299
|
+
if (os33.id === "win32") {
|
|
11277
11300
|
console.error(
|
|
11278
11301
|
"\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
|
|
11279
11302
|
);
|
|
@@ -11288,8 +11311,8 @@ async function ensureCoderabbitInstalled(os32) {
|
|
|
11288
11311
|
proc.on("error", () => resolve7(false));
|
|
11289
11312
|
});
|
|
11290
11313
|
if (!ok) return false;
|
|
11291
|
-
|
|
11292
|
-
return
|
|
11314
|
+
os33.augmentPath([`${os33.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
11315
|
+
return os33.findInPath("coderabbit") !== null;
|
|
11293
11316
|
}
|
|
11294
11317
|
|
|
11295
11318
|
// src/agents/coderabbit/link.ts
|
|
@@ -11316,10 +11339,10 @@ function coderabbitCredentialLocator() {
|
|
|
11316
11339
|
extract: extractLocalCoderabbitToken
|
|
11317
11340
|
};
|
|
11318
11341
|
}
|
|
11319
|
-
function coderabbitLoginLauncher(
|
|
11342
|
+
function coderabbitLoginLauncher(os33) {
|
|
11320
11343
|
return {
|
|
11321
11344
|
async ensureInstalled() {
|
|
11322
|
-
return ensureCoderabbitInstalled(
|
|
11345
|
+
return ensureCoderabbitInstalled(os33);
|
|
11323
11346
|
},
|
|
11324
11347
|
launch() {
|
|
11325
11348
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -11342,11 +11365,11 @@ function parseReview(stdout) {
|
|
|
11342
11365
|
for (const line of lines) {
|
|
11343
11366
|
const m = line.match(HUNK_LINE_RE);
|
|
11344
11367
|
if (!m) continue;
|
|
11345
|
-
const [,
|
|
11346
|
-
if (!
|
|
11368
|
+
const [, path55, lineNo, sevToken, message] = m;
|
|
11369
|
+
if (!path55 || !lineNo || !message) continue;
|
|
11347
11370
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11371
|
hunks.push({
|
|
11349
|
-
path:
|
|
11372
|
+
path: path55.trim(),
|
|
11350
11373
|
line: Number(lineNo),
|
|
11351
11374
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11375
|
message: cleanedMessage
|
|
@@ -11365,8 +11388,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
11365
11388
|
meta = getAgent("coderabbit");
|
|
11366
11389
|
mode = "batch";
|
|
11367
11390
|
os;
|
|
11368
|
-
constructor(
|
|
11369
|
-
this.os =
|
|
11391
|
+
constructor(os33) {
|
|
11392
|
+
this.os = os33;
|
|
11370
11393
|
}
|
|
11371
11394
|
getDefaultArgs() {
|
|
11372
11395
|
return ["review"];
|
|
@@ -11481,10 +11504,10 @@ function cursorCredentialLocator() {
|
|
|
11481
11504
|
extract: extractLocalCursorToken
|
|
11482
11505
|
};
|
|
11483
11506
|
}
|
|
11484
|
-
function cursorLoginLauncher(
|
|
11507
|
+
function cursorLoginLauncher(os33) {
|
|
11485
11508
|
return {
|
|
11486
11509
|
async ensureInstalled() {
|
|
11487
|
-
if (
|
|
11510
|
+
if (os33.findInPath("cursor-agent")) return true;
|
|
11488
11511
|
console.error(
|
|
11489
11512
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
11490
11513
|
);
|
|
@@ -11546,8 +11569,8 @@ var CursorRuntimeStrategy = class {
|
|
|
11546
11569
|
meta = getAgent("cursor");
|
|
11547
11570
|
mode = "interactive";
|
|
11548
11571
|
os;
|
|
11549
|
-
constructor(
|
|
11550
|
-
this.os =
|
|
11572
|
+
constructor(os33) {
|
|
11573
|
+
this.os = os33;
|
|
11551
11574
|
}
|
|
11552
11575
|
async prepareLaunch() {
|
|
11553
11576
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -11667,10 +11690,10 @@ function aiderCredentialLocator() {
|
|
|
11667
11690
|
extract: extractLocalAiderToken
|
|
11668
11691
|
};
|
|
11669
11692
|
}
|
|
11670
|
-
function aiderLoginLauncher(
|
|
11693
|
+
function aiderLoginLauncher(os33) {
|
|
11671
11694
|
return {
|
|
11672
11695
|
async ensureInstalled() {
|
|
11673
|
-
if (
|
|
11696
|
+
if (os33.findInPath("aider")) return true;
|
|
11674
11697
|
console.error(
|
|
11675
11698
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
11676
11699
|
);
|
|
@@ -11680,7 +11703,7 @@ function aiderLoginLauncher(os32) {
|
|
|
11680
11703
|
console.error(
|
|
11681
11704
|
"\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"
|
|
11682
11705
|
);
|
|
11683
|
-
return (0, import_node_child_process9.spawn)(
|
|
11706
|
+
return (0, import_node_child_process9.spawn)(os33.id === "win32" ? "cmd.exe" : "sh", os33.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
11684
11707
|
stdio: "ignore"
|
|
11685
11708
|
});
|
|
11686
11709
|
}
|
|
@@ -11752,8 +11775,8 @@ var AiderRuntimeStrategy = class {
|
|
|
11752
11775
|
meta = getAgent("aider");
|
|
11753
11776
|
mode = "interactive";
|
|
11754
11777
|
os;
|
|
11755
|
-
constructor(
|
|
11756
|
-
this.os =
|
|
11778
|
+
constructor(os33) {
|
|
11779
|
+
this.os = os33;
|
|
11757
11780
|
}
|
|
11758
11781
|
async prepareLaunch() {
|
|
11759
11782
|
const binary = this.os.findInPath("aider");
|
|
@@ -11882,8 +11905,8 @@ function geminiCredentialLocator() {
|
|
|
11882
11905
|
function geminiLoginLauncher() {
|
|
11883
11906
|
return {
|
|
11884
11907
|
async ensureInstalled() {
|
|
11885
|
-
const
|
|
11886
|
-
return
|
|
11908
|
+
const os33 = createOsStrategy();
|
|
11909
|
+
return os33.findInPath("gemini") !== null;
|
|
11887
11910
|
},
|
|
11888
11911
|
launch() {
|
|
11889
11912
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -11916,8 +11939,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
11916
11939
|
meta = getAgent("gemini");
|
|
11917
11940
|
mode = "interactive";
|
|
11918
11941
|
os;
|
|
11919
|
-
constructor(
|
|
11920
|
-
this.os =
|
|
11942
|
+
constructor(os33) {
|
|
11943
|
+
this.os = os33;
|
|
11921
11944
|
}
|
|
11922
11945
|
async prepareLaunch() {
|
|
11923
11946
|
const binary = this.os.findInPath("gemini");
|
|
@@ -12017,18 +12040,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
12017
12040
|
|
|
12018
12041
|
// src/agents/registry.ts
|
|
12019
12042
|
var runtimeBuilders = {
|
|
12020
|
-
claude: (
|
|
12021
|
-
codex: (
|
|
12022
|
-
coderabbit: (
|
|
12023
|
-
cursor: (
|
|
12024
|
-
aider: (
|
|
12025
|
-
gemini: (
|
|
12043
|
+
claude: (os33) => new ClaudeRuntimeStrategy(os33),
|
|
12044
|
+
codex: (os33) => new CodexRuntimeStrategy(os33),
|
|
12045
|
+
coderabbit: (os33) => new CoderabbitRuntimeStrategy(os33),
|
|
12046
|
+
cursor: (os33) => new CursorRuntimeStrategy(os33),
|
|
12047
|
+
aider: (os33) => new AiderRuntimeStrategy(os33),
|
|
12048
|
+
gemini: (os33) => new GeminiRuntimeStrategy(os33)
|
|
12026
12049
|
};
|
|
12027
12050
|
var deployBuilders = {
|
|
12028
12051
|
claude: () => new ClaudeDeployStrategy(),
|
|
12029
12052
|
codex: () => new CodexDeployStrategy()
|
|
12030
12053
|
};
|
|
12031
|
-
function createAgentStrategy(agent,
|
|
12054
|
+
function createAgentStrategy(agent, os33 = createOsStrategy()) {
|
|
12032
12055
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
12033
12056
|
throw new Error(
|
|
12034
12057
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -12038,10 +12061,10 @@ function createAgentStrategy(agent, os32 = createOsStrategy()) {
|
|
|
12038
12061
|
if (!build) {
|
|
12039
12062
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
12040
12063
|
}
|
|
12041
|
-
return build(
|
|
12064
|
+
return build(os33);
|
|
12042
12065
|
}
|
|
12043
|
-
function createInteractiveAgentStrategy(agent,
|
|
12044
|
-
const s = createAgentStrategy(agent,
|
|
12066
|
+
function createInteractiveAgentStrategy(agent, os33 = createOsStrategy()) {
|
|
12067
|
+
const s = createAgentStrategy(agent, os33);
|
|
12045
12068
|
if (s.mode !== "interactive") {
|
|
12046
12069
|
throw new Error(
|
|
12047
12070
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -17970,11 +17993,11 @@ function resolveDoltInstallStrategy(platform2) {
|
|
|
17970
17993
|
}
|
|
17971
17994
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17972
17995
|
function doltPlatformTuple(platform2, arch) {
|
|
17973
|
-
const
|
|
17996
|
+
const os33 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
|
|
17974
17997
|
const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
17975
17998
|
if (!a) return null;
|
|
17976
|
-
if (
|
|
17977
|
-
return `${
|
|
17999
|
+
if (os33 === "windows" && a !== "amd64") return null;
|
|
18000
|
+
return `${os33}-${a}`;
|
|
17978
18001
|
}
|
|
17979
18002
|
function resolveDoltTarballStrategy(targetDir, platform2, arch) {
|
|
17980
18003
|
const tuple = doltPlatformTuple(platform2, arch);
|
|
@@ -19457,6 +19480,9 @@ var requestPreviewDetectH = (ctx) => {
|
|
|
19457
19480
|
return;
|
|
19458
19481
|
}
|
|
19459
19482
|
log.info("preview", `detect: ${detection.framework} on :${detection.port} (took ${tookMs}ms)`);
|
|
19483
|
+
void writePreviewConfig(process.cwd(), detection).catch((err) => {
|
|
19484
|
+
log.info("preview", `detect: writePreviewConfig failed (non-fatal): ${String(err)}`);
|
|
19485
|
+
});
|
|
19460
19486
|
void postPreviewEvent({
|
|
19461
19487
|
sessionId: ctx.sessionId,
|
|
19462
19488
|
pluginId: ctx.pluginId,
|
|
@@ -20085,10 +20111,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
20085
20111
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
20086
20112
|
/[\\/]Templates([\\/]|$)/i
|
|
20087
20113
|
];
|
|
20088
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
20114
|
+
function isUnsafeWindowsWatchRoot(dir, homedir26) {
|
|
20089
20115
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
20090
20116
|
const cwd = norm(dir);
|
|
20091
|
-
const home = norm(
|
|
20117
|
+
const home = norm(homedir26);
|
|
20092
20118
|
if (cwd === home) return true;
|
|
20093
20119
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
20094
20120
|
const sysRoots = [
|
|
@@ -20882,7 +20908,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20882
20908
|
});
|
|
20883
20909
|
}
|
|
20884
20910
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20885
|
-
const
|
|
20911
|
+
const fs43 = await import("fs/promises");
|
|
20886
20912
|
const out2 = [];
|
|
20887
20913
|
await walk(workingDir, 0);
|
|
20888
20914
|
return out2;
|
|
@@ -20890,7 +20916,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20890
20916
|
if (depth > maxDepth) return;
|
|
20891
20917
|
let entries = [];
|
|
20892
20918
|
try {
|
|
20893
|
-
const dirents = await
|
|
20919
|
+
const dirents = await fs43.readdir(dir, { withFileTypes: true });
|
|
20894
20920
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20895
20921
|
} catch {
|
|
20896
20922
|
return;
|
|
@@ -23843,6 +23869,34 @@ function buildKeepAlive(ctx) {
|
|
|
23843
23869
|
};
|
|
23844
23870
|
}
|
|
23845
23871
|
|
|
23872
|
+
// src/agents/claude/onboarding.ts
|
|
23873
|
+
var fs39 = __toESM(require("fs"));
|
|
23874
|
+
var os30 = __toESM(require("os"));
|
|
23875
|
+
var path47 = __toESM(require("path"));
|
|
23876
|
+
function ensureClaudeOnboarded() {
|
|
23877
|
+
try {
|
|
23878
|
+
const file = path47.join(os30.homedir(), ".claude.json");
|
|
23879
|
+
let config = {};
|
|
23880
|
+
try {
|
|
23881
|
+
config = JSON.parse(fs39.readFileSync(file, "utf8"));
|
|
23882
|
+
} catch {
|
|
23883
|
+
}
|
|
23884
|
+
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
23885
|
+
return;
|
|
23886
|
+
}
|
|
23887
|
+
config.hasCompletedOnboarding = true;
|
|
23888
|
+
config.theme = typeof config.theme === "string" ? config.theme : "dark";
|
|
23889
|
+
if (typeof config.lastOnboardingVersion !== "string") {
|
|
23890
|
+
config.lastOnboardingVersion = "2.1.177";
|
|
23891
|
+
}
|
|
23892
|
+
fs39.mkdirSync(path47.dirname(file), { recursive: true });
|
|
23893
|
+
fs39.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
23894
|
+
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
23895
|
+
} catch (err) {
|
|
23896
|
+
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
23897
|
+
}
|
|
23898
|
+
}
|
|
23899
|
+
|
|
23846
23900
|
// src/commands/start.ts
|
|
23847
23901
|
async function start(requestedAgent) {
|
|
23848
23902
|
showIntro();
|
|
@@ -23897,6 +23951,7 @@ async function start(requestedAgent) {
|
|
|
23897
23951
|
"pluginAuth",
|
|
23898
23952
|
`boot triple sessionId=${session.id} pluginId=${pluginId} tokenLen=${tokenForLog.length} tokenHead=${tokenForLog.slice(0, 12)} tokenTail=${tokenForLog.slice(-8)} mintedEqualsCached=${refreshed === session.pluginAuthToken}`
|
|
23899
23953
|
);
|
|
23954
|
+
if (process.env.CODESPACES === "true") ensureClaudeOnboarded();
|
|
23900
23955
|
let beads = null;
|
|
23901
23956
|
const getBeads = () => beads;
|
|
23902
23957
|
const beadsReady = provisionBeadsForStart({
|
|
@@ -24312,9 +24367,9 @@ async function autoLinkAfterPair(opts) {
|
|
|
24312
24367
|
}
|
|
24313
24368
|
|
|
24314
24369
|
// src/commands/pair-auto.ts
|
|
24315
|
-
var
|
|
24316
|
-
var
|
|
24317
|
-
var
|
|
24370
|
+
var fs40 = __toESM(require("fs"));
|
|
24371
|
+
var os31 = __toESM(require("os"));
|
|
24372
|
+
var path48 = __toESM(require("path"));
|
|
24318
24373
|
var import_crypto7 = require("crypto");
|
|
24319
24374
|
|
|
24320
24375
|
// src/commands/start-infra-only.ts
|
|
@@ -24509,12 +24564,12 @@ function readTokenFromArgs(args2) {
|
|
|
24509
24564
|
}
|
|
24510
24565
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24511
24566
|
if (fileFlag) {
|
|
24512
|
-
const
|
|
24567
|
+
const path55 = fileFlag.slice("--token-file=".length);
|
|
24513
24568
|
try {
|
|
24514
|
-
const content =
|
|
24515
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24569
|
+
const content = fs40.readFileSync(path55, "utf8").trim();
|
|
24570
|
+
if (content.length === 0) fail(`--token-file ${path55} is empty`);
|
|
24516
24571
|
try {
|
|
24517
|
-
|
|
24572
|
+
fs40.unlinkSync(path55);
|
|
24518
24573
|
} catch {
|
|
24519
24574
|
}
|
|
24520
24575
|
return content;
|
|
@@ -24540,7 +24595,7 @@ async function claimOnce(token, pluginId) {
|
|
|
24540
24595
|
pluginId,
|
|
24541
24596
|
ideName: "codeam-cli (codespace)",
|
|
24542
24597
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
24543
|
-
hostname:
|
|
24598
|
+
hostname: os31.hostname(),
|
|
24544
24599
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
24545
24600
|
// Current git branch of the codespace's working directory, so the
|
|
24546
24601
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24597,7 +24652,7 @@ async function claim(token, pluginId) {
|
|
|
24597
24652
|
}
|
|
24598
24653
|
}
|
|
24599
24654
|
function pairAutoLockPath() {
|
|
24600
|
-
return
|
|
24655
|
+
return path48.join(os31.homedir(), ".codeam", "pair-auto.lock");
|
|
24601
24656
|
}
|
|
24602
24657
|
function isLivePairAuto(pid) {
|
|
24603
24658
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -24607,7 +24662,7 @@ function isLivePairAuto(pid) {
|
|
|
24607
24662
|
if (e.code !== "EPERM") return false;
|
|
24608
24663
|
}
|
|
24609
24664
|
try {
|
|
24610
|
-
return
|
|
24665
|
+
return fs40.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
24611
24666
|
} catch {
|
|
24612
24667
|
return true;
|
|
24613
24668
|
}
|
|
@@ -24615,19 +24670,19 @@ function isLivePairAuto(pid) {
|
|
|
24615
24670
|
function acquireSingletonLock() {
|
|
24616
24671
|
const lockPath = pairAutoLockPath();
|
|
24617
24672
|
try {
|
|
24618
|
-
|
|
24673
|
+
fs40.mkdirSync(path48.dirname(lockPath), { recursive: true });
|
|
24619
24674
|
try {
|
|
24620
|
-
|
|
24675
|
+
fs40.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
24621
24676
|
} catch (e) {
|
|
24622
24677
|
if (e.code !== "EEXIST") throw e;
|
|
24623
|
-
const holder = Number(
|
|
24678
|
+
const holder = Number(fs40.readFileSync(lockPath, "utf8").trim());
|
|
24624
24679
|
if (isLivePairAuto(holder)) return false;
|
|
24625
|
-
|
|
24680
|
+
fs40.writeFileSync(lockPath, String(process.pid));
|
|
24626
24681
|
}
|
|
24627
24682
|
process.once("exit", () => {
|
|
24628
24683
|
try {
|
|
24629
|
-
if (
|
|
24630
|
-
|
|
24684
|
+
if (fs40.existsSync(lockPath) && Number(fs40.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24685
|
+
fs40.unlinkSync(lockPath);
|
|
24631
24686
|
}
|
|
24632
24687
|
} catch {
|
|
24633
24688
|
}
|
|
@@ -24826,7 +24881,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24826
24881
|
var import_child_process22 = require("child_process");
|
|
24827
24882
|
var import_util4 = require("util");
|
|
24828
24883
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24829
|
-
var
|
|
24884
|
+
var path49 = __toESM(require("path"));
|
|
24830
24885
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24831
24886
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24832
24887
|
function resetStdinForChild() {
|
|
@@ -25315,7 +25370,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25315
25370
|
});
|
|
25316
25371
|
}
|
|
25317
25372
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25318
|
-
const remoteDir =
|
|
25373
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25319
25374
|
const parts = [
|
|
25320
25375
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25321
25376
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25385,7 +25440,7 @@ function shellQuote(s) {
|
|
|
25385
25440
|
// src/services/providers/gitpod.ts
|
|
25386
25441
|
var import_child_process23 = require("child_process");
|
|
25387
25442
|
var import_util5 = require("util");
|
|
25388
|
-
var
|
|
25443
|
+
var path50 = __toESM(require("path"));
|
|
25389
25444
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25390
25445
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25391
25446
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25625,7 +25680,7 @@ var GitpodProvider = class {
|
|
|
25625
25680
|
});
|
|
25626
25681
|
}
|
|
25627
25682
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25628
|
-
const remoteDir =
|
|
25683
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25629
25684
|
const parts = [
|
|
25630
25685
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25631
25686
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25661,7 +25716,7 @@ function shellQuote2(s) {
|
|
|
25661
25716
|
// src/services/providers/gitlab-workspaces.ts
|
|
25662
25717
|
var import_child_process24 = require("child_process");
|
|
25663
25718
|
var import_util6 = require("util");
|
|
25664
|
-
var
|
|
25719
|
+
var path51 = __toESM(require("path"));
|
|
25665
25720
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25666
25721
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25667
25722
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25921,7 +25976,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25921
25976
|
}
|
|
25922
25977
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25923
25978
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25924
|
-
const remoteDir =
|
|
25979
|
+
const remoteDir = path51.posix.dirname(remotePath);
|
|
25925
25980
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25926
25981
|
if (options.mode != null) {
|
|
25927
25982
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25989,7 +26044,7 @@ function shellQuote3(s) {
|
|
|
25989
26044
|
// src/services/providers/railway.ts
|
|
25990
26045
|
var import_child_process25 = require("child_process");
|
|
25991
26046
|
var import_util7 = require("util");
|
|
25992
|
-
var
|
|
26047
|
+
var path52 = __toESM(require("path"));
|
|
25993
26048
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25994
26049
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25995
26050
|
function resetStdinForChild4() {
|
|
@@ -26225,7 +26280,7 @@ var RailwayProvider = class {
|
|
|
26225
26280
|
if (!projectId || !serviceId) {
|
|
26226
26281
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
26227
26282
|
}
|
|
26228
|
-
const remoteDir =
|
|
26283
|
+
const remoteDir = path52.posix.dirname(remotePath);
|
|
26229
26284
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
26230
26285
|
if (options.mode != null) {
|
|
26231
26286
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26768,8 +26823,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26768
26823
|
var import_node_dns = require("dns");
|
|
26769
26824
|
var import_node_util4 = require("util");
|
|
26770
26825
|
var import_node_crypto8 = require("crypto");
|
|
26771
|
-
var
|
|
26772
|
-
var
|
|
26826
|
+
var fs41 = __toESM(require("fs"));
|
|
26827
|
+
var path53 = __toESM(require("path"));
|
|
26773
26828
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26774
26829
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26775
26830
|
async function checkDns(apiBase) {
|
|
@@ -26825,13 +26880,13 @@ async function checkHealth(apiBase) {
|
|
|
26825
26880
|
}
|
|
26826
26881
|
}
|
|
26827
26882
|
function checkConfigDir() {
|
|
26828
|
-
const dir =
|
|
26883
|
+
const dir = path53.join(require("os").homedir(), ".codeam");
|
|
26829
26884
|
try {
|
|
26830
|
-
|
|
26831
|
-
const probe =
|
|
26832
|
-
|
|
26833
|
-
const read =
|
|
26834
|
-
|
|
26885
|
+
fs41.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26886
|
+
const probe = path53.join(dir, ".doctor-probe");
|
|
26887
|
+
fs41.writeFileSync(probe, "ok", { mode: 384 });
|
|
26888
|
+
const read = fs41.readFileSync(probe, "utf8");
|
|
26889
|
+
fs41.unlinkSync(probe);
|
|
26835
26890
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26836
26891
|
return {
|
|
26837
26892
|
id: "config-dir",
|
|
@@ -26871,9 +26926,9 @@ function checkSessions() {
|
|
|
26871
26926
|
}
|
|
26872
26927
|
}
|
|
26873
26928
|
function checkAgentBinaries() {
|
|
26874
|
-
const
|
|
26929
|
+
const os33 = createOsStrategy();
|
|
26875
26930
|
return getEnabledAgents().map((meta) => {
|
|
26876
|
-
const found =
|
|
26931
|
+
const found = os33.findInPath(meta.binaryName);
|
|
26877
26932
|
return {
|
|
26878
26933
|
id: `agent-${meta.id}`,
|
|
26879
26934
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -26895,7 +26950,7 @@ function checkNodePty() {
|
|
|
26895
26950
|
detail: "not required on this platform"
|
|
26896
26951
|
};
|
|
26897
26952
|
}
|
|
26898
|
-
const vendoredPath =
|
|
26953
|
+
const vendoredPath = path53.join(__dirname, "vendor", "node-pty");
|
|
26899
26954
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26900
26955
|
try {
|
|
26901
26956
|
require(target);
|
|
@@ -26937,7 +26992,7 @@ function checkChokidar() {
|
|
|
26937
26992
|
}
|
|
26938
26993
|
async function doctor(args2 = []) {
|
|
26939
26994
|
const json = args2.includes("--json");
|
|
26940
|
-
const cliVersion = true ? "2.39.
|
|
26995
|
+
const cliVersion = true ? "2.39.11" : "0.0.0-dev";
|
|
26941
26996
|
const apiBase = resolveApiBaseUrl();
|
|
26942
26997
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26943
26998
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -27136,7 +27191,7 @@ async function completion(args2) {
|
|
|
27136
27191
|
// src/commands/version.ts
|
|
27137
27192
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
27138
27193
|
function version2() {
|
|
27139
|
-
const v = true ? "2.39.
|
|
27194
|
+
const v = true ? "2.39.11" : "unknown";
|
|
27140
27195
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
27141
27196
|
}
|
|
27142
27197
|
|
|
@@ -27264,9 +27319,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
27264
27319
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
27265
27320
|
|
|
27266
27321
|
// src/lib/updateNotifier.ts
|
|
27267
|
-
var
|
|
27268
|
-
var
|
|
27269
|
-
var
|
|
27322
|
+
var fs42 = __toESM(require("fs"));
|
|
27323
|
+
var os32 = __toESM(require("os"));
|
|
27324
|
+
var path54 = __toESM(require("path"));
|
|
27270
27325
|
var https8 = __toESM(require("https"));
|
|
27271
27326
|
var import_node_child_process12 = require("child_process");
|
|
27272
27327
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -27275,12 +27330,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27275
27330
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27276
27331
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27277
27332
|
function cachePath() {
|
|
27278
|
-
const dir =
|
|
27279
|
-
return
|
|
27333
|
+
const dir = path54.join(os32.homedir(), ".codeam");
|
|
27334
|
+
return path54.join(dir, "update-check.json");
|
|
27280
27335
|
}
|
|
27281
27336
|
function readCache() {
|
|
27282
27337
|
try {
|
|
27283
|
-
const raw =
|
|
27338
|
+
const raw = fs42.readFileSync(cachePath(), "utf8");
|
|
27284
27339
|
const parsed = JSON.parse(raw);
|
|
27285
27340
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
27286
27341
|
return parsed;
|
|
@@ -27291,10 +27346,10 @@ function readCache() {
|
|
|
27291
27346
|
function writeCache(cache) {
|
|
27292
27347
|
try {
|
|
27293
27348
|
const file = cachePath();
|
|
27294
|
-
|
|
27349
|
+
fs42.mkdirSync(path54.dirname(file), { recursive: true });
|
|
27295
27350
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27296
|
-
|
|
27297
|
-
|
|
27351
|
+
fs42.writeFileSync(tmp, JSON.stringify(cache));
|
|
27352
|
+
fs42.renameSync(tmp, file);
|
|
27298
27353
|
} catch {
|
|
27299
27354
|
}
|
|
27300
27355
|
}
|
|
@@ -27368,8 +27423,8 @@ function isLinkedInstall() {
|
|
|
27368
27423
|
timeout: 2e3
|
|
27369
27424
|
}).trim();
|
|
27370
27425
|
if (!root) return false;
|
|
27371
|
-
const pkgPath =
|
|
27372
|
-
return
|
|
27426
|
+
const pkgPath = path54.join(root, PKG_NAME);
|
|
27427
|
+
return fs42.lstatSync(pkgPath).isSymbolicLink();
|
|
27373
27428
|
} catch {
|
|
27374
27429
|
return false;
|
|
27375
27430
|
}
|
|
@@ -27405,7 +27460,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27405
27460
|
return;
|
|
27406
27461
|
}
|
|
27407
27462
|
try {
|
|
27408
|
-
|
|
27463
|
+
fs42.unlinkSync(cachePath());
|
|
27409
27464
|
} catch {
|
|
27410
27465
|
}
|
|
27411
27466
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27422,7 +27477,7 @@ function checkForUpdates() {
|
|
|
27422
27477
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27423
27478
|
if (process.env.CI) return;
|
|
27424
27479
|
if (!process.stdout.isTTY) return;
|
|
27425
|
-
const current = true ? "2.39.
|
|
27480
|
+
const current = true ? "2.39.11" : null;
|
|
27426
27481
|
if (!current) return;
|
|
27427
27482
|
const cache = readCache();
|
|
27428
27483
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.11",
|
|
4
4
|
"description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|