codeam-cli 2.39.2 → 2.39.3
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 +6 -0
- package/dist/index.js +88 -41
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.2] — 2026-06-12
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Pre-warm preview detection so the first Start Preview is instant
|
|
12
|
+
|
|
7
13
|
## [2.39.1] — 2026-06-12
|
|
8
14
|
|
|
9
15
|
### 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.3",
|
|
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(path53) {
|
|
1190
|
+
return path53.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(path53, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path53);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path52, 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(path53, 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(path53) {
|
|
3749
|
+
return path53.startsWith("node:") || path53.endsWith(".min.js") || path53.endsWith(".min.cjs") || path53.endsWith(".min.mjs") || path53.startsWith("data:");
|
|
3750
3750
|
}
|
|
3751
3751
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3752
3752
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5900,7 +5900,7 @@ function readAnonId() {
|
|
|
5900
5900
|
}
|
|
5901
5901
|
function superProperties() {
|
|
5902
5902
|
return {
|
|
5903
|
-
cliVersion: true ? "2.39.
|
|
5903
|
+
cliVersion: true ? "2.39.3" : "0.0.0-dev",
|
|
5904
5904
|
nodeVersion: process.version,
|
|
5905
5905
|
platform: process.platform,
|
|
5906
5906
|
arch: process.arch,
|
|
@@ -9978,13 +9978,13 @@ function detectStartupBanner(lines) {
|
|
|
9978
9978
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9979
9979
|
if (metaIdx - artStart < 2) return null;
|
|
9980
9980
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9981
|
-
const
|
|
9981
|
+
const path53 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path53,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path53 ? 1 : 0)
|
|
9988
9988
|
};
|
|
9989
9989
|
}
|
|
9990
9990
|
|
|
@@ -11342,11 +11342,11 @@ function parseReview(stdout) {
|
|
|
11342
11342
|
for (const line of lines) {
|
|
11343
11343
|
const m = line.match(HUNK_LINE_RE);
|
|
11344
11344
|
if (!m) continue;
|
|
11345
|
-
const [,
|
|
11346
|
-
if (!
|
|
11345
|
+
const [, path53, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path53 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path53.trim(),
|
|
11350
11350
|
line: Number(lineNo),
|
|
11351
11351
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11352
|
message: cleanedMessage
|
|
@@ -19891,10 +19891,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19891
19891
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19892
19892
|
/[\\/]Templates([\\/]|$)/i
|
|
19893
19893
|
];
|
|
19894
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
19894
|
+
function isUnsafeWindowsWatchRoot(dir, homedir25) {
|
|
19895
19895
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19896
19896
|
const cwd = norm(dir);
|
|
19897
|
-
const home = norm(
|
|
19897
|
+
const home = norm(homedir25);
|
|
19898
19898
|
if (cwd === home) return true;
|
|
19899
19899
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19900
19900
|
const sysRoots = [
|
|
@@ -24105,6 +24105,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
24105
24105
|
// src/commands/pair-auto.ts
|
|
24106
24106
|
var fs38 = __toESM(require("fs"));
|
|
24107
24107
|
var os30 = __toESM(require("os"));
|
|
24108
|
+
var path46 = __toESM(require("path"));
|
|
24108
24109
|
var import_crypto7 = require("crypto");
|
|
24109
24110
|
|
|
24110
24111
|
// src/commands/start-infra-only.ts
|
|
@@ -24299,12 +24300,12 @@ function readTokenFromArgs(args2) {
|
|
|
24299
24300
|
}
|
|
24300
24301
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24301
24302
|
if (fileFlag) {
|
|
24302
|
-
const
|
|
24303
|
+
const path53 = fileFlag.slice("--token-file=".length);
|
|
24303
24304
|
try {
|
|
24304
|
-
const content = fs38.readFileSync(
|
|
24305
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24305
|
+
const content = fs38.readFileSync(path53, "utf8").trim();
|
|
24306
|
+
if (content.length === 0) fail(`--token-file ${path53} is empty`);
|
|
24306
24307
|
try {
|
|
24307
|
-
fs38.unlinkSync(
|
|
24308
|
+
fs38.unlinkSync(path53);
|
|
24308
24309
|
} catch {
|
|
24309
24310
|
}
|
|
24310
24311
|
return content;
|
|
@@ -24386,7 +24387,53 @@ async function claim(token, pluginId) {
|
|
|
24386
24387
|
}
|
|
24387
24388
|
}
|
|
24388
24389
|
}
|
|
24390
|
+
function pairAutoLockPath() {
|
|
24391
|
+
return path46.join(os30.homedir(), ".codeam", "pair-auto.lock");
|
|
24392
|
+
}
|
|
24393
|
+
function isLivePairAuto(pid) {
|
|
24394
|
+
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
24395
|
+
try {
|
|
24396
|
+
process.kill(pid, 0);
|
|
24397
|
+
} catch (e) {
|
|
24398
|
+
if (e.code !== "EPERM") return false;
|
|
24399
|
+
}
|
|
24400
|
+
try {
|
|
24401
|
+
return fs38.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
24402
|
+
} catch {
|
|
24403
|
+
return true;
|
|
24404
|
+
}
|
|
24405
|
+
}
|
|
24406
|
+
function acquireSingletonLock() {
|
|
24407
|
+
const lockPath = pairAutoLockPath();
|
|
24408
|
+
try {
|
|
24409
|
+
fs38.mkdirSync(path46.dirname(lockPath), { recursive: true });
|
|
24410
|
+
try {
|
|
24411
|
+
fs38.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
24412
|
+
} catch (e) {
|
|
24413
|
+
if (e.code !== "EEXIST") throw e;
|
|
24414
|
+
const holder = Number(fs38.readFileSync(lockPath, "utf8").trim());
|
|
24415
|
+
if (isLivePairAuto(holder)) return false;
|
|
24416
|
+
fs38.writeFileSync(lockPath, String(process.pid));
|
|
24417
|
+
}
|
|
24418
|
+
process.once("exit", () => {
|
|
24419
|
+
try {
|
|
24420
|
+
if (fs38.existsSync(lockPath) && Number(fs38.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24421
|
+
fs38.unlinkSync(lockPath);
|
|
24422
|
+
}
|
|
24423
|
+
} catch {
|
|
24424
|
+
}
|
|
24425
|
+
});
|
|
24426
|
+
return true;
|
|
24427
|
+
} catch {
|
|
24428
|
+
return true;
|
|
24429
|
+
}
|
|
24430
|
+
}
|
|
24389
24431
|
async function pairAuto(args2) {
|
|
24432
|
+
if (!acquireSingletonLock()) {
|
|
24433
|
+
capture("pair_auto_deferred_singleton", {});
|
|
24434
|
+
console.log(" A codeam session is already running here \u2014 deferring to it.");
|
|
24435
|
+
return;
|
|
24436
|
+
}
|
|
24390
24437
|
const token = readTokenFromArgs(args2);
|
|
24391
24438
|
const pluginId = (0, import_crypto7.randomUUID)();
|
|
24392
24439
|
capture("pair_auto_started", { pluginId });
|
|
@@ -24570,7 +24617,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24570
24617
|
var import_child_process22 = require("child_process");
|
|
24571
24618
|
var import_util4 = require("util");
|
|
24572
24619
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24573
|
-
var
|
|
24620
|
+
var path47 = __toESM(require("path"));
|
|
24574
24621
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24575
24622
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24576
24623
|
function resetStdinForChild() {
|
|
@@ -25059,7 +25106,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25059
25106
|
});
|
|
25060
25107
|
}
|
|
25061
25108
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25062
|
-
const remoteDir =
|
|
25109
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25063
25110
|
const parts = [
|
|
25064
25111
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25065
25112
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25129,7 +25176,7 @@ function shellQuote(s) {
|
|
|
25129
25176
|
// src/services/providers/gitpod.ts
|
|
25130
25177
|
var import_child_process23 = require("child_process");
|
|
25131
25178
|
var import_util5 = require("util");
|
|
25132
|
-
var
|
|
25179
|
+
var path48 = __toESM(require("path"));
|
|
25133
25180
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25134
25181
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25135
25182
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25369,7 +25416,7 @@ var GitpodProvider = class {
|
|
|
25369
25416
|
});
|
|
25370
25417
|
}
|
|
25371
25418
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25372
|
-
const remoteDir =
|
|
25419
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25373
25420
|
const parts = [
|
|
25374
25421
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25375
25422
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25405,7 +25452,7 @@ function shellQuote2(s) {
|
|
|
25405
25452
|
// src/services/providers/gitlab-workspaces.ts
|
|
25406
25453
|
var import_child_process24 = require("child_process");
|
|
25407
25454
|
var import_util6 = require("util");
|
|
25408
|
-
var
|
|
25455
|
+
var path49 = __toESM(require("path"));
|
|
25409
25456
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25410
25457
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25411
25458
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25665,7 +25712,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25665
25712
|
}
|
|
25666
25713
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25667
25714
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25668
|
-
const remoteDir =
|
|
25715
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25669
25716
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25670
25717
|
if (options.mode != null) {
|
|
25671
25718
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25733,7 +25780,7 @@ function shellQuote3(s) {
|
|
|
25733
25780
|
// src/services/providers/railway.ts
|
|
25734
25781
|
var import_child_process25 = require("child_process");
|
|
25735
25782
|
var import_util7 = require("util");
|
|
25736
|
-
var
|
|
25783
|
+
var path50 = __toESM(require("path"));
|
|
25737
25784
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25738
25785
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25739
25786
|
function resetStdinForChild4() {
|
|
@@ -25969,7 +26016,7 @@ var RailwayProvider = class {
|
|
|
25969
26016
|
if (!projectId || !serviceId) {
|
|
25970
26017
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25971
26018
|
}
|
|
25972
|
-
const remoteDir =
|
|
26019
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25973
26020
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25974
26021
|
if (options.mode != null) {
|
|
25975
26022
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26513,7 +26560,7 @@ var import_node_dns = require("dns");
|
|
|
26513
26560
|
var import_node_util4 = require("util");
|
|
26514
26561
|
var import_node_crypto8 = require("crypto");
|
|
26515
26562
|
var fs39 = __toESM(require("fs"));
|
|
26516
|
-
var
|
|
26563
|
+
var path51 = __toESM(require("path"));
|
|
26517
26564
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26518
26565
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26519
26566
|
async function checkDns(apiBase) {
|
|
@@ -26569,10 +26616,10 @@ async function checkHealth(apiBase) {
|
|
|
26569
26616
|
}
|
|
26570
26617
|
}
|
|
26571
26618
|
function checkConfigDir() {
|
|
26572
|
-
const dir =
|
|
26619
|
+
const dir = path51.join(require("os").homedir(), ".codeam");
|
|
26573
26620
|
try {
|
|
26574
26621
|
fs39.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26575
|
-
const probe =
|
|
26622
|
+
const probe = path51.join(dir, ".doctor-probe");
|
|
26576
26623
|
fs39.writeFileSync(probe, "ok", { mode: 384 });
|
|
26577
26624
|
const read = fs39.readFileSync(probe, "utf8");
|
|
26578
26625
|
fs39.unlinkSync(probe);
|
|
@@ -26639,7 +26686,7 @@ function checkNodePty() {
|
|
|
26639
26686
|
detail: "not required on this platform"
|
|
26640
26687
|
};
|
|
26641
26688
|
}
|
|
26642
|
-
const vendoredPath =
|
|
26689
|
+
const vendoredPath = path51.join(__dirname, "vendor", "node-pty");
|
|
26643
26690
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26644
26691
|
try {
|
|
26645
26692
|
require(target);
|
|
@@ -26681,7 +26728,7 @@ function checkChokidar() {
|
|
|
26681
26728
|
}
|
|
26682
26729
|
async function doctor(args2 = []) {
|
|
26683
26730
|
const json = args2.includes("--json");
|
|
26684
|
-
const cliVersion = true ? "2.39.
|
|
26731
|
+
const cliVersion = true ? "2.39.3" : "0.0.0-dev";
|
|
26685
26732
|
const apiBase = resolveApiBaseUrl();
|
|
26686
26733
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26687
26734
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26880,7 +26927,7 @@ async function completion(args2) {
|
|
|
26880
26927
|
// src/commands/version.ts
|
|
26881
26928
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26882
26929
|
function version2() {
|
|
26883
|
-
const v = true ? "2.39.
|
|
26930
|
+
const v = true ? "2.39.3" : "unknown";
|
|
26884
26931
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26885
26932
|
}
|
|
26886
26933
|
|
|
@@ -27010,7 +27057,7 @@ var _subcommandHelpKeys = Object.keys(HELPS);
|
|
|
27010
27057
|
// src/lib/updateNotifier.ts
|
|
27011
27058
|
var fs40 = __toESM(require("fs"));
|
|
27012
27059
|
var os31 = __toESM(require("os"));
|
|
27013
|
-
var
|
|
27060
|
+
var path52 = __toESM(require("path"));
|
|
27014
27061
|
var https8 = __toESM(require("https"));
|
|
27015
27062
|
var import_node_child_process12 = require("child_process");
|
|
27016
27063
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -27019,8 +27066,8 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27019
27066
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27020
27067
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27021
27068
|
function cachePath() {
|
|
27022
|
-
const dir =
|
|
27023
|
-
return
|
|
27069
|
+
const dir = path52.join(os31.homedir(), ".codeam");
|
|
27070
|
+
return path52.join(dir, "update-check.json");
|
|
27024
27071
|
}
|
|
27025
27072
|
function readCache() {
|
|
27026
27073
|
try {
|
|
@@ -27035,7 +27082,7 @@ function readCache() {
|
|
|
27035
27082
|
function writeCache(cache) {
|
|
27036
27083
|
try {
|
|
27037
27084
|
const file = cachePath();
|
|
27038
|
-
fs40.mkdirSync(
|
|
27085
|
+
fs40.mkdirSync(path52.dirname(file), { recursive: true });
|
|
27039
27086
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27040
27087
|
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
27041
27088
|
fs40.renameSync(tmp, file);
|
|
@@ -27112,7 +27159,7 @@ function isLinkedInstall() {
|
|
|
27112
27159
|
timeout: 2e3
|
|
27113
27160
|
}).trim();
|
|
27114
27161
|
if (!root) return false;
|
|
27115
|
-
const pkgPath =
|
|
27162
|
+
const pkgPath = path52.join(root, PKG_NAME);
|
|
27116
27163
|
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
27117
27164
|
} catch {
|
|
27118
27165
|
return false;
|
|
@@ -27166,7 +27213,7 @@ function checkForUpdates() {
|
|
|
27166
27213
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27167
27214
|
if (process.env.CI) return;
|
|
27168
27215
|
if (!process.stdout.isTTY) return;
|
|
27169
|
-
const current = true ? "2.39.
|
|
27216
|
+
const current = true ? "2.39.3" : null;
|
|
27170
27217
|
if (!current) return;
|
|
27171
27218
|
const cache = readCache();
|
|
27172
27219
|
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.3",
|
|
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",
|