codeam-cli 2.38.0 → 2.39.0
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 +11 -0
- package/dist/index.js +365 -156
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ 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.38.0] — 2026-06-12
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Inherit team memories into the active repo's Beads DB (P3b)
|
|
12
|
+
|
|
13
|
+
### Chore
|
|
14
|
+
|
|
15
|
+
- **deps:** Bump com.squareup.okhttp3:okhttp in /apps/jetbrains-plugin (#326)
|
|
16
|
+
- **deps-dev:** Bump @vscode/test-electron from 2.5.2 to 3.0.0 in /apps/vsc-plugin (#322)
|
|
17
|
+
|
|
7
18
|
## [2.37.3] — 2026-06-11
|
|
8
19
|
|
|
9
20
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.
|
|
501
|
+
version: "2.39.0",
|
|
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(path53) {
|
|
1190
|
+
return path53.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(path53, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path53);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path52, 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(path53, 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(path53) {
|
|
3749
|
+
return path53.startsWith("node:") || path53.endsWith(".min.js") || path53.endsWith(".min.cjs") || path53.endsWith(".min.mjs") || path53.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.
|
|
5903
|
+
cliVersion: true ? "2.39.0" : "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 path53 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path53,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path53 ? 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 [, path53, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path53 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path53.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 fs35 = __toESM(require("fs"));
|
|
15915
15915
|
var os27 = __toESM(require("os"));
|
|
15916
|
-
var
|
|
15916
|
+
var path42 = __toESM(require("path"));
|
|
15917
15917
|
var import_crypto3 = require("crypto");
|
|
15918
15918
|
var import_child_process18 = require("child_process");
|
|
15919
15919
|
|
|
@@ -17364,6 +17364,10 @@ 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
|
+
|
|
17367
17371
|
// src/services/preview/run-setup.ts
|
|
17368
17372
|
var import_child_process12 = require("child_process");
|
|
17369
17373
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
@@ -17408,19 +17412,215 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
|
17408
17412
|
});
|
|
17409
17413
|
}
|
|
17410
17414
|
|
|
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
|
+
|
|
17411
17611
|
// src/services/preview/setup-deps.ts
|
|
17412
|
-
var
|
|
17413
|
-
var
|
|
17612
|
+
var import_fs3 = __toESM(require("fs"));
|
|
17613
|
+
var import_path7 = __toESM(require("path"));
|
|
17414
17614
|
function detectMissingNodeDeps(cwd) {
|
|
17415
|
-
if (!
|
|
17416
|
-
if (
|
|
17417
|
-
if (
|
|
17615
|
+
if (!import_fs3.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
|
|
17616
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
|
|
17617
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
17418
17618
|
return { cmd: "pnpm", args: ["install"] };
|
|
17419
17619
|
}
|
|
17420
|
-
if (
|
|
17620
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
|
|
17421
17621
|
return { cmd: "yarn", args: ["install"] };
|
|
17422
17622
|
}
|
|
17423
|
-
if (
|
|
17623
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lockb")) || import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lock"))) {
|
|
17424
17624
|
return { cmd: "bun", args: ["install"] };
|
|
17425
17625
|
}
|
|
17426
17626
|
return { cmd: "npm", args: ["install"] };
|
|
@@ -17475,8 +17675,8 @@ function activePreviewSessionIds() {
|
|
|
17475
17675
|
|
|
17476
17676
|
// src/beads/bd-adapter.ts
|
|
17477
17677
|
var import_child_process13 = require("child_process");
|
|
17478
|
-
var
|
|
17479
|
-
var
|
|
17678
|
+
var fs31 = __toESM(require("fs"));
|
|
17679
|
+
var path37 = __toESM(require("path"));
|
|
17480
17680
|
var BD_PACKAGE = "@beads/bd";
|
|
17481
17681
|
function resolveBundledBdBinary() {
|
|
17482
17682
|
return _resolveSeam.resolveBundled();
|
|
@@ -17488,11 +17688,11 @@ function _defaultResolveBundled() {
|
|
|
17488
17688
|
} catch {
|
|
17489
17689
|
return null;
|
|
17490
17690
|
}
|
|
17491
|
-
const binDir =
|
|
17691
|
+
const binDir = path37.join(path37.dirname(pkgJsonPath), "bin");
|
|
17492
17692
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17493
|
-
const binaryPath =
|
|
17693
|
+
const binaryPath = path37.join(binDir, binaryName);
|
|
17494
17694
|
try {
|
|
17495
|
-
|
|
17695
|
+
fs31.accessSync(binaryPath, fs31.constants.F_OK);
|
|
17496
17696
|
return binaryPath;
|
|
17497
17697
|
} catch {
|
|
17498
17698
|
return null;
|
|
@@ -17502,13 +17702,13 @@ function resolveBdOnPath() {
|
|
|
17502
17702
|
return _resolveSeam.resolveOnPath();
|
|
17503
17703
|
}
|
|
17504
17704
|
function _defaultResolveOnPath() {
|
|
17505
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17705
|
+
const dirs = (process.env.PATH ?? "").split(path37.delimiter).filter(Boolean);
|
|
17506
17706
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17507
17707
|
for (const dir of dirs) {
|
|
17508
17708
|
for (const candidate of candidates) {
|
|
17509
|
-
const full =
|
|
17709
|
+
const full = path37.join(dir, candidate);
|
|
17510
17710
|
try {
|
|
17511
|
-
|
|
17711
|
+
fs31.accessSync(full, fs31.constants.F_OK);
|
|
17512
17712
|
return full;
|
|
17513
17713
|
} catch {
|
|
17514
17714
|
}
|
|
@@ -17674,9 +17874,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17674
17874
|
|
|
17675
17875
|
// src/beads/provisioner.ts
|
|
17676
17876
|
var import_child_process17 = require("child_process");
|
|
17677
|
-
var
|
|
17877
|
+
var fs34 = __toESM(require("fs"));
|
|
17678
17878
|
var os26 = __toESM(require("os"));
|
|
17679
|
-
var
|
|
17879
|
+
var path40 = __toESM(require("path"));
|
|
17680
17880
|
|
|
17681
17881
|
// src/beads/install-bd.ts
|
|
17682
17882
|
var import_child_process14 = require("child_process");
|
|
@@ -17741,9 +17941,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17741
17941
|
|
|
17742
17942
|
// src/beads/install-dolt.ts
|
|
17743
17943
|
var import_child_process15 = require("child_process");
|
|
17744
|
-
var
|
|
17944
|
+
var fs32 = __toESM(require("fs"));
|
|
17745
17945
|
var os25 = __toESM(require("os"));
|
|
17746
|
-
var
|
|
17946
|
+
var path38 = __toESM(require("path"));
|
|
17747
17947
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17748
17948
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17749
17949
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -17839,7 +18039,7 @@ var _doltPathSeam = {
|
|
|
17839
18039
|
},
|
|
17840
18040
|
exists: (p2) => {
|
|
17841
18041
|
try {
|
|
17842
|
-
|
|
18042
|
+
fs32.accessSync(p2, fs32.constants.F_OK);
|
|
17843
18043
|
return true;
|
|
17844
18044
|
} catch {
|
|
17845
18045
|
return false;
|
|
@@ -17850,7 +18050,7 @@ function doltBinaryNames(platform2) {
|
|
|
17850
18050
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17851
18051
|
}
|
|
17852
18052
|
function knownDoltDirs(platform2) {
|
|
17853
|
-
const P3 = platform2 === "win32" ?
|
|
18053
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17854
18054
|
const home = _doltPathSeam.homedir();
|
|
17855
18055
|
if (platform2 === "win32") {
|
|
17856
18056
|
return [
|
|
@@ -17866,7 +18066,7 @@ function knownDoltDirs(platform2) {
|
|
|
17866
18066
|
].filter(Boolean);
|
|
17867
18067
|
}
|
|
17868
18068
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17869
|
-
const P3 = platform2 === "win32" ?
|
|
18069
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17870
18070
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
17871
18071
|
const names = doltBinaryNames(platform2);
|
|
17872
18072
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17977,8 +18177,8 @@ async function ensureSharedServer(adapter) {
|
|
|
17977
18177
|
// src/beads/project-key.ts
|
|
17978
18178
|
var import_child_process16 = require("child_process");
|
|
17979
18179
|
var crypto2 = __toESM(require("crypto"));
|
|
17980
|
-
var
|
|
17981
|
-
var
|
|
18180
|
+
var fs33 = __toESM(require("fs"));
|
|
18181
|
+
var path39 = __toESM(require("path"));
|
|
17982
18182
|
function normalizeOrigin(raw) {
|
|
17983
18183
|
const trimmed = raw.trim();
|
|
17984
18184
|
if (!trimmed) return null;
|
|
@@ -18004,17 +18204,17 @@ function normalizeOrigin(raw) {
|
|
|
18004
18204
|
return `${host}/${pathPart}`;
|
|
18005
18205
|
}
|
|
18006
18206
|
function findRepoRoot(cwd) {
|
|
18007
|
-
let dir =
|
|
18207
|
+
let dir = path39.resolve(cwd);
|
|
18008
18208
|
const seen = /* @__PURE__ */ new Set();
|
|
18009
18209
|
for (let i = 0; i < 256; i++) {
|
|
18010
18210
|
if (seen.has(dir)) return null;
|
|
18011
18211
|
seen.add(dir);
|
|
18012
18212
|
try {
|
|
18013
|
-
const stat3 =
|
|
18213
|
+
const stat3 = fs33.statSync(path39.join(dir, ".git"), { throwIfNoEntry: false });
|
|
18014
18214
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
18015
18215
|
} catch {
|
|
18016
18216
|
}
|
|
18017
|
-
const parent =
|
|
18217
|
+
const parent = path39.dirname(dir);
|
|
18018
18218
|
if (parent === dir) return null;
|
|
18019
18219
|
dir = parent;
|
|
18020
18220
|
}
|
|
@@ -18025,7 +18225,7 @@ var _execSeam2 = {
|
|
|
18025
18225
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
18026
18226
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
18027
18227
|
},
|
|
18028
|
-
realpath: (p2) =>
|
|
18228
|
+
realpath: (p2) => fs33.realpathSync(p2)
|
|
18029
18229
|
};
|
|
18030
18230
|
function readOrigin(cwd) {
|
|
18031
18231
|
try {
|
|
@@ -18054,7 +18254,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
18054
18254
|
} catch {
|
|
18055
18255
|
}
|
|
18056
18256
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
18057
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18257
|
+
return { projectKey: `path:${hash}`, projectLabel: path39.basename(real) || "project" };
|
|
18058
18258
|
}
|
|
18059
18259
|
|
|
18060
18260
|
// src/beads/project-prefix.ts
|
|
@@ -18099,14 +18299,14 @@ var _linkSeam = {
|
|
|
18099
18299
|
homedir: () => os26.homedir(),
|
|
18100
18300
|
isWritableDir: (dir) => {
|
|
18101
18301
|
try {
|
|
18102
|
-
|
|
18302
|
+
fs34.accessSync(dir, fs34.constants.W_OK);
|
|
18103
18303
|
return true;
|
|
18104
18304
|
} catch {
|
|
18105
18305
|
return false;
|
|
18106
18306
|
}
|
|
18107
18307
|
},
|
|
18108
18308
|
ensureDir: (dir) => {
|
|
18109
|
-
|
|
18309
|
+
fs34.mkdirSync(dir, { recursive: true });
|
|
18110
18310
|
},
|
|
18111
18311
|
/**
|
|
18112
18312
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18127,12 +18327,12 @@ var _linkSeam = {
|
|
|
18127
18327
|
* which `linkBdOntoPath` creates if missing.
|
|
18128
18328
|
*/
|
|
18129
18329
|
cliBinDir: () => {
|
|
18130
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18330
|
+
const pathDirs = (process.env.PATH ?? "").split(path40.delimiter).filter(Boolean);
|
|
18131
18331
|
const home = _linkSeam.homedir();
|
|
18132
|
-
const localBin = home ?
|
|
18332
|
+
const localBin = home ? path40.join(home, ".local", "bin") : null;
|
|
18133
18333
|
const candidates = [];
|
|
18134
18334
|
try {
|
|
18135
|
-
candidates.push(
|
|
18335
|
+
candidates.push(path40.dirname(process.execPath));
|
|
18136
18336
|
} catch {
|
|
18137
18337
|
}
|
|
18138
18338
|
if (localBin) candidates.push(localBin);
|
|
@@ -18140,9 +18340,9 @@ var _linkSeam = {
|
|
|
18140
18340
|
const entry = process.argv[1];
|
|
18141
18341
|
if (entry) {
|
|
18142
18342
|
try {
|
|
18143
|
-
candidates.push(
|
|
18343
|
+
candidates.push(path40.dirname(fs34.realpathSync(entry)));
|
|
18144
18344
|
} catch {
|
|
18145
|
-
candidates.push(
|
|
18345
|
+
candidates.push(path40.dirname(entry));
|
|
18146
18346
|
}
|
|
18147
18347
|
}
|
|
18148
18348
|
const onPathWritable = candidates.find(
|
|
@@ -18154,20 +18354,20 @@ var _linkSeam = {
|
|
|
18154
18354
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18155
18355
|
readlink: (linkPath) => {
|
|
18156
18356
|
try {
|
|
18157
|
-
return
|
|
18357
|
+
return fs34.readlinkSync(linkPath);
|
|
18158
18358
|
} catch {
|
|
18159
18359
|
return null;
|
|
18160
18360
|
}
|
|
18161
18361
|
},
|
|
18162
|
-
unlink: (linkPath) =>
|
|
18163
|
-
symlink: (target, linkPath) =>
|
|
18362
|
+
unlink: (linkPath) => fs34.unlinkSync(linkPath),
|
|
18363
|
+
symlink: (target, linkPath) => fs34.symlinkSync(target, linkPath)
|
|
18164
18364
|
};
|
|
18165
18365
|
function linkBdOntoPath(binaryPath) {
|
|
18166
18366
|
if (_linkSeam.platform() === "win32") return;
|
|
18167
18367
|
const binDir = _linkSeam.cliBinDir();
|
|
18168
18368
|
if (!binDir) return;
|
|
18169
18369
|
_linkSeam.ensureDir(binDir);
|
|
18170
|
-
const linkPath =
|
|
18370
|
+
const linkPath = path40.join(binDir, "bd");
|
|
18171
18371
|
if (linkPath === binaryPath) return;
|
|
18172
18372
|
const current = _linkSeam.readlink(linkPath);
|
|
18173
18373
|
if (current === binaryPath) return;
|
|
@@ -18308,7 +18508,7 @@ function dedupeRecipes(agents) {
|
|
|
18308
18508
|
|
|
18309
18509
|
// src/beads/watcher.ts
|
|
18310
18510
|
var crypto4 = __toESM(require("crypto"));
|
|
18311
|
-
var
|
|
18511
|
+
var path41 = __toESM(require("path"));
|
|
18312
18512
|
|
|
18313
18513
|
// src/services/file-watcher/transport.ts
|
|
18314
18514
|
var http5 = __toESM(require("http"));
|
|
@@ -18383,7 +18583,7 @@ var BeadsWatcher = class {
|
|
|
18383
18583
|
constructor(opts) {
|
|
18384
18584
|
this.opts = opts;
|
|
18385
18585
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18386
|
-
this.feedPath = opts.feedPath ??
|
|
18586
|
+
this.feedPath = opts.feedPath ?? path41.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
|
|
18387
18587
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18388
18588
|
}
|
|
18389
18589
|
opts;
|
|
@@ -18706,7 +18906,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18706
18906
|
function cleanupAttachmentTempFiles() {
|
|
18707
18907
|
for (const p2 of pendingAttachmentFiles) {
|
|
18708
18908
|
try {
|
|
18709
|
-
|
|
18909
|
+
fs35.unlinkSync(p2);
|
|
18710
18910
|
} catch {
|
|
18711
18911
|
}
|
|
18712
18912
|
}
|
|
@@ -18715,8 +18915,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18715
18915
|
function saveFilesTemp(files) {
|
|
18716
18916
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18717
18917
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18718
|
-
const tmpPath =
|
|
18719
|
-
|
|
18918
|
+
const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18919
|
+
fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18720
18920
|
pendingAttachmentFiles.add(tmpPath);
|
|
18721
18921
|
return tmpPath;
|
|
18722
18922
|
});
|
|
@@ -18736,7 +18936,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18736
18936
|
setTimeout(() => {
|
|
18737
18937
|
for (const p2 of paths) {
|
|
18738
18938
|
try {
|
|
18739
|
-
|
|
18939
|
+
fs35.unlinkSync(p2);
|
|
18740
18940
|
} catch {
|
|
18741
18941
|
}
|
|
18742
18942
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19319,8 +19519,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19319
19519
|
if (args2.length === 0) return detection;
|
|
19320
19520
|
const binName = args2[0];
|
|
19321
19521
|
if (binName.startsWith("-")) return detection;
|
|
19322
|
-
const binPath =
|
|
19323
|
-
if (!
|
|
19522
|
+
const binPath = path42.join(cwd, "node_modules", ".bin", binName);
|
|
19523
|
+
if (!fs35.existsSync(binPath)) return detection;
|
|
19324
19524
|
return {
|
|
19325
19525
|
...detection,
|
|
19326
19526
|
command: binPath,
|
|
@@ -19454,11 +19654,13 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19454
19654
|
emitProgress("BIND_PORT", String(detection.port));
|
|
19455
19655
|
emitProgress("WAITING_FOR_READY", detection.ready_pattern);
|
|
19456
19656
|
let expoUrl = null;
|
|
19657
|
+
let outputTail = "";
|
|
19457
19658
|
const readyRe = compileReadyPattern(detection.ready_pattern);
|
|
19458
19659
|
const isNextJs = /next/i.test(detection.framework);
|
|
19459
19660
|
const outcome = await waitForDevServerReady(devServer, readyRe, {
|
|
19460
19661
|
timeoutMs: 12e4,
|
|
19461
19662
|
onChunk: (s) => {
|
|
19663
|
+
outputTail = (outputTail + s).slice(-4e3);
|
|
19462
19664
|
if (!expoUrl && detection.framework === "Expo") {
|
|
19463
19665
|
expoUrl = parseExpoUrl(s);
|
|
19464
19666
|
}
|
|
@@ -19473,7 +19675,8 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19473
19675
|
type: "preview_error",
|
|
19474
19676
|
payload: {
|
|
19475
19677
|
stage: "spawn",
|
|
19476
|
-
message: `
|
|
19678
|
+
message: `The dev server exited (code ${outcome.code}) before it was ready. It may need a database or other services.`,
|
|
19679
|
+
stderrTail: outputTail.slice(-2e3)
|
|
19477
19680
|
}
|
|
19478
19681
|
});
|
|
19479
19682
|
return;
|
|
@@ -19488,7 +19691,11 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19488
19691
|
pluginId: ctx.pluginId,
|
|
19489
19692
|
pluginAuthToken,
|
|
19490
19693
|
type: "preview_error",
|
|
19491
|
-
payload: {
|
|
19694
|
+
payload: {
|
|
19695
|
+
stage: "ready_timeout",
|
|
19696
|
+
message: "The dev server didn't become ready in time. It may be stuck waiting on a database or other service.",
|
|
19697
|
+
stderrTail: outputTail.slice(-2e3)
|
|
19698
|
+
}
|
|
19492
19699
|
});
|
|
19493
19700
|
return;
|
|
19494
19701
|
}
|
|
@@ -19750,9 +19957,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19750
19957
|
|
|
19751
19958
|
// src/services/file-watcher.service.ts
|
|
19752
19959
|
var import_child_process19 = require("child_process");
|
|
19753
|
-
var
|
|
19960
|
+
var fs36 = __toESM(require("fs"));
|
|
19754
19961
|
var os28 = __toESM(require("os"));
|
|
19755
|
-
var
|
|
19962
|
+
var path43 = __toESM(require("path"));
|
|
19756
19963
|
var import_ignore = __toESM(require("ignore"));
|
|
19757
19964
|
|
|
19758
19965
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19895,18 +20102,18 @@ var _findGitRootSeam = {
|
|
|
19895
20102
|
resolve: _defaultFindGitRoot
|
|
19896
20103
|
};
|
|
19897
20104
|
function _defaultFindGitRoot(startDir) {
|
|
19898
|
-
let dir =
|
|
20105
|
+
let dir = path43.resolve(startDir);
|
|
19899
20106
|
const seen = /* @__PURE__ */ new Set();
|
|
19900
20107
|
for (let i = 0; i < 256; i++) {
|
|
19901
20108
|
if (seen.has(dir)) return null;
|
|
19902
20109
|
seen.add(dir);
|
|
19903
20110
|
try {
|
|
19904
|
-
const gitPath =
|
|
19905
|
-
const stat3 =
|
|
20111
|
+
const gitPath = path43.join(dir, ".git");
|
|
20112
|
+
const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
|
|
19906
20113
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19907
20114
|
} catch {
|
|
19908
20115
|
}
|
|
19909
|
-
const parent =
|
|
20116
|
+
const parent = path43.dirname(dir);
|
|
19910
20117
|
if (parent === dir) return null;
|
|
19911
20118
|
dir = parent;
|
|
19912
20119
|
}
|
|
@@ -20151,7 +20358,7 @@ var FileWatcherService = class {
|
|
|
20151
20358
|
}
|
|
20152
20359
|
async emitForFile(absPath, changeType) {
|
|
20153
20360
|
if (this.stopped) return;
|
|
20154
|
-
const fileDir =
|
|
20361
|
+
const fileDir = path43.dirname(absPath);
|
|
20155
20362
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20156
20363
|
if (gitRoot === void 0) {
|
|
20157
20364
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20164,19 +20371,19 @@ var FileWatcherService = class {
|
|
|
20164
20371
|
);
|
|
20165
20372
|
return;
|
|
20166
20373
|
}
|
|
20167
|
-
const relPathInRepo =
|
|
20374
|
+
const relPathInRepo = path43.relative(gitRoot, absPath);
|
|
20168
20375
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20169
20376
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20170
20377
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20171
20378
|
log.trace(
|
|
20172
20379
|
"fileWatcher",
|
|
20173
|
-
`${relPathInRepo} ignored by ${
|
|
20380
|
+
`${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20174
20381
|
);
|
|
20175
20382
|
return;
|
|
20176
20383
|
}
|
|
20177
20384
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20178
|
-
const repoPath =
|
|
20179
|
-
const repoName =
|
|
20385
|
+
const repoPath = path43.relative(this.opts.workingDir, gitRoot);
|
|
20386
|
+
const repoName = path43.basename(gitRoot);
|
|
20180
20387
|
let diffText = "";
|
|
20181
20388
|
let fileStatus = "modified";
|
|
20182
20389
|
if (changeType === "unlink") {
|
|
@@ -20351,7 +20558,7 @@ var FileWatcherService = class {
|
|
|
20351
20558
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20352
20559
|
let entries;
|
|
20353
20560
|
try {
|
|
20354
|
-
entries =
|
|
20561
|
+
entries = fs36.readdirSync(dir, { withFileTypes: true });
|
|
20355
20562
|
} catch {
|
|
20356
20563
|
return;
|
|
20357
20564
|
}
|
|
@@ -20360,16 +20567,16 @@ var FileWatcherService = class {
|
|
|
20360
20567
|
);
|
|
20361
20568
|
if (gitignoreEntry) {
|
|
20362
20569
|
try {
|
|
20363
|
-
const body =
|
|
20364
|
-
const rel =
|
|
20570
|
+
const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
|
|
20571
|
+
const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20365
20572
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20366
20573
|
const trimmed = line.trim();
|
|
20367
20574
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20368
20575
|
if (!rel) return line;
|
|
20369
20576
|
if (trimmed.startsWith("!")) {
|
|
20370
|
-
return "!" +
|
|
20577
|
+
return "!" + path43.posix.join(rel, trimmed.slice(1));
|
|
20371
20578
|
}
|
|
20372
|
-
return
|
|
20579
|
+
return path43.posix.join(rel, trimmed);
|
|
20373
20580
|
}).join("\n");
|
|
20374
20581
|
matcher.add(prefixed);
|
|
20375
20582
|
} catch {
|
|
@@ -20378,7 +20585,7 @@ var FileWatcherService = class {
|
|
|
20378
20585
|
for (const entry of entries) {
|
|
20379
20586
|
if (!entry.isDirectory()) continue;
|
|
20380
20587
|
if (entry.name === ".git") continue;
|
|
20381
|
-
const childAbs =
|
|
20588
|
+
const childAbs = path43.join(dir, entry.name);
|
|
20382
20589
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20383
20590
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20384
20591
|
}
|
|
@@ -20548,7 +20755,7 @@ var import_crypto4 = require("crypto");
|
|
|
20548
20755
|
|
|
20549
20756
|
// src/services/turn-files/git-changeset.ts
|
|
20550
20757
|
var import_child_process20 = require("child_process");
|
|
20551
|
-
var
|
|
20758
|
+
var path44 = __toESM(require("path"));
|
|
20552
20759
|
async function collectRepoChangeset(opts) {
|
|
20553
20760
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20554
20761
|
if (status2 === null) return null;
|
|
@@ -20659,7 +20866,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20659
20866
|
});
|
|
20660
20867
|
}
|
|
20661
20868
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20662
|
-
const
|
|
20869
|
+
const fs42 = await import("fs/promises");
|
|
20663
20870
|
const out2 = [];
|
|
20664
20871
|
await walk(workingDir, 0);
|
|
20665
20872
|
return out2;
|
|
@@ -20667,7 +20874,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20667
20874
|
if (depth > maxDepth) return;
|
|
20668
20875
|
let entries = [];
|
|
20669
20876
|
try {
|
|
20670
|
-
const dirents = await
|
|
20877
|
+
const dirents = await fs42.readdir(dir, { withFileTypes: true });
|
|
20671
20878
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20672
20879
|
} catch {
|
|
20673
20880
|
return;
|
|
@@ -20678,8 +20885,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20678
20885
|
if (hasGit) {
|
|
20679
20886
|
out2.push({
|
|
20680
20887
|
repoRoot: dir,
|
|
20681
|
-
repoPath:
|
|
20682
|
-
repoName:
|
|
20888
|
+
repoPath: path44.relative(workingDir, dir),
|
|
20889
|
+
repoName: path44.basename(dir)
|
|
20683
20890
|
});
|
|
20684
20891
|
return;
|
|
20685
20892
|
}
|
|
@@ -20687,14 +20894,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20687
20894
|
if (!entry.isDirectory) continue;
|
|
20688
20895
|
if (entry.name === "node_modules") continue;
|
|
20689
20896
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20690
|
-
await walk(
|
|
20897
|
+
await walk(path44.join(dir, entry.name), depth + 1);
|
|
20691
20898
|
}
|
|
20692
20899
|
}
|
|
20693
20900
|
}
|
|
20694
20901
|
|
|
20695
20902
|
// src/services/turn-files/files-outbox.ts
|
|
20696
|
-
var
|
|
20697
|
-
var
|
|
20903
|
+
var fs37 = __toESM(require("fs/promises"));
|
|
20904
|
+
var path45 = __toESM(require("path"));
|
|
20698
20905
|
var import_os7 = require("os");
|
|
20699
20906
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20700
20907
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20727,16 +20934,16 @@ var FilesOutbox = class {
|
|
|
20727
20934
|
backoffIndex = 0;
|
|
20728
20935
|
stopped = false;
|
|
20729
20936
|
constructor(opts) {
|
|
20730
|
-
const base = opts.baseDir ??
|
|
20731
|
-
this.filePath =
|
|
20937
|
+
const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20938
|
+
this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
|
|
20732
20939
|
this.post = opts.post;
|
|
20733
20940
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20734
20941
|
}
|
|
20735
20942
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20736
20943
|
* line is durable on disk (not once the POST succeeds). */
|
|
20737
20944
|
async enqueue(entry) {
|
|
20738
|
-
await
|
|
20739
|
-
await
|
|
20945
|
+
await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
|
|
20946
|
+
await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20740
20947
|
this.backoffIndex = 0;
|
|
20741
20948
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20742
20949
|
}
|
|
@@ -20825,7 +21032,7 @@ var FilesOutbox = class {
|
|
|
20825
21032
|
async readAll() {
|
|
20826
21033
|
let raw = "";
|
|
20827
21034
|
try {
|
|
20828
|
-
raw = await
|
|
21035
|
+
raw = await fs37.readFile(this.filePath, "utf8");
|
|
20829
21036
|
} catch {
|
|
20830
21037
|
return [];
|
|
20831
21038
|
}
|
|
@@ -20849,12 +21056,12 @@ var FilesOutbox = class {
|
|
|
20849
21056
|
async rewrite(entries) {
|
|
20850
21057
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20851
21058
|
if (entries.length === 0) {
|
|
20852
|
-
await
|
|
21059
|
+
await fs37.unlink(this.filePath).catch(() => void 0);
|
|
20853
21060
|
return;
|
|
20854
21061
|
}
|
|
20855
21062
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20856
|
-
await
|
|
20857
|
-
await
|
|
21063
|
+
await fs37.writeFile(tmpPath, payload, "utf8");
|
|
21064
|
+
await fs37.rename(tmpPath, this.filePath);
|
|
20858
21065
|
}
|
|
20859
21066
|
};
|
|
20860
21067
|
function applyJitter(ms) {
|
|
@@ -21951,10 +22158,10 @@ var ChromeStepTracker = class {
|
|
|
21951
22158
|
const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
|
|
21952
22159
|
if (visible.length === 0) return;
|
|
21953
22160
|
for (const step of visible) {
|
|
21954
|
-
const
|
|
22161
|
+
const exists2 = this.history.some(
|
|
21955
22162
|
(s) => s.tool === step.tool && s.label === step.label
|
|
21956
22163
|
);
|
|
21957
|
-
if (!
|
|
22164
|
+
if (!exists2) this.history.push(step);
|
|
21958
22165
|
}
|
|
21959
22166
|
}
|
|
21960
22167
|
/**
|
|
@@ -22699,8 +22906,8 @@ var OutputService = class _OutputService {
|
|
|
22699
22906
|
};
|
|
22700
22907
|
|
|
22701
22908
|
// src/services/history.service.ts
|
|
22702
|
-
var
|
|
22703
|
-
var
|
|
22909
|
+
var fs38 = __toESM(require("fs"));
|
|
22910
|
+
var path46 = __toESM(require("path"));
|
|
22704
22911
|
var os29 = __toESM(require("os"));
|
|
22705
22912
|
var https7 = __toESM(require("https"));
|
|
22706
22913
|
var http7 = __toESM(require("http"));
|
|
@@ -22728,7 +22935,7 @@ function parseJsonl(filePath) {
|
|
|
22728
22935
|
const messages = [];
|
|
22729
22936
|
let raw;
|
|
22730
22937
|
try {
|
|
22731
|
-
raw =
|
|
22938
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22732
22939
|
} catch (err) {
|
|
22733
22940
|
if (err.code !== "ENOENT") {
|
|
22734
22941
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22863,7 +23070,7 @@ var HistoryService = class _HistoryService {
|
|
|
22863
23070
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22864
23071
|
}
|
|
22865
23072
|
get projectDir() {
|
|
22866
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23073
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22867
23074
|
}
|
|
22868
23075
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22869
23076
|
setCurrentConversationId(id) {
|
|
@@ -22875,7 +23082,7 @@ var HistoryService = class _HistoryService {
|
|
|
22875
23082
|
/** Return the current message count in the active conversation. */
|
|
22876
23083
|
getCurrentMessageCount() {
|
|
22877
23084
|
if (!this.currentConversationId) return 0;
|
|
22878
|
-
const filePath =
|
|
23085
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22879
23086
|
return parseJsonl(filePath).length;
|
|
22880
23087
|
}
|
|
22881
23088
|
/**
|
|
@@ -22886,7 +23093,7 @@ var HistoryService = class _HistoryService {
|
|
|
22886
23093
|
const deadline = Date.now() + timeoutMs;
|
|
22887
23094
|
while (Date.now() < deadline) {
|
|
22888
23095
|
if (!this.currentConversationId) return null;
|
|
22889
|
-
const filePath =
|
|
23096
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22890
23097
|
const messages = parseJsonl(filePath);
|
|
22891
23098
|
if (messages.length > previousCount) {
|
|
22892
23099
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22912,16 +23119,16 @@ var HistoryService = class _HistoryService {
|
|
|
22912
23119
|
const dir = this.projectDir;
|
|
22913
23120
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22914
23121
|
try {
|
|
22915
|
-
const files =
|
|
23122
|
+
const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22916
23123
|
try {
|
|
22917
|
-
const stat3 =
|
|
23124
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22918
23125
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22919
23126
|
} catch {
|
|
22920
23127
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22921
23128
|
}
|
|
22922
23129
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22923
23130
|
if (files.length > 0) {
|
|
22924
|
-
this.currentConversationId =
|
|
23131
|
+
this.currentConversationId = path46.basename(files[0].name, ".jsonl");
|
|
22925
23132
|
}
|
|
22926
23133
|
} catch {
|
|
22927
23134
|
}
|
|
@@ -22955,13 +23162,13 @@ var HistoryService = class _HistoryService {
|
|
|
22955
23162
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22956
23163
|
let entries;
|
|
22957
23164
|
try {
|
|
22958
|
-
entries =
|
|
23165
|
+
entries = fs38.readdirSync(dir, { withFileTypes: true });
|
|
22959
23166
|
} catch {
|
|
22960
23167
|
return null;
|
|
22961
23168
|
}
|
|
22962
23169
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22963
23170
|
try {
|
|
22964
|
-
const stat3 =
|
|
23171
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22965
23172
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22966
23173
|
} catch {
|
|
22967
23174
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22970,12 +23177,12 @@ var HistoryService = class _HistoryService {
|
|
|
22970
23177
|
if (files.length === 0) return null;
|
|
22971
23178
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22972
23179
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22973
|
-
return this.extractUsageFromFile(
|
|
23180
|
+
return this.extractUsageFromFile(path46.join(dir, targetFile));
|
|
22974
23181
|
}
|
|
22975
23182
|
extractUsageFromFile(filePath) {
|
|
22976
23183
|
let raw;
|
|
22977
23184
|
try {
|
|
22978
|
-
raw =
|
|
23185
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22979
23186
|
} catch {
|
|
22980
23187
|
return null;
|
|
22981
23188
|
}
|
|
@@ -23020,9 +23227,9 @@ var HistoryService = class _HistoryService {
|
|
|
23020
23227
|
let totalCost = 0;
|
|
23021
23228
|
let files;
|
|
23022
23229
|
try {
|
|
23023
|
-
files =
|
|
23230
|
+
files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23024
23231
|
try {
|
|
23025
|
-
return
|
|
23232
|
+
return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23026
23233
|
} catch {
|
|
23027
23234
|
return false;
|
|
23028
23235
|
}
|
|
@@ -23033,7 +23240,7 @@ var HistoryService = class _HistoryService {
|
|
|
23033
23240
|
for (const file of files) {
|
|
23034
23241
|
let raw;
|
|
23035
23242
|
try {
|
|
23036
|
-
raw =
|
|
23243
|
+
raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
|
|
23037
23244
|
} catch {
|
|
23038
23245
|
continue;
|
|
23039
23246
|
}
|
|
@@ -23097,7 +23304,7 @@ var HistoryService = class _HistoryService {
|
|
|
23097
23304
|
* showing an empty conversation.
|
|
23098
23305
|
*/
|
|
23099
23306
|
async loadConversation(sessionId) {
|
|
23100
|
-
const filePath =
|
|
23307
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23101
23308
|
const messages = parseJsonl(filePath);
|
|
23102
23309
|
if (messages.length === 0) return;
|
|
23103
23310
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23151,7 +23358,7 @@ var HistoryService = class _HistoryService {
|
|
|
23151
23358
|
if (!this.currentConversationId) return 0;
|
|
23152
23359
|
}
|
|
23153
23360
|
const sessionId = this.currentConversationId;
|
|
23154
|
-
const filePath =
|
|
23361
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23155
23362
|
const messages = parseJsonl(filePath);
|
|
23156
23363
|
if (messages.length === 0) return 0;
|
|
23157
23364
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -24072,7 +24279,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
24072
24279
|
}
|
|
24073
24280
|
|
|
24074
24281
|
// src/commands/pair-auto.ts
|
|
24075
|
-
var
|
|
24282
|
+
var fs39 = __toESM(require("fs"));
|
|
24076
24283
|
var os30 = __toESM(require("os"));
|
|
24077
24284
|
var import_crypto7 = require("crypto");
|
|
24078
24285
|
|
|
@@ -24268,12 +24475,12 @@ function readTokenFromArgs(args2) {
|
|
|
24268
24475
|
}
|
|
24269
24476
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24270
24477
|
if (fileFlag) {
|
|
24271
|
-
const
|
|
24478
|
+
const path53 = fileFlag.slice("--token-file=".length);
|
|
24272
24479
|
try {
|
|
24273
|
-
const content =
|
|
24274
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24480
|
+
const content = fs39.readFileSync(path53, "utf8").trim();
|
|
24481
|
+
if (content.length === 0) fail(`--token-file ${path53} is empty`);
|
|
24275
24482
|
try {
|
|
24276
|
-
|
|
24483
|
+
fs39.unlinkSync(path53);
|
|
24277
24484
|
} catch {
|
|
24278
24485
|
}
|
|
24279
24486
|
return content;
|
|
@@ -24391,6 +24598,8 @@ async function pairAuto(args2) {
|
|
|
24391
24598
|
codespaceName: process.env.CODESPACE_NAME ?? void 0
|
|
24392
24599
|
});
|
|
24393
24600
|
console.log(` Paired with ${claimed.user.name} (${claimed.user.plan})`);
|
|
24601
|
+
void provisionProjectDependencies(process.cwd()).catch(() => {
|
|
24602
|
+
});
|
|
24394
24603
|
if (process.env.CODEAM_SKIP_AGENT_LAUNCH === "true") {
|
|
24395
24604
|
capture("pair_auto_skipped_launch", {
|
|
24396
24605
|
sessionId: claimed.sessionId,
|
|
@@ -24539,7 +24748,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24539
24748
|
var import_child_process22 = require("child_process");
|
|
24540
24749
|
var import_util4 = require("util");
|
|
24541
24750
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24542
|
-
var
|
|
24751
|
+
var path47 = __toESM(require("path"));
|
|
24543
24752
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24544
24753
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24545
24754
|
function resetStdinForChild() {
|
|
@@ -25028,7 +25237,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25028
25237
|
});
|
|
25029
25238
|
}
|
|
25030
25239
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25031
|
-
const remoteDir =
|
|
25240
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25032
25241
|
const parts = [
|
|
25033
25242
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25034
25243
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25098,7 +25307,7 @@ function shellQuote(s) {
|
|
|
25098
25307
|
// src/services/providers/gitpod.ts
|
|
25099
25308
|
var import_child_process23 = require("child_process");
|
|
25100
25309
|
var import_util5 = require("util");
|
|
25101
|
-
var
|
|
25310
|
+
var path48 = __toESM(require("path"));
|
|
25102
25311
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25103
25312
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25104
25313
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25338,7 +25547,7 @@ var GitpodProvider = class {
|
|
|
25338
25547
|
});
|
|
25339
25548
|
}
|
|
25340
25549
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25341
|
-
const remoteDir =
|
|
25550
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25342
25551
|
const parts = [
|
|
25343
25552
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25344
25553
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25374,7 +25583,7 @@ function shellQuote2(s) {
|
|
|
25374
25583
|
// src/services/providers/gitlab-workspaces.ts
|
|
25375
25584
|
var import_child_process24 = require("child_process");
|
|
25376
25585
|
var import_util6 = require("util");
|
|
25377
|
-
var
|
|
25586
|
+
var path49 = __toESM(require("path"));
|
|
25378
25587
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25379
25588
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25380
25589
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25634,7 +25843,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25634
25843
|
}
|
|
25635
25844
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25636
25845
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25637
|
-
const remoteDir =
|
|
25846
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25638
25847
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25639
25848
|
if (options.mode != null) {
|
|
25640
25849
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25702,7 +25911,7 @@ function shellQuote3(s) {
|
|
|
25702
25911
|
// src/services/providers/railway.ts
|
|
25703
25912
|
var import_child_process25 = require("child_process");
|
|
25704
25913
|
var import_util7 = require("util");
|
|
25705
|
-
var
|
|
25914
|
+
var path50 = __toESM(require("path"));
|
|
25706
25915
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25707
25916
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25708
25917
|
function resetStdinForChild4() {
|
|
@@ -25938,7 +26147,7 @@ var RailwayProvider = class {
|
|
|
25938
26147
|
if (!projectId || !serviceId) {
|
|
25939
26148
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25940
26149
|
}
|
|
25941
|
-
const remoteDir =
|
|
26150
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25942
26151
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25943
26152
|
if (options.mode != null) {
|
|
25944
26153
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26481,8 +26690,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26481
26690
|
var import_node_dns = require("dns");
|
|
26482
26691
|
var import_node_util4 = require("util");
|
|
26483
26692
|
var import_node_crypto8 = require("crypto");
|
|
26484
|
-
var
|
|
26485
|
-
var
|
|
26693
|
+
var fs40 = __toESM(require("fs"));
|
|
26694
|
+
var path51 = __toESM(require("path"));
|
|
26486
26695
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26487
26696
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26488
26697
|
async function checkDns(apiBase) {
|
|
@@ -26538,13 +26747,13 @@ async function checkHealth(apiBase) {
|
|
|
26538
26747
|
}
|
|
26539
26748
|
}
|
|
26540
26749
|
function checkConfigDir() {
|
|
26541
|
-
const dir =
|
|
26750
|
+
const dir = path51.join(require("os").homedir(), ".codeam");
|
|
26542
26751
|
try {
|
|
26543
|
-
|
|
26544
|
-
const probe =
|
|
26545
|
-
|
|
26546
|
-
const read =
|
|
26547
|
-
|
|
26752
|
+
fs40.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26753
|
+
const probe = path51.join(dir, ".doctor-probe");
|
|
26754
|
+
fs40.writeFileSync(probe, "ok", { mode: 384 });
|
|
26755
|
+
const read = fs40.readFileSync(probe, "utf8");
|
|
26756
|
+
fs40.unlinkSync(probe);
|
|
26548
26757
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26549
26758
|
return {
|
|
26550
26759
|
id: "config-dir",
|
|
@@ -26608,7 +26817,7 @@ function checkNodePty() {
|
|
|
26608
26817
|
detail: "not required on this platform"
|
|
26609
26818
|
};
|
|
26610
26819
|
}
|
|
26611
|
-
const vendoredPath =
|
|
26820
|
+
const vendoredPath = path51.join(__dirname, "vendor", "node-pty");
|
|
26612
26821
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26613
26822
|
try {
|
|
26614
26823
|
require(target);
|
|
@@ -26650,7 +26859,7 @@ function checkChokidar() {
|
|
|
26650
26859
|
}
|
|
26651
26860
|
async function doctor(args2 = []) {
|
|
26652
26861
|
const json = args2.includes("--json");
|
|
26653
|
-
const cliVersion = true ? "2.
|
|
26862
|
+
const cliVersion = true ? "2.39.0" : "0.0.0-dev";
|
|
26654
26863
|
const apiBase = resolveApiBaseUrl();
|
|
26655
26864
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26656
26865
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26849,7 +27058,7 @@ async function completion(args2) {
|
|
|
26849
27058
|
// src/commands/version.ts
|
|
26850
27059
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26851
27060
|
function version2() {
|
|
26852
|
-
const v = true ? "2.
|
|
27061
|
+
const v = true ? "2.39.0" : "unknown";
|
|
26853
27062
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26854
27063
|
}
|
|
26855
27064
|
|
|
@@ -26977,9 +27186,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26977
27186
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26978
27187
|
|
|
26979
27188
|
// src/lib/updateNotifier.ts
|
|
26980
|
-
var
|
|
27189
|
+
var fs41 = __toESM(require("fs"));
|
|
26981
27190
|
var os31 = __toESM(require("os"));
|
|
26982
|
-
var
|
|
27191
|
+
var path52 = __toESM(require("path"));
|
|
26983
27192
|
var https8 = __toESM(require("https"));
|
|
26984
27193
|
var import_node_child_process12 = require("child_process");
|
|
26985
27194
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26988,12 +27197,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26988
27197
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26989
27198
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26990
27199
|
function cachePath() {
|
|
26991
|
-
const dir =
|
|
26992
|
-
return
|
|
27200
|
+
const dir = path52.join(os31.homedir(), ".codeam");
|
|
27201
|
+
return path52.join(dir, "update-check.json");
|
|
26993
27202
|
}
|
|
26994
27203
|
function readCache() {
|
|
26995
27204
|
try {
|
|
26996
|
-
const raw =
|
|
27205
|
+
const raw = fs41.readFileSync(cachePath(), "utf8");
|
|
26997
27206
|
const parsed = JSON.parse(raw);
|
|
26998
27207
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26999
27208
|
return parsed;
|
|
@@ -27004,10 +27213,10 @@ function readCache() {
|
|
|
27004
27213
|
function writeCache(cache) {
|
|
27005
27214
|
try {
|
|
27006
27215
|
const file = cachePath();
|
|
27007
|
-
|
|
27216
|
+
fs41.mkdirSync(path52.dirname(file), { recursive: true });
|
|
27008
27217
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27009
|
-
|
|
27010
|
-
|
|
27218
|
+
fs41.writeFileSync(tmp, JSON.stringify(cache));
|
|
27219
|
+
fs41.renameSync(tmp, file);
|
|
27011
27220
|
} catch {
|
|
27012
27221
|
}
|
|
27013
27222
|
}
|
|
@@ -27081,8 +27290,8 @@ function isLinkedInstall() {
|
|
|
27081
27290
|
timeout: 2e3
|
|
27082
27291
|
}).trim();
|
|
27083
27292
|
if (!root) return false;
|
|
27084
|
-
const pkgPath =
|
|
27085
|
-
return
|
|
27293
|
+
const pkgPath = path52.join(root, PKG_NAME);
|
|
27294
|
+
return fs41.lstatSync(pkgPath).isSymbolicLink();
|
|
27086
27295
|
} catch {
|
|
27087
27296
|
return false;
|
|
27088
27297
|
}
|
|
@@ -27118,7 +27327,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27118
27327
|
return;
|
|
27119
27328
|
}
|
|
27120
27329
|
try {
|
|
27121
|
-
|
|
27330
|
+
fs41.unlinkSync(cachePath());
|
|
27122
27331
|
} catch {
|
|
27123
27332
|
}
|
|
27124
27333
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27135,7 +27344,7 @@ function checkForUpdates() {
|
|
|
27135
27344
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27136
27345
|
if (process.env.CI) return;
|
|
27137
27346
|
if (!process.stdout.isTTY) return;
|
|
27138
|
-
const current = true ? "2.
|
|
27347
|
+
const current = true ? "2.39.0" : null;
|
|
27139
27348
|
if (!current) return;
|
|
27140
27349
|
const cache = readCache();
|
|
27141
27350
|
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.
|
|
3
|
+
"version": "2.39.0",
|
|
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",
|