codeam-cli 2.16.0 → 2.16.1
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 +326 -219
- 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.16.0] — 2026-05-21
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli,vsc-plugin,jetbrains-plugin:** Codeam link <agent> CLI handoff (#41)
|
|
12
|
+
|
|
7
13
|
## [2.15.8] — 2026-05-21
|
|
8
14
|
|
|
9
15
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
@@ -30,6 +33,38 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
33
|
mod
|
|
31
34
|
));
|
|
32
35
|
|
|
36
|
+
// src/services/pty/types.ts
|
|
37
|
+
var types_exports = {};
|
|
38
|
+
__export(types_exports, {
|
|
39
|
+
findInPath: () => findInPath
|
|
40
|
+
});
|
|
41
|
+
function findInPath(name) {
|
|
42
|
+
const isWin = process.platform === "win32";
|
|
43
|
+
const dirs = (process.env.PATH ?? "").split(path3.delimiter).filter(Boolean);
|
|
44
|
+
const hasExt = path3.extname(name).length > 0;
|
|
45
|
+
const candidates = isWin && !hasExt ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, `${name}.ps1`, name] : [name];
|
|
46
|
+
const accessFlag = isWin ? fs3.constants.F_OK : fs3.constants.X_OK;
|
|
47
|
+
for (const dir of dirs) {
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
const full = path3.join(dir, candidate);
|
|
50
|
+
try {
|
|
51
|
+
fs3.accessSync(full, accessFlag);
|
|
52
|
+
return full;
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
var fs3, path3;
|
|
60
|
+
var init_types = __esm({
|
|
61
|
+
"src/services/pty/types.ts"() {
|
|
62
|
+
"use strict";
|
|
63
|
+
fs3 = __toESM(require("fs"));
|
|
64
|
+
path3 = __toESM(require("path"));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
33
68
|
// ../../node_modules/sisteransi/src/index.js
|
|
34
69
|
var require_src = __commonJS({
|
|
35
70
|
"../../node_modules/sisteransi/src/index.js"(exports2, module2) {
|
|
@@ -389,7 +424,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
389
424
|
// package.json
|
|
390
425
|
var package_default = {
|
|
391
426
|
name: "codeam-cli",
|
|
392
|
-
version: "2.16.
|
|
427
|
+
version: "2.16.1",
|
|
393
428
|
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.",
|
|
394
429
|
type: "commonjs",
|
|
395
430
|
main: "dist/index.js",
|
|
@@ -676,7 +711,7 @@ async function postLinkCredential(input) {
|
|
|
676
711
|
}
|
|
677
712
|
}
|
|
678
713
|
async function _postJsonAuthed(url, body, pluginAuthToken) {
|
|
679
|
-
return new Promise((
|
|
714
|
+
return new Promise((resolve3, reject) => {
|
|
680
715
|
const data = JSON.stringify(body);
|
|
681
716
|
const u2 = new URL(url);
|
|
682
717
|
const transport = u2.protocol === "https:" ? https : http;
|
|
@@ -708,9 +743,9 @@ async function _postJsonAuthed(url, body, pluginAuthToken) {
|
|
|
708
743
|
return;
|
|
709
744
|
}
|
|
710
745
|
try {
|
|
711
|
-
|
|
746
|
+
resolve3(JSON.parse(responseBody));
|
|
712
747
|
} catch {
|
|
713
|
-
|
|
748
|
+
resolve3(null);
|
|
714
749
|
}
|
|
715
750
|
});
|
|
716
751
|
}
|
|
@@ -725,7 +760,7 @@ async function _postJsonAuthed(url, body, pluginAuthToken) {
|
|
|
725
760
|
});
|
|
726
761
|
}
|
|
727
762
|
async function _postJson(url, body) {
|
|
728
|
-
return new Promise((
|
|
763
|
+
return new Promise((resolve3, reject) => {
|
|
729
764
|
const data = JSON.stringify(body);
|
|
730
765
|
const u2 = new URL(url);
|
|
731
766
|
const transport = u2.protocol === "https:" ? https : http;
|
|
@@ -754,9 +789,9 @@ async function _postJson(url, body) {
|
|
|
754
789
|
return;
|
|
755
790
|
}
|
|
756
791
|
try {
|
|
757
|
-
|
|
792
|
+
resolve3(JSON.parse(body2));
|
|
758
793
|
} catch {
|
|
759
|
-
|
|
794
|
+
resolve3(null);
|
|
760
795
|
}
|
|
761
796
|
});
|
|
762
797
|
}
|
|
@@ -771,7 +806,7 @@ async function _postJson(url, body) {
|
|
|
771
806
|
});
|
|
772
807
|
}
|
|
773
808
|
async function _getJson(url) {
|
|
774
|
-
return new Promise((
|
|
809
|
+
return new Promise((resolve3, reject) => {
|
|
775
810
|
const u2 = new URL(url);
|
|
776
811
|
const transport = u2.protocol === "https:" ? https : http;
|
|
777
812
|
const req = transport.request(
|
|
@@ -795,9 +830,9 @@ async function _getJson(url) {
|
|
|
795
830
|
return;
|
|
796
831
|
}
|
|
797
832
|
try {
|
|
798
|
-
|
|
833
|
+
resolve3(JSON.parse(body));
|
|
799
834
|
} catch {
|
|
800
|
-
|
|
835
|
+
resolve3(null);
|
|
801
836
|
}
|
|
802
837
|
});
|
|
803
838
|
}
|
|
@@ -1105,30 +1140,7 @@ var import_child_process2 = require("child_process");
|
|
|
1105
1140
|
var fs4 = __toESM(require("fs"));
|
|
1106
1141
|
var os4 = __toESM(require("os"));
|
|
1107
1142
|
var path4 = __toESM(require("path"));
|
|
1108
|
-
|
|
1109
|
-
// src/services/pty/types.ts
|
|
1110
|
-
var fs3 = __toESM(require("fs"));
|
|
1111
|
-
var path3 = __toESM(require("path"));
|
|
1112
|
-
function findInPath(name) {
|
|
1113
|
-
const isWin = process.platform === "win32";
|
|
1114
|
-
const dirs = (process.env.PATH ?? "").split(path3.delimiter).filter(Boolean);
|
|
1115
|
-
const hasExt = path3.extname(name).length > 0;
|
|
1116
|
-
const candidates = isWin && !hasExt ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, `${name}.ps1`, name] : [name];
|
|
1117
|
-
const accessFlag = isWin ? fs3.constants.F_OK : fs3.constants.X_OK;
|
|
1118
|
-
for (const dir of dirs) {
|
|
1119
|
-
for (const candidate of candidates) {
|
|
1120
|
-
const full = path3.join(dir, candidate);
|
|
1121
|
-
try {
|
|
1122
|
-
fs3.accessSync(full, accessFlag);
|
|
1123
|
-
return full;
|
|
1124
|
-
} catch {
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
return null;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
// src/services/pty/unix.strategy.ts
|
|
1143
|
+
init_types();
|
|
1132
1144
|
var PYTHON_PTY_HELPER = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
|
|
1133
1145
|
m,s=pty.openpty()
|
|
1134
1146
|
try:
|
|
@@ -3441,6 +3453,7 @@ ${c2}
|
|
|
3441
3453
|
} }).prompt();
|
|
3442
3454
|
|
|
3443
3455
|
// src/services/claude-installer.ts
|
|
3456
|
+
init_types();
|
|
3444
3457
|
function probeInstallDirs() {
|
|
3445
3458
|
const home = os5.homedir();
|
|
3446
3459
|
if (process.platform === "win32") {
|
|
@@ -3478,15 +3491,15 @@ function runInstaller() {
|
|
|
3478
3491
|
"-Command",
|
|
3479
3492
|
"irm https://claude.ai/install.ps1 | iex"
|
|
3480
3493
|
] : ["-c", "curl -fsSL https://claude.ai/install.sh | bash"];
|
|
3481
|
-
return new Promise((
|
|
3494
|
+
return new Promise((resolve3) => {
|
|
3482
3495
|
const proc = (0, import_child_process4.spawn)(cmd, args2, { stdio: "inherit" });
|
|
3483
3496
|
proc.on("error", (err) => {
|
|
3484
3497
|
console.error(`
|
|
3485
3498
|
\u2717 Installer failed to launch: ${err.message}`);
|
|
3486
|
-
|
|
3499
|
+
resolve3(false);
|
|
3487
3500
|
});
|
|
3488
3501
|
proc.on("exit", (code) => {
|
|
3489
|
-
|
|
3502
|
+
resolve3(code === 0);
|
|
3490
3503
|
});
|
|
3491
3504
|
});
|
|
3492
3505
|
}
|
|
@@ -3520,6 +3533,7 @@ async function ensureClaudeInstalled() {
|
|
|
3520
3533
|
|
|
3521
3534
|
// src/services/claude-resolver.ts
|
|
3522
3535
|
var path7 = __toESM(require("path"));
|
|
3536
|
+
init_types();
|
|
3523
3537
|
function buildClaudeLaunch(extraArgs = []) {
|
|
3524
3538
|
const found = findInPath("claude") ?? findInPath("claude-code");
|
|
3525
3539
|
if (!found) return null;
|
|
@@ -3779,6 +3793,7 @@ var fs5 = __toESM(require("fs"));
|
|
|
3779
3793
|
var os6 = __toESM(require("os"));
|
|
3780
3794
|
var path8 = __toESM(require("path"));
|
|
3781
3795
|
var import_child_process5 = require("child_process");
|
|
3796
|
+
init_types();
|
|
3782
3797
|
var HELPER_SCRIPT = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
|
|
3783
3798
|
m,s=pty.openpty()
|
|
3784
3799
|
try:
|
|
@@ -3834,17 +3849,17 @@ function parseUsageOutput(raw) {
|
|
|
3834
3849
|
return { percent, resetAt };
|
|
3835
3850
|
}
|
|
3836
3851
|
async function fetchClaudeQuota() {
|
|
3837
|
-
return new Promise((
|
|
3852
|
+
return new Promise((resolve3) => {
|
|
3838
3853
|
const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
|
|
3839
3854
|
if (!claudeCmd) {
|
|
3840
|
-
|
|
3855
|
+
resolve3(null);
|
|
3841
3856
|
return;
|
|
3842
3857
|
}
|
|
3843
3858
|
const helperPath = path8.join(os6.tmpdir(), "codeam-quota-helper.py");
|
|
3844
3859
|
fs5.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
|
|
3845
3860
|
const python = findInPath("python3") ?? findInPath("python");
|
|
3846
3861
|
if (!python) {
|
|
3847
|
-
|
|
3862
|
+
resolve3(null);
|
|
3848
3863
|
return;
|
|
3849
3864
|
}
|
|
3850
3865
|
const proc = (0, import_child_process5.spawn)(python, [helperPath, claudeCmd, "--tools", ""], {
|
|
@@ -3871,13 +3886,13 @@ async function fetchClaudeQuota() {
|
|
|
3871
3886
|
fs5.unlinkSync(helperPath);
|
|
3872
3887
|
} catch {
|
|
3873
3888
|
}
|
|
3874
|
-
|
|
3889
|
+
resolve3(result);
|
|
3875
3890
|
}, 5e3);
|
|
3876
3891
|
}, 8e3);
|
|
3877
3892
|
setTimeout(() => {
|
|
3878
3893
|
if (!resolved) {
|
|
3879
3894
|
resolved = true;
|
|
3880
|
-
|
|
3895
|
+
resolve3(null);
|
|
3881
3896
|
}
|
|
3882
3897
|
try {
|
|
3883
3898
|
proc.kill();
|
|
@@ -4522,6 +4537,7 @@ var ClaudeDeployStrategy = class {
|
|
|
4522
4537
|
|
|
4523
4538
|
// src/agents/codex/runtime.ts
|
|
4524
4539
|
var import_node_child_process = require("child_process");
|
|
4540
|
+
init_types();
|
|
4525
4541
|
|
|
4526
4542
|
// src/agents/codex/history.ts
|
|
4527
4543
|
var import_node_fs2 = __toESM(require("fs"));
|
|
@@ -5116,13 +5132,13 @@ var CodexRuntimeStrategy = class {
|
|
|
5116
5132
|
}
|
|
5117
5133
|
};
|
|
5118
5134
|
async function installCodexViaNpm() {
|
|
5119
|
-
return new Promise((
|
|
5135
|
+
return new Promise((resolve3, reject) => {
|
|
5120
5136
|
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
5121
5137
|
const proc = (0, import_node_child_process.spawn)(npm, ["install", "-g", "@openai/codex"], {
|
|
5122
5138
|
stdio: "inherit"
|
|
5123
5139
|
});
|
|
5124
5140
|
proc.on("close", (code) => {
|
|
5125
|
-
if (code === 0)
|
|
5141
|
+
if (code === 0) resolve3();
|
|
5126
5142
|
else reject(new Error(`npm install -g @openai/codex exited ${code}`));
|
|
5127
5143
|
});
|
|
5128
5144
|
proc.on("error", reject);
|
|
@@ -5321,14 +5337,14 @@ var ChunkEmitter = class {
|
|
|
5321
5337
|
"chunkEmitter",
|
|
5322
5338
|
`send type=${body.type ?? "(clear)"} bytes=${payload.length} done=${body.done === true}`
|
|
5323
5339
|
);
|
|
5324
|
-
return new Promise((
|
|
5340
|
+
return new Promise((resolve3) => {
|
|
5325
5341
|
const attempt = (attemptsLeft) => {
|
|
5326
5342
|
_transport2.post(this.url, this.headers, payload).then(({ statusCode, body: resBody }) => {
|
|
5327
5343
|
const tookMs = Date.now() - t0;
|
|
5328
5344
|
if (statusCode === 410 || statusCode === 404 && /SESSION_NOT_FOUND|SESSION_GONE/.test(resBody)) {
|
|
5329
5345
|
process.stderr.write("[codeam] session was deleted/disconnected \u2014 stopping output stream.\n");
|
|
5330
5346
|
log.info("chunkEmitter", `dead status=${statusCode} took=${tookMs}ms`);
|
|
5331
|
-
|
|
5347
|
+
resolve3({ dead: true });
|
|
5332
5348
|
return;
|
|
5333
5349
|
}
|
|
5334
5350
|
if (statusCode >= 400) {
|
|
@@ -5338,7 +5354,7 @@ var ChunkEmitter = class {
|
|
|
5338
5354
|
} else {
|
|
5339
5355
|
log.info("chunkEmitter", `ok status=${statusCode} took=${tookMs}ms`);
|
|
5340
5356
|
}
|
|
5341
|
-
|
|
5357
|
+
resolve3({ dead: false });
|
|
5342
5358
|
}).catch((err) => {
|
|
5343
5359
|
log.warn(
|
|
5344
5360
|
"chunkEmitter",
|
|
@@ -5349,7 +5365,7 @@ var ChunkEmitter = class {
|
|
|
5349
5365
|
const delay = 200 * (maxRetries - attemptsLeft + 1);
|
|
5350
5366
|
setTimeout(() => attempt(attemptsLeft - 1), delay);
|
|
5351
5367
|
} else {
|
|
5352
|
-
|
|
5368
|
+
resolve3({ dead: false });
|
|
5353
5369
|
}
|
|
5354
5370
|
});
|
|
5355
5371
|
};
|
|
@@ -5361,7 +5377,7 @@ var _transport2 = {
|
|
|
5361
5377
|
post: _post
|
|
5362
5378
|
};
|
|
5363
5379
|
function _post(url, headers, payload) {
|
|
5364
|
-
return new Promise((
|
|
5380
|
+
return new Promise((resolve3, reject) => {
|
|
5365
5381
|
let settled = false;
|
|
5366
5382
|
const u2 = new URL(url);
|
|
5367
5383
|
const transport = u2.protocol === "https:" ? https3 : http3;
|
|
@@ -5385,7 +5401,7 @@ function _post(url, headers, payload) {
|
|
|
5385
5401
|
res.on("end", () => {
|
|
5386
5402
|
if (settled) return;
|
|
5387
5403
|
settled = true;
|
|
5388
|
-
|
|
5404
|
+
resolve3({ statusCode: res.statusCode ?? 0, body: resData });
|
|
5389
5405
|
});
|
|
5390
5406
|
}
|
|
5391
5407
|
);
|
|
@@ -5821,7 +5837,7 @@ function parseJsonl(filePath) {
|
|
|
5821
5837
|
return messages;
|
|
5822
5838
|
}
|
|
5823
5839
|
function post(endpoint, body) {
|
|
5824
|
-
return new Promise((
|
|
5840
|
+
return new Promise((resolve3) => {
|
|
5825
5841
|
const payload = JSON.stringify(body);
|
|
5826
5842
|
const u2 = new URL(`${API_BASE4}${endpoint}`);
|
|
5827
5843
|
const transport = u2.protocol === "https:" ? https4 : http4;
|
|
@@ -5842,17 +5858,17 @@ function post(endpoint, body) {
|
|
|
5842
5858
|
res.resume();
|
|
5843
5859
|
const ok = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
|
|
5844
5860
|
if (!ok) log.warn("history:post", `${endpoint} \u2192 HTTP ${res.statusCode}`);
|
|
5845
|
-
|
|
5861
|
+
resolve3(ok);
|
|
5846
5862
|
}
|
|
5847
5863
|
);
|
|
5848
5864
|
req.on("error", (err) => {
|
|
5849
5865
|
log.warn("history:post", `${endpoint} network error`, err);
|
|
5850
|
-
|
|
5866
|
+
resolve3(false);
|
|
5851
5867
|
});
|
|
5852
5868
|
req.on("timeout", () => {
|
|
5853
5869
|
log.warn("history:post", `${endpoint} timeout after 15s`);
|
|
5854
5870
|
req.destroy();
|
|
5855
|
-
|
|
5871
|
+
resolve3(false);
|
|
5856
5872
|
});
|
|
5857
5873
|
req.write(payload);
|
|
5858
5874
|
req.end();
|
|
@@ -6334,7 +6350,7 @@ var _transport3 = {
|
|
|
6334
6350
|
post: _post2
|
|
6335
6351
|
};
|
|
6336
6352
|
function _post2(url, headers, payload) {
|
|
6337
|
-
return new Promise((
|
|
6353
|
+
return new Promise((resolve3, reject) => {
|
|
6338
6354
|
let settled = false;
|
|
6339
6355
|
const u2 = new URL(url);
|
|
6340
6356
|
const lib = u2.protocol === "https:" ? https5 : http5;
|
|
@@ -6359,7 +6375,7 @@ function _post2(url, headers, payload) {
|
|
|
6359
6375
|
res.on("end", () => {
|
|
6360
6376
|
if (settled) return;
|
|
6361
6377
|
settled = true;
|
|
6362
|
-
|
|
6378
|
+
resolve3({ statusCode: res.statusCode ?? 0, body });
|
|
6363
6379
|
});
|
|
6364
6380
|
}
|
|
6365
6381
|
);
|
|
@@ -6403,9 +6419,9 @@ var FileWatcherService = class {
|
|
|
6403
6419
|
if (this.stopped) {
|
|
6404
6420
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
6405
6421
|
}
|
|
6406
|
-
let
|
|
6422
|
+
let chokidar2;
|
|
6407
6423
|
try {
|
|
6408
|
-
|
|
6424
|
+
chokidar2 = require("chokidar");
|
|
6409
6425
|
} catch (err) {
|
|
6410
6426
|
log.warn(
|
|
6411
6427
|
"fileWatcher",
|
|
@@ -6414,7 +6430,7 @@ var FileWatcherService = class {
|
|
|
6414
6430
|
);
|
|
6415
6431
|
return;
|
|
6416
6432
|
}
|
|
6417
|
-
const watcher =
|
|
6433
|
+
const watcher = chokidar2.watch(this.opts.workingDir, {
|
|
6418
6434
|
ignored: [
|
|
6419
6435
|
/(^|[\\/])\../,
|
|
6420
6436
|
// dot-files & dot-dirs (.git, .next, .expo, .DS_Store, …)
|
|
@@ -6667,12 +6683,12 @@ var _gitSeam = {
|
|
|
6667
6683
|
run: _runGitImpl
|
|
6668
6684
|
};
|
|
6669
6685
|
async function _runGitImpl(cwd, args2, opts = {}) {
|
|
6670
|
-
return new Promise((
|
|
6686
|
+
return new Promise((resolve3) => {
|
|
6671
6687
|
let proc;
|
|
6672
6688
|
try {
|
|
6673
6689
|
proc = (0, import_child_process7.spawn)("git", args2, { cwd, env: process.env });
|
|
6674
6690
|
} catch {
|
|
6675
|
-
|
|
6691
|
+
resolve3(null);
|
|
6676
6692
|
return;
|
|
6677
6693
|
}
|
|
6678
6694
|
let stdout = "";
|
|
@@ -6683,13 +6699,13 @@ async function _runGitImpl(cwd, args2, opts = {}) {
|
|
|
6683
6699
|
proc.stderr?.on("data", (c2) => {
|
|
6684
6700
|
stderr += c2.toString();
|
|
6685
6701
|
});
|
|
6686
|
-
proc.on("error", () =>
|
|
6702
|
+
proc.on("error", () => resolve3(null));
|
|
6687
6703
|
proc.on("close", (code) => {
|
|
6688
6704
|
if (code === 0 || opts.allowNonZeroExit) {
|
|
6689
|
-
|
|
6705
|
+
resolve3(stdout);
|
|
6690
6706
|
} else {
|
|
6691
6707
|
log.trace("fileWatcher", `git ${args2.join(" ")} exited ${code} stderr=${stderr.slice(0, 200)}`);
|
|
6692
|
-
|
|
6708
|
+
resolve3(null);
|
|
6693
6709
|
}
|
|
6694
6710
|
});
|
|
6695
6711
|
});
|
|
@@ -6709,7 +6725,7 @@ var _transport4 = {
|
|
|
6709
6725
|
get: _get
|
|
6710
6726
|
};
|
|
6711
6727
|
function _post3(url, headers, payload) {
|
|
6712
|
-
return new Promise((
|
|
6728
|
+
return new Promise((resolve3, reject) => {
|
|
6713
6729
|
let settled = false;
|
|
6714
6730
|
const u2 = new URL(url);
|
|
6715
6731
|
const lib = u2.protocol === "https:" ? https6 : http6;
|
|
@@ -6734,7 +6750,7 @@ function _post3(url, headers, payload) {
|
|
|
6734
6750
|
res.on("end", () => {
|
|
6735
6751
|
if (settled) return;
|
|
6736
6752
|
settled = true;
|
|
6737
|
-
|
|
6753
|
+
resolve3({ statusCode: res.statusCode ?? 0, body });
|
|
6738
6754
|
});
|
|
6739
6755
|
}
|
|
6740
6756
|
);
|
|
@@ -6751,7 +6767,7 @@ function _post3(url, headers, payload) {
|
|
|
6751
6767
|
});
|
|
6752
6768
|
}
|
|
6753
6769
|
function _get(url, headers) {
|
|
6754
|
-
return new Promise((
|
|
6770
|
+
return new Promise((resolve3, reject) => {
|
|
6755
6771
|
let settled = false;
|
|
6756
6772
|
const u2 = new URL(url);
|
|
6757
6773
|
const lib = u2.protocol === "https:" ? https6 : http6;
|
|
@@ -6775,7 +6791,7 @@ function _get(url, headers) {
|
|
|
6775
6791
|
res.on("end", () => {
|
|
6776
6792
|
if (settled) return;
|
|
6777
6793
|
settled = true;
|
|
6778
|
-
|
|
6794
|
+
resolve3({ statusCode: res.statusCode ?? 0, body });
|
|
6779
6795
|
});
|
|
6780
6796
|
}
|
|
6781
6797
|
);
|
|
@@ -7144,7 +7160,7 @@ function buildKeepAlive(ctx) {
|
|
|
7144
7160
|
let timer = null;
|
|
7145
7161
|
async function setIdleTimeout(minutes) {
|
|
7146
7162
|
if (!ctx.inCodespace || !ctx.codespaceName) return;
|
|
7147
|
-
await new Promise((
|
|
7163
|
+
await new Promise((resolve3) => {
|
|
7148
7164
|
const proc = (0, import_child_process8.spawn)(
|
|
7149
7165
|
"gh",
|
|
7150
7166
|
[
|
|
@@ -7158,8 +7174,8 @@ function buildKeepAlive(ctx) {
|
|
|
7158
7174
|
{ stdio: "ignore", detached: true }
|
|
7159
7175
|
);
|
|
7160
7176
|
proc.unref();
|
|
7161
|
-
proc.on("exit", () =>
|
|
7162
|
-
proc.on("error", () =>
|
|
7177
|
+
proc.on("exit", () => resolve3());
|
|
7178
|
+
proc.on("error", () => resolve3());
|
|
7163
7179
|
});
|
|
7164
7180
|
}
|
|
7165
7181
|
return {
|
|
@@ -8537,7 +8553,7 @@ async function pair(args2 = []) {
|
|
|
8537
8553
|
waitSpin.message(waitMessage());
|
|
8538
8554
|
}, 1e3);
|
|
8539
8555
|
countdownInterval.unref?.();
|
|
8540
|
-
await new Promise((
|
|
8556
|
+
await new Promise((resolve3) => {
|
|
8541
8557
|
let stopPolling = null;
|
|
8542
8558
|
function sigintHandler() {
|
|
8543
8559
|
clearInterval(countdownInterval);
|
|
@@ -8564,7 +8580,7 @@ async function pair(args2 = []) {
|
|
|
8564
8580
|
saveCliConfig({ ...loadCliConfig(), preferredAgent: agentId });
|
|
8565
8581
|
showSuccess(`Paired with ${info.userName} (${info.plan})`);
|
|
8566
8582
|
console.log("");
|
|
8567
|
-
|
|
8583
|
+
resolve3();
|
|
8568
8584
|
},
|
|
8569
8585
|
() => {
|
|
8570
8586
|
clearInterval(countdownInterval);
|
|
@@ -8597,12 +8613,12 @@ function readTokenFromArgs(args2) {
|
|
|
8597
8613
|
}
|
|
8598
8614
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
8599
8615
|
if (fileFlag) {
|
|
8600
|
-
const
|
|
8616
|
+
const path28 = fileFlag.slice("--token-file=".length);
|
|
8601
8617
|
try {
|
|
8602
|
-
const content = fs15.readFileSync(
|
|
8603
|
-
if (content.length === 0) fail(`--token-file ${
|
|
8618
|
+
const content = fs15.readFileSync(path28, "utf8").trim();
|
|
8619
|
+
if (content.length === 0) fail(`--token-file ${path28} is empty`);
|
|
8604
8620
|
try {
|
|
8605
|
-
fs15.unlinkSync(
|
|
8621
|
+
fs15.unlinkSync(path28);
|
|
8606
8622
|
} catch {
|
|
8607
8623
|
}
|
|
8608
8624
|
return content;
|
|
@@ -8820,12 +8836,12 @@ var GitHubCodespacesProvider = class {
|
|
|
8820
8836
|
}
|
|
8821
8837
|
if (!isAuthed) {
|
|
8822
8838
|
resetStdinForChild();
|
|
8823
|
-
await new Promise((
|
|
8839
|
+
await new Promise((resolve3, reject) => {
|
|
8824
8840
|
const proc = (0, import_child_process12.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
|
|
8825
8841
|
stdio: "inherit"
|
|
8826
8842
|
});
|
|
8827
8843
|
proc.on("exit", (code) => {
|
|
8828
|
-
if (code === 0)
|
|
8844
|
+
if (code === 0) resolve3();
|
|
8829
8845
|
else reject(new Error("gh auth login failed."));
|
|
8830
8846
|
});
|
|
8831
8847
|
proc.on("error", reject);
|
|
@@ -8854,13 +8870,13 @@ var GitHubCodespacesProvider = class {
|
|
|
8854
8870
|
}
|
|
8855
8871
|
wt(noteLines.join("\n"), "One more permission needed");
|
|
8856
8872
|
resetStdinForChild();
|
|
8857
|
-
const refreshCode = await new Promise((
|
|
8873
|
+
const refreshCode = await new Promise((resolve3, reject) => {
|
|
8858
8874
|
const proc = (0, import_child_process12.spawn)(
|
|
8859
8875
|
"gh",
|
|
8860
8876
|
["auth", "refresh", "-h", "github.com", "-s", "codespace"],
|
|
8861
8877
|
{ stdio: "inherit" }
|
|
8862
8878
|
);
|
|
8863
|
-
proc.on("exit", (code) =>
|
|
8879
|
+
proc.on("exit", (code) => resolve3(code ?? 1));
|
|
8864
8880
|
proc.on("error", reject);
|
|
8865
8881
|
});
|
|
8866
8882
|
if (refreshCode !== 0) {
|
|
@@ -9004,10 +9020,10 @@ var GitHubCodespacesProvider = class {
|
|
|
9004
9020
|
if (q(proceed) || !proceed) return;
|
|
9005
9021
|
O2.step(`Installing gh via ${installCmd.describe}\u2026`);
|
|
9006
9022
|
resetStdinForChild();
|
|
9007
|
-
const ok = await new Promise((
|
|
9023
|
+
const ok = await new Promise((resolve3) => {
|
|
9008
9024
|
const proc = (0, import_child_process12.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
|
|
9009
|
-
proc.on("exit", (code) =>
|
|
9010
|
-
proc.on("error", () =>
|
|
9025
|
+
proc.on("exit", (code) => resolve3(code === 0));
|
|
9026
|
+
proc.on("error", () => resolve3(false));
|
|
9011
9027
|
});
|
|
9012
9028
|
if (ok) O2.success("gh installed");
|
|
9013
9029
|
else O2.error("gh install failed");
|
|
@@ -9031,14 +9047,14 @@ var GitHubCodespacesProvider = class {
|
|
|
9031
9047
|
"Expanding GitHub scopes"
|
|
9032
9048
|
);
|
|
9033
9049
|
resetStdinForChild();
|
|
9034
|
-
await new Promise((
|
|
9050
|
+
await new Promise((resolve3, reject) => {
|
|
9035
9051
|
const proc = (0, import_child_process12.spawn)(
|
|
9036
9052
|
"gh",
|
|
9037
9053
|
["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
|
|
9038
9054
|
{ stdio: "inherit" }
|
|
9039
9055
|
);
|
|
9040
9056
|
proc.on("exit", (code) => {
|
|
9041
|
-
if (code === 0)
|
|
9057
|
+
if (code === 0) resolve3();
|
|
9042
9058
|
else reject(new Error(
|
|
9043
9059
|
"gh auth refresh failed. Re-run `gh auth refresh -h github.com -s repo,read:org` manually."
|
|
9044
9060
|
));
|
|
@@ -9209,13 +9225,13 @@ var GitHubCodespacesProvider = class {
|
|
|
9209
9225
|
}
|
|
9210
9226
|
async streamCommand(workspaceId, command2) {
|
|
9211
9227
|
resetStdinForChild();
|
|
9212
|
-
return new Promise((
|
|
9228
|
+
return new Promise((resolve3, reject) => {
|
|
9213
9229
|
const proc = (0, import_child_process12.spawn)(
|
|
9214
9230
|
"gh",
|
|
9215
9231
|
["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
|
|
9216
9232
|
{ stdio: "inherit" }
|
|
9217
9233
|
);
|
|
9218
|
-
proc.on("exit", (code) =>
|
|
9234
|
+
proc.on("exit", (code) => resolve3({ code: code ?? 0 }));
|
|
9219
9235
|
proc.on("error", reject);
|
|
9220
9236
|
});
|
|
9221
9237
|
}
|
|
@@ -9236,7 +9252,7 @@ var GitHubCodespacesProvider = class {
|
|
|
9236
9252
|
"--",
|
|
9237
9253
|
`mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
|
|
9238
9254
|
];
|
|
9239
|
-
await new Promise((
|
|
9255
|
+
await new Promise((resolve3, reject) => {
|
|
9240
9256
|
const tar = (0, import_child_process12.spawn)("tar", tarArgs, {
|
|
9241
9257
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9242
9258
|
env: tarEnv
|
|
@@ -9256,7 +9272,7 @@ var GitHubCodespacesProvider = class {
|
|
|
9256
9272
|
ssh.on("error", reject);
|
|
9257
9273
|
ssh.on("exit", (code) => {
|
|
9258
9274
|
if (code === 0) {
|
|
9259
|
-
|
|
9275
|
+
resolve3();
|
|
9260
9276
|
} else {
|
|
9261
9277
|
const reason = (sshErr || tarErr || `exit ${code}`).trim().slice(0, 500);
|
|
9262
9278
|
reject(new Error(`Remote tar failed: ${reason}`));
|
|
@@ -9274,7 +9290,7 @@ var GitHubCodespacesProvider = class {
|
|
|
9274
9290
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote(remotePath)}`);
|
|
9275
9291
|
}
|
|
9276
9292
|
const cmd = parts.join(" && ");
|
|
9277
|
-
await new Promise((
|
|
9293
|
+
await new Promise((resolve3, reject) => {
|
|
9278
9294
|
const proc = (0, import_child_process12.spawn)(
|
|
9279
9295
|
"gh",
|
|
9280
9296
|
["codespace", "ssh", "-c", workspaceId, "--", cmd],
|
|
@@ -9286,7 +9302,7 @@ var GitHubCodespacesProvider = class {
|
|
|
9286
9302
|
});
|
|
9287
9303
|
proc.on("error", reject);
|
|
9288
9304
|
proc.on("exit", (code) => {
|
|
9289
|
-
if (code === 0)
|
|
9305
|
+
if (code === 0) resolve3();
|
|
9290
9306
|
else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
9291
9307
|
});
|
|
9292
9308
|
proc.stdin?.write(contents);
|
|
@@ -9376,10 +9392,10 @@ var GitpodProvider = class {
|
|
|
9376
9392
|
"Authenticating Gitpod"
|
|
9377
9393
|
);
|
|
9378
9394
|
resetStdinForChild2();
|
|
9379
|
-
await new Promise((
|
|
9395
|
+
await new Promise((resolve3, reject) => {
|
|
9380
9396
|
const proc = (0, import_child_process13.spawn)("gitpod", ["login"], { stdio: "inherit" });
|
|
9381
9397
|
proc.on("exit", (code) => {
|
|
9382
|
-
if (code === 0)
|
|
9398
|
+
if (code === 0) resolve3();
|
|
9383
9399
|
else reject(new Error("gitpod login failed."));
|
|
9384
9400
|
});
|
|
9385
9401
|
proc.on("error", reject);
|
|
@@ -9528,13 +9544,13 @@ var GitpodProvider = class {
|
|
|
9528
9544
|
}
|
|
9529
9545
|
async streamCommand(workspaceId, command2) {
|
|
9530
9546
|
resetStdinForChild2();
|
|
9531
|
-
return new Promise((
|
|
9547
|
+
return new Promise((resolve3, reject) => {
|
|
9532
9548
|
const proc = (0, import_child_process13.spawn)(
|
|
9533
9549
|
"gitpod",
|
|
9534
9550
|
["workspace", "ssh", workspaceId, "--", "-tt", command2],
|
|
9535
9551
|
{ stdio: "inherit" }
|
|
9536
9552
|
);
|
|
9537
|
-
proc.on("exit", (code) =>
|
|
9553
|
+
proc.on("exit", (code) => resolve3({ code: code ?? 0 }));
|
|
9538
9554
|
proc.on("error", reject);
|
|
9539
9555
|
});
|
|
9540
9556
|
}
|
|
@@ -9548,7 +9564,7 @@ var GitpodProvider = class {
|
|
|
9548
9564
|
tarArgs.push(".");
|
|
9549
9565
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
9550
9566
|
const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
|
|
9551
|
-
await new Promise((
|
|
9567
|
+
await new Promise((resolve3, reject) => {
|
|
9552
9568
|
const tar = (0, import_child_process13.spawn)("tar", tarArgs, {
|
|
9553
9569
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9554
9570
|
env: tarEnv
|
|
@@ -9569,7 +9585,7 @@ var GitpodProvider = class {
|
|
|
9569
9585
|
tar.on("error", reject);
|
|
9570
9586
|
ssh.on("error", reject);
|
|
9571
9587
|
ssh.on("exit", (code) => {
|
|
9572
|
-
if (code === 0)
|
|
9588
|
+
if (code === 0) resolve3();
|
|
9573
9589
|
else reject(new Error(`Remote tar failed: ${(sshErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
9574
9590
|
});
|
|
9575
9591
|
});
|
|
@@ -9584,7 +9600,7 @@ var GitpodProvider = class {
|
|
|
9584
9600
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote2(remotePath)}`);
|
|
9585
9601
|
}
|
|
9586
9602
|
const cmd = parts.join(" && ");
|
|
9587
|
-
await new Promise((
|
|
9603
|
+
await new Promise((resolve3, reject) => {
|
|
9588
9604
|
const proc = (0, import_child_process13.spawn)(
|
|
9589
9605
|
"gitpod",
|
|
9590
9606
|
["workspace", "ssh", workspaceId, "--", cmd],
|
|
@@ -9596,7 +9612,7 @@ var GitpodProvider = class {
|
|
|
9596
9612
|
});
|
|
9597
9613
|
proc.on("error", reject);
|
|
9598
9614
|
proc.on("exit", (code) => {
|
|
9599
|
-
if (code === 0)
|
|
9615
|
+
if (code === 0) resolve3();
|
|
9600
9616
|
else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
9601
9617
|
});
|
|
9602
9618
|
proc.stdin?.write(contents);
|
|
@@ -9653,14 +9669,14 @@ var GitLabWorkspacesProvider = class {
|
|
|
9653
9669
|
"Authenticating GitLab"
|
|
9654
9670
|
);
|
|
9655
9671
|
resetStdinForChild3();
|
|
9656
|
-
await new Promise((
|
|
9672
|
+
await new Promise((resolve3, reject) => {
|
|
9657
9673
|
const proc = (0, import_child_process14.spawn)(
|
|
9658
9674
|
"glab",
|
|
9659
9675
|
["auth", "login", "--scopes", "api,read_user,read_repository"],
|
|
9660
9676
|
{ stdio: "inherit" }
|
|
9661
9677
|
);
|
|
9662
9678
|
proc.on("exit", (code) => {
|
|
9663
|
-
if (code === 0)
|
|
9679
|
+
if (code === 0) resolve3();
|
|
9664
9680
|
else reject(new Error("glab auth login failed."));
|
|
9665
9681
|
});
|
|
9666
9682
|
proc.on("error", reject);
|
|
@@ -9825,13 +9841,13 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
9825
9841
|
async streamCommand(workspaceId, command2) {
|
|
9826
9842
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
9827
9843
|
resetStdinForChild3();
|
|
9828
|
-
return new Promise((
|
|
9844
|
+
return new Promise((resolve3, reject) => {
|
|
9829
9845
|
const proc = (0, import_child_process14.spawn)(
|
|
9830
9846
|
"ssh",
|
|
9831
9847
|
["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
|
|
9832
9848
|
{ stdio: "inherit" }
|
|
9833
9849
|
);
|
|
9834
|
-
proc.on("exit", (code) =>
|
|
9850
|
+
proc.on("exit", (code) => resolve3({ code: code ?? 0 }));
|
|
9835
9851
|
proc.on("error", reject);
|
|
9836
9852
|
});
|
|
9837
9853
|
}
|
|
@@ -9846,7 +9862,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
9846
9862
|
tarArgs.push(".");
|
|
9847
9863
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
9848
9864
|
const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
|
|
9849
|
-
await new Promise((
|
|
9865
|
+
await new Promise((resolve3, reject) => {
|
|
9850
9866
|
const tar = (0, import_child_process14.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
9851
9867
|
const ssh = (0, import_child_process14.spawn)(
|
|
9852
9868
|
"ssh",
|
|
@@ -9864,7 +9880,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
9864
9880
|
tar.on("error", reject);
|
|
9865
9881
|
ssh.on("error", reject);
|
|
9866
9882
|
ssh.on("exit", (code) => {
|
|
9867
|
-
if (code === 0)
|
|
9883
|
+
if (code === 0) resolve3();
|
|
9868
9884
|
else reject(new Error(`Remote tar failed: ${(sshErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
9869
9885
|
});
|
|
9870
9886
|
});
|
|
@@ -9877,7 +9893,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
9877
9893
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
9878
9894
|
}
|
|
9879
9895
|
const cmd = parts.join(" && ");
|
|
9880
|
-
await new Promise((
|
|
9896
|
+
await new Promise((resolve3, reject) => {
|
|
9881
9897
|
const proc = (0, import_child_process14.spawn)(
|
|
9882
9898
|
"ssh",
|
|
9883
9899
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
|
|
@@ -9889,7 +9905,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
9889
9905
|
});
|
|
9890
9906
|
proc.on("error", reject);
|
|
9891
9907
|
proc.on("exit", (code) => {
|
|
9892
|
-
if (code === 0)
|
|
9908
|
+
if (code === 0) resolve3();
|
|
9893
9909
|
else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
9894
9910
|
});
|
|
9895
9911
|
proc.stdin?.write(contents);
|
|
@@ -9980,10 +9996,10 @@ var RailwayProvider = class {
|
|
|
9980
9996
|
"Authenticating Railway"
|
|
9981
9997
|
);
|
|
9982
9998
|
resetStdinForChild4();
|
|
9983
|
-
await new Promise((
|
|
9999
|
+
await new Promise((resolve3, reject) => {
|
|
9984
10000
|
const proc = (0, import_child_process15.spawn)("railway", ["login"], { stdio: "inherit" });
|
|
9985
10001
|
proc.on("exit", (code) => {
|
|
9986
|
-
if (code === 0)
|
|
10002
|
+
if (code === 0) resolve3();
|
|
9987
10003
|
else reject(new Error("railway login failed."));
|
|
9988
10004
|
});
|
|
9989
10005
|
proc.on("error", reject);
|
|
@@ -10123,13 +10139,13 @@ var RailwayProvider = class {
|
|
|
10123
10139
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
10124
10140
|
}
|
|
10125
10141
|
resetStdinForChild4();
|
|
10126
|
-
return new Promise((
|
|
10142
|
+
return new Promise((resolve3, reject) => {
|
|
10127
10143
|
const proc = (0, import_child_process15.spawn)(
|
|
10128
10144
|
"railway",
|
|
10129
10145
|
["shell", "--project", projectId, "--service", serviceId, "--command", command2],
|
|
10130
10146
|
{ stdio: "inherit" }
|
|
10131
10147
|
);
|
|
10132
|
-
proc.on("exit", (code) =>
|
|
10148
|
+
proc.on("exit", (code) => resolve3({ code: code ?? 0 }));
|
|
10133
10149
|
proc.on("error", reject);
|
|
10134
10150
|
});
|
|
10135
10151
|
}
|
|
@@ -10147,7 +10163,7 @@ var RailwayProvider = class {
|
|
|
10147
10163
|
tarArgs.push(".");
|
|
10148
10164
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
10149
10165
|
const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
|
|
10150
|
-
await new Promise((
|
|
10166
|
+
await new Promise((resolve3, reject) => {
|
|
10151
10167
|
const tar = (0, import_child_process15.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
10152
10168
|
const sh = (0, import_child_process15.spawn)(
|
|
10153
10169
|
"railway",
|
|
@@ -10165,7 +10181,7 @@ var RailwayProvider = class {
|
|
|
10165
10181
|
tar.on("error", reject);
|
|
10166
10182
|
sh.on("error", reject);
|
|
10167
10183
|
sh.on("exit", (code) => {
|
|
10168
|
-
if (code === 0)
|
|
10184
|
+
if (code === 0) resolve3();
|
|
10169
10185
|
else reject(new Error(`Remote tar failed: ${(shErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
10170
10186
|
});
|
|
10171
10187
|
});
|
|
@@ -10181,7 +10197,7 @@ var RailwayProvider = class {
|
|
|
10181
10197
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
10182
10198
|
}
|
|
10183
10199
|
const cmd = parts.join(" && ");
|
|
10184
|
-
await new Promise((
|
|
10200
|
+
await new Promise((resolve3, reject) => {
|
|
10185
10201
|
const proc = (0, import_child_process15.spawn)(
|
|
10186
10202
|
"railway",
|
|
10187
10203
|
["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
|
|
@@ -10193,7 +10209,7 @@ var RailwayProvider = class {
|
|
|
10193
10209
|
});
|
|
10194
10210
|
proc.on("error", reject);
|
|
10195
10211
|
proc.on("exit", (code) => {
|
|
10196
|
-
if (code === 0)
|
|
10212
|
+
if (code === 0) resolve3();
|
|
10197
10213
|
else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
|
|
10198
10214
|
});
|
|
10199
10215
|
proc.stdin?.write(contents);
|
|
@@ -10717,6 +10733,9 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
10717
10733
|
// src/commands/link.ts
|
|
10718
10734
|
var import_node_child_process3 = require("child_process");
|
|
10719
10735
|
var import_node_crypto = require("crypto");
|
|
10736
|
+
var fs18 = __toESM(require("fs"));
|
|
10737
|
+
var path26 = __toESM(require("path"));
|
|
10738
|
+
var import_chokidar = __toESM(require("chokidar"));
|
|
10720
10739
|
var import_picocolors11 = __toESM(require("picocolors"));
|
|
10721
10740
|
|
|
10722
10741
|
// src/agents/claude/local-token.ts
|
|
@@ -10726,41 +10745,45 @@ var os15 = __toESM(require("os"));
|
|
|
10726
10745
|
var path24 = __toESM(require("path"));
|
|
10727
10746
|
var import_node_util3 = require("util");
|
|
10728
10747
|
var execFileP7 = (0, import_node_util3.promisify)(import_node_child_process2.execFile);
|
|
10729
|
-
|
|
10730
|
-
|
|
10748
|
+
var KEYCHAIN_SERVICE_NAMES = [
|
|
10749
|
+
"Claude Code-credentials",
|
|
10750
|
+
"claude-code-credentials",
|
|
10751
|
+
"Claude",
|
|
10752
|
+
"Anthropic Claude"
|
|
10753
|
+
];
|
|
10754
|
+
function claudeCredentialsPaths() {
|
|
10755
|
+
const home = os15.homedir();
|
|
10756
|
+
return [
|
|
10757
|
+
path24.join(home, ".claude", ".credentials.json"),
|
|
10758
|
+
path24.join(home, ".config", "claude", ".credentials.json")
|
|
10759
|
+
];
|
|
10731
10760
|
}
|
|
10732
10761
|
async function extractLocalClaudeToken() {
|
|
10733
|
-
const flat
|
|
10734
|
-
|
|
10762
|
+
for (const flat of claudeCredentialsPaths()) {
|
|
10763
|
+
if (!fs16.existsSync(flat)) continue;
|
|
10735
10764
|
const credential = fs16.readFileSync(flat, "utf8").trim();
|
|
10736
10765
|
if (credential.length > 0) {
|
|
10737
10766
|
return { method: "oauth", credential, source: "flat-file" };
|
|
10738
10767
|
}
|
|
10739
10768
|
}
|
|
10740
10769
|
if (process.platform === "darwin") {
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10770
|
+
for (const service of KEYCHAIN_SERVICE_NAMES) {
|
|
10771
|
+
try {
|
|
10772
|
+
const { stdout } = await execFileP7(
|
|
10773
|
+
"security",
|
|
10774
|
+
["find-generic-password", "-s", service, "-w"],
|
|
10775
|
+
{ maxBuffer: 1024 * 1024 }
|
|
10776
|
+
);
|
|
10777
|
+
const credential = stdout.trim();
|
|
10778
|
+
if (credential.length > 0) {
|
|
10779
|
+
return { method: "oauth", credential, source: "macos-keychain" };
|
|
10780
|
+
}
|
|
10781
|
+
} catch {
|
|
10750
10782
|
}
|
|
10751
|
-
} catch {
|
|
10752
10783
|
}
|
|
10753
10784
|
}
|
|
10754
10785
|
return null;
|
|
10755
10786
|
}
|
|
10756
|
-
function claudeCredentialsMtime() {
|
|
10757
|
-
const flat = claudeCredentialsPath();
|
|
10758
|
-
try {
|
|
10759
|
-
return fs16.statSync(flat).mtimeMs;
|
|
10760
|
-
} catch {
|
|
10761
|
-
return null;
|
|
10762
|
-
}
|
|
10763
|
-
}
|
|
10764
10787
|
|
|
10765
10788
|
// src/agents/codex/local-token.ts
|
|
10766
10789
|
var fs17 = __toESM(require("fs"));
|
|
@@ -10776,13 +10799,8 @@ async function extractLocalCodexToken() {
|
|
|
10776
10799
|
if (credential.length === 0) return null;
|
|
10777
10800
|
return { method: "oauth", credential, source: "flat-file" };
|
|
10778
10801
|
}
|
|
10779
|
-
function
|
|
10780
|
-
|
|
10781
|
-
try {
|
|
10782
|
-
return fs17.statSync(file).mtimeMs;
|
|
10783
|
-
} catch {
|
|
10784
|
-
return null;
|
|
10785
|
-
}
|
|
10802
|
+
function codexCredentialsPaths() {
|
|
10803
|
+
return [codexCredentialsPath()];
|
|
10786
10804
|
}
|
|
10787
10805
|
|
|
10788
10806
|
// src/commands/link.ts
|
|
@@ -10791,23 +10809,38 @@ var AGENT_META = {
|
|
|
10791
10809
|
internalId: "claude",
|
|
10792
10810
|
publicId: "claude_code",
|
|
10793
10811
|
binary: "claude",
|
|
10794
|
-
loginArgs: ["login"],
|
|
10795
10812
|
displayName: "Claude Code",
|
|
10796
10813
|
vendor: "Anthropic",
|
|
10797
|
-
credentialsHint: "~/.claude/.credentials.json
|
|
10814
|
+
credentialsHint: "~/.claude/.credentials.json or the macOS Keychain",
|
|
10815
|
+
watchPaths: claudeCredentialsPaths,
|
|
10798
10816
|
extract: extractLocalClaudeToken,
|
|
10799
|
-
|
|
10817
|
+
ensureInstalled: ensureClaudeInstalled,
|
|
10818
|
+
launchLogin: () => {
|
|
10819
|
+
const child = (0, import_node_child_process3.spawn)("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
|
|
10820
|
+
child.stdin?.write("/login\n");
|
|
10821
|
+
return child;
|
|
10822
|
+
}
|
|
10800
10823
|
},
|
|
10801
10824
|
codex: {
|
|
10802
10825
|
internalId: "codex",
|
|
10803
10826
|
publicId: "codex",
|
|
10804
10827
|
binary: "codex",
|
|
10805
|
-
loginArgs: ["login"],
|
|
10806
10828
|
displayName: "Codex",
|
|
10807
10829
|
vendor: "OpenAI",
|
|
10808
10830
|
credentialsHint: "~/.codex/auth.json",
|
|
10831
|
+
watchPaths: codexCredentialsPaths,
|
|
10809
10832
|
extract: extractLocalCodexToken,
|
|
10810
|
-
|
|
10833
|
+
ensureInstalled: async () => {
|
|
10834
|
+
const { findInPath: findInPath2 } = await Promise.resolve().then(() => (init_types(), types_exports));
|
|
10835
|
+
if (findInPath2("codex")) return true;
|
|
10836
|
+
showError(
|
|
10837
|
+
"codex binary not found on PATH. Install it first (https://github.com/openai/codex-cli) then re-run `codeam link codex`."
|
|
10838
|
+
);
|
|
10839
|
+
return false;
|
|
10840
|
+
},
|
|
10841
|
+
launchLogin: () => {
|
|
10842
|
+
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
10843
|
+
}
|
|
10811
10844
|
}
|
|
10812
10845
|
};
|
|
10813
10846
|
function parseLinkArgs(args2) {
|
|
@@ -10825,11 +10858,15 @@ function parseLinkArgs(args2) {
|
|
|
10825
10858
|
);
|
|
10826
10859
|
}
|
|
10827
10860
|
const reuseExisting = args2.includes("--reuse-existing");
|
|
10828
|
-
|
|
10861
|
+
const apiKeyArg = args2.find((a) => a.startsWith("--api-key="));
|
|
10862
|
+
const apiKey = apiKeyArg ? apiKeyArg.slice("--api-key=".length) : null;
|
|
10863
|
+
const tokenFileArg = args2.find((a) => a.startsWith("--token-file="));
|
|
10864
|
+
const tokenFile = tokenFileArg ? tokenFileArg.slice("--token-file=".length) : null;
|
|
10865
|
+
return { agent: normalised, reuseExisting, apiKey, tokenFile };
|
|
10829
10866
|
}
|
|
10830
10867
|
async function link(args2 = []) {
|
|
10831
|
-
const
|
|
10832
|
-
const meta = AGENT_META[agent];
|
|
10868
|
+
const parsed = parseLinkArgs(args2);
|
|
10869
|
+
const meta = AGENT_META[parsed.agent];
|
|
10833
10870
|
showIntro();
|
|
10834
10871
|
console.log(
|
|
10835
10872
|
import_picocolors11.default.bold(` Link ${meta.displayName}`) + import_picocolors11.default.dim(` \xB7 ${meta.vendor}`)
|
|
@@ -10853,7 +10890,7 @@ async function link(args2 = []) {
|
|
|
10853
10890
|
waitSpin.start(waitMsg());
|
|
10854
10891
|
const countdown = setInterval(() => waitSpin.message(waitMsg()), 1e3);
|
|
10855
10892
|
countdown.unref?.();
|
|
10856
|
-
const paired = await new Promise((
|
|
10893
|
+
const paired = await new Promise((resolve3, reject) => {
|
|
10857
10894
|
let stopPoll = null;
|
|
10858
10895
|
const sigint = () => {
|
|
10859
10896
|
clearInterval(countdown);
|
|
@@ -10866,7 +10903,7 @@ async function link(args2 = []) {
|
|
|
10866
10903
|
process.removeListener("SIGINT", sigint);
|
|
10867
10904
|
clearInterval(countdown);
|
|
10868
10905
|
waitSpin.stop("Paired");
|
|
10869
|
-
|
|
10906
|
+
resolve3(info);
|
|
10870
10907
|
},
|
|
10871
10908
|
() => {
|
|
10872
10909
|
clearInterval(countdown);
|
|
@@ -10893,36 +10930,125 @@ async function link(args2 = []) {
|
|
|
10893
10930
|
agent: meta.internalId
|
|
10894
10931
|
});
|
|
10895
10932
|
saveCliConfig({ ...loadCliConfig(), preferredAgent: meta.internalId });
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
);
|
|
10909
|
-
process.exit(1);
|
|
10910
|
-
}
|
|
10911
|
-
const refreshed = await meta.extract();
|
|
10912
|
-
const afterMtime = meta.mtime();
|
|
10913
|
-
if (!refreshed) {
|
|
10914
|
-
showError(
|
|
10915
|
-
`${meta.displayName} login finished but no credential was found at ${meta.credentialsHint}. Re-run when ready.`
|
|
10916
|
-
);
|
|
10933
|
+
if (parsed.apiKey) {
|
|
10934
|
+
await uploadAndSucceed(meta, paired, pluginId, {
|
|
10935
|
+
method: "api_key",
|
|
10936
|
+
credential: parsed.apiKey.trim(),
|
|
10937
|
+
source: "manual"
|
|
10938
|
+
});
|
|
10939
|
+
return;
|
|
10940
|
+
}
|
|
10941
|
+
if (parsed.tokenFile) {
|
|
10942
|
+
const credential = fs18.readFileSync(path26.resolve(parsed.tokenFile), "utf8").trim();
|
|
10943
|
+
if (!credential) {
|
|
10944
|
+
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
10917
10945
|
process.exit(1);
|
|
10918
10946
|
}
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
10947
|
+
await uploadAndSucceed(meta, paired, pluginId, {
|
|
10948
|
+
method: "oauth",
|
|
10949
|
+
credential,
|
|
10950
|
+
source: "manual"
|
|
10951
|
+
});
|
|
10952
|
+
return;
|
|
10953
|
+
}
|
|
10954
|
+
const installSpin = dist_exports.spinner();
|
|
10955
|
+
installSpin.start(`Checking that ${meta.binary} is installed...`);
|
|
10956
|
+
const installed = await meta.ensureInstalled();
|
|
10957
|
+
if (!installed) {
|
|
10958
|
+
installSpin.stop("Failed");
|
|
10959
|
+
showError(`Could not install ${meta.displayName}. Install it manually then re-run.`);
|
|
10960
|
+
process.exit(1);
|
|
10961
|
+
}
|
|
10962
|
+
installSpin.stop(`${meta.displayName} is installed`);
|
|
10963
|
+
const existing = await meta.extract();
|
|
10964
|
+
if (existing) {
|
|
10965
|
+
showInfo(`Found existing ${meta.displayName} credentials at ${import_picocolors11.default.bold(existing.source)}.`);
|
|
10966
|
+
await uploadAndSucceed(meta, paired, pluginId, existing);
|
|
10967
|
+
return;
|
|
10968
|
+
}
|
|
10969
|
+
if (parsed.reuseExisting) {
|
|
10970
|
+
showError(
|
|
10971
|
+
`--reuse-existing set, but no local ${meta.displayName} credentials were found at ${meta.credentialsHint}.`
|
|
10972
|
+
);
|
|
10973
|
+
process.exit(1);
|
|
10974
|
+
}
|
|
10975
|
+
showInfo(
|
|
10976
|
+
`No local ${meta.displayName} credentials found. Launching the sign-in \u2014 complete it in your browser, the CLI will detect the new token and finish automatically.`
|
|
10977
|
+
);
|
|
10978
|
+
console.log("");
|
|
10979
|
+
const captured = await captureFreshCredentials(meta);
|
|
10980
|
+
console.log("");
|
|
10981
|
+
await uploadAndSucceed(meta, paired, pluginId, captured);
|
|
10982
|
+
}
|
|
10983
|
+
async function captureFreshCredentials(meta) {
|
|
10984
|
+
const watcher = import_chokidar.default.watch(meta.watchPaths(), {
|
|
10985
|
+
persistent: true,
|
|
10986
|
+
ignoreInitial: false,
|
|
10987
|
+
awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 }
|
|
10988
|
+
});
|
|
10989
|
+
let child = null;
|
|
10990
|
+
let keychainPoll = null;
|
|
10991
|
+
const cleanup = () => {
|
|
10992
|
+
void watcher.close();
|
|
10993
|
+
if (keychainPoll) clearInterval(keychainPoll);
|
|
10994
|
+
if (child && !child.killed) {
|
|
10995
|
+
try {
|
|
10996
|
+
child.kill("SIGTERM");
|
|
10997
|
+
} catch {
|
|
10998
|
+
}
|
|
10924
10999
|
}
|
|
10925
|
-
|
|
11000
|
+
};
|
|
11001
|
+
try {
|
|
11002
|
+
const token = await new Promise((resolve3, reject) => {
|
|
11003
|
+
let settled = false;
|
|
11004
|
+
const tryExtract = async () => {
|
|
11005
|
+
if (settled) return;
|
|
11006
|
+
const t2 = await meta.extract();
|
|
11007
|
+
if (t2 && !settled) {
|
|
11008
|
+
settled = true;
|
|
11009
|
+
resolve3(t2);
|
|
11010
|
+
}
|
|
11011
|
+
};
|
|
11012
|
+
watcher.on("add", () => void tryExtract());
|
|
11013
|
+
watcher.on("change", () => void tryExtract());
|
|
11014
|
+
keychainPoll = setInterval(() => void tryExtract(), 2e3);
|
|
11015
|
+
keychainPoll.unref?.();
|
|
11016
|
+
const sigint = () => {
|
|
11017
|
+
if (settled) return;
|
|
11018
|
+
settled = true;
|
|
11019
|
+
reject(new Error("cancelled"));
|
|
11020
|
+
};
|
|
11021
|
+
process.once("SIGINT", sigint);
|
|
11022
|
+
setTimeout(() => {
|
|
11023
|
+
if (settled) return;
|
|
11024
|
+
settled = true;
|
|
11025
|
+
reject(new Error(`Timed out waiting for ${meta.displayName} sign-in (5 minutes).`));
|
|
11026
|
+
}, 5 * 6e4);
|
|
11027
|
+
child = meta.launchLogin();
|
|
11028
|
+
child.on("exit", () => {
|
|
11029
|
+
void tryExtract().then(() => {
|
|
11030
|
+
if (!settled) {
|
|
11031
|
+
settled = true;
|
|
11032
|
+
reject(
|
|
11033
|
+
new Error(
|
|
11034
|
+
`${meta.binary} exited but no credentials were written at ${meta.credentialsHint}.`
|
|
11035
|
+
)
|
|
11036
|
+
);
|
|
11037
|
+
}
|
|
11038
|
+
});
|
|
11039
|
+
});
|
|
11040
|
+
});
|
|
11041
|
+
cleanup();
|
|
11042
|
+
return token;
|
|
11043
|
+
} catch (err) {
|
|
11044
|
+
cleanup();
|
|
11045
|
+
throw err;
|
|
11046
|
+
}
|
|
11047
|
+
}
|
|
11048
|
+
async function uploadAndSucceed(meta, paired, pluginId, token) {
|
|
11049
|
+
if (!paired.pluginAuthToken) {
|
|
11050
|
+
showError("Missing pluginAuthToken; re-run codeam link.");
|
|
11051
|
+
process.exit(1);
|
|
10926
11052
|
}
|
|
10927
11053
|
const uploadSpin = dist_exports.spinner();
|
|
10928
11054
|
uploadSpin.start("Sealing credential in your vault...");
|
|
@@ -10937,12 +11063,10 @@ async function link(args2 = []) {
|
|
|
10937
11063
|
if (!result.ok) {
|
|
10938
11064
|
uploadSpin.stop("Failed");
|
|
10939
11065
|
if (result.status === 401) {
|
|
10940
|
-
showError(
|
|
10941
|
-
"Pair token rejected by the backend (401). Re-run `codeam link` to start fresh."
|
|
10942
|
-
);
|
|
11066
|
+
showError("Pair token rejected by the backend (401). Re-run `codeam link`.");
|
|
10943
11067
|
} else if (result.status === 404) {
|
|
10944
11068
|
showError(
|
|
10945
|
-
`${meta.displayName} link endpoint not available on this backend (404). The api-v2 deployment may not yet include the
|
|
11069
|
+
`${meta.displayName} link endpoint not available on this backend (404). The api-v2 deployment may not yet include the route.`
|
|
10946
11070
|
);
|
|
10947
11071
|
} else {
|
|
10948
11072
|
showError(`Upload failed: ${result.message}`);
|
|
@@ -10957,28 +11081,11 @@ async function link(args2 = []) {
|
|
|
10957
11081
|
);
|
|
10958
11082
|
console.log("");
|
|
10959
11083
|
}
|
|
10960
|
-
function runAgentLogin(meta) {
|
|
10961
|
-
return new Promise((resolve2) => {
|
|
10962
|
-
const child = (0, import_node_child_process3.spawn)(meta.binary, meta.loginArgs, { stdio: "inherit" });
|
|
10963
|
-
child.on("error", (err) => {
|
|
10964
|
-
if (err.code === "ENOENT") {
|
|
10965
|
-
showError(
|
|
10966
|
-
`${meta.binary} binary not found on PATH. Install ${meta.displayName} first, then re-run \`codeam link ${meta.internalId}\`.`
|
|
10967
|
-
);
|
|
10968
|
-
resolve2(127);
|
|
10969
|
-
return;
|
|
10970
|
-
}
|
|
10971
|
-
showError(`Failed to launch ${meta.binary}: ${err.message}`);
|
|
10972
|
-
resolve2(1);
|
|
10973
|
-
});
|
|
10974
|
-
child.on("exit", (code) => resolve2(code ?? 1));
|
|
10975
|
-
});
|
|
10976
|
-
}
|
|
10977
11084
|
|
|
10978
11085
|
// src/commands/version.ts
|
|
10979
11086
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
10980
11087
|
function version() {
|
|
10981
|
-
const v = true ? "2.16.
|
|
11088
|
+
const v = true ? "2.16.1" : "unknown";
|
|
10982
11089
|
console.log(`${import_picocolors12.default.bold("codeam-cli")} ${import_picocolors12.default.cyan(v)}`);
|
|
10983
11090
|
}
|
|
10984
11091
|
|
|
@@ -11020,9 +11127,9 @@ function help() {
|
|
|
11020
11127
|
}
|
|
11021
11128
|
|
|
11022
11129
|
// src/lib/updateNotifier.ts
|
|
11023
|
-
var
|
|
11130
|
+
var fs19 = __toESM(require("fs"));
|
|
11024
11131
|
var os17 = __toESM(require("os"));
|
|
11025
|
-
var
|
|
11132
|
+
var path27 = __toESM(require("path"));
|
|
11026
11133
|
var https7 = __toESM(require("https"));
|
|
11027
11134
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
11028
11135
|
var PKG_NAME = "codeam-cli";
|
|
@@ -11030,12 +11137,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
11030
11137
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
11031
11138
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
11032
11139
|
function cachePath() {
|
|
11033
|
-
const dir =
|
|
11034
|
-
return
|
|
11140
|
+
const dir = path27.join(os17.homedir(), ".codeam");
|
|
11141
|
+
return path27.join(dir, "update-check.json");
|
|
11035
11142
|
}
|
|
11036
11143
|
function readCache() {
|
|
11037
11144
|
try {
|
|
11038
|
-
const raw =
|
|
11145
|
+
const raw = fs19.readFileSync(cachePath(), "utf8");
|
|
11039
11146
|
const parsed = JSON.parse(raw);
|
|
11040
11147
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
11041
11148
|
return parsed;
|
|
@@ -11046,8 +11153,8 @@ function readCache() {
|
|
|
11046
11153
|
function writeCache(cache) {
|
|
11047
11154
|
try {
|
|
11048
11155
|
const file = cachePath();
|
|
11049
|
-
|
|
11050
|
-
|
|
11156
|
+
fs19.mkdirSync(path27.dirname(file), { recursive: true });
|
|
11157
|
+
fs19.writeFileSync(file, JSON.stringify(cache));
|
|
11051
11158
|
} catch {
|
|
11052
11159
|
}
|
|
11053
11160
|
}
|
|
@@ -11065,14 +11172,14 @@ function compareSemver(a, b) {
|
|
|
11065
11172
|
return 0;
|
|
11066
11173
|
}
|
|
11067
11174
|
function fetchLatest() {
|
|
11068
|
-
return new Promise((
|
|
11175
|
+
return new Promise((resolve3) => {
|
|
11069
11176
|
const req = https7.get(
|
|
11070
11177
|
REGISTRY_URL,
|
|
11071
11178
|
{ headers: { Accept: "application/json" }, timeout: REQUEST_TIMEOUT_MS },
|
|
11072
11179
|
(res) => {
|
|
11073
11180
|
if (res.statusCode !== 200) {
|
|
11074
11181
|
res.resume();
|
|
11075
|
-
|
|
11182
|
+
resolve3(null);
|
|
11076
11183
|
return;
|
|
11077
11184
|
}
|
|
11078
11185
|
let buf = "";
|
|
@@ -11084,21 +11191,21 @@ function fetchLatest() {
|
|
|
11084
11191
|
try {
|
|
11085
11192
|
const json = JSON.parse(buf);
|
|
11086
11193
|
if (typeof json.version === "string") {
|
|
11087
|
-
|
|
11194
|
+
resolve3(json.version);
|
|
11088
11195
|
} else {
|
|
11089
|
-
|
|
11196
|
+
resolve3(null);
|
|
11090
11197
|
}
|
|
11091
11198
|
} catch {
|
|
11092
|
-
|
|
11199
|
+
resolve3(null);
|
|
11093
11200
|
}
|
|
11094
11201
|
});
|
|
11095
11202
|
}
|
|
11096
11203
|
);
|
|
11097
11204
|
req.on("timeout", () => {
|
|
11098
11205
|
req.destroy();
|
|
11099
|
-
|
|
11206
|
+
resolve3(null);
|
|
11100
11207
|
});
|
|
11101
|
-
req.on("error", () =>
|
|
11208
|
+
req.on("error", () => resolve3(null));
|
|
11102
11209
|
});
|
|
11103
11210
|
}
|
|
11104
11211
|
function notifyIfStale(currentVersion, latest) {
|
|
@@ -11118,7 +11225,7 @@ function checkForUpdates() {
|
|
|
11118
11225
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
11119
11226
|
if (process.env.CI) return;
|
|
11120
11227
|
if (!process.stdout.isTTY) return;
|
|
11121
|
-
const current = true ? "2.16.
|
|
11228
|
+
const current = true ? "2.16.1" : null;
|
|
11122
11229
|
if (!current) return;
|
|
11123
11230
|
const cache = readCache();
|
|
11124
11231
|
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.16.
|
|
3
|
+
"version": "2.16.1",
|
|
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",
|