codeam-cli 2.4.31 → 2.4.32
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 +101 -71
- 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.4.31] — 2026-05-05
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Vendor node-pty into dist/ — guarantees ConPTY binary on Windows (v2.4.31)
|
|
12
|
+
|
|
7
13
|
## [2.4.30] — 2026-05-05
|
|
8
14
|
|
|
9
15
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -521,7 +521,7 @@ var require_windowsPtyAgent = __commonJS({
|
|
|
521
521
|
exports2.argsToCommandLine = exports2.WindowsPtyAgent = void 0;
|
|
522
522
|
var fs9 = require("fs");
|
|
523
523
|
var os8 = require("os");
|
|
524
|
-
var
|
|
524
|
+
var path16 = require("path");
|
|
525
525
|
var child_process_1 = require("child_process");
|
|
526
526
|
var net_1 = require("net");
|
|
527
527
|
var windowsConoutConnection_1 = require_windowsConoutConnection();
|
|
@@ -557,7 +557,7 @@ var require_windowsPtyAgent = __commonJS({
|
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
559
|
this._ptyNative = this._useConpty ? conptyNative : winptyNative;
|
|
560
|
-
cwd =
|
|
560
|
+
cwd = path16.resolve(cwd);
|
|
561
561
|
var commandLine = argsToCommandLine(file, args2);
|
|
562
562
|
var term;
|
|
563
563
|
if (this._useConpty) {
|
|
@@ -679,7 +679,7 @@ var require_windowsPtyAgent = __commonJS({
|
|
|
679
679
|
WindowsPtyAgent2.prototype._getConsoleProcessList = function() {
|
|
680
680
|
var _this = this;
|
|
681
681
|
return new Promise(function(resolve2) {
|
|
682
|
-
var agent = child_process_1.fork(
|
|
682
|
+
var agent = child_process_1.fork(path16.join(__dirname, "conpty_console_list_agent"), [_this._innerPid.toString()]);
|
|
683
683
|
agent.on("message", function(message) {
|
|
684
684
|
clearTimeout(timeout);
|
|
685
685
|
resolve2(message.consoleProcessList);
|
|
@@ -1013,14 +1013,14 @@ var require_unixTerminal = __commonJS({
|
|
|
1013
1013
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1014
1014
|
exports2.UnixTerminal = void 0;
|
|
1015
1015
|
var fs9 = require("fs");
|
|
1016
|
-
var
|
|
1016
|
+
var path16 = require("path");
|
|
1017
1017
|
var tty = require("tty");
|
|
1018
1018
|
var terminal_1 = require_terminal();
|
|
1019
1019
|
var utils_1 = require_utils();
|
|
1020
1020
|
var native = utils_1.loadNativeModule("pty");
|
|
1021
1021
|
var pty = native.module;
|
|
1022
1022
|
var helperPath = native.dir + "/spawn-helper";
|
|
1023
|
-
helperPath =
|
|
1023
|
+
helperPath = path16.resolve(__dirname, helperPath);
|
|
1024
1024
|
helperPath = helperPath.replace("app.asar", "app.asar.unpacked");
|
|
1025
1025
|
helperPath = helperPath.replace("node_modules.asar", "node_modules.asar.unpacked");
|
|
1026
1026
|
var DEFAULT_FILE = "sh";
|
|
@@ -1392,7 +1392,7 @@ var require_src = __commonJS({
|
|
|
1392
1392
|
// src/commands/start.ts
|
|
1393
1393
|
var fs7 = __toESM(require("fs"));
|
|
1394
1394
|
var os6 = __toESM(require("os"));
|
|
1395
|
-
var
|
|
1395
|
+
var path10 = __toESM(require("path"));
|
|
1396
1396
|
var import_crypto = require("crypto");
|
|
1397
1397
|
var import_child_process5 = require("child_process");
|
|
1398
1398
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
@@ -1482,7 +1482,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
1482
1482
|
// package.json
|
|
1483
1483
|
var package_default = {
|
|
1484
1484
|
name: "codeam-cli",
|
|
1485
|
-
version: "2.4.
|
|
1485
|
+
version: "2.4.32",
|
|
1486
1486
|
description: "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands \u2014 from anywhere.",
|
|
1487
1487
|
main: "dist/index.js",
|
|
1488
1488
|
bin: {
|
|
@@ -1963,27 +1963,35 @@ var CommandRelayService = class {
|
|
|
1963
1963
|
}
|
|
1964
1964
|
};
|
|
1965
1965
|
|
|
1966
|
+
// src/services/pty/unix.strategy.ts
|
|
1967
|
+
var import_child_process = require("child_process");
|
|
1968
|
+
var fs3 = __toESM(require("fs"));
|
|
1969
|
+
var os3 = __toESM(require("os"));
|
|
1970
|
+
var path3 = __toESM(require("path"));
|
|
1971
|
+
|
|
1966
1972
|
// src/services/pty/types.ts
|
|
1967
1973
|
var fs2 = __toESM(require("fs"));
|
|
1968
1974
|
var path2 = __toESM(require("path"));
|
|
1969
1975
|
function findInPath(name) {
|
|
1970
|
-
const
|
|
1976
|
+
const isWin = process.platform === "win32";
|
|
1977
|
+
const dirs = (process.env.PATH ?? "").split(path2.delimiter).filter(Boolean);
|
|
1978
|
+
const hasExt = path2.extname(name).length > 0;
|
|
1979
|
+
const candidates = isWin && !hasExt ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, `${name}.ps1`, name] : [name];
|
|
1980
|
+
const accessFlag = isWin ? fs2.constants.F_OK : fs2.constants.X_OK;
|
|
1971
1981
|
for (const dir of dirs) {
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1982
|
+
for (const candidate of candidates) {
|
|
1983
|
+
const full = path2.join(dir, candidate);
|
|
1984
|
+
try {
|
|
1985
|
+
fs2.accessSync(full, accessFlag);
|
|
1986
|
+
return full;
|
|
1987
|
+
} catch {
|
|
1988
|
+
}
|
|
1977
1989
|
}
|
|
1978
1990
|
}
|
|
1979
1991
|
return null;
|
|
1980
1992
|
}
|
|
1981
1993
|
|
|
1982
1994
|
// src/services/pty/unix.strategy.ts
|
|
1983
|
-
var import_child_process = require("child_process");
|
|
1984
|
-
var fs3 = __toESM(require("fs"));
|
|
1985
|
-
var os3 = __toESM(require("os"));
|
|
1986
|
-
var path3 = __toESM(require("path"));
|
|
1987
1995
|
var PYTHON_PTY_HELPER = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
|
|
1988
1996
|
m,s=pty.openpty()
|
|
1989
1997
|
try:
|
|
@@ -4351,6 +4359,26 @@ async function ensureClaudeInstalled() {
|
|
|
4351
4359
|
return true;
|
|
4352
4360
|
}
|
|
4353
4361
|
|
|
4362
|
+
// src/services/claude-resolver.ts
|
|
4363
|
+
var path6 = __toESM(require("path"));
|
|
4364
|
+
function buildClaudeLaunch(extraArgs = []) {
|
|
4365
|
+
const found = findInPath("claude") ?? findInPath("claude-code");
|
|
4366
|
+
if (!found) return null;
|
|
4367
|
+
if (process.platform === "win32") {
|
|
4368
|
+
const ext = path6.extname(found).toLowerCase();
|
|
4369
|
+
if (ext === ".cmd" || ext === ".bat") {
|
|
4370
|
+
return { cmd: "cmd.exe", args: ["/c", found, ...extraArgs] };
|
|
4371
|
+
}
|
|
4372
|
+
if (ext === ".ps1") {
|
|
4373
|
+
return {
|
|
4374
|
+
cmd: "powershell.exe",
|
|
4375
|
+
args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", found, ...extraArgs]
|
|
4376
|
+
};
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
return { cmd: found, args: extraArgs };
|
|
4380
|
+
}
|
|
4381
|
+
|
|
4354
4382
|
// src/services/claude.service.ts
|
|
4355
4383
|
var ClaudeService = class {
|
|
4356
4384
|
constructor(opts) {
|
|
@@ -4368,9 +4396,11 @@ var ClaudeService = class {
|
|
|
4368
4396
|
strategy = null;
|
|
4369
4397
|
strategyOpts;
|
|
4370
4398
|
async spawn() {
|
|
4371
|
-
|
|
4399
|
+
let launch = buildClaudeLaunch();
|
|
4400
|
+
if (!launch) {
|
|
4372
4401
|
const installed = await ensureClaudeInstalled();
|
|
4373
|
-
if (
|
|
4402
|
+
if (installed) launch = buildClaudeLaunch();
|
|
4403
|
+
if (!launch) {
|
|
4374
4404
|
const cmd = process.platform === "win32" ? "irm https://claude.ai/install.ps1 | iex" : "curl -fsSL https://claude.ai/install.sh | bash";
|
|
4375
4405
|
console.error(
|
|
4376
4406
|
`
|
|
@@ -4382,12 +4412,11 @@ var ClaudeService = class {
|
|
|
4382
4412
|
process.exit(1);
|
|
4383
4413
|
}
|
|
4384
4414
|
}
|
|
4385
|
-
const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
|
|
4386
4415
|
if (process.platform === "win32") {
|
|
4387
4416
|
const conpty = WindowsConPtyStrategy.tryCreate(this.strategyOpts);
|
|
4388
4417
|
if (conpty) {
|
|
4389
4418
|
try {
|
|
4390
|
-
conpty.spawn(
|
|
4419
|
+
conpty.spawn(launch.cmd, this.opts.cwd, launch.args);
|
|
4391
4420
|
this.strategy = conpty;
|
|
4392
4421
|
return;
|
|
4393
4422
|
} catch (err) {
|
|
@@ -4406,12 +4435,12 @@ var ClaudeService = class {
|
|
|
4406
4435
|
);
|
|
4407
4436
|
}
|
|
4408
4437
|
const pipe = new WindowsPtyStrategy(this.strategyOpts);
|
|
4409
|
-
pipe.spawn(
|
|
4438
|
+
pipe.spawn(launch.cmd, this.opts.cwd, launch.args);
|
|
4410
4439
|
this.strategy = pipe;
|
|
4411
4440
|
return;
|
|
4412
4441
|
}
|
|
4413
4442
|
const unix = new UnixPtyStrategy(this.strategyOpts);
|
|
4414
|
-
unix.spawn(
|
|
4443
|
+
unix.spawn(launch.cmd, this.opts.cwd, launch.args);
|
|
4415
4444
|
this.strategy = unix;
|
|
4416
4445
|
}
|
|
4417
4446
|
/**
|
|
@@ -4489,11 +4518,12 @@ var ClaudeService = class {
|
|
|
4489
4518
|
*/
|
|
4490
4519
|
restart(sessionId, auto = false) {
|
|
4491
4520
|
if (!this.strategy) return;
|
|
4492
|
-
const
|
|
4521
|
+
const extraArgs = ["--resume", sessionId];
|
|
4522
|
+
if (auto) extraArgs.push("--dangerously-skip-permissions");
|
|
4523
|
+
const launch = buildClaudeLaunch(extraArgs);
|
|
4524
|
+
if (!launch) return;
|
|
4493
4525
|
this.strategy.kill();
|
|
4494
|
-
|
|
4495
|
-
if (auto) args2.push("--dangerously-skip-permissions");
|
|
4496
|
-
this.strategy.spawn(claudeCmd, this.opts.cwd, args2);
|
|
4526
|
+
this.strategy.spawn(launch.cmd, this.opts.cwd, launch.args);
|
|
4497
4527
|
}
|
|
4498
4528
|
};
|
|
4499
4529
|
|
|
@@ -5175,7 +5205,7 @@ function _sendOutputChunk(url, headers, payload) {
|
|
|
5175
5205
|
|
|
5176
5206
|
// src/services/history.service.ts
|
|
5177
5207
|
var fs4 = __toESM(require("fs"));
|
|
5178
|
-
var
|
|
5208
|
+
var path7 = __toESM(require("path"));
|
|
5179
5209
|
var os5 = __toESM(require("os"));
|
|
5180
5210
|
var https3 = __toESM(require("https"));
|
|
5181
5211
|
var http3 = __toESM(require("http"));
|
|
@@ -5331,7 +5361,7 @@ var HistoryService = class {
|
|
|
5331
5361
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
5332
5362
|
}
|
|
5333
5363
|
get projectDir() {
|
|
5334
|
-
return
|
|
5364
|
+
return path7.join(os5.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
5335
5365
|
}
|
|
5336
5366
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
5337
5367
|
setCurrentConversationId(id) {
|
|
@@ -5343,7 +5373,7 @@ var HistoryService = class {
|
|
|
5343
5373
|
/** Return the current message count in the active conversation. */
|
|
5344
5374
|
getCurrentMessageCount() {
|
|
5345
5375
|
if (!this.currentConversationId) return 0;
|
|
5346
|
-
const filePath =
|
|
5376
|
+
const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
5347
5377
|
return parseJsonl(filePath).length;
|
|
5348
5378
|
}
|
|
5349
5379
|
/**
|
|
@@ -5354,7 +5384,7 @@ var HistoryService = class {
|
|
|
5354
5384
|
const deadline = Date.now() + timeoutMs;
|
|
5355
5385
|
while (Date.now() < deadline) {
|
|
5356
5386
|
if (!this.currentConversationId) return null;
|
|
5357
|
-
const filePath =
|
|
5387
|
+
const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
5358
5388
|
const messages = parseJsonl(filePath);
|
|
5359
5389
|
if (messages.length > previousCount) {
|
|
5360
5390
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -5371,13 +5401,13 @@ var HistoryService = class {
|
|
|
5371
5401
|
try {
|
|
5372
5402
|
const files = fs4.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
5373
5403
|
try {
|
|
5374
|
-
return { name: e.name, mtime: fs4.statSync(
|
|
5404
|
+
return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
|
|
5375
5405
|
} catch {
|
|
5376
5406
|
return { name: e.name, mtime: 0 };
|
|
5377
5407
|
}
|
|
5378
5408
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
5379
5409
|
if (files.length > 0) {
|
|
5380
|
-
this.currentConversationId =
|
|
5410
|
+
this.currentConversationId = path7.basename(files[0].name, ".jsonl");
|
|
5381
5411
|
}
|
|
5382
5412
|
} catch {
|
|
5383
5413
|
}
|
|
@@ -5415,7 +5445,7 @@ var HistoryService = class {
|
|
|
5415
5445
|
}
|
|
5416
5446
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
5417
5447
|
try {
|
|
5418
|
-
return { name: e.name, mtime: fs4.statSync(
|
|
5448
|
+
return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
|
|
5419
5449
|
} catch {
|
|
5420
5450
|
return { name: e.name, mtime: 0 };
|
|
5421
5451
|
}
|
|
@@ -5423,7 +5453,7 @@ var HistoryService = class {
|
|
|
5423
5453
|
if (files.length === 0) return null;
|
|
5424
5454
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
5425
5455
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
5426
|
-
return this.extractUsageFromFile(
|
|
5456
|
+
return this.extractUsageFromFile(path7.join(dir, targetFile));
|
|
5427
5457
|
}
|
|
5428
5458
|
extractUsageFromFile(filePath) {
|
|
5429
5459
|
let raw;
|
|
@@ -5475,7 +5505,7 @@ var HistoryService = class {
|
|
|
5475
5505
|
try {
|
|
5476
5506
|
files = fs4.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
5477
5507
|
try {
|
|
5478
|
-
return fs4.statSync(
|
|
5508
|
+
return fs4.statSync(path7.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
5479
5509
|
} catch {
|
|
5480
5510
|
return false;
|
|
5481
5511
|
}
|
|
@@ -5486,7 +5516,7 @@ var HistoryService = class {
|
|
|
5486
5516
|
for (const file of files) {
|
|
5487
5517
|
let raw;
|
|
5488
5518
|
try {
|
|
5489
|
-
raw = fs4.readFileSync(
|
|
5519
|
+
raw = fs4.readFileSync(path7.join(projectDir, file), "utf8");
|
|
5490
5520
|
} catch {
|
|
5491
5521
|
continue;
|
|
5492
5522
|
}
|
|
@@ -5528,8 +5558,8 @@ var HistoryService = class {
|
|
|
5528
5558
|
const sessions2 = [];
|
|
5529
5559
|
for (const entry of entries) {
|
|
5530
5560
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
|
|
5531
|
-
const id =
|
|
5532
|
-
const filePath =
|
|
5561
|
+
const id = path7.basename(entry.name, ".jsonl");
|
|
5562
|
+
const filePath = path7.join(dir, entry.name);
|
|
5533
5563
|
let mtime = Date.now();
|
|
5534
5564
|
try {
|
|
5535
5565
|
mtime = fs4.statSync(filePath).mtimeMs;
|
|
@@ -5570,7 +5600,7 @@ var HistoryService = class {
|
|
|
5570
5600
|
* showing an empty conversation.
|
|
5571
5601
|
*/
|
|
5572
5602
|
async loadConversation(sessionId) {
|
|
5573
|
-
const filePath =
|
|
5603
|
+
const filePath = path7.join(this.projectDir, `${sessionId}.jsonl`);
|
|
5574
5604
|
const messages = parseJsonl(filePath);
|
|
5575
5605
|
if (messages.length === 0) return;
|
|
5576
5606
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -5626,7 +5656,7 @@ function parsePayload(schema, raw) {
|
|
|
5626
5656
|
|
|
5627
5657
|
// src/services/file-ops.service.ts
|
|
5628
5658
|
var fs5 = __toESM(require("fs/promises"));
|
|
5629
|
-
var
|
|
5659
|
+
var path8 = __toESM(require("path"));
|
|
5630
5660
|
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
5631
5661
|
var MAX_WALK_DEPTH = 6;
|
|
5632
5662
|
var MAX_VISITED_DIRS = 5e3;
|
|
@@ -5661,8 +5691,8 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
|
|
|
5661
5691
|
"__pycache__"
|
|
5662
5692
|
]);
|
|
5663
5693
|
function isUnder(parent, candidate) {
|
|
5664
|
-
const rel =
|
|
5665
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5694
|
+
const rel = path8.relative(parent, candidate);
|
|
5695
|
+
return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
|
|
5666
5696
|
}
|
|
5667
5697
|
async function isExistingFile(absPath) {
|
|
5668
5698
|
try {
|
|
@@ -5685,7 +5715,7 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
5685
5715
|
}
|
|
5686
5716
|
for (const e of entries) {
|
|
5687
5717
|
if (!e.isFile()) continue;
|
|
5688
|
-
const full =
|
|
5718
|
+
const full = path8.join(dir, e.name);
|
|
5689
5719
|
if (needleVariants.some((needle) => full.endsWith(needle))) {
|
|
5690
5720
|
ctx.matches.push(full);
|
|
5691
5721
|
if (ctx.matches.length >= ctx.cap) return;
|
|
@@ -5695,21 +5725,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
5695
5725
|
if (!e.isDirectory()) continue;
|
|
5696
5726
|
if (SUBDIR_IGNORE.has(e.name)) continue;
|
|
5697
5727
|
if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
|
|
5698
|
-
await walkForSuffix(
|
|
5728
|
+
await walkForSuffix(path8.join(dir, e.name), needleVariants, depth + 1, ctx);
|
|
5699
5729
|
if (ctx.matches.length >= ctx.cap) return;
|
|
5700
5730
|
}
|
|
5701
5731
|
}
|
|
5702
5732
|
async function findFile(rawPath) {
|
|
5703
5733
|
const cwd = process.cwd();
|
|
5704
|
-
if (
|
|
5705
|
-
const abs =
|
|
5734
|
+
if (path8.isAbsolute(rawPath)) {
|
|
5735
|
+
const abs = path8.normalize(rawPath);
|
|
5706
5736
|
if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
|
|
5707
5737
|
}
|
|
5708
|
-
const direct =
|
|
5738
|
+
const direct = path8.resolve(cwd, rawPath);
|
|
5709
5739
|
if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
|
|
5710
|
-
const normalized =
|
|
5740
|
+
const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
|
|
5711
5741
|
const needles = [
|
|
5712
|
-
`${
|
|
5742
|
+
`${path8.sep}${normalized}`,
|
|
5713
5743
|
`/${normalized}`
|
|
5714
5744
|
].filter((v, i, a) => a.indexOf(v) === i);
|
|
5715
5745
|
const ctx = { visited: 0, matches: [], cap: 16 };
|
|
@@ -5723,7 +5753,7 @@ async function findWriteTarget(rawPath) {
|
|
|
5723
5753
|
const found = await findFile(rawPath);
|
|
5724
5754
|
if (found) return found;
|
|
5725
5755
|
const cwd = process.cwd();
|
|
5726
|
-
const fallback =
|
|
5756
|
+
const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
|
|
5727
5757
|
if (!isUnder(cwd, fallback)) return null;
|
|
5728
5758
|
return fallback;
|
|
5729
5759
|
}
|
|
@@ -5763,7 +5793,7 @@ async function writeProjectFile(rawPath, content) {
|
|
|
5763
5793
|
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
|
|
5764
5794
|
return { error: "Content too large." };
|
|
5765
5795
|
}
|
|
5766
|
-
await fs5.mkdir(
|
|
5796
|
+
await fs5.mkdir(path8.dirname(abs), { recursive: true });
|
|
5767
5797
|
await fs5.writeFile(abs, content, "utf-8");
|
|
5768
5798
|
return { ok: true };
|
|
5769
5799
|
} catch (e) {
|
|
@@ -5776,7 +5806,7 @@ async function writeProjectFile(rawPath, content) {
|
|
|
5776
5806
|
var import_child_process4 = require("child_process");
|
|
5777
5807
|
var import_util = require("util");
|
|
5778
5808
|
var fs6 = __toESM(require("fs/promises"));
|
|
5779
|
-
var
|
|
5809
|
+
var path9 = __toESM(require("path"));
|
|
5780
5810
|
var execFileP = (0, import_util.promisify)(import_child_process4.execFile);
|
|
5781
5811
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
5782
5812
|
"node_modules",
|
|
@@ -5834,12 +5864,12 @@ async function listProjectFiles(opts = {}) {
|
|
|
5834
5864
|
return;
|
|
5835
5865
|
}
|
|
5836
5866
|
if (PROJECT_IGNORE.has(e.name)) continue;
|
|
5837
|
-
const full =
|
|
5867
|
+
const full = path9.join(dir, e.name);
|
|
5838
5868
|
if (e.isDirectory()) {
|
|
5839
5869
|
if (depth >= 12) continue;
|
|
5840
5870
|
await walk(full, depth + 1);
|
|
5841
5871
|
} else if (e.isFile()) {
|
|
5842
|
-
const rel =
|
|
5872
|
+
const rel = path9.relative(root, full);
|
|
5843
5873
|
if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
|
|
5844
5874
|
continue;
|
|
5845
5875
|
}
|
|
@@ -5947,7 +5977,7 @@ async function gitStatus(cwd) {
|
|
|
5947
5977
|
let hasMergeInProgress = false;
|
|
5948
5978
|
try {
|
|
5949
5979
|
const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
|
|
5950
|
-
const mergeHead =
|
|
5980
|
+
const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
|
|
5951
5981
|
await fs6.access(mergeHead);
|
|
5952
5982
|
hasMergeInProgress = true;
|
|
5953
5983
|
} catch {
|
|
@@ -6025,7 +6055,7 @@ async function gitResolve(file, side, cwd) {
|
|
|
6025
6055
|
function saveFilesTemp(files) {
|
|
6026
6056
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
6027
6057
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
6028
|
-
const tmpPath =
|
|
6058
|
+
const tmpPath = path10.join(os6.tmpdir(), `codeam-${(0, import_crypto.randomUUID)()}-${safeName}`);
|
|
6029
6059
|
fs7.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
6030
6060
|
return tmpPath;
|
|
6031
6061
|
});
|
|
@@ -6099,7 +6129,7 @@ try:
|
|
|
6099
6129
|
sys.exit((st>>8)&0xFF)
|
|
6100
6130
|
except Exception:sys.exit(0)
|
|
6101
6131
|
`;
|
|
6102
|
-
const helperPath =
|
|
6132
|
+
const helperPath = path10.join(os6.tmpdir(), "codeam-quota-helper.py");
|
|
6103
6133
|
fs7.writeFileSync(helperPath, helperScript, { mode: 420 });
|
|
6104
6134
|
const python = findInPath("python3") ?? findInPath("python");
|
|
6105
6135
|
if (!python) {
|
|
@@ -6702,7 +6732,7 @@ async function logout() {
|
|
|
6702
6732
|
var import_child_process10 = require("child_process");
|
|
6703
6733
|
var fs8 = __toESM(require("fs"));
|
|
6704
6734
|
var os7 = __toESM(require("os"));
|
|
6705
|
-
var
|
|
6735
|
+
var path15 = __toESM(require("path"));
|
|
6706
6736
|
var import_util6 = require("util");
|
|
6707
6737
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
6708
6738
|
|
|
@@ -6710,7 +6740,7 @@ var import_picocolors9 = __toESM(require("picocolors"));
|
|
|
6710
6740
|
var import_child_process6 = require("child_process");
|
|
6711
6741
|
var import_util2 = require("util");
|
|
6712
6742
|
var import_picocolors7 = __toESM(require("picocolors"));
|
|
6713
|
-
var
|
|
6743
|
+
var path11 = __toESM(require("path"));
|
|
6714
6744
|
var execFileP2 = (0, import_util2.promisify)(import_child_process6.execFile);
|
|
6715
6745
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
6716
6746
|
function resetStdinForChild() {
|
|
@@ -7199,7 +7229,7 @@ var GitHubCodespacesProvider = class {
|
|
|
7199
7229
|
});
|
|
7200
7230
|
}
|
|
7201
7231
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
7202
|
-
const remoteDir =
|
|
7232
|
+
const remoteDir = path11.posix.dirname(remotePath);
|
|
7203
7233
|
const parts = [
|
|
7204
7234
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
7205
7235
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -7269,7 +7299,7 @@ function shellQuote(s) {
|
|
|
7269
7299
|
// src/services/providers/gitpod.ts
|
|
7270
7300
|
var import_child_process7 = require("child_process");
|
|
7271
7301
|
var import_util3 = require("util");
|
|
7272
|
-
var
|
|
7302
|
+
var path12 = __toESM(require("path"));
|
|
7273
7303
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
7274
7304
|
var execFileP3 = (0, import_util3.promisify)(import_child_process7.execFile);
|
|
7275
7305
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -7509,7 +7539,7 @@ var GitpodProvider = class {
|
|
|
7509
7539
|
});
|
|
7510
7540
|
}
|
|
7511
7541
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
7512
|
-
const remoteDir =
|
|
7542
|
+
const remoteDir = path12.posix.dirname(remotePath);
|
|
7513
7543
|
const parts = [
|
|
7514
7544
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
7515
7545
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -7545,7 +7575,7 @@ function shellQuote2(s) {
|
|
|
7545
7575
|
// src/services/providers/gitlab-workspaces.ts
|
|
7546
7576
|
var import_child_process8 = require("child_process");
|
|
7547
7577
|
var import_util4 = require("util");
|
|
7548
|
-
var
|
|
7578
|
+
var path13 = __toESM(require("path"));
|
|
7549
7579
|
var execFileP4 = (0, import_util4.promisify)(import_child_process8.execFile);
|
|
7550
7580
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
7551
7581
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -7805,7 +7835,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
7805
7835
|
}
|
|
7806
7836
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
7807
7837
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
7808
|
-
const remoteDir =
|
|
7838
|
+
const remoteDir = path13.posix.dirname(remotePath);
|
|
7809
7839
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
7810
7840
|
if (options.mode != null) {
|
|
7811
7841
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -7873,7 +7903,7 @@ function shellQuote3(s) {
|
|
|
7873
7903
|
// src/services/providers/railway.ts
|
|
7874
7904
|
var import_child_process9 = require("child_process");
|
|
7875
7905
|
var import_util5 = require("util");
|
|
7876
|
-
var
|
|
7906
|
+
var path14 = __toESM(require("path"));
|
|
7877
7907
|
var execFileP5 = (0, import_util5.promisify)(import_child_process9.execFile);
|
|
7878
7908
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
7879
7909
|
function resetStdinForChild4() {
|
|
@@ -8109,7 +8139,7 @@ var RailwayProvider = class {
|
|
|
8109
8139
|
if (!projectId || !serviceId) {
|
|
8110
8140
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
8111
8141
|
}
|
|
8112
|
-
const remoteDir =
|
|
8142
|
+
const remoteDir = path14.posix.dirname(remotePath);
|
|
8113
8143
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
8114
8144
|
if (options.mode != null) {
|
|
8115
8145
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -8301,7 +8331,7 @@ async function deploy() {
|
|
|
8301
8331
|
process.exit(1);
|
|
8302
8332
|
}
|
|
8303
8333
|
}
|
|
8304
|
-
const localClaudeDir =
|
|
8334
|
+
const localClaudeDir = path15.join(os7.homedir(), ".claude");
|
|
8305
8335
|
const localCredsKind = await detectLocalClaudeCredentials(localClaudeDir);
|
|
8306
8336
|
let bridged = "none";
|
|
8307
8337
|
if (localCredsKind !== "none") {
|
|
@@ -8399,7 +8429,7 @@ async function deploy() {
|
|
|
8399
8429
|
}
|
|
8400
8430
|
}
|
|
8401
8431
|
if (bridged !== "none") {
|
|
8402
|
-
const localClaudeJson =
|
|
8432
|
+
const localClaudeJson = path15.join(os7.homedir(), ".claude.json");
|
|
8403
8433
|
if (fs8.existsSync(localClaudeJson)) {
|
|
8404
8434
|
try {
|
|
8405
8435
|
const contents = fs8.readFileSync(localClaudeJson);
|
|
@@ -8592,7 +8622,7 @@ async function runRemoteClaudeLogin(provider, workspaceId) {
|
|
|
8592
8622
|
}
|
|
8593
8623
|
}
|
|
8594
8624
|
async function detectLocalClaudeCredentials(localClaudeDir) {
|
|
8595
|
-
if (fs8.existsSync(
|
|
8625
|
+
if (fs8.existsSync(path15.join(localClaudeDir, ".credentials.json"))) {
|
|
8596
8626
|
return "flat-file";
|
|
8597
8627
|
}
|
|
8598
8628
|
if (process.platform === "darwin") {
|
|
@@ -8625,7 +8655,7 @@ async function verifyClaudeAuth(provider, workspaceId) {
|
|
|
8625
8655
|
}
|
|
8626
8656
|
}
|
|
8627
8657
|
async function bridgeClaudeCredentials(provider, workspaceId, localClaudeDir) {
|
|
8628
|
-
const fileBased =
|
|
8658
|
+
const fileBased = path15.join(localClaudeDir, ".credentials.json");
|
|
8629
8659
|
if (fs8.existsSync(fileBased)) return "flat-file";
|
|
8630
8660
|
if (process.platform === "darwin") {
|
|
8631
8661
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.32",
|
|
4
4
|
"description": "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands — from anywhere.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|