codeam-cli 2.26.11 → 2.26.13
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 +141 -70
- 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.26.12] — 2026-06-04
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Gate preview_ready on DNS resolution via c-ares + 1.1.1.1 (#249)
|
|
12
|
+
|
|
13
|
+
## [2.26.11] — 2026-06-03
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Emit preview_progress SSE events at each bring-up milestone (#244)
|
|
18
|
+
|
|
7
19
|
## [2.26.10] — 2026-06-03
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -472,7 +472,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
472
472
|
// package.json
|
|
473
473
|
var package_default = {
|
|
474
474
|
name: "codeam-cli",
|
|
475
|
-
version: "2.26.
|
|
475
|
+
version: "2.26.13",
|
|
476
476
|
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.",
|
|
477
477
|
type: "commonjs",
|
|
478
478
|
main: "dist/index.js",
|
|
@@ -1115,8 +1115,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1115
1115
|
return decodedFile;
|
|
1116
1116
|
};
|
|
1117
1117
|
}
|
|
1118
|
-
function normalizeWindowsPath(
|
|
1119
|
-
return
|
|
1118
|
+
function normalizeWindowsPath(path43) {
|
|
1119
|
+
return path43.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
1122
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3596,9 +3596,9 @@ async function addSourceContext(frames) {
|
|
|
3596
3596
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3597
3597
|
return frames;
|
|
3598
3598
|
}
|
|
3599
|
-
function getContextLinesFromFile(
|
|
3599
|
+
function getContextLinesFromFile(path43, ranges, output) {
|
|
3600
3600
|
return new Promise((resolve5) => {
|
|
3601
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3601
|
+
const stream = (0, import_node_fs.createReadStream)(path43);
|
|
3602
3602
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3603
3603
|
input: stream
|
|
3604
3604
|
});
|
|
@@ -3613,7 +3613,7 @@ function getContextLinesFromFile(path42, ranges, output) {
|
|
|
3613
3613
|
let rangeStart = range[0];
|
|
3614
3614
|
let rangeEnd = range[1];
|
|
3615
3615
|
function onStreamError() {
|
|
3616
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3616
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path43, 1);
|
|
3617
3617
|
lineReaded.close();
|
|
3618
3618
|
lineReaded.removeAllListeners();
|
|
3619
3619
|
destroyStreamAndResolve();
|
|
@@ -3674,8 +3674,8 @@ function clearLineContext(frame) {
|
|
|
3674
3674
|
delete frame.context_line;
|
|
3675
3675
|
delete frame.post_context;
|
|
3676
3676
|
}
|
|
3677
|
-
function shouldSkipContextLinesForFile(
|
|
3678
|
-
return
|
|
3677
|
+
function shouldSkipContextLinesForFile(path43) {
|
|
3678
|
+
return path43.startsWith("node:") || path43.endsWith(".min.js") || path43.endsWith(".min.cjs") || path43.endsWith(".min.mjs") || path43.startsWith("data:");
|
|
3679
3679
|
}
|
|
3680
3680
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3681
3681
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5829,7 +5829,7 @@ function readAnonId() {
|
|
|
5829
5829
|
}
|
|
5830
5830
|
function superProperties() {
|
|
5831
5831
|
return {
|
|
5832
|
-
cliVersion: true ? "2.26.
|
|
5832
|
+
cliVersion: true ? "2.26.13" : "0.0.0-dev",
|
|
5833
5833
|
nodeVersion: process.version,
|
|
5834
5834
|
platform: process.platform,
|
|
5835
5835
|
arch: process.arch,
|
|
@@ -9901,13 +9901,13 @@ function detectStartupBanner(lines) {
|
|
|
9901
9901
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9902
9902
|
if (metaIdx - artStart < 2) return null;
|
|
9903
9903
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9904
|
-
const
|
|
9904
|
+
const path43 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9905
9905
|
return {
|
|
9906
9906
|
title: "",
|
|
9907
9907
|
subtitle: lines[metaIdx].trim(),
|
|
9908
|
-
path:
|
|
9908
|
+
path: path43,
|
|
9909
9909
|
startIdx: artStart,
|
|
9910
|
-
endIdx: metaIdx + (
|
|
9910
|
+
endIdx: metaIdx + (path43 ? 1 : 0)
|
|
9911
9911
|
};
|
|
9912
9912
|
}
|
|
9913
9913
|
|
|
@@ -11205,11 +11205,11 @@ function parseReview(stdout) {
|
|
|
11205
11205
|
for (const line of lines) {
|
|
11206
11206
|
const m = line.match(HUNK_LINE_RE);
|
|
11207
11207
|
if (!m) continue;
|
|
11208
|
-
const [,
|
|
11209
|
-
if (!
|
|
11208
|
+
const [, path43, lineNo, sevToken, message] = m;
|
|
11209
|
+
if (!path43 || !lineNo || !message) continue;
|
|
11210
11210
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11211
11211
|
hunks.push({
|
|
11212
|
-
path:
|
|
11212
|
+
path: path43.trim(),
|
|
11213
11213
|
line: Number(lineNo),
|
|
11214
11214
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11215
11215
|
message: cleanedMessage
|
|
@@ -13845,7 +13845,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
13845
13845
|
});
|
|
13846
13846
|
}
|
|
13847
13847
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
13848
|
-
const
|
|
13848
|
+
const fs34 = await import("fs/promises");
|
|
13849
13849
|
const out2 = [];
|
|
13850
13850
|
await walk(workingDir, 0);
|
|
13851
13851
|
return out2;
|
|
@@ -13853,7 +13853,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
13853
13853
|
if (depth > maxDepth) return;
|
|
13854
13854
|
let entries = [];
|
|
13855
13855
|
try {
|
|
13856
|
-
const dirents = await
|
|
13856
|
+
const dirents = await fs34.readdir(dir, { withFileTypes: true });
|
|
13857
13857
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
13858
13858
|
} catch {
|
|
13859
13859
|
return;
|
|
@@ -14755,9 +14755,9 @@ function buildKeepAlive(ctx) {
|
|
|
14755
14755
|
}
|
|
14756
14756
|
|
|
14757
14757
|
// src/commands/start/handlers.ts
|
|
14758
|
-
var
|
|
14758
|
+
var fs30 = __toESM(require("fs"));
|
|
14759
14759
|
var os24 = __toESM(require("os"));
|
|
14760
|
-
var
|
|
14760
|
+
var path36 = __toESM(require("path"));
|
|
14761
14761
|
var import_crypto5 = require("crypto");
|
|
14762
14762
|
var import_child_process15 = require("child_process");
|
|
14763
14763
|
|
|
@@ -16057,25 +16057,29 @@ async function linkDryRunPreflight(ctx) {
|
|
|
16057
16057
|
}
|
|
16058
16058
|
|
|
16059
16059
|
// src/services/preview/cloudflared.ts
|
|
16060
|
+
var import_promises = require("dns/promises");
|
|
16060
16061
|
var import_fs = require("fs");
|
|
16061
|
-
var
|
|
16062
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
16062
16063
|
var import_os7 = __toESM(require("os"));
|
|
16063
16064
|
var import_path4 = __toESM(require("path"));
|
|
16064
|
-
var
|
|
16065
|
+
var import_promises3 = require("stream/promises");
|
|
16065
16066
|
var import_which = __toESM(require("which"));
|
|
16066
16067
|
var CACHED_BINARY = import_path4.default.join(import_os7.default.homedir(), ".codeam", "bin", "cloudflared");
|
|
16067
|
-
async function waitForCloudflaredReady(url, timeoutMs =
|
|
16068
|
+
async function waitForCloudflaredReady(url, timeoutMs = 6e4) {
|
|
16069
|
+
const hostname3 = new URL(url).hostname;
|
|
16070
|
+
const resolver = new import_promises.Resolver();
|
|
16071
|
+
resolver.setServers(["1.1.1.1", "1.0.0.1"]);
|
|
16068
16072
|
const start2 = Date.now();
|
|
16069
16073
|
while (Date.now() - start2 < timeoutMs) {
|
|
16070
16074
|
try {
|
|
16071
|
-
const
|
|
16072
|
-
if (
|
|
16075
|
+
const addrs = await resolver.resolve4(hostname3);
|
|
16076
|
+
if (addrs.length > 0) return;
|
|
16073
16077
|
} catch {
|
|
16074
16078
|
}
|
|
16075
16079
|
await new Promise((r) => setTimeout(r, 500));
|
|
16076
16080
|
}
|
|
16077
16081
|
throw new Error(
|
|
16078
|
-
`
|
|
16082
|
+
`DNS for ${hostname3} did not resolve within ${timeoutMs}ms (Cloudflare Quick Tunnel registration may have failed).`
|
|
16079
16083
|
);
|
|
16080
16084
|
}
|
|
16081
16085
|
async function resolveCloudflared(opts = {}) {
|
|
@@ -16084,7 +16088,7 @@ async function resolveCloudflared(opts = {}) {
|
|
|
16084
16088
|
} catch {
|
|
16085
16089
|
}
|
|
16086
16090
|
try {
|
|
16087
|
-
await
|
|
16091
|
+
await import_promises2.default.access(CACHED_BINARY);
|
|
16088
16092
|
return CACHED_BINARY;
|
|
16089
16093
|
} catch {
|
|
16090
16094
|
}
|
|
@@ -16098,14 +16102,14 @@ async function resolveCloudflared(opts = {}) {
|
|
|
16098
16102
|
}
|
|
16099
16103
|
async function downloadCloudflared(target) {
|
|
16100
16104
|
const url = downloadUrlForPlatform();
|
|
16101
|
-
await
|
|
16105
|
+
await import_promises2.default.mkdir(import_path4.default.dirname(target), { recursive: true });
|
|
16102
16106
|
const response = await fetch(url);
|
|
16103
16107
|
if (!response.ok || !response.body) {
|
|
16104
16108
|
throw new Error(
|
|
16105
16109
|
`Failed to download cloudflared from ${url}: HTTP ${response.status}. Install manually from https://github.com/cloudflare/cloudflared/releases.`
|
|
16106
16110
|
);
|
|
16107
16111
|
}
|
|
16108
|
-
await (0,
|
|
16112
|
+
await (0, import_promises3.pipeline)(
|
|
16109
16113
|
response.body,
|
|
16110
16114
|
(0, import_fs.createWriteStream)(target, { mode: 493 })
|
|
16111
16115
|
);
|
|
@@ -16158,7 +16162,7 @@ async function waitForCodespacePortReady(url, timeoutMs = 15e3) {
|
|
|
16158
16162
|
}
|
|
16159
16163
|
|
|
16160
16164
|
// src/services/preview/config-file.ts
|
|
16161
|
-
var
|
|
16165
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
16162
16166
|
var import_path5 = __toESM(require("path"));
|
|
16163
16167
|
var CONFIG_DIR = ".codeam";
|
|
16164
16168
|
var CONFIG_FILE = "preview.json";
|
|
@@ -16175,7 +16179,7 @@ var REQUIRED_FIELDS = [
|
|
|
16175
16179
|
async function readPreviewConfig(cwd) {
|
|
16176
16180
|
let raw;
|
|
16177
16181
|
try {
|
|
16178
|
-
raw = await
|
|
16182
|
+
raw = await import_promises4.default.readFile(configPath(cwd), "utf-8");
|
|
16179
16183
|
} catch {
|
|
16180
16184
|
return null;
|
|
16181
16185
|
}
|
|
@@ -16194,8 +16198,8 @@ async function readPreviewConfig(cwd) {
|
|
|
16194
16198
|
}
|
|
16195
16199
|
async function writePreviewConfig(cwd, detection) {
|
|
16196
16200
|
const filePath = configPath(cwd);
|
|
16197
|
-
await
|
|
16198
|
-
await
|
|
16201
|
+
await import_promises4.default.mkdir(import_path5.default.dirname(filePath), { recursive: true });
|
|
16202
|
+
await import_promises4.default.writeFile(filePath, JSON.stringify(detection, null, 2) + "\n", "utf-8");
|
|
16199
16203
|
}
|
|
16200
16204
|
|
|
16201
16205
|
// src/services/preview/parser.ts
|
|
@@ -16277,6 +16281,24 @@ function parseExpoUrl(stdout) {
|
|
|
16277
16281
|
return match ? match[0] : null;
|
|
16278
16282
|
}
|
|
16279
16283
|
|
|
16284
|
+
// src/services/preview/setup-deps.ts
|
|
16285
|
+
var import_fs2 = __toESM(require("fs"));
|
|
16286
|
+
var import_path6 = __toESM(require("path"));
|
|
16287
|
+
function detectMissingNodeDeps(cwd) {
|
|
16288
|
+
if (!import_fs2.default.existsSync(import_path6.default.join(cwd, "package.json"))) return null;
|
|
16289
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "node_modules"))) return null;
|
|
16290
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
16291
|
+
return { cmd: "pnpm", args: ["install"] };
|
|
16292
|
+
}
|
|
16293
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "yarn.lock"))) {
|
|
16294
|
+
return { cmd: "yarn", args: ["install"] };
|
|
16295
|
+
}
|
|
16296
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lockb")) || import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lock"))) {
|
|
16297
|
+
return { cmd: "bun", args: ["install"] };
|
|
16298
|
+
}
|
|
16299
|
+
return { cmd: "npm", args: ["install"] };
|
|
16300
|
+
}
|
|
16301
|
+
|
|
16280
16302
|
// src/services/preview/index.ts
|
|
16281
16303
|
var activePreviews = /* @__PURE__ */ new Map();
|
|
16282
16304
|
function registerPreview(sessionId, preview) {
|
|
@@ -16322,7 +16344,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
16322
16344
|
function cleanupAttachmentTempFiles() {
|
|
16323
16345
|
for (const p2 of pendingAttachmentFiles) {
|
|
16324
16346
|
try {
|
|
16325
|
-
|
|
16347
|
+
fs30.unlinkSync(p2);
|
|
16326
16348
|
} catch {
|
|
16327
16349
|
}
|
|
16328
16350
|
}
|
|
@@ -16331,8 +16353,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
16331
16353
|
function saveFilesTemp(files) {
|
|
16332
16354
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
16333
16355
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
16334
|
-
const tmpPath =
|
|
16335
|
-
|
|
16356
|
+
const tmpPath = path36.join(os24.tmpdir(), `codeam-${(0, import_crypto5.randomUUID)()}-${safeName}`);
|
|
16357
|
+
fs30.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
16336
16358
|
pendingAttachmentFiles.add(tmpPath);
|
|
16337
16359
|
return tmpPath;
|
|
16338
16360
|
});
|
|
@@ -16352,7 +16374,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
16352
16374
|
setTimeout(() => {
|
|
16353
16375
|
for (const p2 of paths) {
|
|
16354
16376
|
try {
|
|
16355
|
-
|
|
16377
|
+
fs30.unlinkSync(p2);
|
|
16356
16378
|
} catch {
|
|
16357
16379
|
}
|
|
16358
16380
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -16917,6 +16939,32 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16917
16939
|
payload: { framework: detection.framework, port: detection.port }
|
|
16918
16940
|
});
|
|
16919
16941
|
emitProgress("ENV_DETECTED", `${detection.framework}`);
|
|
16942
|
+
const missingDeps = detectMissingNodeDeps(process.cwd());
|
|
16943
|
+
if (missingDeps) {
|
|
16944
|
+
emitProgress(
|
|
16945
|
+
"SETUP_RUN",
|
|
16946
|
+
`${missingDeps.cmd} ${missingDeps.args.join(" ")} (pre-flight \u2014 node_modules missing)`
|
|
16947
|
+
);
|
|
16948
|
+
const exitCode = await runOnce(
|
|
16949
|
+
missingDeps.cmd,
|
|
16950
|
+
missingDeps.args,
|
|
16951
|
+
process.cwd(),
|
|
16952
|
+
detection.env
|
|
16953
|
+
);
|
|
16954
|
+
if (exitCode !== 0) {
|
|
16955
|
+
void postPreviewEvent({
|
|
16956
|
+
sessionId: ctx.sessionId,
|
|
16957
|
+
pluginId: ctx.pluginId,
|
|
16958
|
+
pluginAuthToken,
|
|
16959
|
+
type: "preview_error",
|
|
16960
|
+
payload: {
|
|
16961
|
+
stage: "spawn",
|
|
16962
|
+
message: `Dependency install failed (${missingDeps.cmd} ${missingDeps.args.join(" ")}, exit ${exitCode}). Run it manually in this project and try again.`
|
|
16963
|
+
}
|
|
16964
|
+
});
|
|
16965
|
+
return;
|
|
16966
|
+
}
|
|
16967
|
+
}
|
|
16920
16968
|
for (const setup of detection.setup_commands ?? []) {
|
|
16921
16969
|
emitProgress("SETUP_RUN", `${setup.cmd} ${setup.args.join(" ")}`);
|
|
16922
16970
|
const exitCode = await runOnce(setup.cmd, setup.args, process.cwd(), detection.env);
|
|
@@ -17102,7 +17150,30 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
17102
17150
|
});
|
|
17103
17151
|
return;
|
|
17104
17152
|
}
|
|
17105
|
-
|
|
17153
|
+
try {
|
|
17154
|
+
await waitForCloudflaredReady(parsedUrl, 6e4);
|
|
17155
|
+
log.info("preview", `cloudflared probe: ${parsedUrl} reachable from CLI host`);
|
|
17156
|
+
} catch (e) {
|
|
17157
|
+
try {
|
|
17158
|
+
tunnel.kill("SIGTERM");
|
|
17159
|
+
} catch {
|
|
17160
|
+
}
|
|
17161
|
+
try {
|
|
17162
|
+
devServer.kill("SIGTERM");
|
|
17163
|
+
} catch {
|
|
17164
|
+
}
|
|
17165
|
+
void postPreviewEvent({
|
|
17166
|
+
sessionId: ctx.sessionId,
|
|
17167
|
+
pluginId: ctx.pluginId,
|
|
17168
|
+
pluginAuthToken,
|
|
17169
|
+
type: "preview_error",
|
|
17170
|
+
payload: {
|
|
17171
|
+
stage: "tunnel",
|
|
17172
|
+
message: `Tunnel ${parsedUrl} did not become reachable within 60s (${e.message}). Cloudflare Quick Tunnels occasionally fail to register \u2014 retry usually succeeds.`
|
|
17173
|
+
}
|
|
17174
|
+
});
|
|
17175
|
+
return;
|
|
17176
|
+
}
|
|
17106
17177
|
url = parsedUrl;
|
|
17107
17178
|
}
|
|
17108
17179
|
emitProgress("TUNNEL_READY", url);
|
|
@@ -17609,7 +17680,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
17609
17680
|
}
|
|
17610
17681
|
|
|
17611
17682
|
// src/commands/pair-auto.ts
|
|
17612
|
-
var
|
|
17683
|
+
var fs31 = __toESM(require("fs"));
|
|
17613
17684
|
var os25 = __toESM(require("os"));
|
|
17614
17685
|
var import_crypto7 = require("crypto");
|
|
17615
17686
|
|
|
@@ -17778,12 +17849,12 @@ function readTokenFromArgs(args2) {
|
|
|
17778
17849
|
}
|
|
17779
17850
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
17780
17851
|
if (fileFlag) {
|
|
17781
|
-
const
|
|
17852
|
+
const path43 = fileFlag.slice("--token-file=".length);
|
|
17782
17853
|
try {
|
|
17783
|
-
const content =
|
|
17784
|
-
if (content.length === 0) fail(`--token-file ${
|
|
17854
|
+
const content = fs31.readFileSync(path43, "utf8").trim();
|
|
17855
|
+
if (content.length === 0) fail(`--token-file ${path43} is empty`);
|
|
17785
17856
|
try {
|
|
17786
|
-
|
|
17857
|
+
fs31.unlinkSync(path43);
|
|
17787
17858
|
} catch {
|
|
17788
17859
|
}
|
|
17789
17860
|
return content;
|
|
@@ -18049,7 +18120,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
18049
18120
|
var import_child_process16 = require("child_process");
|
|
18050
18121
|
var import_util4 = require("util");
|
|
18051
18122
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
18052
|
-
var
|
|
18123
|
+
var path37 = __toESM(require("path"));
|
|
18053
18124
|
var execFileP5 = (0, import_util4.promisify)(import_child_process16.execFile);
|
|
18054
18125
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
18055
18126
|
function resetStdinForChild() {
|
|
@@ -18538,7 +18609,7 @@ var GitHubCodespacesProvider = class {
|
|
|
18538
18609
|
});
|
|
18539
18610
|
}
|
|
18540
18611
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
18541
|
-
const remoteDir =
|
|
18612
|
+
const remoteDir = path37.posix.dirname(remotePath);
|
|
18542
18613
|
const parts = [
|
|
18543
18614
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
18544
18615
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -18608,7 +18679,7 @@ function shellQuote(s) {
|
|
|
18608
18679
|
// src/services/providers/gitpod.ts
|
|
18609
18680
|
var import_child_process17 = require("child_process");
|
|
18610
18681
|
var import_util5 = require("util");
|
|
18611
|
-
var
|
|
18682
|
+
var path38 = __toESM(require("path"));
|
|
18612
18683
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
18613
18684
|
var execFileP6 = (0, import_util5.promisify)(import_child_process17.execFile);
|
|
18614
18685
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -18848,7 +18919,7 @@ var GitpodProvider = class {
|
|
|
18848
18919
|
});
|
|
18849
18920
|
}
|
|
18850
18921
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
18851
|
-
const remoteDir =
|
|
18922
|
+
const remoteDir = path38.posix.dirname(remotePath);
|
|
18852
18923
|
const parts = [
|
|
18853
18924
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
18854
18925
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -18884,7 +18955,7 @@ function shellQuote2(s) {
|
|
|
18884
18955
|
// src/services/providers/gitlab-workspaces.ts
|
|
18885
18956
|
var import_child_process18 = require("child_process");
|
|
18886
18957
|
var import_util6 = require("util");
|
|
18887
|
-
var
|
|
18958
|
+
var path39 = __toESM(require("path"));
|
|
18888
18959
|
var execFileP7 = (0, import_util6.promisify)(import_child_process18.execFile);
|
|
18889
18960
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
18890
18961
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -19144,7 +19215,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
19144
19215
|
}
|
|
19145
19216
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
19146
19217
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
19147
|
-
const remoteDir =
|
|
19218
|
+
const remoteDir = path39.posix.dirname(remotePath);
|
|
19148
19219
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
19149
19220
|
if (options.mode != null) {
|
|
19150
19221
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -19212,7 +19283,7 @@ function shellQuote3(s) {
|
|
|
19212
19283
|
// src/services/providers/railway.ts
|
|
19213
19284
|
var import_child_process19 = require("child_process");
|
|
19214
19285
|
var import_util7 = require("util");
|
|
19215
|
-
var
|
|
19286
|
+
var path40 = __toESM(require("path"));
|
|
19216
19287
|
var execFileP8 = (0, import_util7.promisify)(import_child_process19.execFile);
|
|
19217
19288
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
19218
19289
|
function resetStdinForChild4() {
|
|
@@ -19448,7 +19519,7 @@ var RailwayProvider = class {
|
|
|
19448
19519
|
if (!projectId || !serviceId) {
|
|
19449
19520
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
19450
19521
|
}
|
|
19451
|
-
const remoteDir =
|
|
19522
|
+
const remoteDir = path40.posix.dirname(remotePath);
|
|
19452
19523
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
19453
19524
|
if (options.mode != null) {
|
|
19454
19525
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -19991,8 +20062,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
19991
20062
|
var import_node_dns = require("dns");
|
|
19992
20063
|
var import_node_util4 = require("util");
|
|
19993
20064
|
var import_node_crypto6 = require("crypto");
|
|
19994
|
-
var
|
|
19995
|
-
var
|
|
20065
|
+
var fs32 = __toESM(require("fs"));
|
|
20066
|
+
var path41 = __toESM(require("path"));
|
|
19996
20067
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
19997
20068
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
19998
20069
|
async function checkDns(apiBase) {
|
|
@@ -20048,13 +20119,13 @@ async function checkHealth(apiBase) {
|
|
|
20048
20119
|
}
|
|
20049
20120
|
}
|
|
20050
20121
|
function checkConfigDir() {
|
|
20051
|
-
const dir =
|
|
20122
|
+
const dir = path41.join(require("os").homedir(), ".codeam");
|
|
20052
20123
|
try {
|
|
20053
|
-
|
|
20054
|
-
const probe =
|
|
20055
|
-
|
|
20056
|
-
const read =
|
|
20057
|
-
|
|
20124
|
+
fs32.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
20125
|
+
const probe = path41.join(dir, ".doctor-probe");
|
|
20126
|
+
fs32.writeFileSync(probe, "ok", { mode: 384 });
|
|
20127
|
+
const read = fs32.readFileSync(probe, "utf8");
|
|
20128
|
+
fs32.unlinkSync(probe);
|
|
20058
20129
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
20059
20130
|
return {
|
|
20060
20131
|
id: "config-dir",
|
|
@@ -20118,7 +20189,7 @@ function checkNodePty() {
|
|
|
20118
20189
|
detail: "not required on this platform"
|
|
20119
20190
|
};
|
|
20120
20191
|
}
|
|
20121
|
-
const vendoredPath =
|
|
20192
|
+
const vendoredPath = path41.join(__dirname, "vendor", "node-pty");
|
|
20122
20193
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
20123
20194
|
try {
|
|
20124
20195
|
require(target);
|
|
@@ -20160,7 +20231,7 @@ function checkChokidar() {
|
|
|
20160
20231
|
}
|
|
20161
20232
|
async function doctor(args2 = []) {
|
|
20162
20233
|
const json = args2.includes("--json");
|
|
20163
|
-
const cliVersion = true ? "2.26.
|
|
20234
|
+
const cliVersion = true ? "2.26.13" : "0.0.0-dev";
|
|
20164
20235
|
const apiBase = resolveApiBaseUrl();
|
|
20165
20236
|
const diagnosticId = (0, import_node_crypto6.randomUUID)();
|
|
20166
20237
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -20359,7 +20430,7 @@ async function completion(args2) {
|
|
|
20359
20430
|
// src/commands/version.ts
|
|
20360
20431
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
20361
20432
|
function version2() {
|
|
20362
|
-
const v = true ? "2.26.
|
|
20433
|
+
const v = true ? "2.26.13" : "unknown";
|
|
20363
20434
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
20364
20435
|
}
|
|
20365
20436
|
|
|
@@ -20487,9 +20558,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
20487
20558
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
20488
20559
|
|
|
20489
20560
|
// src/lib/updateNotifier.ts
|
|
20490
|
-
var
|
|
20561
|
+
var fs33 = __toESM(require("fs"));
|
|
20491
20562
|
var os26 = __toESM(require("os"));
|
|
20492
|
-
var
|
|
20563
|
+
var path42 = __toESM(require("path"));
|
|
20493
20564
|
var https7 = __toESM(require("https"));
|
|
20494
20565
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
20495
20566
|
var PKG_NAME = "codeam-cli";
|
|
@@ -20497,12 +20568,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
20497
20568
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
20498
20569
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
20499
20570
|
function cachePath() {
|
|
20500
|
-
const dir =
|
|
20501
|
-
return
|
|
20571
|
+
const dir = path42.join(os26.homedir(), ".codeam");
|
|
20572
|
+
return path42.join(dir, "update-check.json");
|
|
20502
20573
|
}
|
|
20503
20574
|
function readCache() {
|
|
20504
20575
|
try {
|
|
20505
|
-
const raw =
|
|
20576
|
+
const raw = fs33.readFileSync(cachePath(), "utf8");
|
|
20506
20577
|
const parsed = JSON.parse(raw);
|
|
20507
20578
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
20508
20579
|
return parsed;
|
|
@@ -20513,10 +20584,10 @@ function readCache() {
|
|
|
20513
20584
|
function writeCache(cache) {
|
|
20514
20585
|
try {
|
|
20515
20586
|
const file = cachePath();
|
|
20516
|
-
|
|
20587
|
+
fs33.mkdirSync(path42.dirname(file), { recursive: true });
|
|
20517
20588
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
20518
|
-
|
|
20519
|
-
|
|
20589
|
+
fs33.writeFileSync(tmp, JSON.stringify(cache));
|
|
20590
|
+
fs33.renameSync(tmp, file);
|
|
20520
20591
|
} catch {
|
|
20521
20592
|
}
|
|
20522
20593
|
}
|
|
@@ -20587,7 +20658,7 @@ function checkForUpdates() {
|
|
|
20587
20658
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
20588
20659
|
if (process.env.CI) return;
|
|
20589
20660
|
if (!process.stdout.isTTY) return;
|
|
20590
|
-
const current = true ? "2.26.
|
|
20661
|
+
const current = true ? "2.26.13" : null;
|
|
20591
20662
|
if (!current) return;
|
|
20592
20663
|
const cache = readCache();
|
|
20593
20664
|
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.26.
|
|
3
|
+
"version": "2.26.13",
|
|
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",
|