codeam-cli 2.39.0 → 2.39.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 +10 -0
- package/dist/index.js +154 -356
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.39.0] — 2026-06-12
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Auto-provision project dependencies in codespaces + preview_failed
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **cli:** Emit preview_error (not a new type) with stderr tail on dev-server failure
|
|
16
|
+
|
|
7
17
|
## [2.38.0] — 2026-06-12
|
|
8
18
|
|
|
9
19
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.39.
|
|
501
|
+
version: "2.39.1",
|
|
502
502
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -1186,8 +1186,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1186
1186
|
return decodedFile;
|
|
1187
1187
|
};
|
|
1188
1188
|
}
|
|
1189
|
-
function normalizeWindowsPath(
|
|
1190
|
-
return
|
|
1189
|
+
function normalizeWindowsPath(path52) {
|
|
1190
|
+
return path52.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1191
1191
|
}
|
|
1192
1192
|
|
|
1193
1193
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3667,9 +3667,9 @@ async function addSourceContext(frames) {
|
|
|
3667
3667
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3668
3668
|
return frames;
|
|
3669
3669
|
}
|
|
3670
|
-
function getContextLinesFromFile(
|
|
3670
|
+
function getContextLinesFromFile(path52, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path52);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path53, ranges, output) {
|
|
|
3684
3684
|
let rangeStart = range[0];
|
|
3685
3685
|
let rangeEnd = range[1];
|
|
3686
3686
|
function onStreamError() {
|
|
3687
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3687
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path52, 1);
|
|
3688
3688
|
lineReaded.close();
|
|
3689
3689
|
lineReaded.removeAllListeners();
|
|
3690
3690
|
destroyStreamAndResolve();
|
|
@@ -3745,8 +3745,8 @@ function clearLineContext(frame) {
|
|
|
3745
3745
|
delete frame.context_line;
|
|
3746
3746
|
delete frame.post_context;
|
|
3747
3747
|
}
|
|
3748
|
-
function shouldSkipContextLinesForFile(
|
|
3749
|
-
return
|
|
3748
|
+
function shouldSkipContextLinesForFile(path52) {
|
|
3749
|
+
return path52.startsWith("node:") || path52.endsWith(".min.js") || path52.endsWith(".min.cjs") || path52.endsWith(".min.mjs") || path52.startsWith("data:");
|
|
3750
3750
|
}
|
|
3751
3751
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3752
3752
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5900,7 +5900,7 @@ function readAnonId() {
|
|
|
5900
5900
|
}
|
|
5901
5901
|
function superProperties() {
|
|
5902
5902
|
return {
|
|
5903
|
-
cliVersion: true ? "2.39.
|
|
5903
|
+
cliVersion: true ? "2.39.1" : "0.0.0-dev",
|
|
5904
5904
|
nodeVersion: process.version,
|
|
5905
5905
|
platform: process.platform,
|
|
5906
5906
|
arch: process.arch,
|
|
@@ -9978,13 +9978,13 @@ function detectStartupBanner(lines) {
|
|
|
9978
9978
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9979
9979
|
if (metaIdx - artStart < 2) return null;
|
|
9980
9980
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9981
|
-
const
|
|
9981
|
+
const path52 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path52,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path52 ? 1 : 0)
|
|
9988
9988
|
};
|
|
9989
9989
|
}
|
|
9990
9990
|
|
|
@@ -11342,11 +11342,11 @@ function parseReview(stdout) {
|
|
|
11342
11342
|
for (const line of lines) {
|
|
11343
11343
|
const m = line.match(HUNK_LINE_RE);
|
|
11344
11344
|
if (!m) continue;
|
|
11345
|
-
const [,
|
|
11346
|
-
if (!
|
|
11345
|
+
const [, path52, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path52 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path52.trim(),
|
|
11350
11350
|
line: Number(lineNo),
|
|
11351
11351
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11352
|
message: cleanedMessage
|
|
@@ -15911,9 +15911,9 @@ function extractSelectPrompt(text) {
|
|
|
15911
15911
|
}
|
|
15912
15912
|
|
|
15913
15913
|
// src/commands/start/handlers.ts
|
|
15914
|
-
var
|
|
15914
|
+
var fs34 = __toESM(require("fs"));
|
|
15915
15915
|
var os27 = __toESM(require("os"));
|
|
15916
|
-
var
|
|
15916
|
+
var path41 = __toESM(require("path"));
|
|
15917
15917
|
var import_crypto3 = require("crypto");
|
|
15918
15918
|
var import_child_process18 = require("child_process");
|
|
15919
15919
|
|
|
@@ -17364,10 +17364,6 @@ async function waitForPortListening(port, opts) {
|
|
|
17364
17364
|
}
|
|
17365
17365
|
}
|
|
17366
17366
|
|
|
17367
|
-
// src/services/preview/provision-deps.ts
|
|
17368
|
-
var import_fs2 = require("fs");
|
|
17369
|
-
var import_path6 = __toESM(require("path"));
|
|
17370
|
-
|
|
17371
17367
|
// src/services/preview/run-setup.ts
|
|
17372
17368
|
var import_child_process12 = require("child_process");
|
|
17373
17369
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
@@ -17412,215 +17408,19 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
|
17412
17408
|
});
|
|
17413
17409
|
}
|
|
17414
17410
|
|
|
17415
|
-
// src/services/preview/provision-deps.ts
|
|
17416
|
-
var COMPOSE_FILES = [
|
|
17417
|
-
"docker-compose.yml",
|
|
17418
|
-
"docker-compose.yaml",
|
|
17419
|
-
"compose.yaml",
|
|
17420
|
-
"compose.yml"
|
|
17421
|
-
];
|
|
17422
|
-
var ENV_SAMPLES = [".env.example", ".env.sample", ".env.local.example", ".env.template"];
|
|
17423
|
-
var POSTGRES = {
|
|
17424
|
-
name: "postgres",
|
|
17425
|
-
image: "postgres:16",
|
|
17426
|
-
port: 5432,
|
|
17427
|
-
environment: { POSTGRES_USER: "postgres", POSTGRES_PASSWORD: "postgres", POSTGRES_DB: "app" },
|
|
17428
|
-
healthTest: ["CMD-SHELL", "pg_isready -U postgres"],
|
|
17429
|
-
envLines: [
|
|
17430
|
-
"DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app",
|
|
17431
|
-
"DB_HOST=localhost",
|
|
17432
|
-
"DB_PORT=5432",
|
|
17433
|
-
"DB_USERNAME=postgres",
|
|
17434
|
-
"DB_PASSWORD=postgres",
|
|
17435
|
-
"DB_NAME=app"
|
|
17436
|
-
]
|
|
17437
|
-
};
|
|
17438
|
-
var MYSQL = {
|
|
17439
|
-
name: "mysql",
|
|
17440
|
-
image: "mysql:8",
|
|
17441
|
-
port: 3306,
|
|
17442
|
-
environment: { MYSQL_ROOT_PASSWORD: "mysql", MYSQL_DATABASE: "app" },
|
|
17443
|
-
healthTest: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pmysql"],
|
|
17444
|
-
envLines: ["DATABASE_URL=mysql://root:mysql@localhost:3306/app"]
|
|
17445
|
-
};
|
|
17446
|
-
var MONGO = {
|
|
17447
|
-
name: "mongo",
|
|
17448
|
-
image: "mongo:7",
|
|
17449
|
-
port: 27017,
|
|
17450
|
-
environment: {},
|
|
17451
|
-
healthTest: ["CMD", "mongosh", "--eval", 'db.adminCommand("ping")'],
|
|
17452
|
-
envLines: ["MONGODB_URI=mongodb://localhost:27017/app", "MONGO_URL=mongodb://localhost:27017/app"]
|
|
17453
|
-
};
|
|
17454
|
-
var REDIS = {
|
|
17455
|
-
name: "redis",
|
|
17456
|
-
image: "redis:7",
|
|
17457
|
-
port: 6379,
|
|
17458
|
-
environment: {},
|
|
17459
|
-
healthTest: ["CMD", "redis-cli", "ping"],
|
|
17460
|
-
envLines: ["REDIS_URL=redis://localhost:6379", "REDIS_HOST=localhost", "REDIS_PORT=6379"]
|
|
17461
|
-
};
|
|
17462
|
-
function detectServicesFromDeps(pkg) {
|
|
17463
|
-
const deps = /* @__PURE__ */ new Set([
|
|
17464
|
-
...Object.keys(pkg.dependencies ?? {}),
|
|
17465
|
-
...Object.keys(pkg.devDependencies ?? {})
|
|
17466
|
-
]);
|
|
17467
|
-
const has = (...names) => names.some((n) => deps.has(n));
|
|
17468
|
-
const out2 = [];
|
|
17469
|
-
if (has("pg", "typeorm", "@nestjs/typeorm", "sequelize", "postgres", "postgres.js", "pg-promise"))
|
|
17470
|
-
out2.push(POSTGRES);
|
|
17471
|
-
if (has("mysql", "mysql2")) out2.push(MYSQL);
|
|
17472
|
-
if (has("mongoose", "mongodb")) out2.push(MONGO);
|
|
17473
|
-
if (has("ioredis", "redis", "cache-manager-ioredis-yet", "cache-manager-redis-store"))
|
|
17474
|
-
out2.push(REDIS);
|
|
17475
|
-
return out2;
|
|
17476
|
-
}
|
|
17477
|
-
function renderComposeYaml(services) {
|
|
17478
|
-
const blocks = services.map((s) => {
|
|
17479
|
-
const env = Object.entries(s.environment);
|
|
17480
|
-
const envYaml = env.length ? " environment:\n" + env.map(([k2, v]) => ` ${k2}: "${v}"`).join("\n") + "\n" : "";
|
|
17481
|
-
const health = JSON.stringify(s.healthTest);
|
|
17482
|
-
return ` ${s.name}:
|
|
17483
|
-
image: ${s.image}
|
|
17484
|
-
restart: unless-stopped
|
|
17485
|
-
ports:
|
|
17486
|
-
- "${s.port}:${s.port}"
|
|
17487
|
-
` + envYaml + ` healthcheck:
|
|
17488
|
-
test: ${health}
|
|
17489
|
-
interval: 5s
|
|
17490
|
-
timeout: 3s
|
|
17491
|
-
retries: 12
|
|
17492
|
-
`;
|
|
17493
|
-
});
|
|
17494
|
-
return `# Generated by codeam \u2014 auto-provisioned project dependencies.
|
|
17495
|
-
# Do not edit; regenerated on each provision. See .codeam/provision/.
|
|
17496
|
-
services:
|
|
17497
|
-
${blocks.join("")}`;
|
|
17498
|
-
}
|
|
17499
|
-
function pickMigrationScript(scripts) {
|
|
17500
|
-
const preferred = [
|
|
17501
|
-
"migration:run",
|
|
17502
|
-
"db:migrate",
|
|
17503
|
-
"migrate:deploy",
|
|
17504
|
-
"migrate:latest",
|
|
17505
|
-
"migrate:up",
|
|
17506
|
-
"prisma:migrate",
|
|
17507
|
-
"migrate"
|
|
17508
|
-
];
|
|
17509
|
-
for (const k2 of preferred) if (scripts[k2]) return k2;
|
|
17510
|
-
for (const k2 of Object.keys(scripts)) {
|
|
17511
|
-
if (/migrat/i.test(k2) && /(run|deploy|latest|up)/i.test(k2) && !/(generate|create|revert|rollback|undo|down|reset|drop)/i.test(k2)) {
|
|
17512
|
-
return k2;
|
|
17513
|
-
}
|
|
17514
|
-
}
|
|
17515
|
-
return null;
|
|
17516
|
-
}
|
|
17517
|
-
async function exists(p2) {
|
|
17518
|
-
try {
|
|
17519
|
-
await import_fs2.promises.access(p2);
|
|
17520
|
-
return true;
|
|
17521
|
-
} catch {
|
|
17522
|
-
return false;
|
|
17523
|
-
}
|
|
17524
|
-
}
|
|
17525
|
-
async function firstExisting(cwd, names) {
|
|
17526
|
-
for (const n of names) if (await exists(import_path6.default.join(cwd, n))) return n;
|
|
17527
|
-
return null;
|
|
17528
|
-
}
|
|
17529
|
-
async function ensureEnvFile(cwd, generated) {
|
|
17530
|
-
if (await exists(import_path6.default.join(cwd, ".env"))) {
|
|
17531
|
-
log.info("provision", ".env already present \u2014 leaving it untouched");
|
|
17532
|
-
return;
|
|
17533
|
-
}
|
|
17534
|
-
const sample = await firstExisting(cwd, ENV_SAMPLES);
|
|
17535
|
-
if (sample) {
|
|
17536
|
-
const body = await import_fs2.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
|
|
17537
|
-
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17538
|
-
log.info("provision", `wrote .env from ${sample}`);
|
|
17539
|
-
return;
|
|
17540
|
-
}
|
|
17541
|
-
if (generated.length > 0) {
|
|
17542
|
-
const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
|
|
17543
|
-
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17544
|
-
log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
|
|
17545
|
-
}
|
|
17546
|
-
}
|
|
17547
|
-
async function readPackageJson(cwd) {
|
|
17548
|
-
try {
|
|
17549
|
-
return JSON.parse(await import_fs2.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
|
|
17550
|
-
} catch {
|
|
17551
|
-
return null;
|
|
17552
|
-
}
|
|
17553
|
-
}
|
|
17554
|
-
async function runMigrationsIfPresent(cwd, scripts) {
|
|
17555
|
-
const script = pickMigrationScript(scripts);
|
|
17556
|
-
if (!script) return;
|
|
17557
|
-
log.info("provision", `running migrations: npm run ${script}`);
|
|
17558
|
-
const res = await runSetupCommand("npm", ["run", script], cwd, void 0, { timeoutMs: 12e4 });
|
|
17559
|
-
if (res.status !== "ok") log.warn("provision", `migration script "${script}" \u2192 ${res.status} (non-fatal)`);
|
|
17560
|
-
}
|
|
17561
|
-
async function provisionProjectDependencies(cwd) {
|
|
17562
|
-
try {
|
|
17563
|
-
const docker = await runSetupCommand("docker", ["info"], cwd, void 0, { timeoutMs: 15e3 });
|
|
17564
|
-
if (docker.status !== "ok") {
|
|
17565
|
-
log.info("provision", "docker not usable \u2014 skipping dependency provisioning");
|
|
17566
|
-
return;
|
|
17567
|
-
}
|
|
17568
|
-
const pkg = await readPackageJson(cwd);
|
|
17569
|
-
let started = false;
|
|
17570
|
-
let generated = [];
|
|
17571
|
-
const composeFile = await firstExisting(cwd, COMPOSE_FILES);
|
|
17572
|
-
if (composeFile) {
|
|
17573
|
-
log.info("provision", `compose found (${composeFile}) \u2014 docker compose up -d --wait`);
|
|
17574
|
-
const up = await runSetupCommand("docker", ["compose", "up", "-d", "--wait"], cwd, void 0, {
|
|
17575
|
-
timeoutMs: 18e4
|
|
17576
|
-
});
|
|
17577
|
-
started = up.status === "ok";
|
|
17578
|
-
if (!started) log.warn("provision", `compose up \u2192 ${up.status} (non-fatal)`);
|
|
17579
|
-
} else if (pkg) {
|
|
17580
|
-
generated = detectServicesFromDeps(pkg);
|
|
17581
|
-
if (generated.length > 0) {
|
|
17582
|
-
const dir = import_path6.default.join(cwd, ".codeam", "provision");
|
|
17583
|
-
await import_fs2.promises.mkdir(dir, { recursive: true });
|
|
17584
|
-
const file = import_path6.default.join(dir, "compose.generated.yaml");
|
|
17585
|
-
await import_fs2.promises.writeFile(file, renderComposeYaml(generated));
|
|
17586
|
-
log.info(
|
|
17587
|
-
"provision",
|
|
17588
|
-
`no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
|
|
17589
|
-
);
|
|
17590
|
-
const up = await runSetupCommand(
|
|
17591
|
-
"docker",
|
|
17592
|
-
["compose", "-f", file, "up", "-d", "--wait"],
|
|
17593
|
-
cwd,
|
|
17594
|
-
void 0,
|
|
17595
|
-
{ timeoutMs: 18e4 }
|
|
17596
|
-
);
|
|
17597
|
-
started = up.status === "ok";
|
|
17598
|
-
if (!started) log.warn("provision", `generated compose up \u2192 ${up.status} (non-fatal)`);
|
|
17599
|
-
} else {
|
|
17600
|
-
log.info("provision", "no compose + no known service deps \u2014 nothing to provision");
|
|
17601
|
-
}
|
|
17602
|
-
}
|
|
17603
|
-
await ensureEnvFile(cwd, generated);
|
|
17604
|
-
if (started && pkg?.scripts) await runMigrationsIfPresent(cwd, pkg.scripts);
|
|
17605
|
-
log.info("provision", "project dependency provisioning complete");
|
|
17606
|
-
} catch (err) {
|
|
17607
|
-
log.warn("provision", "provisionProjectDependencies failed (non-fatal)", err);
|
|
17608
|
-
}
|
|
17609
|
-
}
|
|
17610
|
-
|
|
17611
17411
|
// src/services/preview/setup-deps.ts
|
|
17612
|
-
var
|
|
17613
|
-
var
|
|
17412
|
+
var import_fs2 = __toESM(require("fs"));
|
|
17413
|
+
var import_path6 = __toESM(require("path"));
|
|
17614
17414
|
function detectMissingNodeDeps(cwd) {
|
|
17615
|
-
if (!
|
|
17616
|
-
if (
|
|
17617
|
-
if (
|
|
17415
|
+
if (!import_fs2.default.existsSync(import_path6.default.join(cwd, "package.json"))) return null;
|
|
17416
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "node_modules"))) return null;
|
|
17417
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
17618
17418
|
return { cmd: "pnpm", args: ["install"] };
|
|
17619
17419
|
}
|
|
17620
|
-
if (
|
|
17420
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "yarn.lock"))) {
|
|
17621
17421
|
return { cmd: "yarn", args: ["install"] };
|
|
17622
17422
|
}
|
|
17623
|
-
if (
|
|
17423
|
+
if (import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lockb")) || import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lock"))) {
|
|
17624
17424
|
return { cmd: "bun", args: ["install"] };
|
|
17625
17425
|
}
|
|
17626
17426
|
return { cmd: "npm", args: ["install"] };
|
|
@@ -17675,8 +17475,8 @@ function activePreviewSessionIds() {
|
|
|
17675
17475
|
|
|
17676
17476
|
// src/beads/bd-adapter.ts
|
|
17677
17477
|
var import_child_process13 = require("child_process");
|
|
17678
|
-
var
|
|
17679
|
-
var
|
|
17478
|
+
var fs30 = __toESM(require("fs"));
|
|
17479
|
+
var path36 = __toESM(require("path"));
|
|
17680
17480
|
var BD_PACKAGE = "@beads/bd";
|
|
17681
17481
|
function resolveBundledBdBinary() {
|
|
17682
17482
|
return _resolveSeam.resolveBundled();
|
|
@@ -17688,11 +17488,11 @@ function _defaultResolveBundled() {
|
|
|
17688
17488
|
} catch {
|
|
17689
17489
|
return null;
|
|
17690
17490
|
}
|
|
17691
|
-
const binDir =
|
|
17491
|
+
const binDir = path36.join(path36.dirname(pkgJsonPath), "bin");
|
|
17692
17492
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17693
|
-
const binaryPath =
|
|
17493
|
+
const binaryPath = path36.join(binDir, binaryName);
|
|
17694
17494
|
try {
|
|
17695
|
-
|
|
17495
|
+
fs30.accessSync(binaryPath, fs30.constants.F_OK);
|
|
17696
17496
|
return binaryPath;
|
|
17697
17497
|
} catch {
|
|
17698
17498
|
return null;
|
|
@@ -17702,13 +17502,13 @@ function resolveBdOnPath() {
|
|
|
17702
17502
|
return _resolveSeam.resolveOnPath();
|
|
17703
17503
|
}
|
|
17704
17504
|
function _defaultResolveOnPath() {
|
|
17705
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17505
|
+
const dirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
|
|
17706
17506
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17707
17507
|
for (const dir of dirs) {
|
|
17708
17508
|
for (const candidate of candidates) {
|
|
17709
|
-
const full =
|
|
17509
|
+
const full = path36.join(dir, candidate);
|
|
17710
17510
|
try {
|
|
17711
|
-
|
|
17511
|
+
fs30.accessSync(full, fs30.constants.F_OK);
|
|
17712
17512
|
return full;
|
|
17713
17513
|
} catch {
|
|
17714
17514
|
}
|
|
@@ -17874,9 +17674,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17874
17674
|
|
|
17875
17675
|
// src/beads/provisioner.ts
|
|
17876
17676
|
var import_child_process17 = require("child_process");
|
|
17877
|
-
var
|
|
17677
|
+
var fs33 = __toESM(require("fs"));
|
|
17878
17678
|
var os26 = __toESM(require("os"));
|
|
17879
|
-
var
|
|
17679
|
+
var path39 = __toESM(require("path"));
|
|
17880
17680
|
|
|
17881
17681
|
// src/beads/install-bd.ts
|
|
17882
17682
|
var import_child_process14 = require("child_process");
|
|
@@ -17941,9 +17741,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17941
17741
|
|
|
17942
17742
|
// src/beads/install-dolt.ts
|
|
17943
17743
|
var import_child_process15 = require("child_process");
|
|
17944
|
-
var
|
|
17744
|
+
var fs31 = __toESM(require("fs"));
|
|
17945
17745
|
var os25 = __toESM(require("os"));
|
|
17946
|
-
var
|
|
17746
|
+
var path37 = __toESM(require("path"));
|
|
17947
17747
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17948
17748
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17949
17749
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -18039,7 +17839,7 @@ var _doltPathSeam = {
|
|
|
18039
17839
|
},
|
|
18040
17840
|
exists: (p2) => {
|
|
18041
17841
|
try {
|
|
18042
|
-
|
|
17842
|
+
fs31.accessSync(p2, fs31.constants.F_OK);
|
|
18043
17843
|
return true;
|
|
18044
17844
|
} catch {
|
|
18045
17845
|
return false;
|
|
@@ -18050,7 +17850,7 @@ function doltBinaryNames(platform2) {
|
|
|
18050
17850
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
18051
17851
|
}
|
|
18052
17852
|
function knownDoltDirs(platform2) {
|
|
18053
|
-
const P3 = platform2 === "win32" ?
|
|
17853
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
18054
17854
|
const home = _doltPathSeam.homedir();
|
|
18055
17855
|
if (platform2 === "win32") {
|
|
18056
17856
|
return [
|
|
@@ -18066,7 +17866,7 @@ function knownDoltDirs(platform2) {
|
|
|
18066
17866
|
].filter(Boolean);
|
|
18067
17867
|
}
|
|
18068
17868
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
18069
|
-
const P3 = platform2 === "win32" ?
|
|
17869
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
18070
17870
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
18071
17871
|
const names = doltBinaryNames(platform2);
|
|
18072
17872
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -18177,8 +17977,8 @@ async function ensureSharedServer(adapter) {
|
|
|
18177
17977
|
// src/beads/project-key.ts
|
|
18178
17978
|
var import_child_process16 = require("child_process");
|
|
18179
17979
|
var crypto2 = __toESM(require("crypto"));
|
|
18180
|
-
var
|
|
18181
|
-
var
|
|
17980
|
+
var fs32 = __toESM(require("fs"));
|
|
17981
|
+
var path38 = __toESM(require("path"));
|
|
18182
17982
|
function normalizeOrigin(raw) {
|
|
18183
17983
|
const trimmed = raw.trim();
|
|
18184
17984
|
if (!trimmed) return null;
|
|
@@ -18204,17 +18004,17 @@ function normalizeOrigin(raw) {
|
|
|
18204
18004
|
return `${host}/${pathPart}`;
|
|
18205
18005
|
}
|
|
18206
18006
|
function findRepoRoot(cwd) {
|
|
18207
|
-
let dir =
|
|
18007
|
+
let dir = path38.resolve(cwd);
|
|
18208
18008
|
const seen = /* @__PURE__ */ new Set();
|
|
18209
18009
|
for (let i = 0; i < 256; i++) {
|
|
18210
18010
|
if (seen.has(dir)) return null;
|
|
18211
18011
|
seen.add(dir);
|
|
18212
18012
|
try {
|
|
18213
|
-
const stat3 =
|
|
18013
|
+
const stat3 = fs32.statSync(path38.join(dir, ".git"), { throwIfNoEntry: false });
|
|
18214
18014
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
18215
18015
|
} catch {
|
|
18216
18016
|
}
|
|
18217
|
-
const parent =
|
|
18017
|
+
const parent = path38.dirname(dir);
|
|
18218
18018
|
if (parent === dir) return null;
|
|
18219
18019
|
dir = parent;
|
|
18220
18020
|
}
|
|
@@ -18225,7 +18025,7 @@ var _execSeam2 = {
|
|
|
18225
18025
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
18226
18026
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
18227
18027
|
},
|
|
18228
|
-
realpath: (p2) =>
|
|
18028
|
+
realpath: (p2) => fs32.realpathSync(p2)
|
|
18229
18029
|
};
|
|
18230
18030
|
function readOrigin(cwd) {
|
|
18231
18031
|
try {
|
|
@@ -18254,7 +18054,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
18254
18054
|
} catch {
|
|
18255
18055
|
}
|
|
18256
18056
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
18257
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18057
|
+
return { projectKey: `path:${hash}`, projectLabel: path38.basename(real) || "project" };
|
|
18258
18058
|
}
|
|
18259
18059
|
|
|
18260
18060
|
// src/beads/project-prefix.ts
|
|
@@ -18299,14 +18099,14 @@ var _linkSeam = {
|
|
|
18299
18099
|
homedir: () => os26.homedir(),
|
|
18300
18100
|
isWritableDir: (dir) => {
|
|
18301
18101
|
try {
|
|
18302
|
-
|
|
18102
|
+
fs33.accessSync(dir, fs33.constants.W_OK);
|
|
18303
18103
|
return true;
|
|
18304
18104
|
} catch {
|
|
18305
18105
|
return false;
|
|
18306
18106
|
}
|
|
18307
18107
|
},
|
|
18308
18108
|
ensureDir: (dir) => {
|
|
18309
|
-
|
|
18109
|
+
fs33.mkdirSync(dir, { recursive: true });
|
|
18310
18110
|
},
|
|
18311
18111
|
/**
|
|
18312
18112
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18327,12 +18127,12 @@ var _linkSeam = {
|
|
|
18327
18127
|
* which `linkBdOntoPath` creates if missing.
|
|
18328
18128
|
*/
|
|
18329
18129
|
cliBinDir: () => {
|
|
18330
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18130
|
+
const pathDirs = (process.env.PATH ?? "").split(path39.delimiter).filter(Boolean);
|
|
18331
18131
|
const home = _linkSeam.homedir();
|
|
18332
|
-
const localBin = home ?
|
|
18132
|
+
const localBin = home ? path39.join(home, ".local", "bin") : null;
|
|
18333
18133
|
const candidates = [];
|
|
18334
18134
|
try {
|
|
18335
|
-
candidates.push(
|
|
18135
|
+
candidates.push(path39.dirname(process.execPath));
|
|
18336
18136
|
} catch {
|
|
18337
18137
|
}
|
|
18338
18138
|
if (localBin) candidates.push(localBin);
|
|
@@ -18340,9 +18140,9 @@ var _linkSeam = {
|
|
|
18340
18140
|
const entry = process.argv[1];
|
|
18341
18141
|
if (entry) {
|
|
18342
18142
|
try {
|
|
18343
|
-
candidates.push(
|
|
18143
|
+
candidates.push(path39.dirname(fs33.realpathSync(entry)));
|
|
18344
18144
|
} catch {
|
|
18345
|
-
candidates.push(
|
|
18145
|
+
candidates.push(path39.dirname(entry));
|
|
18346
18146
|
}
|
|
18347
18147
|
}
|
|
18348
18148
|
const onPathWritable = candidates.find(
|
|
@@ -18354,20 +18154,20 @@ var _linkSeam = {
|
|
|
18354
18154
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18355
18155
|
readlink: (linkPath) => {
|
|
18356
18156
|
try {
|
|
18357
|
-
return
|
|
18157
|
+
return fs33.readlinkSync(linkPath);
|
|
18358
18158
|
} catch {
|
|
18359
18159
|
return null;
|
|
18360
18160
|
}
|
|
18361
18161
|
},
|
|
18362
|
-
unlink: (linkPath) =>
|
|
18363
|
-
symlink: (target, linkPath) =>
|
|
18162
|
+
unlink: (linkPath) => fs33.unlinkSync(linkPath),
|
|
18163
|
+
symlink: (target, linkPath) => fs33.symlinkSync(target, linkPath)
|
|
18364
18164
|
};
|
|
18365
18165
|
function linkBdOntoPath(binaryPath) {
|
|
18366
18166
|
if (_linkSeam.platform() === "win32") return;
|
|
18367
18167
|
const binDir = _linkSeam.cliBinDir();
|
|
18368
18168
|
if (!binDir) return;
|
|
18369
18169
|
_linkSeam.ensureDir(binDir);
|
|
18370
|
-
const linkPath =
|
|
18170
|
+
const linkPath = path39.join(binDir, "bd");
|
|
18371
18171
|
if (linkPath === binaryPath) return;
|
|
18372
18172
|
const current = _linkSeam.readlink(linkPath);
|
|
18373
18173
|
if (current === binaryPath) return;
|
|
@@ -18508,7 +18308,7 @@ function dedupeRecipes(agents) {
|
|
|
18508
18308
|
|
|
18509
18309
|
// src/beads/watcher.ts
|
|
18510
18310
|
var crypto4 = __toESM(require("crypto"));
|
|
18511
|
-
var
|
|
18311
|
+
var path40 = __toESM(require("path"));
|
|
18512
18312
|
|
|
18513
18313
|
// src/services/file-watcher/transport.ts
|
|
18514
18314
|
var http5 = __toESM(require("http"));
|
|
@@ -18583,7 +18383,7 @@ var BeadsWatcher = class {
|
|
|
18583
18383
|
constructor(opts) {
|
|
18584
18384
|
this.opts = opts;
|
|
18585
18385
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18586
|
-
this.feedPath = opts.feedPath ??
|
|
18386
|
+
this.feedPath = opts.feedPath ?? path40.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
|
|
18587
18387
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18588
18388
|
}
|
|
18589
18389
|
opts;
|
|
@@ -18906,7 +18706,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18906
18706
|
function cleanupAttachmentTempFiles() {
|
|
18907
18707
|
for (const p2 of pendingAttachmentFiles) {
|
|
18908
18708
|
try {
|
|
18909
|
-
|
|
18709
|
+
fs34.unlinkSync(p2);
|
|
18910
18710
|
} catch {
|
|
18911
18711
|
}
|
|
18912
18712
|
}
|
|
@@ -18915,8 +18715,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18915
18715
|
function saveFilesTemp(files) {
|
|
18916
18716
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18917
18717
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18918
|
-
const tmpPath =
|
|
18919
|
-
|
|
18718
|
+
const tmpPath = path41.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18719
|
+
fs34.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18920
18720
|
pendingAttachmentFiles.add(tmpPath);
|
|
18921
18721
|
return tmpPath;
|
|
18922
18722
|
});
|
|
@@ -18936,7 +18736,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18936
18736
|
setTimeout(() => {
|
|
18937
18737
|
for (const p2 of paths) {
|
|
18938
18738
|
try {
|
|
18939
|
-
|
|
18739
|
+
fs34.unlinkSync(p2);
|
|
18940
18740
|
} catch {
|
|
18941
18741
|
}
|
|
18942
18742
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19519,8 +19319,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19519
19319
|
if (args2.length === 0) return detection;
|
|
19520
19320
|
const binName = args2[0];
|
|
19521
19321
|
if (binName.startsWith("-")) return detection;
|
|
19522
|
-
const binPath =
|
|
19523
|
-
if (!
|
|
19322
|
+
const binPath = path41.join(cwd, "node_modules", ".bin", binName);
|
|
19323
|
+
if (!fs34.existsSync(binPath)) return detection;
|
|
19524
19324
|
return {
|
|
19525
19325
|
...detection,
|
|
19526
19326
|
command: binPath,
|
|
@@ -19957,9 +19757,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19957
19757
|
|
|
19958
19758
|
// src/services/file-watcher.service.ts
|
|
19959
19759
|
var import_child_process19 = require("child_process");
|
|
19960
|
-
var
|
|
19760
|
+
var fs35 = __toESM(require("fs"));
|
|
19961
19761
|
var os28 = __toESM(require("os"));
|
|
19962
|
-
var
|
|
19762
|
+
var path42 = __toESM(require("path"));
|
|
19963
19763
|
var import_ignore = __toESM(require("ignore"));
|
|
19964
19764
|
|
|
19965
19765
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -20102,18 +19902,18 @@ var _findGitRootSeam = {
|
|
|
20102
19902
|
resolve: _defaultFindGitRoot
|
|
20103
19903
|
};
|
|
20104
19904
|
function _defaultFindGitRoot(startDir) {
|
|
20105
|
-
let dir =
|
|
19905
|
+
let dir = path42.resolve(startDir);
|
|
20106
19906
|
const seen = /* @__PURE__ */ new Set();
|
|
20107
19907
|
for (let i = 0; i < 256; i++) {
|
|
20108
19908
|
if (seen.has(dir)) return null;
|
|
20109
19909
|
seen.add(dir);
|
|
20110
19910
|
try {
|
|
20111
|
-
const gitPath =
|
|
20112
|
-
const stat3 =
|
|
19911
|
+
const gitPath = path42.join(dir, ".git");
|
|
19912
|
+
const stat3 = fs35.statSync(gitPath, { throwIfNoEntry: false });
|
|
20113
19913
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
20114
19914
|
} catch {
|
|
20115
19915
|
}
|
|
20116
|
-
const parent =
|
|
19916
|
+
const parent = path42.dirname(dir);
|
|
20117
19917
|
if (parent === dir) return null;
|
|
20118
19918
|
dir = parent;
|
|
20119
19919
|
}
|
|
@@ -20358,7 +20158,7 @@ var FileWatcherService = class {
|
|
|
20358
20158
|
}
|
|
20359
20159
|
async emitForFile(absPath, changeType) {
|
|
20360
20160
|
if (this.stopped) return;
|
|
20361
|
-
const fileDir =
|
|
20161
|
+
const fileDir = path42.dirname(absPath);
|
|
20362
20162
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20363
20163
|
if (gitRoot === void 0) {
|
|
20364
20164
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20371,19 +20171,19 @@ var FileWatcherService = class {
|
|
|
20371
20171
|
);
|
|
20372
20172
|
return;
|
|
20373
20173
|
}
|
|
20374
|
-
const relPathInRepo =
|
|
20174
|
+
const relPathInRepo = path42.relative(gitRoot, absPath);
|
|
20375
20175
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20376
20176
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20377
20177
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20378
20178
|
log.trace(
|
|
20379
20179
|
"fileWatcher",
|
|
20380
|
-
`${relPathInRepo} ignored by ${
|
|
20180
|
+
`${relPathInRepo} ignored by ${path42.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20381
20181
|
);
|
|
20382
20182
|
return;
|
|
20383
20183
|
}
|
|
20384
20184
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20385
|
-
const repoPath =
|
|
20386
|
-
const repoName =
|
|
20185
|
+
const repoPath = path42.relative(this.opts.workingDir, gitRoot);
|
|
20186
|
+
const repoName = path42.basename(gitRoot);
|
|
20387
20187
|
let diffText = "";
|
|
20388
20188
|
let fileStatus = "modified";
|
|
20389
20189
|
if (changeType === "unlink") {
|
|
@@ -20558,7 +20358,7 @@ var FileWatcherService = class {
|
|
|
20558
20358
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20559
20359
|
let entries;
|
|
20560
20360
|
try {
|
|
20561
|
-
entries =
|
|
20361
|
+
entries = fs35.readdirSync(dir, { withFileTypes: true });
|
|
20562
20362
|
} catch {
|
|
20563
20363
|
return;
|
|
20564
20364
|
}
|
|
@@ -20567,16 +20367,16 @@ var FileWatcherService = class {
|
|
|
20567
20367
|
);
|
|
20568
20368
|
if (gitignoreEntry) {
|
|
20569
20369
|
try {
|
|
20570
|
-
const body =
|
|
20571
|
-
const rel =
|
|
20370
|
+
const body = fs35.readFileSync(path42.join(dir, ".gitignore"), "utf8");
|
|
20371
|
+
const rel = path42.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20572
20372
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20573
20373
|
const trimmed = line.trim();
|
|
20574
20374
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20575
20375
|
if (!rel) return line;
|
|
20576
20376
|
if (trimmed.startsWith("!")) {
|
|
20577
|
-
return "!" +
|
|
20377
|
+
return "!" + path42.posix.join(rel, trimmed.slice(1));
|
|
20578
20378
|
}
|
|
20579
|
-
return
|
|
20379
|
+
return path42.posix.join(rel, trimmed);
|
|
20580
20380
|
}).join("\n");
|
|
20581
20381
|
matcher.add(prefixed);
|
|
20582
20382
|
} catch {
|
|
@@ -20585,7 +20385,7 @@ var FileWatcherService = class {
|
|
|
20585
20385
|
for (const entry of entries) {
|
|
20586
20386
|
if (!entry.isDirectory()) continue;
|
|
20587
20387
|
if (entry.name === ".git") continue;
|
|
20588
|
-
const childAbs =
|
|
20388
|
+
const childAbs = path42.join(dir, entry.name);
|
|
20589
20389
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20590
20390
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20591
20391
|
}
|
|
@@ -20755,7 +20555,7 @@ var import_crypto4 = require("crypto");
|
|
|
20755
20555
|
|
|
20756
20556
|
// src/services/turn-files/git-changeset.ts
|
|
20757
20557
|
var import_child_process20 = require("child_process");
|
|
20758
|
-
var
|
|
20558
|
+
var path43 = __toESM(require("path"));
|
|
20759
20559
|
async function collectRepoChangeset(opts) {
|
|
20760
20560
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20761
20561
|
if (status2 === null) return null;
|
|
@@ -20866,7 +20666,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20866
20666
|
});
|
|
20867
20667
|
}
|
|
20868
20668
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20869
|
-
const
|
|
20669
|
+
const fs41 = await import("fs/promises");
|
|
20870
20670
|
const out2 = [];
|
|
20871
20671
|
await walk(workingDir, 0);
|
|
20872
20672
|
return out2;
|
|
@@ -20874,7 +20674,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20874
20674
|
if (depth > maxDepth) return;
|
|
20875
20675
|
let entries = [];
|
|
20876
20676
|
try {
|
|
20877
|
-
const dirents = await
|
|
20677
|
+
const dirents = await fs41.readdir(dir, { withFileTypes: true });
|
|
20878
20678
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20879
20679
|
} catch {
|
|
20880
20680
|
return;
|
|
@@ -20885,8 +20685,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20885
20685
|
if (hasGit) {
|
|
20886
20686
|
out2.push({
|
|
20887
20687
|
repoRoot: dir,
|
|
20888
|
-
repoPath:
|
|
20889
|
-
repoName:
|
|
20688
|
+
repoPath: path43.relative(workingDir, dir),
|
|
20689
|
+
repoName: path43.basename(dir)
|
|
20890
20690
|
});
|
|
20891
20691
|
return;
|
|
20892
20692
|
}
|
|
@@ -20894,14 +20694,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20894
20694
|
if (!entry.isDirectory) continue;
|
|
20895
20695
|
if (entry.name === "node_modules") continue;
|
|
20896
20696
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20897
|
-
await walk(
|
|
20697
|
+
await walk(path43.join(dir, entry.name), depth + 1);
|
|
20898
20698
|
}
|
|
20899
20699
|
}
|
|
20900
20700
|
}
|
|
20901
20701
|
|
|
20902
20702
|
// src/services/turn-files/files-outbox.ts
|
|
20903
|
-
var
|
|
20904
|
-
var
|
|
20703
|
+
var fs36 = __toESM(require("fs/promises"));
|
|
20704
|
+
var path44 = __toESM(require("path"));
|
|
20905
20705
|
var import_os7 = require("os");
|
|
20906
20706
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20907
20707
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20934,16 +20734,16 @@ var FilesOutbox = class {
|
|
|
20934
20734
|
backoffIndex = 0;
|
|
20935
20735
|
stopped = false;
|
|
20936
20736
|
constructor(opts) {
|
|
20937
|
-
const base = opts.baseDir ??
|
|
20938
|
-
this.filePath =
|
|
20737
|
+
const base = opts.baseDir ?? path44.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20738
|
+
this.filePath = path44.join(base, `${opts.sessionId}.jsonl`);
|
|
20939
20739
|
this.post = opts.post;
|
|
20940
20740
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20941
20741
|
}
|
|
20942
20742
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20943
20743
|
* line is durable on disk (not once the POST succeeds). */
|
|
20944
20744
|
async enqueue(entry) {
|
|
20945
|
-
await
|
|
20946
|
-
await
|
|
20745
|
+
await fs36.mkdir(path44.dirname(this.filePath), { recursive: true });
|
|
20746
|
+
await fs36.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20947
20747
|
this.backoffIndex = 0;
|
|
20948
20748
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20949
20749
|
}
|
|
@@ -21032,7 +20832,7 @@ var FilesOutbox = class {
|
|
|
21032
20832
|
async readAll() {
|
|
21033
20833
|
let raw = "";
|
|
21034
20834
|
try {
|
|
21035
|
-
raw = await
|
|
20835
|
+
raw = await fs36.readFile(this.filePath, "utf8");
|
|
21036
20836
|
} catch {
|
|
21037
20837
|
return [];
|
|
21038
20838
|
}
|
|
@@ -21056,12 +20856,12 @@ var FilesOutbox = class {
|
|
|
21056
20856
|
async rewrite(entries) {
|
|
21057
20857
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
21058
20858
|
if (entries.length === 0) {
|
|
21059
|
-
await
|
|
20859
|
+
await fs36.unlink(this.filePath).catch(() => void 0);
|
|
21060
20860
|
return;
|
|
21061
20861
|
}
|
|
21062
20862
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
21063
|
-
await
|
|
21064
|
-
await
|
|
20863
|
+
await fs36.writeFile(tmpPath, payload, "utf8");
|
|
20864
|
+
await fs36.rename(tmpPath, this.filePath);
|
|
21065
20865
|
}
|
|
21066
20866
|
};
|
|
21067
20867
|
function applyJitter(ms) {
|
|
@@ -22158,10 +21958,10 @@ var ChromeStepTracker = class {
|
|
|
22158
21958
|
const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
|
|
22159
21959
|
if (visible.length === 0) return;
|
|
22160
21960
|
for (const step of visible) {
|
|
22161
|
-
const
|
|
21961
|
+
const exists = this.history.some(
|
|
22162
21962
|
(s) => s.tool === step.tool && s.label === step.label
|
|
22163
21963
|
);
|
|
22164
|
-
if (!
|
|
21964
|
+
if (!exists) this.history.push(step);
|
|
22165
21965
|
}
|
|
22166
21966
|
}
|
|
22167
21967
|
/**
|
|
@@ -22906,8 +22706,8 @@ var OutputService = class _OutputService {
|
|
|
22906
22706
|
};
|
|
22907
22707
|
|
|
22908
22708
|
// src/services/history.service.ts
|
|
22909
|
-
var
|
|
22910
|
-
var
|
|
22709
|
+
var fs37 = __toESM(require("fs"));
|
|
22710
|
+
var path45 = __toESM(require("path"));
|
|
22911
22711
|
var os29 = __toESM(require("os"));
|
|
22912
22712
|
var https7 = __toESM(require("https"));
|
|
22913
22713
|
var http7 = __toESM(require("http"));
|
|
@@ -22935,7 +22735,7 @@ function parseJsonl(filePath) {
|
|
|
22935
22735
|
const messages = [];
|
|
22936
22736
|
let raw;
|
|
22937
22737
|
try {
|
|
22938
|
-
raw =
|
|
22738
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
22939
22739
|
} catch (err) {
|
|
22940
22740
|
if (err.code !== "ENOENT") {
|
|
22941
22741
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -23070,7 +22870,7 @@ var HistoryService = class _HistoryService {
|
|
|
23070
22870
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
23071
22871
|
}
|
|
23072
22872
|
get projectDir() {
|
|
23073
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
22873
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path45.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
23074
22874
|
}
|
|
23075
22875
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
23076
22876
|
setCurrentConversationId(id) {
|
|
@@ -23082,7 +22882,7 @@ var HistoryService = class _HistoryService {
|
|
|
23082
22882
|
/** Return the current message count in the active conversation. */
|
|
23083
22883
|
getCurrentMessageCount() {
|
|
23084
22884
|
if (!this.currentConversationId) return 0;
|
|
23085
|
-
const filePath =
|
|
22885
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23086
22886
|
return parseJsonl(filePath).length;
|
|
23087
22887
|
}
|
|
23088
22888
|
/**
|
|
@@ -23093,7 +22893,7 @@ var HistoryService = class _HistoryService {
|
|
|
23093
22893
|
const deadline = Date.now() + timeoutMs;
|
|
23094
22894
|
while (Date.now() < deadline) {
|
|
23095
22895
|
if (!this.currentConversationId) return null;
|
|
23096
|
-
const filePath =
|
|
22896
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
23097
22897
|
const messages = parseJsonl(filePath);
|
|
23098
22898
|
if (messages.length > previousCount) {
|
|
23099
22899
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -23119,16 +22919,16 @@ var HistoryService = class _HistoryService {
|
|
|
23119
22919
|
const dir = this.projectDir;
|
|
23120
22920
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23121
22921
|
try {
|
|
23122
|
-
const files =
|
|
22922
|
+
const files = fs37.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23123
22923
|
try {
|
|
23124
|
-
const stat3 =
|
|
22924
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
23125
22925
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23126
22926
|
} catch {
|
|
23127
22927
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
23128
22928
|
}
|
|
23129
22929
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
23130
22930
|
if (files.length > 0) {
|
|
23131
|
-
this.currentConversationId =
|
|
22931
|
+
this.currentConversationId = path45.basename(files[0].name, ".jsonl");
|
|
23132
22932
|
}
|
|
23133
22933
|
} catch {
|
|
23134
22934
|
}
|
|
@@ -23162,13 +22962,13 @@ var HistoryService = class _HistoryService {
|
|
|
23162
22962
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
23163
22963
|
let entries;
|
|
23164
22964
|
try {
|
|
23165
|
-
entries =
|
|
22965
|
+
entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
23166
22966
|
} catch {
|
|
23167
22967
|
return null;
|
|
23168
22968
|
}
|
|
23169
22969
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
23170
22970
|
try {
|
|
23171
|
-
const stat3 =
|
|
22971
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
23172
22972
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
23173
22973
|
} catch {
|
|
23174
22974
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -23177,12 +22977,12 @@ var HistoryService = class _HistoryService {
|
|
|
23177
22977
|
if (files.length === 0) return null;
|
|
23178
22978
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
23179
22979
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
23180
|
-
return this.extractUsageFromFile(
|
|
22980
|
+
return this.extractUsageFromFile(path45.join(dir, targetFile));
|
|
23181
22981
|
}
|
|
23182
22982
|
extractUsageFromFile(filePath) {
|
|
23183
22983
|
let raw;
|
|
23184
22984
|
try {
|
|
23185
|
-
raw =
|
|
22985
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
23186
22986
|
} catch {
|
|
23187
22987
|
return null;
|
|
23188
22988
|
}
|
|
@@ -23227,9 +23027,9 @@ var HistoryService = class _HistoryService {
|
|
|
23227
23027
|
let totalCost = 0;
|
|
23228
23028
|
let files;
|
|
23229
23029
|
try {
|
|
23230
|
-
files =
|
|
23030
|
+
files = fs37.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23231
23031
|
try {
|
|
23232
|
-
return
|
|
23032
|
+
return fs37.statSync(path45.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23233
23033
|
} catch {
|
|
23234
23034
|
return false;
|
|
23235
23035
|
}
|
|
@@ -23240,7 +23040,7 @@ var HistoryService = class _HistoryService {
|
|
|
23240
23040
|
for (const file of files) {
|
|
23241
23041
|
let raw;
|
|
23242
23042
|
try {
|
|
23243
|
-
raw =
|
|
23043
|
+
raw = fs37.readFileSync(path45.join(projectDir, file), "utf8");
|
|
23244
23044
|
} catch {
|
|
23245
23045
|
continue;
|
|
23246
23046
|
}
|
|
@@ -23304,7 +23104,7 @@ var HistoryService = class _HistoryService {
|
|
|
23304
23104
|
* showing an empty conversation.
|
|
23305
23105
|
*/
|
|
23306
23106
|
async loadConversation(sessionId) {
|
|
23307
|
-
const filePath =
|
|
23107
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23308
23108
|
const messages = parseJsonl(filePath);
|
|
23309
23109
|
if (messages.length === 0) return;
|
|
23310
23110
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23358,7 +23158,7 @@ var HistoryService = class _HistoryService {
|
|
|
23358
23158
|
if (!this.currentConversationId) return 0;
|
|
23359
23159
|
}
|
|
23360
23160
|
const sessionId = this.currentConversationId;
|
|
23361
|
-
const filePath =
|
|
23161
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23362
23162
|
const messages = parseJsonl(filePath);
|
|
23363
23163
|
if (messages.length === 0) return 0;
|
|
23364
23164
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -24279,7 +24079,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
24279
24079
|
}
|
|
24280
24080
|
|
|
24281
24081
|
// src/commands/pair-auto.ts
|
|
24282
|
-
var
|
|
24082
|
+
var fs38 = __toESM(require("fs"));
|
|
24283
24083
|
var os30 = __toESM(require("os"));
|
|
24284
24084
|
var import_crypto7 = require("crypto");
|
|
24285
24085
|
|
|
@@ -24475,12 +24275,12 @@ function readTokenFromArgs(args2) {
|
|
|
24475
24275
|
}
|
|
24476
24276
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24477
24277
|
if (fileFlag) {
|
|
24478
|
-
const
|
|
24278
|
+
const path52 = fileFlag.slice("--token-file=".length);
|
|
24479
24279
|
try {
|
|
24480
|
-
const content =
|
|
24481
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24280
|
+
const content = fs38.readFileSync(path52, "utf8").trim();
|
|
24281
|
+
if (content.length === 0) fail(`--token-file ${path52} is empty`);
|
|
24482
24282
|
try {
|
|
24483
|
-
|
|
24283
|
+
fs38.unlinkSync(path52);
|
|
24484
24284
|
} catch {
|
|
24485
24285
|
}
|
|
24486
24286
|
return content;
|
|
@@ -24598,8 +24398,6 @@ async function pairAuto(args2) {
|
|
|
24598
24398
|
codespaceName: process.env.CODESPACE_NAME ?? void 0
|
|
24599
24399
|
});
|
|
24600
24400
|
console.log(` Paired with ${claimed.user.name} (${claimed.user.plan})`);
|
|
24601
|
-
void provisionProjectDependencies(process.cwd()).catch(() => {
|
|
24602
|
-
});
|
|
24603
24401
|
if (process.env.CODEAM_SKIP_AGENT_LAUNCH === "true") {
|
|
24604
24402
|
capture("pair_auto_skipped_launch", {
|
|
24605
24403
|
sessionId: claimed.sessionId,
|
|
@@ -24748,7 +24546,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24748
24546
|
var import_child_process22 = require("child_process");
|
|
24749
24547
|
var import_util4 = require("util");
|
|
24750
24548
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24751
|
-
var
|
|
24549
|
+
var path46 = __toESM(require("path"));
|
|
24752
24550
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24753
24551
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24754
24552
|
function resetStdinForChild() {
|
|
@@ -25237,7 +25035,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25237
25035
|
});
|
|
25238
25036
|
}
|
|
25239
25037
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25240
|
-
const remoteDir =
|
|
25038
|
+
const remoteDir = path46.posix.dirname(remotePath);
|
|
25241
25039
|
const parts = [
|
|
25242
25040
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25243
25041
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25307,7 +25105,7 @@ function shellQuote(s) {
|
|
|
25307
25105
|
// src/services/providers/gitpod.ts
|
|
25308
25106
|
var import_child_process23 = require("child_process");
|
|
25309
25107
|
var import_util5 = require("util");
|
|
25310
|
-
var
|
|
25108
|
+
var path47 = __toESM(require("path"));
|
|
25311
25109
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25312
25110
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25313
25111
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25547,7 +25345,7 @@ var GitpodProvider = class {
|
|
|
25547
25345
|
});
|
|
25548
25346
|
}
|
|
25549
25347
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25550
|
-
const remoteDir =
|
|
25348
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25551
25349
|
const parts = [
|
|
25552
25350
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25553
25351
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25583,7 +25381,7 @@ function shellQuote2(s) {
|
|
|
25583
25381
|
// src/services/providers/gitlab-workspaces.ts
|
|
25584
25382
|
var import_child_process24 = require("child_process");
|
|
25585
25383
|
var import_util6 = require("util");
|
|
25586
|
-
var
|
|
25384
|
+
var path48 = __toESM(require("path"));
|
|
25587
25385
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25588
25386
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25589
25387
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25843,7 +25641,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25843
25641
|
}
|
|
25844
25642
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25845
25643
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25846
|
-
const remoteDir =
|
|
25644
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25847
25645
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25848
25646
|
if (options.mode != null) {
|
|
25849
25647
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25911,7 +25709,7 @@ function shellQuote3(s) {
|
|
|
25911
25709
|
// src/services/providers/railway.ts
|
|
25912
25710
|
var import_child_process25 = require("child_process");
|
|
25913
25711
|
var import_util7 = require("util");
|
|
25914
|
-
var
|
|
25712
|
+
var path49 = __toESM(require("path"));
|
|
25915
25713
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25916
25714
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25917
25715
|
function resetStdinForChild4() {
|
|
@@ -26147,7 +25945,7 @@ var RailwayProvider = class {
|
|
|
26147
25945
|
if (!projectId || !serviceId) {
|
|
26148
25946
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
26149
25947
|
}
|
|
26150
|
-
const remoteDir =
|
|
25948
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
26151
25949
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
26152
25950
|
if (options.mode != null) {
|
|
26153
25951
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26690,8 +26488,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26690
26488
|
var import_node_dns = require("dns");
|
|
26691
26489
|
var import_node_util4 = require("util");
|
|
26692
26490
|
var import_node_crypto8 = require("crypto");
|
|
26693
|
-
var
|
|
26694
|
-
var
|
|
26491
|
+
var fs39 = __toESM(require("fs"));
|
|
26492
|
+
var path50 = __toESM(require("path"));
|
|
26695
26493
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26696
26494
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26697
26495
|
async function checkDns(apiBase) {
|
|
@@ -26747,13 +26545,13 @@ async function checkHealth(apiBase) {
|
|
|
26747
26545
|
}
|
|
26748
26546
|
}
|
|
26749
26547
|
function checkConfigDir() {
|
|
26750
|
-
const dir =
|
|
26548
|
+
const dir = path50.join(require("os").homedir(), ".codeam");
|
|
26751
26549
|
try {
|
|
26752
|
-
|
|
26753
|
-
const probe =
|
|
26754
|
-
|
|
26755
|
-
const read =
|
|
26756
|
-
|
|
26550
|
+
fs39.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26551
|
+
const probe = path50.join(dir, ".doctor-probe");
|
|
26552
|
+
fs39.writeFileSync(probe, "ok", { mode: 384 });
|
|
26553
|
+
const read = fs39.readFileSync(probe, "utf8");
|
|
26554
|
+
fs39.unlinkSync(probe);
|
|
26757
26555
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26758
26556
|
return {
|
|
26759
26557
|
id: "config-dir",
|
|
@@ -26817,7 +26615,7 @@ function checkNodePty() {
|
|
|
26817
26615
|
detail: "not required on this platform"
|
|
26818
26616
|
};
|
|
26819
26617
|
}
|
|
26820
|
-
const vendoredPath =
|
|
26618
|
+
const vendoredPath = path50.join(__dirname, "vendor", "node-pty");
|
|
26821
26619
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26822
26620
|
try {
|
|
26823
26621
|
require(target);
|
|
@@ -26859,7 +26657,7 @@ function checkChokidar() {
|
|
|
26859
26657
|
}
|
|
26860
26658
|
async function doctor(args2 = []) {
|
|
26861
26659
|
const json = args2.includes("--json");
|
|
26862
|
-
const cliVersion = true ? "2.39.
|
|
26660
|
+
const cliVersion = true ? "2.39.1" : "0.0.0-dev";
|
|
26863
26661
|
const apiBase = resolveApiBaseUrl();
|
|
26864
26662
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26865
26663
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -27058,7 +26856,7 @@ async function completion(args2) {
|
|
|
27058
26856
|
// src/commands/version.ts
|
|
27059
26857
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
27060
26858
|
function version2() {
|
|
27061
|
-
const v = true ? "2.39.
|
|
26859
|
+
const v = true ? "2.39.1" : "unknown";
|
|
27062
26860
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
27063
26861
|
}
|
|
27064
26862
|
|
|
@@ -27186,9 +26984,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
27186
26984
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
27187
26985
|
|
|
27188
26986
|
// src/lib/updateNotifier.ts
|
|
27189
|
-
var
|
|
26987
|
+
var fs40 = __toESM(require("fs"));
|
|
27190
26988
|
var os31 = __toESM(require("os"));
|
|
27191
|
-
var
|
|
26989
|
+
var path51 = __toESM(require("path"));
|
|
27192
26990
|
var https8 = __toESM(require("https"));
|
|
27193
26991
|
var import_node_child_process12 = require("child_process");
|
|
27194
26992
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -27197,12 +26995,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27197
26995
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27198
26996
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27199
26997
|
function cachePath() {
|
|
27200
|
-
const dir =
|
|
27201
|
-
return
|
|
26998
|
+
const dir = path51.join(os31.homedir(), ".codeam");
|
|
26999
|
+
return path51.join(dir, "update-check.json");
|
|
27202
27000
|
}
|
|
27203
27001
|
function readCache() {
|
|
27204
27002
|
try {
|
|
27205
|
-
const raw =
|
|
27003
|
+
const raw = fs40.readFileSync(cachePath(), "utf8");
|
|
27206
27004
|
const parsed = JSON.parse(raw);
|
|
27207
27005
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
27208
27006
|
return parsed;
|
|
@@ -27213,10 +27011,10 @@ function readCache() {
|
|
|
27213
27011
|
function writeCache(cache) {
|
|
27214
27012
|
try {
|
|
27215
27013
|
const file = cachePath();
|
|
27216
|
-
|
|
27014
|
+
fs40.mkdirSync(path51.dirname(file), { recursive: true });
|
|
27217
27015
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27218
|
-
|
|
27219
|
-
|
|
27016
|
+
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
27017
|
+
fs40.renameSync(tmp, file);
|
|
27220
27018
|
} catch {
|
|
27221
27019
|
}
|
|
27222
27020
|
}
|
|
@@ -27290,8 +27088,8 @@ function isLinkedInstall() {
|
|
|
27290
27088
|
timeout: 2e3
|
|
27291
27089
|
}).trim();
|
|
27292
27090
|
if (!root) return false;
|
|
27293
|
-
const pkgPath =
|
|
27294
|
-
return
|
|
27091
|
+
const pkgPath = path51.join(root, PKG_NAME);
|
|
27092
|
+
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
27295
27093
|
} catch {
|
|
27296
27094
|
return false;
|
|
27297
27095
|
}
|
|
@@ -27327,7 +27125,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27327
27125
|
return;
|
|
27328
27126
|
}
|
|
27329
27127
|
try {
|
|
27330
|
-
|
|
27128
|
+
fs40.unlinkSync(cachePath());
|
|
27331
27129
|
} catch {
|
|
27332
27130
|
}
|
|
27333
27131
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27344,7 +27142,7 @@ function checkForUpdates() {
|
|
|
27344
27142
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27345
27143
|
if (process.env.CI) return;
|
|
27346
27144
|
if (!process.stdout.isTTY) return;
|
|
27347
|
-
const current = true ? "2.39.
|
|
27145
|
+
const current = true ? "2.39.1" : null;
|
|
27348
27146
|
if (!current) return;
|
|
27349
27147
|
const cache = readCache();
|
|
27350
27148
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.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",
|