codeam-cli 2.39.7 → 2.39.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +373 -167
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.39.8] — 2026-06-13
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Beads watcher trigger — watch .beads/last-touched + initial push
|
|
12
|
+
|
|
13
|
+
## [2.39.7] — 2026-06-13
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Hardcode the onboarding welcome (no agent round-trip) + keep beads gate
|
|
18
|
+
|
|
7
19
|
## [2.39.6] — 2026-06-13
|
|
8
20
|
|
|
9
21
|
### 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.39.
|
|
501
|
+
version: "2.39.9",
|
|
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(path54) {
|
|
1190
|
+
return path54.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(path54, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path54);
|
|
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(path54, 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(path54) {
|
|
3749
|
+
return path54.startsWith("node:") || path54.endsWith(".min.js") || path54.endsWith(".min.cjs") || path54.endsWith(".min.mjs") || path54.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.9" : "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 path54 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path54,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path54 ? 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 [, path54, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path54 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path54.trim(),
|
|
11350
11350
|
line: Number(lineNo),
|
|
11351
11351
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11352
|
message: cleanedMessage
|
|
@@ -15896,9 +15896,9 @@ function extractSelectPrompt(text) {
|
|
|
15896
15896
|
}
|
|
15897
15897
|
|
|
15898
15898
|
// src/commands/start/handlers.ts
|
|
15899
|
-
var
|
|
15899
|
+
var fs35 = __toESM(require("fs"));
|
|
15900
15900
|
var os27 = __toESM(require("os"));
|
|
15901
|
-
var
|
|
15901
|
+
var path42 = __toESM(require("path"));
|
|
15902
15902
|
var import_crypto3 = require("crypto");
|
|
15903
15903
|
var import_child_process18 = require("child_process");
|
|
15904
15904
|
|
|
@@ -17349,6 +17349,10 @@ async function waitForPortListening(port, opts) {
|
|
|
17349
17349
|
}
|
|
17350
17350
|
}
|
|
17351
17351
|
|
|
17352
|
+
// src/services/preview/provision-deps.ts
|
|
17353
|
+
var import_fs2 = require("fs");
|
|
17354
|
+
var import_path6 = __toESM(require("path"));
|
|
17355
|
+
|
|
17352
17356
|
// src/services/preview/run-setup.ts
|
|
17353
17357
|
var import_child_process12 = require("child_process");
|
|
17354
17358
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
@@ -17393,19 +17397,216 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
|
17393
17397
|
});
|
|
17394
17398
|
}
|
|
17395
17399
|
|
|
17400
|
+
// src/services/preview/provision-deps.ts
|
|
17401
|
+
var COMPOSE_FILES = [
|
|
17402
|
+
"docker-compose.yml",
|
|
17403
|
+
"docker-compose.yaml",
|
|
17404
|
+
"compose.yaml",
|
|
17405
|
+
"compose.yml"
|
|
17406
|
+
];
|
|
17407
|
+
var ENV_SAMPLES = [".env.example", ".env.sample", ".env.local.example", ".env.template"];
|
|
17408
|
+
var POSTGRES = {
|
|
17409
|
+
name: "postgres",
|
|
17410
|
+
image: "postgres:16",
|
|
17411
|
+
port: 5432,
|
|
17412
|
+
environment: { POSTGRES_USER: "postgres", POSTGRES_PASSWORD: "postgres", POSTGRES_DB: "app" },
|
|
17413
|
+
healthTest: ["CMD-SHELL", "pg_isready -U postgres"],
|
|
17414
|
+
envLines: [
|
|
17415
|
+
"DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app",
|
|
17416
|
+
"DB_HOST=localhost",
|
|
17417
|
+
"DB_PORT=5432",
|
|
17418
|
+
"DB_USERNAME=postgres",
|
|
17419
|
+
"DB_PASSWORD=postgres",
|
|
17420
|
+
"DB_NAME=app"
|
|
17421
|
+
]
|
|
17422
|
+
};
|
|
17423
|
+
var MYSQL = {
|
|
17424
|
+
name: "mysql",
|
|
17425
|
+
image: "mysql:8",
|
|
17426
|
+
port: 3306,
|
|
17427
|
+
environment: { MYSQL_ROOT_PASSWORD: "mysql", MYSQL_DATABASE: "app" },
|
|
17428
|
+
healthTest: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pmysql"],
|
|
17429
|
+
envLines: ["DATABASE_URL=mysql://root:mysql@localhost:3306/app"]
|
|
17430
|
+
};
|
|
17431
|
+
var MONGO = {
|
|
17432
|
+
name: "mongo",
|
|
17433
|
+
image: "mongo:7",
|
|
17434
|
+
port: 27017,
|
|
17435
|
+
environment: {},
|
|
17436
|
+
healthTest: ["CMD", "mongosh", "--eval", 'db.adminCommand("ping")'],
|
|
17437
|
+
envLines: ["MONGODB_URI=mongodb://localhost:27017/app", "MONGO_URL=mongodb://localhost:27017/app"]
|
|
17438
|
+
};
|
|
17439
|
+
var REDIS = {
|
|
17440
|
+
name: "redis",
|
|
17441
|
+
image: "redis:7",
|
|
17442
|
+
port: 6379,
|
|
17443
|
+
environment: {},
|
|
17444
|
+
healthTest: ["CMD", "redis-cli", "ping"],
|
|
17445
|
+
envLines: ["REDIS_URL=redis://localhost:6379", "REDIS_HOST=localhost", "REDIS_PORT=6379"]
|
|
17446
|
+
};
|
|
17447
|
+
function detectServicesFromDeps(pkg) {
|
|
17448
|
+
const deps = /* @__PURE__ */ new Set([
|
|
17449
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
17450
|
+
...Object.keys(pkg.devDependencies ?? {})
|
|
17451
|
+
]);
|
|
17452
|
+
const has = (...names) => names.some((n) => deps.has(n));
|
|
17453
|
+
const out2 = [];
|
|
17454
|
+
if (has("pg", "typeorm", "@nestjs/typeorm", "sequelize", "postgres", "postgres.js", "pg-promise"))
|
|
17455
|
+
out2.push(POSTGRES);
|
|
17456
|
+
if (has("mysql", "mysql2")) out2.push(MYSQL);
|
|
17457
|
+
if (has("mongoose", "mongodb")) out2.push(MONGO);
|
|
17458
|
+
if (has("ioredis", "redis", "cache-manager-ioredis-yet", "cache-manager-redis-store"))
|
|
17459
|
+
out2.push(REDIS);
|
|
17460
|
+
return out2;
|
|
17461
|
+
}
|
|
17462
|
+
function renderComposeYaml(services) {
|
|
17463
|
+
const blocks = services.map((s) => {
|
|
17464
|
+
const env = Object.entries(s.environment);
|
|
17465
|
+
const envYaml = env.length ? " environment:\n" + env.map(([k2, v]) => ` ${k2}: "${v}"`).join("\n") + "\n" : "";
|
|
17466
|
+
const health = JSON.stringify(s.healthTest);
|
|
17467
|
+
return ` ${s.name}:
|
|
17468
|
+
image: ${s.image}
|
|
17469
|
+
restart: unless-stopped
|
|
17470
|
+
ports:
|
|
17471
|
+
- "${s.port}:${s.port}"
|
|
17472
|
+
` + envYaml + ` healthcheck:
|
|
17473
|
+
test: ${health}
|
|
17474
|
+
interval: 5s
|
|
17475
|
+
timeout: 3s
|
|
17476
|
+
retries: 12
|
|
17477
|
+
`;
|
|
17478
|
+
});
|
|
17479
|
+
return `# Generated by codeam \u2014 auto-provisioned project dependencies.
|
|
17480
|
+
# Do not edit; regenerated on each provision. See .codeam/provision/.
|
|
17481
|
+
services:
|
|
17482
|
+
${blocks.join("")}`;
|
|
17483
|
+
}
|
|
17484
|
+
function pickMigrationScript(scripts) {
|
|
17485
|
+
const preferred = [
|
|
17486
|
+
"migration:run",
|
|
17487
|
+
"db:migrate",
|
|
17488
|
+
"migrate:deploy",
|
|
17489
|
+
"migrate:latest",
|
|
17490
|
+
"migrate:up",
|
|
17491
|
+
"prisma:migrate",
|
|
17492
|
+
"migrate"
|
|
17493
|
+
];
|
|
17494
|
+
for (const k2 of preferred) if (scripts[k2]) return k2;
|
|
17495
|
+
for (const k2 of Object.keys(scripts)) {
|
|
17496
|
+
if (/migrat/i.test(k2) && /(run|deploy|latest|up)/i.test(k2) && !/(generate|create|revert|rollback|undo|down|reset|drop)/i.test(k2)) {
|
|
17497
|
+
return k2;
|
|
17498
|
+
}
|
|
17499
|
+
}
|
|
17500
|
+
return null;
|
|
17501
|
+
}
|
|
17502
|
+
async function exists(p2) {
|
|
17503
|
+
try {
|
|
17504
|
+
await import_fs2.promises.access(p2);
|
|
17505
|
+
return true;
|
|
17506
|
+
} catch {
|
|
17507
|
+
return false;
|
|
17508
|
+
}
|
|
17509
|
+
}
|
|
17510
|
+
async function firstExisting(cwd, names) {
|
|
17511
|
+
for (const n of names) if (await exists(import_path6.default.join(cwd, n))) return n;
|
|
17512
|
+
return null;
|
|
17513
|
+
}
|
|
17514
|
+
async function ensureEnvFile(cwd, generated) {
|
|
17515
|
+
if (await exists(import_path6.default.join(cwd, ".env"))) {
|
|
17516
|
+
log.info("provision", ".env already present \u2014 leaving it untouched");
|
|
17517
|
+
return;
|
|
17518
|
+
}
|
|
17519
|
+
const sample = await firstExisting(cwd, ENV_SAMPLES);
|
|
17520
|
+
if (sample) {
|
|
17521
|
+
const body = await import_fs2.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
|
|
17522
|
+
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17523
|
+
log.info("provision", `wrote .env from ${sample}`);
|
|
17524
|
+
return;
|
|
17525
|
+
}
|
|
17526
|
+
if (generated.length > 0) {
|
|
17527
|
+
const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
|
|
17528
|
+
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17529
|
+
log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
|
|
17530
|
+
}
|
|
17531
|
+
}
|
|
17532
|
+
async function readPackageJson(cwd) {
|
|
17533
|
+
try {
|
|
17534
|
+
return JSON.parse(await import_fs2.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
|
|
17535
|
+
} catch {
|
|
17536
|
+
return null;
|
|
17537
|
+
}
|
|
17538
|
+
}
|
|
17539
|
+
async function runMigrationsIfPresent(cwd, scripts) {
|
|
17540
|
+
const script = pickMigrationScript(scripts);
|
|
17541
|
+
if (!script) return;
|
|
17542
|
+
log.info("provision", `running migrations: npm run ${script}`);
|
|
17543
|
+
const res = await runSetupCommand("npm", ["run", script], cwd, void 0, { timeoutMs: 12e4 });
|
|
17544
|
+
if (res.status !== "ok") log.warn("provision", `migration script "${script}" \u2192 ${res.status} (non-fatal)`);
|
|
17545
|
+
}
|
|
17546
|
+
function runDockerComposeUp(cwd, composeArgs) {
|
|
17547
|
+
return runSetupCommand(
|
|
17548
|
+
"nice",
|
|
17549
|
+
["-n", "19", "ionice", "-c", "3", "docker", "compose", ...composeArgs],
|
|
17550
|
+
cwd,
|
|
17551
|
+
void 0,
|
|
17552
|
+
{ timeoutMs: 18e4 }
|
|
17553
|
+
);
|
|
17554
|
+
}
|
|
17555
|
+
async function provisionProjectDependencies(cwd) {
|
|
17556
|
+
try {
|
|
17557
|
+
const docker = await runSetupCommand("docker", ["info"], cwd, void 0, { timeoutMs: 15e3 });
|
|
17558
|
+
if (docker.status !== "ok") {
|
|
17559
|
+
log.info("provision", "docker not usable \u2014 skipping dependency provisioning");
|
|
17560
|
+
return;
|
|
17561
|
+
}
|
|
17562
|
+
const pkg = await readPackageJson(cwd);
|
|
17563
|
+
let started = false;
|
|
17564
|
+
let generated = [];
|
|
17565
|
+
const composeFile = await firstExisting(cwd, COMPOSE_FILES);
|
|
17566
|
+
if (composeFile) {
|
|
17567
|
+
log.info("provision", `compose found (${composeFile}) \u2014 docker compose up -d --wait (idle prio)`);
|
|
17568
|
+
const up = await runDockerComposeUp(cwd, ["up", "-d", "--wait"]);
|
|
17569
|
+
started = up.status === "ok";
|
|
17570
|
+
if (!started) log.warn("provision", `compose up \u2192 ${up.status} (non-fatal)`);
|
|
17571
|
+
} else if (pkg) {
|
|
17572
|
+
generated = detectServicesFromDeps(pkg);
|
|
17573
|
+
if (generated.length > 0) {
|
|
17574
|
+
const dir = import_path6.default.join(cwd, ".codeam", "provision");
|
|
17575
|
+
await import_fs2.promises.mkdir(dir, { recursive: true });
|
|
17576
|
+
const file = import_path6.default.join(dir, "compose.generated.yaml");
|
|
17577
|
+
await import_fs2.promises.writeFile(file, renderComposeYaml(generated));
|
|
17578
|
+
log.info(
|
|
17579
|
+
"provision",
|
|
17580
|
+
`no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
|
|
17581
|
+
);
|
|
17582
|
+
const up = await runDockerComposeUp(cwd, ["-f", file, "up", "-d", "--wait"]);
|
|
17583
|
+
started = up.status === "ok";
|
|
17584
|
+
if (!started) log.warn("provision", `generated compose up \u2192 ${up.status} (non-fatal)`);
|
|
17585
|
+
} else {
|
|
17586
|
+
log.info("provision", "no compose + no known service deps \u2014 nothing to provision");
|
|
17587
|
+
}
|
|
17588
|
+
}
|
|
17589
|
+
await ensureEnvFile(cwd, generated);
|
|
17590
|
+
if (started && pkg?.scripts) await runMigrationsIfPresent(cwd, pkg.scripts);
|
|
17591
|
+
log.info("provision", "project dependency provisioning complete");
|
|
17592
|
+
} catch (err) {
|
|
17593
|
+
log.warn("provision", "provisionProjectDependencies failed (non-fatal)", err);
|
|
17594
|
+
}
|
|
17595
|
+
}
|
|
17596
|
+
|
|
17396
17597
|
// src/services/preview/setup-deps.ts
|
|
17397
|
-
var
|
|
17398
|
-
var
|
|
17598
|
+
var import_fs3 = __toESM(require("fs"));
|
|
17599
|
+
var import_path7 = __toESM(require("path"));
|
|
17399
17600
|
function detectMissingNodeDeps(cwd) {
|
|
17400
|
-
if (!
|
|
17401
|
-
if (
|
|
17402
|
-
if (
|
|
17601
|
+
if (!import_fs3.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
|
|
17602
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
|
|
17603
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
17403
17604
|
return { cmd: "pnpm", args: ["install"] };
|
|
17404
17605
|
}
|
|
17405
|
-
if (
|
|
17606
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
|
|
17406
17607
|
return { cmd: "yarn", args: ["install"] };
|
|
17407
17608
|
}
|
|
17408
|
-
if (
|
|
17609
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lockb")) || import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lock"))) {
|
|
17409
17610
|
return { cmd: "bun", args: ["install"] };
|
|
17410
17611
|
}
|
|
17411
17612
|
return { cmd: "npm", args: ["install"] };
|
|
@@ -17460,8 +17661,8 @@ function activePreviewSessionIds() {
|
|
|
17460
17661
|
|
|
17461
17662
|
// src/beads/bd-adapter.ts
|
|
17462
17663
|
var import_child_process13 = require("child_process");
|
|
17463
|
-
var
|
|
17464
|
-
var
|
|
17664
|
+
var fs31 = __toESM(require("fs"));
|
|
17665
|
+
var path37 = __toESM(require("path"));
|
|
17465
17666
|
var BD_PACKAGE = "@beads/bd";
|
|
17466
17667
|
function resolveBundledBdBinary() {
|
|
17467
17668
|
return _resolveSeam.resolveBundled();
|
|
@@ -17473,11 +17674,11 @@ function _defaultResolveBundled() {
|
|
|
17473
17674
|
} catch {
|
|
17474
17675
|
return null;
|
|
17475
17676
|
}
|
|
17476
|
-
const binDir =
|
|
17677
|
+
const binDir = path37.join(path37.dirname(pkgJsonPath), "bin");
|
|
17477
17678
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17478
|
-
const binaryPath =
|
|
17679
|
+
const binaryPath = path37.join(binDir, binaryName);
|
|
17479
17680
|
try {
|
|
17480
|
-
|
|
17681
|
+
fs31.accessSync(binaryPath, fs31.constants.F_OK);
|
|
17481
17682
|
return binaryPath;
|
|
17482
17683
|
} catch {
|
|
17483
17684
|
return null;
|
|
@@ -17487,13 +17688,13 @@ function resolveBdOnPath() {
|
|
|
17487
17688
|
return _resolveSeam.resolveOnPath();
|
|
17488
17689
|
}
|
|
17489
17690
|
function _defaultResolveOnPath() {
|
|
17490
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17691
|
+
const dirs = (process.env.PATH ?? "").split(path37.delimiter).filter(Boolean);
|
|
17491
17692
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17492
17693
|
for (const dir of dirs) {
|
|
17493
17694
|
for (const candidate of candidates) {
|
|
17494
|
-
const full =
|
|
17695
|
+
const full = path37.join(dir, candidate);
|
|
17495
17696
|
try {
|
|
17496
|
-
|
|
17697
|
+
fs31.accessSync(full, fs31.constants.F_OK);
|
|
17497
17698
|
return full;
|
|
17498
17699
|
} catch {
|
|
17499
17700
|
}
|
|
@@ -17660,9 +17861,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17660
17861
|
|
|
17661
17862
|
// src/beads/provisioner.ts
|
|
17662
17863
|
var import_child_process17 = require("child_process");
|
|
17663
|
-
var
|
|
17864
|
+
var fs34 = __toESM(require("fs"));
|
|
17664
17865
|
var os26 = __toESM(require("os"));
|
|
17665
|
-
var
|
|
17866
|
+
var path40 = __toESM(require("path"));
|
|
17666
17867
|
|
|
17667
17868
|
// src/beads/install-bd.ts
|
|
17668
17869
|
var import_child_process14 = require("child_process");
|
|
@@ -17727,9 +17928,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17727
17928
|
|
|
17728
17929
|
// src/beads/install-dolt.ts
|
|
17729
17930
|
var import_child_process15 = require("child_process");
|
|
17730
|
-
var
|
|
17931
|
+
var fs32 = __toESM(require("fs"));
|
|
17731
17932
|
var os25 = __toESM(require("os"));
|
|
17732
|
-
var
|
|
17933
|
+
var path38 = __toESM(require("path"));
|
|
17733
17934
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17734
17935
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17735
17936
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -17825,7 +18026,7 @@ var _doltPathSeam = {
|
|
|
17825
18026
|
},
|
|
17826
18027
|
exists: (p2) => {
|
|
17827
18028
|
try {
|
|
17828
|
-
|
|
18029
|
+
fs32.accessSync(p2, fs32.constants.F_OK);
|
|
17829
18030
|
return true;
|
|
17830
18031
|
} catch {
|
|
17831
18032
|
return false;
|
|
@@ -17836,7 +18037,7 @@ function doltBinaryNames(platform2) {
|
|
|
17836
18037
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17837
18038
|
}
|
|
17838
18039
|
function knownDoltDirs(platform2) {
|
|
17839
|
-
const P3 = platform2 === "win32" ?
|
|
18040
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17840
18041
|
const home = _doltPathSeam.homedir();
|
|
17841
18042
|
if (platform2 === "win32") {
|
|
17842
18043
|
return [
|
|
@@ -17852,7 +18053,7 @@ function knownDoltDirs(platform2) {
|
|
|
17852
18053
|
].filter(Boolean);
|
|
17853
18054
|
}
|
|
17854
18055
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17855
|
-
const P3 = platform2 === "win32" ?
|
|
18056
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17856
18057
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
17857
18058
|
const names = doltBinaryNames(platform2);
|
|
17858
18059
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17963,8 +18164,8 @@ async function ensureSharedServer(adapter) {
|
|
|
17963
18164
|
// src/beads/project-key.ts
|
|
17964
18165
|
var import_child_process16 = require("child_process");
|
|
17965
18166
|
var crypto2 = __toESM(require("crypto"));
|
|
17966
|
-
var
|
|
17967
|
-
var
|
|
18167
|
+
var fs33 = __toESM(require("fs"));
|
|
18168
|
+
var path39 = __toESM(require("path"));
|
|
17968
18169
|
function normalizeOrigin(raw) {
|
|
17969
18170
|
const trimmed = raw.trim();
|
|
17970
18171
|
if (!trimmed) return null;
|
|
@@ -17990,17 +18191,17 @@ function normalizeOrigin(raw) {
|
|
|
17990
18191
|
return `${host}/${pathPart}`;
|
|
17991
18192
|
}
|
|
17992
18193
|
function findRepoRoot(cwd) {
|
|
17993
|
-
let dir =
|
|
18194
|
+
let dir = path39.resolve(cwd);
|
|
17994
18195
|
const seen = /* @__PURE__ */ new Set();
|
|
17995
18196
|
for (let i = 0; i < 256; i++) {
|
|
17996
18197
|
if (seen.has(dir)) return null;
|
|
17997
18198
|
seen.add(dir);
|
|
17998
18199
|
try {
|
|
17999
|
-
const stat3 =
|
|
18200
|
+
const stat3 = fs33.statSync(path39.join(dir, ".git"), { throwIfNoEntry: false });
|
|
18000
18201
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
18001
18202
|
} catch {
|
|
18002
18203
|
}
|
|
18003
|
-
const parent =
|
|
18204
|
+
const parent = path39.dirname(dir);
|
|
18004
18205
|
if (parent === dir) return null;
|
|
18005
18206
|
dir = parent;
|
|
18006
18207
|
}
|
|
@@ -18011,7 +18212,7 @@ var _execSeam2 = {
|
|
|
18011
18212
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
18012
18213
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
18013
18214
|
},
|
|
18014
|
-
realpath: (p2) =>
|
|
18215
|
+
realpath: (p2) => fs33.realpathSync(p2)
|
|
18015
18216
|
};
|
|
18016
18217
|
function readOrigin(cwd) {
|
|
18017
18218
|
try {
|
|
@@ -18040,7 +18241,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
18040
18241
|
} catch {
|
|
18041
18242
|
}
|
|
18042
18243
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
18043
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18244
|
+
return { projectKey: `path:${hash}`, projectLabel: path39.basename(real) || "project" };
|
|
18044
18245
|
}
|
|
18045
18246
|
|
|
18046
18247
|
// src/beads/project-prefix.ts
|
|
@@ -18085,14 +18286,14 @@ var _linkSeam = {
|
|
|
18085
18286
|
homedir: () => os26.homedir(),
|
|
18086
18287
|
isWritableDir: (dir) => {
|
|
18087
18288
|
try {
|
|
18088
|
-
|
|
18289
|
+
fs34.accessSync(dir, fs34.constants.W_OK);
|
|
18089
18290
|
return true;
|
|
18090
18291
|
} catch {
|
|
18091
18292
|
return false;
|
|
18092
18293
|
}
|
|
18093
18294
|
},
|
|
18094
18295
|
ensureDir: (dir) => {
|
|
18095
|
-
|
|
18296
|
+
fs34.mkdirSync(dir, { recursive: true });
|
|
18096
18297
|
},
|
|
18097
18298
|
/**
|
|
18098
18299
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18113,9 +18314,9 @@ var _linkSeam = {
|
|
|
18113
18314
|
* which `linkBdOntoPath` creates if missing.
|
|
18114
18315
|
*/
|
|
18115
18316
|
cliBinDir: () => {
|
|
18116
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18317
|
+
const pathDirs = (process.env.PATH ?? "").split(path40.delimiter).filter(Boolean);
|
|
18117
18318
|
const home = _linkSeam.homedir();
|
|
18118
|
-
const localBin = home ?
|
|
18319
|
+
const localBin = home ? path40.join(home, ".local", "bin") : null;
|
|
18119
18320
|
if (localBin) {
|
|
18120
18321
|
try {
|
|
18121
18322
|
_linkSeam.ensureDir(localBin);
|
|
@@ -18125,16 +18326,16 @@ var _linkSeam = {
|
|
|
18125
18326
|
const candidates = [];
|
|
18126
18327
|
if (localBin) candidates.push(localBin);
|
|
18127
18328
|
try {
|
|
18128
|
-
candidates.push(
|
|
18329
|
+
candidates.push(path40.dirname(process.execPath));
|
|
18129
18330
|
} catch {
|
|
18130
18331
|
}
|
|
18131
18332
|
candidates.push("/usr/local/bin");
|
|
18132
18333
|
const entry = process.argv[1];
|
|
18133
18334
|
if (entry) {
|
|
18134
18335
|
try {
|
|
18135
|
-
candidates.push(
|
|
18336
|
+
candidates.push(path40.dirname(fs34.realpathSync(entry)));
|
|
18136
18337
|
} catch {
|
|
18137
|
-
candidates.push(
|
|
18338
|
+
candidates.push(path40.dirname(entry));
|
|
18138
18339
|
}
|
|
18139
18340
|
}
|
|
18140
18341
|
const onPathWritable = candidates.find(
|
|
@@ -18146,20 +18347,20 @@ var _linkSeam = {
|
|
|
18146
18347
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18147
18348
|
readlink: (linkPath) => {
|
|
18148
18349
|
try {
|
|
18149
|
-
return
|
|
18350
|
+
return fs34.readlinkSync(linkPath);
|
|
18150
18351
|
} catch {
|
|
18151
18352
|
return null;
|
|
18152
18353
|
}
|
|
18153
18354
|
},
|
|
18154
|
-
unlink: (linkPath) =>
|
|
18155
|
-
symlink: (target, linkPath) =>
|
|
18355
|
+
unlink: (linkPath) => fs34.unlinkSync(linkPath),
|
|
18356
|
+
symlink: (target, linkPath) => fs34.symlinkSync(target, linkPath)
|
|
18156
18357
|
};
|
|
18157
18358
|
function linkBdOntoPath(binaryPath) {
|
|
18158
18359
|
if (_linkSeam.platform() === "win32") return;
|
|
18159
18360
|
const binDir = _linkSeam.cliBinDir();
|
|
18160
18361
|
if (!binDir) return;
|
|
18161
18362
|
_linkSeam.ensureDir(binDir);
|
|
18162
|
-
const linkPath =
|
|
18363
|
+
const linkPath = path40.join(binDir, "bd");
|
|
18163
18364
|
if (linkPath === binaryPath) return;
|
|
18164
18365
|
const current = _linkSeam.readlink(linkPath);
|
|
18165
18366
|
if (current === binaryPath) return;
|
|
@@ -18300,7 +18501,7 @@ function dedupeRecipes(agents) {
|
|
|
18300
18501
|
|
|
18301
18502
|
// src/beads/watcher.ts
|
|
18302
18503
|
var crypto4 = __toESM(require("crypto"));
|
|
18303
|
-
var
|
|
18504
|
+
var path41 = __toESM(require("path"));
|
|
18304
18505
|
|
|
18305
18506
|
// src/services/file-watcher/transport.ts
|
|
18306
18507
|
var http5 = __toESM(require("http"));
|
|
@@ -18375,7 +18576,7 @@ var BeadsWatcher = class {
|
|
|
18375
18576
|
constructor(opts) {
|
|
18376
18577
|
this.opts = opts;
|
|
18377
18578
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18378
|
-
this.feedPath = opts.feedPath ??
|
|
18579
|
+
this.feedPath = opts.feedPath ?? path41.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
18379
18580
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18380
18581
|
}
|
|
18381
18582
|
opts;
|
|
@@ -18408,6 +18609,7 @@ var BeadsWatcher = class {
|
|
|
18408
18609
|
);
|
|
18409
18610
|
this.watcher = watcher;
|
|
18410
18611
|
log.info("beads", `watching ${this.feedPath} for session=${this.opts.sessionId.slice(0, 8)}`);
|
|
18612
|
+
void this.syncNow();
|
|
18411
18613
|
}
|
|
18412
18614
|
async stop() {
|
|
18413
18615
|
if (this.stopped) return;
|
|
@@ -18698,7 +18900,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18698
18900
|
function cleanupAttachmentTempFiles() {
|
|
18699
18901
|
for (const p2 of pendingAttachmentFiles) {
|
|
18700
18902
|
try {
|
|
18701
|
-
|
|
18903
|
+
fs35.unlinkSync(p2);
|
|
18702
18904
|
} catch {
|
|
18703
18905
|
}
|
|
18704
18906
|
}
|
|
@@ -18707,8 +18909,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18707
18909
|
function saveFilesTemp(files) {
|
|
18708
18910
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18709
18911
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18710
|
-
const tmpPath =
|
|
18711
|
-
|
|
18912
|
+
const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18913
|
+
fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18712
18914
|
pendingAttachmentFiles.add(tmpPath);
|
|
18713
18915
|
return tmpPath;
|
|
18714
18916
|
});
|
|
@@ -18728,7 +18930,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18728
18930
|
setTimeout(() => {
|
|
18729
18931
|
for (const p2 of paths) {
|
|
18730
18932
|
try {
|
|
18731
|
-
|
|
18933
|
+
fs35.unlinkSync(p2);
|
|
18732
18934
|
} catch {
|
|
18733
18935
|
}
|
|
18734
18936
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19333,8 +19535,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19333
19535
|
if (args2.length === 0) return detection;
|
|
19334
19536
|
const binName = args2[0];
|
|
19335
19537
|
if (binName.startsWith("-")) return detection;
|
|
19336
|
-
const binPath =
|
|
19337
|
-
if (!
|
|
19538
|
+
const binPath = path42.join(cwd, "node_modules", ".bin", binName);
|
|
19539
|
+
if (!fs35.existsSync(binPath)) return detection;
|
|
19338
19540
|
return {
|
|
19339
19541
|
...detection,
|
|
19340
19542
|
command: binPath,
|
|
@@ -19771,9 +19973,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19771
19973
|
|
|
19772
19974
|
// src/services/file-watcher.service.ts
|
|
19773
19975
|
var import_child_process19 = require("child_process");
|
|
19774
|
-
var
|
|
19976
|
+
var fs36 = __toESM(require("fs"));
|
|
19775
19977
|
var os28 = __toESM(require("os"));
|
|
19776
|
-
var
|
|
19978
|
+
var path43 = __toESM(require("path"));
|
|
19777
19979
|
var import_ignore = __toESM(require("ignore"));
|
|
19778
19980
|
|
|
19779
19981
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19916,18 +20118,18 @@ var _findGitRootSeam = {
|
|
|
19916
20118
|
resolve: _defaultFindGitRoot
|
|
19917
20119
|
};
|
|
19918
20120
|
function _defaultFindGitRoot(startDir) {
|
|
19919
|
-
let dir =
|
|
20121
|
+
let dir = path43.resolve(startDir);
|
|
19920
20122
|
const seen = /* @__PURE__ */ new Set();
|
|
19921
20123
|
for (let i = 0; i < 256; i++) {
|
|
19922
20124
|
if (seen.has(dir)) return null;
|
|
19923
20125
|
seen.add(dir);
|
|
19924
20126
|
try {
|
|
19925
|
-
const gitPath =
|
|
19926
|
-
const stat3 =
|
|
20127
|
+
const gitPath = path43.join(dir, ".git");
|
|
20128
|
+
const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
|
|
19927
20129
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19928
20130
|
} catch {
|
|
19929
20131
|
}
|
|
19930
|
-
const parent =
|
|
20132
|
+
const parent = path43.dirname(dir);
|
|
19931
20133
|
if (parent === dir) return null;
|
|
19932
20134
|
dir = parent;
|
|
19933
20135
|
}
|
|
@@ -20172,7 +20374,7 @@ var FileWatcherService = class {
|
|
|
20172
20374
|
}
|
|
20173
20375
|
async emitForFile(absPath, changeType) {
|
|
20174
20376
|
if (this.stopped) return;
|
|
20175
|
-
const fileDir =
|
|
20377
|
+
const fileDir = path43.dirname(absPath);
|
|
20176
20378
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20177
20379
|
if (gitRoot === void 0) {
|
|
20178
20380
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20185,19 +20387,19 @@ var FileWatcherService = class {
|
|
|
20185
20387
|
);
|
|
20186
20388
|
return;
|
|
20187
20389
|
}
|
|
20188
|
-
const relPathInRepo =
|
|
20390
|
+
const relPathInRepo = path43.relative(gitRoot, absPath);
|
|
20189
20391
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20190
20392
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20191
20393
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20192
20394
|
log.trace(
|
|
20193
20395
|
"fileWatcher",
|
|
20194
|
-
`${relPathInRepo} ignored by ${
|
|
20396
|
+
`${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20195
20397
|
);
|
|
20196
20398
|
return;
|
|
20197
20399
|
}
|
|
20198
20400
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20199
|
-
const repoPath =
|
|
20200
|
-
const repoName =
|
|
20401
|
+
const repoPath = path43.relative(this.opts.workingDir, gitRoot);
|
|
20402
|
+
const repoName = path43.basename(gitRoot);
|
|
20201
20403
|
let diffText = "";
|
|
20202
20404
|
let fileStatus = "modified";
|
|
20203
20405
|
if (changeType === "unlink") {
|
|
@@ -20372,7 +20574,7 @@ var FileWatcherService = class {
|
|
|
20372
20574
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20373
20575
|
let entries;
|
|
20374
20576
|
try {
|
|
20375
|
-
entries =
|
|
20577
|
+
entries = fs36.readdirSync(dir, { withFileTypes: true });
|
|
20376
20578
|
} catch {
|
|
20377
20579
|
return;
|
|
20378
20580
|
}
|
|
@@ -20381,16 +20583,16 @@ var FileWatcherService = class {
|
|
|
20381
20583
|
);
|
|
20382
20584
|
if (gitignoreEntry) {
|
|
20383
20585
|
try {
|
|
20384
|
-
const body =
|
|
20385
|
-
const rel =
|
|
20586
|
+
const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
|
|
20587
|
+
const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20386
20588
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20387
20589
|
const trimmed = line.trim();
|
|
20388
20590
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20389
20591
|
if (!rel) return line;
|
|
20390
20592
|
if (trimmed.startsWith("!")) {
|
|
20391
|
-
return "!" +
|
|
20593
|
+
return "!" + path43.posix.join(rel, trimmed.slice(1));
|
|
20392
20594
|
}
|
|
20393
|
-
return
|
|
20595
|
+
return path43.posix.join(rel, trimmed);
|
|
20394
20596
|
}).join("\n");
|
|
20395
20597
|
matcher.add(prefixed);
|
|
20396
20598
|
} catch {
|
|
@@ -20399,7 +20601,7 @@ var FileWatcherService = class {
|
|
|
20399
20601
|
for (const entry of entries) {
|
|
20400
20602
|
if (!entry.isDirectory()) continue;
|
|
20401
20603
|
if (entry.name === ".git") continue;
|
|
20402
|
-
const childAbs =
|
|
20604
|
+
const childAbs = path43.join(dir, entry.name);
|
|
20403
20605
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20404
20606
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20405
20607
|
}
|
|
@@ -20569,7 +20771,7 @@ var import_crypto4 = require("crypto");
|
|
|
20569
20771
|
|
|
20570
20772
|
// src/services/turn-files/git-changeset.ts
|
|
20571
20773
|
var import_child_process20 = require("child_process");
|
|
20572
|
-
var
|
|
20774
|
+
var path44 = __toESM(require("path"));
|
|
20573
20775
|
async function collectRepoChangeset(opts) {
|
|
20574
20776
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20575
20777
|
if (status2 === null) return null;
|
|
@@ -20680,7 +20882,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20680
20882
|
});
|
|
20681
20883
|
}
|
|
20682
20884
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20683
|
-
const
|
|
20885
|
+
const fs42 = await import("fs/promises");
|
|
20684
20886
|
const out2 = [];
|
|
20685
20887
|
await walk(workingDir, 0);
|
|
20686
20888
|
return out2;
|
|
@@ -20688,7 +20890,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20688
20890
|
if (depth > maxDepth) return;
|
|
20689
20891
|
let entries = [];
|
|
20690
20892
|
try {
|
|
20691
|
-
const dirents = await
|
|
20893
|
+
const dirents = await fs42.readdir(dir, { withFileTypes: true });
|
|
20692
20894
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20693
20895
|
} catch {
|
|
20694
20896
|
return;
|
|
@@ -20699,8 +20901,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20699
20901
|
if (hasGit) {
|
|
20700
20902
|
out2.push({
|
|
20701
20903
|
repoRoot: dir,
|
|
20702
|
-
repoPath:
|
|
20703
|
-
repoName:
|
|
20904
|
+
repoPath: path44.relative(workingDir, dir),
|
|
20905
|
+
repoName: path44.basename(dir)
|
|
20704
20906
|
});
|
|
20705
20907
|
return;
|
|
20706
20908
|
}
|
|
@@ -20708,14 +20910,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20708
20910
|
if (!entry.isDirectory) continue;
|
|
20709
20911
|
if (entry.name === "node_modules") continue;
|
|
20710
20912
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20711
|
-
await walk(
|
|
20913
|
+
await walk(path44.join(dir, entry.name), depth + 1);
|
|
20712
20914
|
}
|
|
20713
20915
|
}
|
|
20714
20916
|
}
|
|
20715
20917
|
|
|
20716
20918
|
// src/services/turn-files/files-outbox.ts
|
|
20717
|
-
var
|
|
20718
|
-
var
|
|
20919
|
+
var fs37 = __toESM(require("fs/promises"));
|
|
20920
|
+
var path45 = __toESM(require("path"));
|
|
20719
20921
|
var import_os7 = require("os");
|
|
20720
20922
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20721
20923
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20748,16 +20950,16 @@ var FilesOutbox = class {
|
|
|
20748
20950
|
backoffIndex = 0;
|
|
20749
20951
|
stopped = false;
|
|
20750
20952
|
constructor(opts) {
|
|
20751
|
-
const base = opts.baseDir ??
|
|
20752
|
-
this.filePath =
|
|
20953
|
+
const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20954
|
+
this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
|
|
20753
20955
|
this.post = opts.post;
|
|
20754
20956
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20755
20957
|
}
|
|
20756
20958
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20757
20959
|
* line is durable on disk (not once the POST succeeds). */
|
|
20758
20960
|
async enqueue(entry) {
|
|
20759
|
-
await
|
|
20760
|
-
await
|
|
20961
|
+
await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
|
|
20962
|
+
await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20761
20963
|
this.backoffIndex = 0;
|
|
20762
20964
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20763
20965
|
}
|
|
@@ -20846,7 +21048,7 @@ var FilesOutbox = class {
|
|
|
20846
21048
|
async readAll() {
|
|
20847
21049
|
let raw = "";
|
|
20848
21050
|
try {
|
|
20849
|
-
raw = await
|
|
21051
|
+
raw = await fs37.readFile(this.filePath, "utf8");
|
|
20850
21052
|
} catch {
|
|
20851
21053
|
return [];
|
|
20852
21054
|
}
|
|
@@ -20870,12 +21072,12 @@ var FilesOutbox = class {
|
|
|
20870
21072
|
async rewrite(entries) {
|
|
20871
21073
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20872
21074
|
if (entries.length === 0) {
|
|
20873
|
-
await
|
|
21075
|
+
await fs37.unlink(this.filePath).catch(() => void 0);
|
|
20874
21076
|
return;
|
|
20875
21077
|
}
|
|
20876
21078
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20877
|
-
await
|
|
20878
|
-
await
|
|
21079
|
+
await fs37.writeFile(tmpPath, payload, "utf8");
|
|
21080
|
+
await fs37.rename(tmpPath, this.filePath);
|
|
20879
21081
|
}
|
|
20880
21082
|
};
|
|
20881
21083
|
function applyJitter(ms) {
|
|
@@ -21973,10 +22175,10 @@ var ChromeStepTracker = class {
|
|
|
21973
22175
|
const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
|
|
21974
22176
|
if (visible.length === 0) return;
|
|
21975
22177
|
for (const step of visible) {
|
|
21976
|
-
const
|
|
22178
|
+
const exists2 = this.history.some(
|
|
21977
22179
|
(s) => s.tool === step.tool && s.label === step.label
|
|
21978
22180
|
);
|
|
21979
|
-
if (!
|
|
22181
|
+
if (!exists2) this.history.push(step);
|
|
21980
22182
|
}
|
|
21981
22183
|
}
|
|
21982
22184
|
/**
|
|
@@ -22721,8 +22923,8 @@ var OutputService = class _OutputService {
|
|
|
22721
22923
|
};
|
|
22722
22924
|
|
|
22723
22925
|
// src/services/history.service.ts
|
|
22724
|
-
var
|
|
22725
|
-
var
|
|
22926
|
+
var fs38 = __toESM(require("fs"));
|
|
22927
|
+
var path46 = __toESM(require("path"));
|
|
22726
22928
|
var os29 = __toESM(require("os"));
|
|
22727
22929
|
var https7 = __toESM(require("https"));
|
|
22728
22930
|
var http7 = __toESM(require("http"));
|
|
@@ -22750,7 +22952,7 @@ function parseJsonl(filePath) {
|
|
|
22750
22952
|
const messages = [];
|
|
22751
22953
|
let raw;
|
|
22752
22954
|
try {
|
|
22753
|
-
raw =
|
|
22955
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22754
22956
|
} catch (err) {
|
|
22755
22957
|
if (err.code !== "ENOENT") {
|
|
22756
22958
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22885,7 +23087,7 @@ var HistoryService = class _HistoryService {
|
|
|
22885
23087
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22886
23088
|
}
|
|
22887
23089
|
get projectDir() {
|
|
22888
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23090
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22889
23091
|
}
|
|
22890
23092
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22891
23093
|
setCurrentConversationId(id) {
|
|
@@ -22897,7 +23099,7 @@ var HistoryService = class _HistoryService {
|
|
|
22897
23099
|
/** Return the current message count in the active conversation. */
|
|
22898
23100
|
getCurrentMessageCount() {
|
|
22899
23101
|
if (!this.currentConversationId) return 0;
|
|
22900
|
-
const filePath =
|
|
23102
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22901
23103
|
return parseJsonl(filePath).length;
|
|
22902
23104
|
}
|
|
22903
23105
|
/**
|
|
@@ -22908,7 +23110,7 @@ var HistoryService = class _HistoryService {
|
|
|
22908
23110
|
const deadline = Date.now() + timeoutMs;
|
|
22909
23111
|
while (Date.now() < deadline) {
|
|
22910
23112
|
if (!this.currentConversationId) return null;
|
|
22911
|
-
const filePath =
|
|
23113
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22912
23114
|
const messages = parseJsonl(filePath);
|
|
22913
23115
|
if (messages.length > previousCount) {
|
|
22914
23116
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22934,16 +23136,16 @@ var HistoryService = class _HistoryService {
|
|
|
22934
23136
|
const dir = this.projectDir;
|
|
22935
23137
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22936
23138
|
try {
|
|
22937
|
-
const files =
|
|
23139
|
+
const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22938
23140
|
try {
|
|
22939
|
-
const stat3 =
|
|
23141
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22940
23142
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22941
23143
|
} catch {
|
|
22942
23144
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22943
23145
|
}
|
|
22944
23146
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22945
23147
|
if (files.length > 0) {
|
|
22946
|
-
this.currentConversationId =
|
|
23148
|
+
this.currentConversationId = path46.basename(files[0].name, ".jsonl");
|
|
22947
23149
|
}
|
|
22948
23150
|
} catch {
|
|
22949
23151
|
}
|
|
@@ -22977,13 +23179,13 @@ var HistoryService = class _HistoryService {
|
|
|
22977
23179
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22978
23180
|
let entries;
|
|
22979
23181
|
try {
|
|
22980
|
-
entries =
|
|
23182
|
+
entries = fs38.readdirSync(dir, { withFileTypes: true });
|
|
22981
23183
|
} catch {
|
|
22982
23184
|
return null;
|
|
22983
23185
|
}
|
|
22984
23186
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22985
23187
|
try {
|
|
22986
|
-
const stat3 =
|
|
23188
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22987
23189
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22988
23190
|
} catch {
|
|
22989
23191
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22992,12 +23194,12 @@ var HistoryService = class _HistoryService {
|
|
|
22992
23194
|
if (files.length === 0) return null;
|
|
22993
23195
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22994
23196
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22995
|
-
return this.extractUsageFromFile(
|
|
23197
|
+
return this.extractUsageFromFile(path46.join(dir, targetFile));
|
|
22996
23198
|
}
|
|
22997
23199
|
extractUsageFromFile(filePath) {
|
|
22998
23200
|
let raw;
|
|
22999
23201
|
try {
|
|
23000
|
-
raw =
|
|
23202
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
23001
23203
|
} catch {
|
|
23002
23204
|
return null;
|
|
23003
23205
|
}
|
|
@@ -23042,9 +23244,9 @@ var HistoryService = class _HistoryService {
|
|
|
23042
23244
|
let totalCost = 0;
|
|
23043
23245
|
let files;
|
|
23044
23246
|
try {
|
|
23045
|
-
files =
|
|
23247
|
+
files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23046
23248
|
try {
|
|
23047
|
-
return
|
|
23249
|
+
return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23048
23250
|
} catch {
|
|
23049
23251
|
return false;
|
|
23050
23252
|
}
|
|
@@ -23055,7 +23257,7 @@ var HistoryService = class _HistoryService {
|
|
|
23055
23257
|
for (const file of files) {
|
|
23056
23258
|
let raw;
|
|
23057
23259
|
try {
|
|
23058
|
-
raw =
|
|
23260
|
+
raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
|
|
23059
23261
|
} catch {
|
|
23060
23262
|
continue;
|
|
23061
23263
|
}
|
|
@@ -23119,7 +23321,7 @@ var HistoryService = class _HistoryService {
|
|
|
23119
23321
|
* showing an empty conversation.
|
|
23120
23322
|
*/
|
|
23121
23323
|
async loadConversation(sessionId) {
|
|
23122
|
-
const filePath =
|
|
23324
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23123
23325
|
const messages = parseJsonl(filePath);
|
|
23124
23326
|
if (messages.length === 0) return;
|
|
23125
23327
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23173,7 +23375,7 @@ var HistoryService = class _HistoryService {
|
|
|
23173
23375
|
if (!this.currentConversationId) return 0;
|
|
23174
23376
|
}
|
|
23175
23377
|
const sessionId = this.currentConversationId;
|
|
23176
|
-
const filePath =
|
|
23378
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23177
23379
|
const messages = parseJsonl(filePath);
|
|
23178
23380
|
if (messages.length === 0) return 0;
|
|
23179
23381
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -23709,17 +23911,21 @@ async function start(requestedAgent) {
|
|
|
23709
23911
|
beads = started;
|
|
23710
23912
|
return started;
|
|
23711
23913
|
});
|
|
23914
|
+
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
23712
23915
|
if (process.env.CODESPACES === "true") {
|
|
23713
|
-
const
|
|
23916
|
+
const GATE_TIMEOUT_MS = 24e4;
|
|
23714
23917
|
let gateTimer;
|
|
23715
23918
|
await Promise.race([
|
|
23716
|
-
beadsReady.catch(() => null),
|
|
23919
|
+
Promise.all([beadsReady.catch(() => null), depsReady]),
|
|
23717
23920
|
new Promise((resolve7) => {
|
|
23718
|
-
gateTimer = setTimeout(resolve7,
|
|
23921
|
+
gateTimer = setTimeout(resolve7, GATE_TIMEOUT_MS);
|
|
23719
23922
|
})
|
|
23720
23923
|
]);
|
|
23721
23924
|
if (gateTimer) clearTimeout(gateTimer);
|
|
23722
|
-
log.info(
|
|
23925
|
+
log.info(
|
|
23926
|
+
"beads",
|
|
23927
|
+
`agent-spawn gate released \u2014 beads ${beads ? "ready" : "pending"}; project deps provisioned`
|
|
23928
|
+
);
|
|
23723
23929
|
}
|
|
23724
23930
|
const acpDisabled = process.env.CODEAM_ACP_DISABLED === "1";
|
|
23725
23931
|
if (!acpDisabled && session.pluginAuthToken) {
|
|
@@ -24106,9 +24312,9 @@ async function autoLinkAfterPair(opts) {
|
|
|
24106
24312
|
}
|
|
24107
24313
|
|
|
24108
24314
|
// src/commands/pair-auto.ts
|
|
24109
|
-
var
|
|
24315
|
+
var fs39 = __toESM(require("fs"));
|
|
24110
24316
|
var os30 = __toESM(require("os"));
|
|
24111
|
-
var
|
|
24317
|
+
var path47 = __toESM(require("path"));
|
|
24112
24318
|
var import_crypto7 = require("crypto");
|
|
24113
24319
|
|
|
24114
24320
|
// src/commands/start-infra-only.ts
|
|
@@ -24303,12 +24509,12 @@ function readTokenFromArgs(args2) {
|
|
|
24303
24509
|
}
|
|
24304
24510
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24305
24511
|
if (fileFlag) {
|
|
24306
|
-
const
|
|
24512
|
+
const path54 = fileFlag.slice("--token-file=".length);
|
|
24307
24513
|
try {
|
|
24308
|
-
const content =
|
|
24309
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24514
|
+
const content = fs39.readFileSync(path54, "utf8").trim();
|
|
24515
|
+
if (content.length === 0) fail(`--token-file ${path54} is empty`);
|
|
24310
24516
|
try {
|
|
24311
|
-
|
|
24517
|
+
fs39.unlinkSync(path54);
|
|
24312
24518
|
} catch {
|
|
24313
24519
|
}
|
|
24314
24520
|
return content;
|
|
@@ -24391,7 +24597,7 @@ async function claim(token, pluginId) {
|
|
|
24391
24597
|
}
|
|
24392
24598
|
}
|
|
24393
24599
|
function pairAutoLockPath() {
|
|
24394
|
-
return
|
|
24600
|
+
return path47.join(os30.homedir(), ".codeam", "pair-auto.lock");
|
|
24395
24601
|
}
|
|
24396
24602
|
function isLivePairAuto(pid) {
|
|
24397
24603
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -24401,7 +24607,7 @@ function isLivePairAuto(pid) {
|
|
|
24401
24607
|
if (e.code !== "EPERM") return false;
|
|
24402
24608
|
}
|
|
24403
24609
|
try {
|
|
24404
|
-
return
|
|
24610
|
+
return fs39.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
24405
24611
|
} catch {
|
|
24406
24612
|
return true;
|
|
24407
24613
|
}
|
|
@@ -24409,19 +24615,19 @@ function isLivePairAuto(pid) {
|
|
|
24409
24615
|
function acquireSingletonLock() {
|
|
24410
24616
|
const lockPath = pairAutoLockPath();
|
|
24411
24617
|
try {
|
|
24412
|
-
|
|
24618
|
+
fs39.mkdirSync(path47.dirname(lockPath), { recursive: true });
|
|
24413
24619
|
try {
|
|
24414
|
-
|
|
24620
|
+
fs39.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
24415
24621
|
} catch (e) {
|
|
24416
24622
|
if (e.code !== "EEXIST") throw e;
|
|
24417
|
-
const holder = Number(
|
|
24623
|
+
const holder = Number(fs39.readFileSync(lockPath, "utf8").trim());
|
|
24418
24624
|
if (isLivePairAuto(holder)) return false;
|
|
24419
|
-
|
|
24625
|
+
fs39.writeFileSync(lockPath, String(process.pid));
|
|
24420
24626
|
}
|
|
24421
24627
|
process.once("exit", () => {
|
|
24422
24628
|
try {
|
|
24423
|
-
if (
|
|
24424
|
-
|
|
24629
|
+
if (fs39.existsSync(lockPath) && Number(fs39.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24630
|
+
fs39.unlinkSync(lockPath);
|
|
24425
24631
|
}
|
|
24426
24632
|
} catch {
|
|
24427
24633
|
}
|
|
@@ -24620,7 +24826,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24620
24826
|
var import_child_process22 = require("child_process");
|
|
24621
24827
|
var import_util4 = require("util");
|
|
24622
24828
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24623
|
-
var
|
|
24829
|
+
var path48 = __toESM(require("path"));
|
|
24624
24830
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24625
24831
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24626
24832
|
function resetStdinForChild() {
|
|
@@ -25109,7 +25315,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25109
25315
|
});
|
|
25110
25316
|
}
|
|
25111
25317
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25112
|
-
const remoteDir =
|
|
25318
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25113
25319
|
const parts = [
|
|
25114
25320
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25115
25321
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25179,7 +25385,7 @@ function shellQuote(s) {
|
|
|
25179
25385
|
// src/services/providers/gitpod.ts
|
|
25180
25386
|
var import_child_process23 = require("child_process");
|
|
25181
25387
|
var import_util5 = require("util");
|
|
25182
|
-
var
|
|
25388
|
+
var path49 = __toESM(require("path"));
|
|
25183
25389
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25184
25390
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25185
25391
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25419,7 +25625,7 @@ var GitpodProvider = class {
|
|
|
25419
25625
|
});
|
|
25420
25626
|
}
|
|
25421
25627
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25422
|
-
const remoteDir =
|
|
25628
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25423
25629
|
const parts = [
|
|
25424
25630
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25425
25631
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25455,7 +25661,7 @@ function shellQuote2(s) {
|
|
|
25455
25661
|
// src/services/providers/gitlab-workspaces.ts
|
|
25456
25662
|
var import_child_process24 = require("child_process");
|
|
25457
25663
|
var import_util6 = require("util");
|
|
25458
|
-
var
|
|
25664
|
+
var path50 = __toESM(require("path"));
|
|
25459
25665
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25460
25666
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25461
25667
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25715,7 +25921,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25715
25921
|
}
|
|
25716
25922
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25717
25923
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25718
|
-
const remoteDir =
|
|
25924
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25719
25925
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25720
25926
|
if (options.mode != null) {
|
|
25721
25927
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25783,7 +25989,7 @@ function shellQuote3(s) {
|
|
|
25783
25989
|
// src/services/providers/railway.ts
|
|
25784
25990
|
var import_child_process25 = require("child_process");
|
|
25785
25991
|
var import_util7 = require("util");
|
|
25786
|
-
var
|
|
25992
|
+
var path51 = __toESM(require("path"));
|
|
25787
25993
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25788
25994
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25789
25995
|
function resetStdinForChild4() {
|
|
@@ -26019,7 +26225,7 @@ var RailwayProvider = class {
|
|
|
26019
26225
|
if (!projectId || !serviceId) {
|
|
26020
26226
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
26021
26227
|
}
|
|
26022
|
-
const remoteDir =
|
|
26228
|
+
const remoteDir = path51.posix.dirname(remotePath);
|
|
26023
26229
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
26024
26230
|
if (options.mode != null) {
|
|
26025
26231
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26562,8 +26768,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26562
26768
|
var import_node_dns = require("dns");
|
|
26563
26769
|
var import_node_util4 = require("util");
|
|
26564
26770
|
var import_node_crypto8 = require("crypto");
|
|
26565
|
-
var
|
|
26566
|
-
var
|
|
26771
|
+
var fs40 = __toESM(require("fs"));
|
|
26772
|
+
var path52 = __toESM(require("path"));
|
|
26567
26773
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26568
26774
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26569
26775
|
async function checkDns(apiBase) {
|
|
@@ -26619,13 +26825,13 @@ async function checkHealth(apiBase) {
|
|
|
26619
26825
|
}
|
|
26620
26826
|
}
|
|
26621
26827
|
function checkConfigDir() {
|
|
26622
|
-
const dir =
|
|
26828
|
+
const dir = path52.join(require("os").homedir(), ".codeam");
|
|
26623
26829
|
try {
|
|
26624
|
-
|
|
26625
|
-
const probe =
|
|
26626
|
-
|
|
26627
|
-
const read =
|
|
26628
|
-
|
|
26830
|
+
fs40.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26831
|
+
const probe = path52.join(dir, ".doctor-probe");
|
|
26832
|
+
fs40.writeFileSync(probe, "ok", { mode: 384 });
|
|
26833
|
+
const read = fs40.readFileSync(probe, "utf8");
|
|
26834
|
+
fs40.unlinkSync(probe);
|
|
26629
26835
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26630
26836
|
return {
|
|
26631
26837
|
id: "config-dir",
|
|
@@ -26689,7 +26895,7 @@ function checkNodePty() {
|
|
|
26689
26895
|
detail: "not required on this platform"
|
|
26690
26896
|
};
|
|
26691
26897
|
}
|
|
26692
|
-
const vendoredPath =
|
|
26898
|
+
const vendoredPath = path52.join(__dirname, "vendor", "node-pty");
|
|
26693
26899
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26694
26900
|
try {
|
|
26695
26901
|
require(target);
|
|
@@ -26731,7 +26937,7 @@ function checkChokidar() {
|
|
|
26731
26937
|
}
|
|
26732
26938
|
async function doctor(args2 = []) {
|
|
26733
26939
|
const json = args2.includes("--json");
|
|
26734
|
-
const cliVersion = true ? "2.39.
|
|
26940
|
+
const cliVersion = true ? "2.39.9" : "0.0.0-dev";
|
|
26735
26941
|
const apiBase = resolveApiBaseUrl();
|
|
26736
26942
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26737
26943
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26930,7 +27136,7 @@ async function completion(args2) {
|
|
|
26930
27136
|
// src/commands/version.ts
|
|
26931
27137
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26932
27138
|
function version2() {
|
|
26933
|
-
const v = true ? "2.39.
|
|
27139
|
+
const v = true ? "2.39.9" : "unknown";
|
|
26934
27140
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26935
27141
|
}
|
|
26936
27142
|
|
|
@@ -27058,9 +27264,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
27058
27264
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
27059
27265
|
|
|
27060
27266
|
// src/lib/updateNotifier.ts
|
|
27061
|
-
var
|
|
27267
|
+
var fs41 = __toESM(require("fs"));
|
|
27062
27268
|
var os31 = __toESM(require("os"));
|
|
27063
|
-
var
|
|
27269
|
+
var path53 = __toESM(require("path"));
|
|
27064
27270
|
var https8 = __toESM(require("https"));
|
|
27065
27271
|
var import_node_child_process12 = require("child_process");
|
|
27066
27272
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -27069,12 +27275,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27069
27275
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27070
27276
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27071
27277
|
function cachePath() {
|
|
27072
|
-
const dir =
|
|
27073
|
-
return
|
|
27278
|
+
const dir = path53.join(os31.homedir(), ".codeam");
|
|
27279
|
+
return path53.join(dir, "update-check.json");
|
|
27074
27280
|
}
|
|
27075
27281
|
function readCache() {
|
|
27076
27282
|
try {
|
|
27077
|
-
const raw =
|
|
27283
|
+
const raw = fs41.readFileSync(cachePath(), "utf8");
|
|
27078
27284
|
const parsed = JSON.parse(raw);
|
|
27079
27285
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
27080
27286
|
return parsed;
|
|
@@ -27085,10 +27291,10 @@ function readCache() {
|
|
|
27085
27291
|
function writeCache(cache) {
|
|
27086
27292
|
try {
|
|
27087
27293
|
const file = cachePath();
|
|
27088
|
-
|
|
27294
|
+
fs41.mkdirSync(path53.dirname(file), { recursive: true });
|
|
27089
27295
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27090
|
-
|
|
27091
|
-
|
|
27296
|
+
fs41.writeFileSync(tmp, JSON.stringify(cache));
|
|
27297
|
+
fs41.renameSync(tmp, file);
|
|
27092
27298
|
} catch {
|
|
27093
27299
|
}
|
|
27094
27300
|
}
|
|
@@ -27162,8 +27368,8 @@ function isLinkedInstall() {
|
|
|
27162
27368
|
timeout: 2e3
|
|
27163
27369
|
}).trim();
|
|
27164
27370
|
if (!root) return false;
|
|
27165
|
-
const pkgPath =
|
|
27166
|
-
return
|
|
27371
|
+
const pkgPath = path53.join(root, PKG_NAME);
|
|
27372
|
+
return fs41.lstatSync(pkgPath).isSymbolicLink();
|
|
27167
27373
|
} catch {
|
|
27168
27374
|
return false;
|
|
27169
27375
|
}
|
|
@@ -27199,7 +27405,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27199
27405
|
return;
|
|
27200
27406
|
}
|
|
27201
27407
|
try {
|
|
27202
|
-
|
|
27408
|
+
fs41.unlinkSync(cachePath());
|
|
27203
27409
|
} catch {
|
|
27204
27410
|
}
|
|
27205
27411
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27216,7 +27422,7 @@ function checkForUpdates() {
|
|
|
27216
27422
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27217
27423
|
if (process.env.CI) return;
|
|
27218
27424
|
if (!process.stdout.isTTY) return;
|
|
27219
|
-
const current = true ? "2.39.
|
|
27425
|
+
const current = true ? "2.39.9" : null;
|
|
27220
27426
|
if (!current) return;
|
|
27221
27427
|
const cache = readCache();
|
|
27222
27428
|
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.9",
|
|
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",
|