codeam-cli 2.39.42 → 2.39.44
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 +143 -67
- 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.43] — 2026-06-19
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Extract macOS cloudflared .tgz + self-heal gzip-corrupt cache
|
|
12
|
+
|
|
13
|
+
## [2.39.42] — 2026-06-19
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Refuse preview + notify app when the detected port is in use
|
|
18
|
+
|
|
7
19
|
## [2.39.41] — 2026-06-19
|
|
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.44",
|
|
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",
|
|
@@ -5908,7 +5908,7 @@ function readAnonId() {
|
|
|
5908
5908
|
}
|
|
5909
5909
|
function superProperties() {
|
|
5910
5910
|
return {
|
|
5911
|
-
cliVersion: true ? "2.39.
|
|
5911
|
+
cliVersion: true ? "2.39.44" : "0.0.0-dev",
|
|
5912
5912
|
nodeVersion: process.version,
|
|
5913
5913
|
platform: process.platform,
|
|
5914
5914
|
arch: process.arch,
|
|
@@ -16480,7 +16480,10 @@ async function resolveCloudflared(opts = {}) {
|
|
|
16480
16480
|
}
|
|
16481
16481
|
try {
|
|
16482
16482
|
await import_promises.default.access(CACHED_BINARY);
|
|
16483
|
-
|
|
16483
|
+
if (await isExecutableBinary(CACHED_BINARY)) {
|
|
16484
|
+
return CACHED_BINARY;
|
|
16485
|
+
}
|
|
16486
|
+
await import_promises.default.rm(CACHED_BINARY, { force: true });
|
|
16484
16487
|
} catch {
|
|
16485
16488
|
}
|
|
16486
16489
|
if (opts.skipDownload) {
|
|
@@ -16500,11 +16503,53 @@ async function downloadCloudflared(target) {
|
|
|
16500
16503
|
`Failed to download cloudflared from ${url}: HTTP ${response.status}. Install manually from https://github.com/cloudflare/cloudflared/releases.`
|
|
16501
16504
|
);
|
|
16502
16505
|
}
|
|
16506
|
+
if (url.endsWith(".tgz")) {
|
|
16507
|
+
const tmp = `${target}.download.tgz`;
|
|
16508
|
+
await (0, import_promises2.pipeline)(
|
|
16509
|
+
response.body,
|
|
16510
|
+
(0, import_fs.createWriteStream)(tmp)
|
|
16511
|
+
);
|
|
16512
|
+
try {
|
|
16513
|
+
await extractTgz(tmp, import_path4.default.dirname(target));
|
|
16514
|
+
await import_promises.default.access(target);
|
|
16515
|
+
await import_promises.default.chmod(target, 493);
|
|
16516
|
+
} catch (err) {
|
|
16517
|
+
throw new Error(
|
|
16518
|
+
`Downloaded the cloudflared archive but could not extract the binary: ${err.message}. Install manually via \`brew install cloudflared\`.`
|
|
16519
|
+
);
|
|
16520
|
+
} finally {
|
|
16521
|
+
await import_promises.default.rm(tmp, { force: true });
|
|
16522
|
+
}
|
|
16523
|
+
return;
|
|
16524
|
+
}
|
|
16503
16525
|
await (0, import_promises2.pipeline)(
|
|
16504
16526
|
response.body,
|
|
16505
16527
|
(0, import_fs.createWriteStream)(target, { mode: 493 })
|
|
16506
16528
|
);
|
|
16507
16529
|
}
|
|
16530
|
+
async function isExecutableBinary(p2) {
|
|
16531
|
+
let handle;
|
|
16532
|
+
try {
|
|
16533
|
+
handle = await import_promises.default.open(p2, "r");
|
|
16534
|
+
const buf = Buffer.alloc(2);
|
|
16535
|
+
await handle.read(buf, 0, 2, 0);
|
|
16536
|
+
return !(buf[0] === 31 && buf[1] === 139);
|
|
16537
|
+
} catch {
|
|
16538
|
+
return false;
|
|
16539
|
+
} finally {
|
|
16540
|
+
await handle?.close();
|
|
16541
|
+
}
|
|
16542
|
+
}
|
|
16543
|
+
function extractTgz(tgzPath, destDir) {
|
|
16544
|
+
return new Promise((resolve7, reject) => {
|
|
16545
|
+
const child = (0, import_child_process11.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
|
|
16546
|
+
child.on("error", (err) => reject(err));
|
|
16547
|
+
child.on(
|
|
16548
|
+
"exit",
|
|
16549
|
+
(code) => code === 0 ? resolve7() : reject(new Error(`tar exited with code ${code} while extracting cloudflared`))
|
|
16550
|
+
);
|
|
16551
|
+
});
|
|
16552
|
+
}
|
|
16508
16553
|
function downloadUrlForPlatform() {
|
|
16509
16554
|
const platform3 = process.platform;
|
|
16510
16555
|
const arch2 = process.arch;
|
|
@@ -20208,6 +20253,7 @@ var import_crypto4 = require("crypto");
|
|
|
20208
20253
|
|
|
20209
20254
|
// src/services/turn-files/git-changeset.ts
|
|
20210
20255
|
var import_child_process21 = require("child_process");
|
|
20256
|
+
var fs37 = __toESM(require("fs/promises"));
|
|
20211
20257
|
var path44 = __toESM(require("path"));
|
|
20212
20258
|
async function collectRepoChangeset(opts) {
|
|
20213
20259
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
@@ -20222,7 +20268,16 @@ async function collectRepoChangeset(opts) {
|
|
|
20222
20268
|
const entries = [];
|
|
20223
20269
|
for (const row of parseStatus(status2)) {
|
|
20224
20270
|
if (isIgnoredFilePath(row.filePath)) continue;
|
|
20225
|
-
const
|
|
20271
|
+
const numstatEntry = numstat.get(row.filePath);
|
|
20272
|
+
let stats;
|
|
20273
|
+
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
20274
|
+
const lineCount = await readUntrackedLineCount(
|
|
20275
|
+
path44.join(opts.repoRoot, row.filePath)
|
|
20276
|
+
);
|
|
20277
|
+
stats = { added: lineCount, removed: 0 };
|
|
20278
|
+
} else {
|
|
20279
|
+
stats = numstatEntry ?? { added: 0, removed: 0 };
|
|
20280
|
+
}
|
|
20226
20281
|
entries.push({
|
|
20227
20282
|
filePath: row.filePath,
|
|
20228
20283
|
fileStatus: row.fileStatus,
|
|
@@ -20239,6 +20294,27 @@ async function collectRepoChangeset(opts) {
|
|
|
20239
20294
|
}
|
|
20240
20295
|
return entries;
|
|
20241
20296
|
}
|
|
20297
|
+
var MAX_UNTRACKED_LINE_SCAN = 1e5;
|
|
20298
|
+
var _readUntrackedLineCountImpl = {
|
|
20299
|
+
read: defaultReadUntrackedLineCount
|
|
20300
|
+
};
|
|
20301
|
+
function readUntrackedLineCount(absPath) {
|
|
20302
|
+
return _readUntrackedLineCountImpl.read(absPath);
|
|
20303
|
+
}
|
|
20304
|
+
async function defaultReadUntrackedLineCount(absPath) {
|
|
20305
|
+
try {
|
|
20306
|
+
const content = await fs37.readFile(absPath, "utf8");
|
|
20307
|
+
let count = 0;
|
|
20308
|
+
let pos = -1;
|
|
20309
|
+
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
20310
|
+
count += 1;
|
|
20311
|
+
if (count >= MAX_UNTRACKED_LINE_SCAN) return count;
|
|
20312
|
+
}
|
|
20313
|
+
return content.length > 0 ? Math.max(count, 1) : 0;
|
|
20314
|
+
} catch {
|
|
20315
|
+
return 0;
|
|
20316
|
+
}
|
|
20317
|
+
}
|
|
20242
20318
|
function parseStatus(raw) {
|
|
20243
20319
|
const tokens = raw.split("\0");
|
|
20244
20320
|
const rows = [];
|
|
@@ -20319,7 +20395,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20319
20395
|
});
|
|
20320
20396
|
}
|
|
20321
20397
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20322
|
-
const
|
|
20398
|
+
const fs47 = await import("fs/promises");
|
|
20323
20399
|
const out2 = [];
|
|
20324
20400
|
await walk(workingDir, 0);
|
|
20325
20401
|
return out2;
|
|
@@ -20327,7 +20403,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20327
20403
|
if (depth > maxDepth) return;
|
|
20328
20404
|
let entries = [];
|
|
20329
20405
|
try {
|
|
20330
|
-
const dirents = await
|
|
20406
|
+
const dirents = await fs47.readdir(dir, { withFileTypes: true });
|
|
20331
20407
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20332
20408
|
} catch {
|
|
20333
20409
|
return;
|
|
@@ -20353,7 +20429,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20353
20429
|
}
|
|
20354
20430
|
|
|
20355
20431
|
// src/services/turn-files/files-outbox.ts
|
|
20356
|
-
var
|
|
20432
|
+
var fs38 = __toESM(require("fs/promises"));
|
|
20357
20433
|
var path45 = __toESM(require("path"));
|
|
20358
20434
|
var import_os7 = require("os");
|
|
20359
20435
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
@@ -20395,8 +20471,8 @@ var FilesOutbox = class {
|
|
|
20395
20471
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20396
20472
|
* line is durable on disk (not once the POST succeeds). */
|
|
20397
20473
|
async enqueue(entry) {
|
|
20398
|
-
await
|
|
20399
|
-
await
|
|
20474
|
+
await fs38.mkdir(path45.dirname(this.filePath), { recursive: true });
|
|
20475
|
+
await fs38.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20400
20476
|
this.backoffIndex = 0;
|
|
20401
20477
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20402
20478
|
}
|
|
@@ -20485,7 +20561,7 @@ var FilesOutbox = class {
|
|
|
20485
20561
|
async readAll() {
|
|
20486
20562
|
let raw = "";
|
|
20487
20563
|
try {
|
|
20488
|
-
raw = await
|
|
20564
|
+
raw = await fs38.readFile(this.filePath, "utf8");
|
|
20489
20565
|
} catch {
|
|
20490
20566
|
return [];
|
|
20491
20567
|
}
|
|
@@ -20509,12 +20585,12 @@ var FilesOutbox = class {
|
|
|
20509
20585
|
async rewrite(entries) {
|
|
20510
20586
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20511
20587
|
if (entries.length === 0) {
|
|
20512
|
-
await
|
|
20588
|
+
await fs38.unlink(this.filePath).catch(() => void 0);
|
|
20513
20589
|
return;
|
|
20514
20590
|
}
|
|
20515
20591
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20516
|
-
await
|
|
20517
|
-
await
|
|
20592
|
+
await fs38.writeFile(tmpPath, payload, "utf8");
|
|
20593
|
+
await fs38.rename(tmpPath, this.filePath);
|
|
20518
20594
|
}
|
|
20519
20595
|
};
|
|
20520
20596
|
function applyJitter(ms) {
|
|
@@ -22412,7 +22488,7 @@ var OutputService = class _OutputService {
|
|
|
22412
22488
|
};
|
|
22413
22489
|
|
|
22414
22490
|
// src/services/history.service.ts
|
|
22415
|
-
var
|
|
22491
|
+
var fs39 = __toESM(require("fs"));
|
|
22416
22492
|
var path46 = __toESM(require("path"));
|
|
22417
22493
|
var os30 = __toESM(require("os"));
|
|
22418
22494
|
var https7 = __toESM(require("https"));
|
|
@@ -22441,7 +22517,7 @@ function parseJsonl(filePath) {
|
|
|
22441
22517
|
const messages = [];
|
|
22442
22518
|
let raw;
|
|
22443
22519
|
try {
|
|
22444
|
-
raw =
|
|
22520
|
+
raw = fs39.readFileSync(filePath, "utf8");
|
|
22445
22521
|
} catch (err) {
|
|
22446
22522
|
if (err.code !== "ENOENT") {
|
|
22447
22523
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22631,9 +22707,9 @@ var HistoryService = class _HistoryService {
|
|
|
22631
22707
|
const dir = this.projectDir;
|
|
22632
22708
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22633
22709
|
try {
|
|
22634
|
-
const files =
|
|
22710
|
+
const files = fs39.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22635
22711
|
try {
|
|
22636
|
-
const stat3 =
|
|
22712
|
+
const stat3 = fs39.statSync(path46.join(dir, e.name));
|
|
22637
22713
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22638
22714
|
} catch {
|
|
22639
22715
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22674,13 +22750,13 @@ var HistoryService = class _HistoryService {
|
|
|
22674
22750
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22675
22751
|
let entries;
|
|
22676
22752
|
try {
|
|
22677
|
-
entries =
|
|
22753
|
+
entries = fs39.readdirSync(dir, { withFileTypes: true });
|
|
22678
22754
|
} catch {
|
|
22679
22755
|
return null;
|
|
22680
22756
|
}
|
|
22681
22757
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22682
22758
|
try {
|
|
22683
|
-
const stat3 =
|
|
22759
|
+
const stat3 = fs39.statSync(path46.join(dir, e.name));
|
|
22684
22760
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22685
22761
|
} catch {
|
|
22686
22762
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22694,7 +22770,7 @@ var HistoryService = class _HistoryService {
|
|
|
22694
22770
|
extractUsageFromFile(filePath) {
|
|
22695
22771
|
let raw;
|
|
22696
22772
|
try {
|
|
22697
|
-
raw =
|
|
22773
|
+
raw = fs39.readFileSync(filePath, "utf8");
|
|
22698
22774
|
} catch {
|
|
22699
22775
|
return null;
|
|
22700
22776
|
}
|
|
@@ -22739,9 +22815,9 @@ var HistoryService = class _HistoryService {
|
|
|
22739
22815
|
let totalCost = 0;
|
|
22740
22816
|
let files;
|
|
22741
22817
|
try {
|
|
22742
|
-
files =
|
|
22818
|
+
files = fs39.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22743
22819
|
try {
|
|
22744
|
-
return
|
|
22820
|
+
return fs39.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22745
22821
|
} catch {
|
|
22746
22822
|
return false;
|
|
22747
22823
|
}
|
|
@@ -22752,7 +22828,7 @@ var HistoryService = class _HistoryService {
|
|
|
22752
22828
|
for (const file of files) {
|
|
22753
22829
|
let raw;
|
|
22754
22830
|
try {
|
|
22755
|
-
raw =
|
|
22831
|
+
raw = fs39.readFileSync(path46.join(projectDir, file), "utf8");
|
|
22756
22832
|
} catch {
|
|
22757
22833
|
continue;
|
|
22758
22834
|
}
|
|
@@ -23343,7 +23419,7 @@ function buildKeepAlive(ctx) {
|
|
|
23343
23419
|
}
|
|
23344
23420
|
|
|
23345
23421
|
// src/agents/claude/onboarding.ts
|
|
23346
|
-
var
|
|
23422
|
+
var fs40 = __toESM(require("fs"));
|
|
23347
23423
|
var os31 = __toESM(require("os"));
|
|
23348
23424
|
var path47 = __toESM(require("path"));
|
|
23349
23425
|
function ensureClaudeOnboarded() {
|
|
@@ -23351,7 +23427,7 @@ function ensureClaudeOnboarded() {
|
|
|
23351
23427
|
const file = path47.join(os31.homedir(), ".claude.json");
|
|
23352
23428
|
let config = {};
|
|
23353
23429
|
try {
|
|
23354
|
-
config = JSON.parse(
|
|
23430
|
+
config = JSON.parse(fs40.readFileSync(file, "utf8"));
|
|
23355
23431
|
} catch {
|
|
23356
23432
|
}
|
|
23357
23433
|
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
@@ -23362,8 +23438,8 @@ function ensureClaudeOnboarded() {
|
|
|
23362
23438
|
if (typeof config.lastOnboardingVersion !== "string") {
|
|
23363
23439
|
config.lastOnboardingVersion = "2.1.177";
|
|
23364
23440
|
}
|
|
23365
|
-
|
|
23366
|
-
|
|
23441
|
+
fs40.mkdirSync(path47.dirname(file), { recursive: true });
|
|
23442
|
+
fs40.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
23367
23443
|
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
23368
23444
|
} catch (err) {
|
|
23369
23445
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
@@ -23854,7 +23930,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
23854
23930
|
}
|
|
23855
23931
|
|
|
23856
23932
|
// src/commands/pair-auto.ts
|
|
23857
|
-
var
|
|
23933
|
+
var fs41 = __toESM(require("fs"));
|
|
23858
23934
|
var os32 = __toESM(require("os"));
|
|
23859
23935
|
var path48 = __toESM(require("path"));
|
|
23860
23936
|
var import_crypto7 = require("crypto");
|
|
@@ -24053,10 +24129,10 @@ function readTokenFromArgs(args2) {
|
|
|
24053
24129
|
if (fileFlag) {
|
|
24054
24130
|
const path58 = fileFlag.slice("--token-file=".length);
|
|
24055
24131
|
try {
|
|
24056
|
-
const content =
|
|
24132
|
+
const content = fs41.readFileSync(path58, "utf8").trim();
|
|
24057
24133
|
if (content.length === 0) fail(`--token-file ${path58} is empty`);
|
|
24058
24134
|
try {
|
|
24059
|
-
|
|
24135
|
+
fs41.unlinkSync(path58);
|
|
24060
24136
|
} catch {
|
|
24061
24137
|
}
|
|
24062
24138
|
return content;
|
|
@@ -24153,7 +24229,7 @@ function isLivePairAuto(pid) {
|
|
|
24153
24229
|
if (e.code !== "EPERM") return false;
|
|
24154
24230
|
}
|
|
24155
24231
|
try {
|
|
24156
|
-
return
|
|
24232
|
+
return fs41.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
24157
24233
|
} catch {
|
|
24158
24234
|
return true;
|
|
24159
24235
|
}
|
|
@@ -24161,19 +24237,19 @@ function isLivePairAuto(pid) {
|
|
|
24161
24237
|
function acquireSingletonLock() {
|
|
24162
24238
|
const lockPath = pairAutoLockPath();
|
|
24163
24239
|
try {
|
|
24164
|
-
|
|
24240
|
+
fs41.mkdirSync(path48.dirname(lockPath), { recursive: true });
|
|
24165
24241
|
try {
|
|
24166
|
-
|
|
24242
|
+
fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
24167
24243
|
} catch (e) {
|
|
24168
24244
|
if (e.code !== "EEXIST") throw e;
|
|
24169
|
-
const holder = Number(
|
|
24245
|
+
const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
|
|
24170
24246
|
if (isLivePairAuto(holder)) return false;
|
|
24171
|
-
|
|
24247
|
+
fs41.writeFileSync(lockPath, String(process.pid));
|
|
24172
24248
|
}
|
|
24173
24249
|
process.once("exit", () => {
|
|
24174
24250
|
try {
|
|
24175
|
-
if (
|
|
24176
|
-
|
|
24251
|
+
if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24252
|
+
fs41.unlinkSync(lockPath);
|
|
24177
24253
|
}
|
|
24178
24254
|
} catch {
|
|
24179
24255
|
}
|
|
@@ -26315,7 +26391,7 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26315
26391
|
}
|
|
26316
26392
|
|
|
26317
26393
|
// src/commands/host/host-client.ts
|
|
26318
|
-
var
|
|
26394
|
+
var fs42 = __toESM(require("fs"));
|
|
26319
26395
|
var os33 = __toESM(require("os"));
|
|
26320
26396
|
var path53 = __toESM(require("path"));
|
|
26321
26397
|
function sampleCpuTimes() {
|
|
@@ -26376,7 +26452,7 @@ function collectOsInfo() {
|
|
|
26376
26452
|
}
|
|
26377
26453
|
function loadHostIdentity() {
|
|
26378
26454
|
try {
|
|
26379
|
-
const raw =
|
|
26455
|
+
const raw = fs42.readFileSync(hostIdentityPath(), "utf8");
|
|
26380
26456
|
const parsed = JSON.parse(raw);
|
|
26381
26457
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
26382
26458
|
const p2 = parsed;
|
|
@@ -26389,12 +26465,12 @@ function loadHostIdentity() {
|
|
|
26389
26465
|
}
|
|
26390
26466
|
function saveHostIdentity(identity) {
|
|
26391
26467
|
const file = hostIdentityPath();
|
|
26392
|
-
|
|
26393
|
-
|
|
26468
|
+
fs42.mkdirSync(path53.dirname(file), { recursive: true, mode: 448 });
|
|
26469
|
+
fs42.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
26394
26470
|
encoding: "utf8",
|
|
26395
26471
|
mode: 384
|
|
26396
26472
|
});
|
|
26397
|
-
|
|
26473
|
+
fs42.chmodSync(file, 384);
|
|
26398
26474
|
}
|
|
26399
26475
|
var HostHttpError = class extends Error {
|
|
26400
26476
|
constructor(message, status2) {
|
|
@@ -26417,7 +26493,7 @@ function isHostAuthRejection(err) {
|
|
|
26417
26493
|
}
|
|
26418
26494
|
function deleteHostIdentity() {
|
|
26419
26495
|
try {
|
|
26420
|
-
|
|
26496
|
+
fs42.rmSync(hostIdentityPath(), { force: true });
|
|
26421
26497
|
} catch {
|
|
26422
26498
|
}
|
|
26423
26499
|
}
|
|
@@ -26581,7 +26657,7 @@ var import_node_child_process13 = require("child_process");
|
|
|
26581
26657
|
var os36 = __toESM(require("os"));
|
|
26582
26658
|
|
|
26583
26659
|
// src/commands/host/workspace.ts
|
|
26584
|
-
var
|
|
26660
|
+
var fs43 = __toESM(require("fs"));
|
|
26585
26661
|
var os34 = __toESM(require("os"));
|
|
26586
26662
|
var path54 = __toESM(require("path"));
|
|
26587
26663
|
var import_node_child_process12 = require("child_process");
|
|
@@ -26634,16 +26710,16 @@ function maskToken(text, cloneToken) {
|
|
|
26634
26710
|
}
|
|
26635
26711
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
26636
26712
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
26637
|
-
if (!
|
|
26713
|
+
if (!fs43.existsSync(repoOrPath)) {
|
|
26638
26714
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
26639
26715
|
}
|
|
26640
26716
|
return repoOrPath;
|
|
26641
26717
|
}
|
|
26642
26718
|
const dest = path54.join(selfHostedWorkspaceRoot(), deployId);
|
|
26643
|
-
if (
|
|
26719
|
+
if (fs43.existsSync(path54.join(dest, ".git"))) {
|
|
26644
26720
|
return dest;
|
|
26645
26721
|
}
|
|
26646
|
-
|
|
26722
|
+
fs43.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
26647
26723
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
26648
26724
|
try {
|
|
26649
26725
|
await execFileP9("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -26659,7 +26735,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
26659
26735
|
}
|
|
26660
26736
|
|
|
26661
26737
|
// src/commands/host/agent-provisioning.ts
|
|
26662
|
-
var
|
|
26738
|
+
var fs44 = __toESM(require("fs"));
|
|
26663
26739
|
var os35 = __toESM(require("os"));
|
|
26664
26740
|
var path55 = __toESM(require("path"));
|
|
26665
26741
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
@@ -26676,12 +26752,12 @@ function toInternalAgentId(publicAgentId) {
|
|
|
26676
26752
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
26677
26753
|
}
|
|
26678
26754
|
function ensureDir(dir) {
|
|
26679
|
-
|
|
26755
|
+
fs44.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26680
26756
|
}
|
|
26681
26757
|
function writeFile0600(filePath, contents) {
|
|
26682
26758
|
ensureDir(path55.dirname(filePath));
|
|
26683
|
-
|
|
26684
|
-
|
|
26759
|
+
fs44.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
26760
|
+
fs44.chmodSync(filePath, 384);
|
|
26685
26761
|
}
|
|
26686
26762
|
var claudeProvisioner = {
|
|
26687
26763
|
write(auth, home) {
|
|
@@ -26690,7 +26766,7 @@ var claudeProvisioner = {
|
|
|
26690
26766
|
}
|
|
26691
26767
|
writeFile0600(path55.join(home, ".claude", ".credentials.json"), auth.value);
|
|
26692
26768
|
const claudeJson = path55.join(home, ".claude.json");
|
|
26693
|
-
if (!
|
|
26769
|
+
if (!fs44.existsSync(claudeJson)) {
|
|
26694
26770
|
writeFile0600(
|
|
26695
26771
|
claudeJson,
|
|
26696
26772
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -27120,7 +27196,7 @@ async function hostAgent(args2 = []) {
|
|
|
27120
27196
|
var import_node_dns = require("dns");
|
|
27121
27197
|
var import_node_util5 = require("util");
|
|
27122
27198
|
var import_node_crypto8 = require("crypto");
|
|
27123
|
-
var
|
|
27199
|
+
var fs45 = __toESM(require("fs"));
|
|
27124
27200
|
var path56 = __toESM(require("path"));
|
|
27125
27201
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
27126
27202
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
@@ -27179,11 +27255,11 @@ async function checkHealth(apiBase2) {
|
|
|
27179
27255
|
function checkConfigDir() {
|
|
27180
27256
|
const dir = path56.join(require("os").homedir(), ".codeam");
|
|
27181
27257
|
try {
|
|
27182
|
-
|
|
27258
|
+
fs45.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
27183
27259
|
const probe = path56.join(dir, ".doctor-probe");
|
|
27184
|
-
|
|
27185
|
-
const read =
|
|
27186
|
-
|
|
27260
|
+
fs45.writeFileSync(probe, "ok", { mode: 384 });
|
|
27261
|
+
const read = fs45.readFileSync(probe, "utf8");
|
|
27262
|
+
fs45.unlinkSync(probe);
|
|
27187
27263
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
27188
27264
|
return {
|
|
27189
27265
|
id: "config-dir",
|
|
@@ -27289,7 +27365,7 @@ function checkChokidar() {
|
|
|
27289
27365
|
}
|
|
27290
27366
|
async function doctor(args2 = []) {
|
|
27291
27367
|
const json = args2.includes("--json");
|
|
27292
|
-
const cliVersion = true ? "2.39.
|
|
27368
|
+
const cliVersion = true ? "2.39.44" : "0.0.0-dev";
|
|
27293
27369
|
const apiBase2 = resolveApiBaseUrl();
|
|
27294
27370
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
27295
27371
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -27488,7 +27564,7 @@ async function completion(args2) {
|
|
|
27488
27564
|
// src/commands/version.ts
|
|
27489
27565
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
27490
27566
|
function version2() {
|
|
27491
|
-
const v = true ? "2.39.
|
|
27567
|
+
const v = true ? "2.39.44" : "unknown";
|
|
27492
27568
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
27493
27569
|
}
|
|
27494
27570
|
|
|
@@ -27616,7 +27692,7 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
27616
27692
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
27617
27693
|
|
|
27618
27694
|
// src/lib/updateNotifier.ts
|
|
27619
|
-
var
|
|
27695
|
+
var fs46 = __toESM(require("fs"));
|
|
27620
27696
|
var os37 = __toESM(require("os"));
|
|
27621
27697
|
var path57 = __toESM(require("path"));
|
|
27622
27698
|
var https8 = __toESM(require("https"));
|
|
@@ -27632,7 +27708,7 @@ function cachePath() {
|
|
|
27632
27708
|
}
|
|
27633
27709
|
function readCache() {
|
|
27634
27710
|
try {
|
|
27635
|
-
const raw =
|
|
27711
|
+
const raw = fs46.readFileSync(cachePath(), "utf8");
|
|
27636
27712
|
const parsed = JSON.parse(raw);
|
|
27637
27713
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
27638
27714
|
return parsed;
|
|
@@ -27643,10 +27719,10 @@ function readCache() {
|
|
|
27643
27719
|
function writeCache(cache) {
|
|
27644
27720
|
try {
|
|
27645
27721
|
const file = cachePath();
|
|
27646
|
-
|
|
27722
|
+
fs46.mkdirSync(path57.dirname(file), { recursive: true });
|
|
27647
27723
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27648
|
-
|
|
27649
|
-
|
|
27724
|
+
fs46.writeFileSync(tmp, JSON.stringify(cache));
|
|
27725
|
+
fs46.renameSync(tmp, file);
|
|
27650
27726
|
} catch {
|
|
27651
27727
|
}
|
|
27652
27728
|
}
|
|
@@ -27721,7 +27797,7 @@ function isLinkedInstall() {
|
|
|
27721
27797
|
}).trim();
|
|
27722
27798
|
if (!root) return false;
|
|
27723
27799
|
const pkgPath = path57.join(root, PKG_NAME);
|
|
27724
|
-
return
|
|
27800
|
+
return fs46.lstatSync(pkgPath).isSymbolicLink();
|
|
27725
27801
|
} catch {
|
|
27726
27802
|
return false;
|
|
27727
27803
|
}
|
|
@@ -27757,7 +27833,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27757
27833
|
return;
|
|
27758
27834
|
}
|
|
27759
27835
|
try {
|
|
27760
|
-
|
|
27836
|
+
fs46.unlinkSync(cachePath());
|
|
27761
27837
|
} catch {
|
|
27762
27838
|
}
|
|
27763
27839
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27774,7 +27850,7 @@ function checkForUpdates() {
|
|
|
27774
27850
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27775
27851
|
if (process.env.CI) return;
|
|
27776
27852
|
if (!process.stdout.isTTY) return;
|
|
27777
|
-
const current = true ? "2.39.
|
|
27853
|
+
const current = true ? "2.39.44" : null;
|
|
27778
27854
|
if (!current) return;
|
|
27779
27855
|
const cache = readCache();
|
|
27780
27856
|
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.44",
|
|
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",
|