codeam-cli 2.37.3 → 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 +17 -0
- package/dist/index.js +410 -156
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ 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
|
+
|
|
18
|
+
## [2.37.3] — 2026-06-11
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **cli:** Force full https:// URLs in onboarding welcome so both render as links
|
|
23
|
+
|
|
7
24
|
## [2.37.2] — 2026-06-11
|
|
8
25
|
|
|
9
26
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.
|
|
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;
|
|
@@ -18508,6 +18708,45 @@ var BeadsWatcher = class {
|
|
|
18508
18708
|
}
|
|
18509
18709
|
};
|
|
18510
18710
|
|
|
18711
|
+
// src/beads/inherit-team-memories.ts
|
|
18712
|
+
async function inheritTeamMemories(opts) {
|
|
18713
|
+
const apiBase = opts.apiBaseUrl ?? resolveApiBaseUrl();
|
|
18714
|
+
let memories = [];
|
|
18715
|
+
try {
|
|
18716
|
+
const res = await _transport3.post(
|
|
18717
|
+
`${apiBase}/api/beads/team-memories`,
|
|
18718
|
+
{
|
|
18719
|
+
"Content-Type": "application/json",
|
|
18720
|
+
"X-Codeam-Protocol-Version": "2.0.0",
|
|
18721
|
+
"X-Plugin-Auth-Token": opts.pluginAuthToken
|
|
18722
|
+
},
|
|
18723
|
+
JSON.stringify({ sessionId: opts.sessionId, pluginId: opts.pluginId })
|
|
18724
|
+
);
|
|
18725
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
18726
|
+
log.trace("beads", `team-memories fetch status=${res.statusCode}`);
|
|
18727
|
+
return;
|
|
18728
|
+
}
|
|
18729
|
+
const parsed = JSON.parse(res.body);
|
|
18730
|
+
memories = Array.isArray(parsed.data?.memories) ? parsed.data.memories : [];
|
|
18731
|
+
} catch (err) {
|
|
18732
|
+
log.warn("beads", "team-memories fetch failed (non-fatal)", err);
|
|
18733
|
+
return;
|
|
18734
|
+
}
|
|
18735
|
+
if (memories.length === 0) return;
|
|
18736
|
+
let written = 0;
|
|
18737
|
+
for (const m of memories) {
|
|
18738
|
+
const body = (m?.body ?? "").trim();
|
|
18739
|
+
if (!m?.id || !body) continue;
|
|
18740
|
+
try {
|
|
18741
|
+
await opts.adapter.run(["remember", "--key", `team-${m.id}`, `Team convention (read-only): ${body}`]);
|
|
18742
|
+
written++;
|
|
18743
|
+
} catch (err) {
|
|
18744
|
+
log.trace("beads", `team memory write failed id=${m.id}: ${err.message}`);
|
|
18745
|
+
}
|
|
18746
|
+
}
|
|
18747
|
+
log.info("beads", `inherited ${written}/${memories.length} team memory(ies) into the active repo`);
|
|
18748
|
+
}
|
|
18749
|
+
|
|
18511
18750
|
// src/beads/apply-actions.ts
|
|
18512
18751
|
function buildBdArgs(action) {
|
|
18513
18752
|
switch (action.kind) {
|
|
@@ -18577,6 +18816,12 @@ async function startBeads(opts) {
|
|
|
18577
18816
|
});
|
|
18578
18817
|
watcher.start();
|
|
18579
18818
|
void watcher.syncNow();
|
|
18819
|
+
void inheritTeamMemories({
|
|
18820
|
+
sessionId: opts.sessionId,
|
|
18821
|
+
pluginId: opts.pluginId,
|
|
18822
|
+
pluginAuthToken: opts.pluginAuthToken,
|
|
18823
|
+
adapter
|
|
18824
|
+
});
|
|
18580
18825
|
return { watcher, adapter };
|
|
18581
18826
|
}
|
|
18582
18827
|
async function handleBeadsActionCommand(action, started) {
|
|
@@ -18661,7 +18906,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18661
18906
|
function cleanupAttachmentTempFiles() {
|
|
18662
18907
|
for (const p2 of pendingAttachmentFiles) {
|
|
18663
18908
|
try {
|
|
18664
|
-
|
|
18909
|
+
fs35.unlinkSync(p2);
|
|
18665
18910
|
} catch {
|
|
18666
18911
|
}
|
|
18667
18912
|
}
|
|
@@ -18670,8 +18915,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18670
18915
|
function saveFilesTemp(files) {
|
|
18671
18916
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18672
18917
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18673
|
-
const tmpPath =
|
|
18674
|
-
|
|
18918
|
+
const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18919
|
+
fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18675
18920
|
pendingAttachmentFiles.add(tmpPath);
|
|
18676
18921
|
return tmpPath;
|
|
18677
18922
|
});
|
|
@@ -18691,7 +18936,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18691
18936
|
setTimeout(() => {
|
|
18692
18937
|
for (const p2 of paths) {
|
|
18693
18938
|
try {
|
|
18694
|
-
|
|
18939
|
+
fs35.unlinkSync(p2);
|
|
18695
18940
|
} catch {
|
|
18696
18941
|
}
|
|
18697
18942
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19274,8 +19519,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19274
19519
|
if (args2.length === 0) return detection;
|
|
19275
19520
|
const binName = args2[0];
|
|
19276
19521
|
if (binName.startsWith("-")) return detection;
|
|
19277
|
-
const binPath =
|
|
19278
|
-
if (!
|
|
19522
|
+
const binPath = path42.join(cwd, "node_modules", ".bin", binName);
|
|
19523
|
+
if (!fs35.existsSync(binPath)) return detection;
|
|
19279
19524
|
return {
|
|
19280
19525
|
...detection,
|
|
19281
19526
|
command: binPath,
|
|
@@ -19409,11 +19654,13 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19409
19654
|
emitProgress("BIND_PORT", String(detection.port));
|
|
19410
19655
|
emitProgress("WAITING_FOR_READY", detection.ready_pattern);
|
|
19411
19656
|
let expoUrl = null;
|
|
19657
|
+
let outputTail = "";
|
|
19412
19658
|
const readyRe = compileReadyPattern(detection.ready_pattern);
|
|
19413
19659
|
const isNextJs = /next/i.test(detection.framework);
|
|
19414
19660
|
const outcome = await waitForDevServerReady(devServer, readyRe, {
|
|
19415
19661
|
timeoutMs: 12e4,
|
|
19416
19662
|
onChunk: (s) => {
|
|
19663
|
+
outputTail = (outputTail + s).slice(-4e3);
|
|
19417
19664
|
if (!expoUrl && detection.framework === "Expo") {
|
|
19418
19665
|
expoUrl = parseExpoUrl(s);
|
|
19419
19666
|
}
|
|
@@ -19428,7 +19675,8 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19428
19675
|
type: "preview_error",
|
|
19429
19676
|
payload: {
|
|
19430
19677
|
stage: "spawn",
|
|
19431
|
-
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)
|
|
19432
19680
|
}
|
|
19433
19681
|
});
|
|
19434
19682
|
return;
|
|
@@ -19443,7 +19691,11 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19443
19691
|
pluginId: ctx.pluginId,
|
|
19444
19692
|
pluginAuthToken,
|
|
19445
19693
|
type: "preview_error",
|
|
19446
|
-
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
|
+
}
|
|
19447
19699
|
});
|
|
19448
19700
|
return;
|
|
19449
19701
|
}
|
|
@@ -19705,9 +19957,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19705
19957
|
|
|
19706
19958
|
// src/services/file-watcher.service.ts
|
|
19707
19959
|
var import_child_process19 = require("child_process");
|
|
19708
|
-
var
|
|
19960
|
+
var fs36 = __toESM(require("fs"));
|
|
19709
19961
|
var os28 = __toESM(require("os"));
|
|
19710
|
-
var
|
|
19962
|
+
var path43 = __toESM(require("path"));
|
|
19711
19963
|
var import_ignore = __toESM(require("ignore"));
|
|
19712
19964
|
|
|
19713
19965
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19850,18 +20102,18 @@ var _findGitRootSeam = {
|
|
|
19850
20102
|
resolve: _defaultFindGitRoot
|
|
19851
20103
|
};
|
|
19852
20104
|
function _defaultFindGitRoot(startDir) {
|
|
19853
|
-
let dir =
|
|
20105
|
+
let dir = path43.resolve(startDir);
|
|
19854
20106
|
const seen = /* @__PURE__ */ new Set();
|
|
19855
20107
|
for (let i = 0; i < 256; i++) {
|
|
19856
20108
|
if (seen.has(dir)) return null;
|
|
19857
20109
|
seen.add(dir);
|
|
19858
20110
|
try {
|
|
19859
|
-
const gitPath =
|
|
19860
|
-
const stat3 =
|
|
20111
|
+
const gitPath = path43.join(dir, ".git");
|
|
20112
|
+
const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
|
|
19861
20113
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19862
20114
|
} catch {
|
|
19863
20115
|
}
|
|
19864
|
-
const parent =
|
|
20116
|
+
const parent = path43.dirname(dir);
|
|
19865
20117
|
if (parent === dir) return null;
|
|
19866
20118
|
dir = parent;
|
|
19867
20119
|
}
|
|
@@ -20106,7 +20358,7 @@ var FileWatcherService = class {
|
|
|
20106
20358
|
}
|
|
20107
20359
|
async emitForFile(absPath, changeType) {
|
|
20108
20360
|
if (this.stopped) return;
|
|
20109
|
-
const fileDir =
|
|
20361
|
+
const fileDir = path43.dirname(absPath);
|
|
20110
20362
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20111
20363
|
if (gitRoot === void 0) {
|
|
20112
20364
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20119,19 +20371,19 @@ var FileWatcherService = class {
|
|
|
20119
20371
|
);
|
|
20120
20372
|
return;
|
|
20121
20373
|
}
|
|
20122
|
-
const relPathInRepo =
|
|
20374
|
+
const relPathInRepo = path43.relative(gitRoot, absPath);
|
|
20123
20375
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20124
20376
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20125
20377
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20126
20378
|
log.trace(
|
|
20127
20379
|
"fileWatcher",
|
|
20128
|
-
`${relPathInRepo} ignored by ${
|
|
20380
|
+
`${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20129
20381
|
);
|
|
20130
20382
|
return;
|
|
20131
20383
|
}
|
|
20132
20384
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20133
|
-
const repoPath =
|
|
20134
|
-
const repoName =
|
|
20385
|
+
const repoPath = path43.relative(this.opts.workingDir, gitRoot);
|
|
20386
|
+
const repoName = path43.basename(gitRoot);
|
|
20135
20387
|
let diffText = "";
|
|
20136
20388
|
let fileStatus = "modified";
|
|
20137
20389
|
if (changeType === "unlink") {
|
|
@@ -20306,7 +20558,7 @@ var FileWatcherService = class {
|
|
|
20306
20558
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20307
20559
|
let entries;
|
|
20308
20560
|
try {
|
|
20309
|
-
entries =
|
|
20561
|
+
entries = fs36.readdirSync(dir, { withFileTypes: true });
|
|
20310
20562
|
} catch {
|
|
20311
20563
|
return;
|
|
20312
20564
|
}
|
|
@@ -20315,16 +20567,16 @@ var FileWatcherService = class {
|
|
|
20315
20567
|
);
|
|
20316
20568
|
if (gitignoreEntry) {
|
|
20317
20569
|
try {
|
|
20318
|
-
const body =
|
|
20319
|
-
const rel =
|
|
20570
|
+
const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
|
|
20571
|
+
const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20320
20572
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20321
20573
|
const trimmed = line.trim();
|
|
20322
20574
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20323
20575
|
if (!rel) return line;
|
|
20324
20576
|
if (trimmed.startsWith("!")) {
|
|
20325
|
-
return "!" +
|
|
20577
|
+
return "!" + path43.posix.join(rel, trimmed.slice(1));
|
|
20326
20578
|
}
|
|
20327
|
-
return
|
|
20579
|
+
return path43.posix.join(rel, trimmed);
|
|
20328
20580
|
}).join("\n");
|
|
20329
20581
|
matcher.add(prefixed);
|
|
20330
20582
|
} catch {
|
|
@@ -20333,7 +20585,7 @@ var FileWatcherService = class {
|
|
|
20333
20585
|
for (const entry of entries) {
|
|
20334
20586
|
if (!entry.isDirectory()) continue;
|
|
20335
20587
|
if (entry.name === ".git") continue;
|
|
20336
|
-
const childAbs =
|
|
20588
|
+
const childAbs = path43.join(dir, entry.name);
|
|
20337
20589
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20338
20590
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20339
20591
|
}
|
|
@@ -20503,7 +20755,7 @@ var import_crypto4 = require("crypto");
|
|
|
20503
20755
|
|
|
20504
20756
|
// src/services/turn-files/git-changeset.ts
|
|
20505
20757
|
var import_child_process20 = require("child_process");
|
|
20506
|
-
var
|
|
20758
|
+
var path44 = __toESM(require("path"));
|
|
20507
20759
|
async function collectRepoChangeset(opts) {
|
|
20508
20760
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20509
20761
|
if (status2 === null) return null;
|
|
@@ -20614,7 +20866,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20614
20866
|
});
|
|
20615
20867
|
}
|
|
20616
20868
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20617
|
-
const
|
|
20869
|
+
const fs42 = await import("fs/promises");
|
|
20618
20870
|
const out2 = [];
|
|
20619
20871
|
await walk(workingDir, 0);
|
|
20620
20872
|
return out2;
|
|
@@ -20622,7 +20874,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20622
20874
|
if (depth > maxDepth) return;
|
|
20623
20875
|
let entries = [];
|
|
20624
20876
|
try {
|
|
20625
|
-
const dirents = await
|
|
20877
|
+
const dirents = await fs42.readdir(dir, { withFileTypes: true });
|
|
20626
20878
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20627
20879
|
} catch {
|
|
20628
20880
|
return;
|
|
@@ -20633,8 +20885,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20633
20885
|
if (hasGit) {
|
|
20634
20886
|
out2.push({
|
|
20635
20887
|
repoRoot: dir,
|
|
20636
|
-
repoPath:
|
|
20637
|
-
repoName:
|
|
20888
|
+
repoPath: path44.relative(workingDir, dir),
|
|
20889
|
+
repoName: path44.basename(dir)
|
|
20638
20890
|
});
|
|
20639
20891
|
return;
|
|
20640
20892
|
}
|
|
@@ -20642,14 +20894,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20642
20894
|
if (!entry.isDirectory) continue;
|
|
20643
20895
|
if (entry.name === "node_modules") continue;
|
|
20644
20896
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20645
|
-
await walk(
|
|
20897
|
+
await walk(path44.join(dir, entry.name), depth + 1);
|
|
20646
20898
|
}
|
|
20647
20899
|
}
|
|
20648
20900
|
}
|
|
20649
20901
|
|
|
20650
20902
|
// src/services/turn-files/files-outbox.ts
|
|
20651
|
-
var
|
|
20652
|
-
var
|
|
20903
|
+
var fs37 = __toESM(require("fs/promises"));
|
|
20904
|
+
var path45 = __toESM(require("path"));
|
|
20653
20905
|
var import_os7 = require("os");
|
|
20654
20906
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20655
20907
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20682,16 +20934,16 @@ var FilesOutbox = class {
|
|
|
20682
20934
|
backoffIndex = 0;
|
|
20683
20935
|
stopped = false;
|
|
20684
20936
|
constructor(opts) {
|
|
20685
|
-
const base = opts.baseDir ??
|
|
20686
|
-
this.filePath =
|
|
20937
|
+
const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20938
|
+
this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
|
|
20687
20939
|
this.post = opts.post;
|
|
20688
20940
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20689
20941
|
}
|
|
20690
20942
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20691
20943
|
* line is durable on disk (not once the POST succeeds). */
|
|
20692
20944
|
async enqueue(entry) {
|
|
20693
|
-
await
|
|
20694
|
-
await
|
|
20945
|
+
await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
|
|
20946
|
+
await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20695
20947
|
this.backoffIndex = 0;
|
|
20696
20948
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20697
20949
|
}
|
|
@@ -20780,7 +21032,7 @@ var FilesOutbox = class {
|
|
|
20780
21032
|
async readAll() {
|
|
20781
21033
|
let raw = "";
|
|
20782
21034
|
try {
|
|
20783
|
-
raw = await
|
|
21035
|
+
raw = await fs37.readFile(this.filePath, "utf8");
|
|
20784
21036
|
} catch {
|
|
20785
21037
|
return [];
|
|
20786
21038
|
}
|
|
@@ -20804,12 +21056,12 @@ var FilesOutbox = class {
|
|
|
20804
21056
|
async rewrite(entries) {
|
|
20805
21057
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20806
21058
|
if (entries.length === 0) {
|
|
20807
|
-
await
|
|
21059
|
+
await fs37.unlink(this.filePath).catch(() => void 0);
|
|
20808
21060
|
return;
|
|
20809
21061
|
}
|
|
20810
21062
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20811
|
-
await
|
|
20812
|
-
await
|
|
21063
|
+
await fs37.writeFile(tmpPath, payload, "utf8");
|
|
21064
|
+
await fs37.rename(tmpPath, this.filePath);
|
|
20813
21065
|
}
|
|
20814
21066
|
};
|
|
20815
21067
|
function applyJitter(ms) {
|
|
@@ -21906,10 +22158,10 @@ var ChromeStepTracker = class {
|
|
|
21906
22158
|
const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
|
|
21907
22159
|
if (visible.length === 0) return;
|
|
21908
22160
|
for (const step of visible) {
|
|
21909
|
-
const
|
|
22161
|
+
const exists2 = this.history.some(
|
|
21910
22162
|
(s) => s.tool === step.tool && s.label === step.label
|
|
21911
22163
|
);
|
|
21912
|
-
if (!
|
|
22164
|
+
if (!exists2) this.history.push(step);
|
|
21913
22165
|
}
|
|
21914
22166
|
}
|
|
21915
22167
|
/**
|
|
@@ -22654,8 +22906,8 @@ var OutputService = class _OutputService {
|
|
|
22654
22906
|
};
|
|
22655
22907
|
|
|
22656
22908
|
// src/services/history.service.ts
|
|
22657
|
-
var
|
|
22658
|
-
var
|
|
22909
|
+
var fs38 = __toESM(require("fs"));
|
|
22910
|
+
var path46 = __toESM(require("path"));
|
|
22659
22911
|
var os29 = __toESM(require("os"));
|
|
22660
22912
|
var https7 = __toESM(require("https"));
|
|
22661
22913
|
var http7 = __toESM(require("http"));
|
|
@@ -22683,7 +22935,7 @@ function parseJsonl(filePath) {
|
|
|
22683
22935
|
const messages = [];
|
|
22684
22936
|
let raw;
|
|
22685
22937
|
try {
|
|
22686
|
-
raw =
|
|
22938
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22687
22939
|
} catch (err) {
|
|
22688
22940
|
if (err.code !== "ENOENT") {
|
|
22689
22941
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22818,7 +23070,7 @@ var HistoryService = class _HistoryService {
|
|
|
22818
23070
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22819
23071
|
}
|
|
22820
23072
|
get projectDir() {
|
|
22821
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23073
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22822
23074
|
}
|
|
22823
23075
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22824
23076
|
setCurrentConversationId(id) {
|
|
@@ -22830,7 +23082,7 @@ var HistoryService = class _HistoryService {
|
|
|
22830
23082
|
/** Return the current message count in the active conversation. */
|
|
22831
23083
|
getCurrentMessageCount() {
|
|
22832
23084
|
if (!this.currentConversationId) return 0;
|
|
22833
|
-
const filePath =
|
|
23085
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22834
23086
|
return parseJsonl(filePath).length;
|
|
22835
23087
|
}
|
|
22836
23088
|
/**
|
|
@@ -22841,7 +23093,7 @@ var HistoryService = class _HistoryService {
|
|
|
22841
23093
|
const deadline = Date.now() + timeoutMs;
|
|
22842
23094
|
while (Date.now() < deadline) {
|
|
22843
23095
|
if (!this.currentConversationId) return null;
|
|
22844
|
-
const filePath =
|
|
23096
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22845
23097
|
const messages = parseJsonl(filePath);
|
|
22846
23098
|
if (messages.length > previousCount) {
|
|
22847
23099
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22867,16 +23119,16 @@ var HistoryService = class _HistoryService {
|
|
|
22867
23119
|
const dir = this.projectDir;
|
|
22868
23120
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22869
23121
|
try {
|
|
22870
|
-
const files =
|
|
23122
|
+
const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22871
23123
|
try {
|
|
22872
|
-
const stat3 =
|
|
23124
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22873
23125
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22874
23126
|
} catch {
|
|
22875
23127
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22876
23128
|
}
|
|
22877
23129
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22878
23130
|
if (files.length > 0) {
|
|
22879
|
-
this.currentConversationId =
|
|
23131
|
+
this.currentConversationId = path46.basename(files[0].name, ".jsonl");
|
|
22880
23132
|
}
|
|
22881
23133
|
} catch {
|
|
22882
23134
|
}
|
|
@@ -22910,13 +23162,13 @@ var HistoryService = class _HistoryService {
|
|
|
22910
23162
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22911
23163
|
let entries;
|
|
22912
23164
|
try {
|
|
22913
|
-
entries =
|
|
23165
|
+
entries = fs38.readdirSync(dir, { withFileTypes: true });
|
|
22914
23166
|
} catch {
|
|
22915
23167
|
return null;
|
|
22916
23168
|
}
|
|
22917
23169
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22918
23170
|
try {
|
|
22919
|
-
const stat3 =
|
|
23171
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22920
23172
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22921
23173
|
} catch {
|
|
22922
23174
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22925,12 +23177,12 @@ var HistoryService = class _HistoryService {
|
|
|
22925
23177
|
if (files.length === 0) return null;
|
|
22926
23178
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22927
23179
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22928
|
-
return this.extractUsageFromFile(
|
|
23180
|
+
return this.extractUsageFromFile(path46.join(dir, targetFile));
|
|
22929
23181
|
}
|
|
22930
23182
|
extractUsageFromFile(filePath) {
|
|
22931
23183
|
let raw;
|
|
22932
23184
|
try {
|
|
22933
|
-
raw =
|
|
23185
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22934
23186
|
} catch {
|
|
22935
23187
|
return null;
|
|
22936
23188
|
}
|
|
@@ -22975,9 +23227,9 @@ var HistoryService = class _HistoryService {
|
|
|
22975
23227
|
let totalCost = 0;
|
|
22976
23228
|
let files;
|
|
22977
23229
|
try {
|
|
22978
|
-
files =
|
|
23230
|
+
files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22979
23231
|
try {
|
|
22980
|
-
return
|
|
23232
|
+
return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22981
23233
|
} catch {
|
|
22982
23234
|
return false;
|
|
22983
23235
|
}
|
|
@@ -22988,7 +23240,7 @@ var HistoryService = class _HistoryService {
|
|
|
22988
23240
|
for (const file of files) {
|
|
22989
23241
|
let raw;
|
|
22990
23242
|
try {
|
|
22991
|
-
raw =
|
|
23243
|
+
raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
|
|
22992
23244
|
} catch {
|
|
22993
23245
|
continue;
|
|
22994
23246
|
}
|
|
@@ -23052,7 +23304,7 @@ var HistoryService = class _HistoryService {
|
|
|
23052
23304
|
* showing an empty conversation.
|
|
23053
23305
|
*/
|
|
23054
23306
|
async loadConversation(sessionId) {
|
|
23055
|
-
const filePath =
|
|
23307
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23056
23308
|
const messages = parseJsonl(filePath);
|
|
23057
23309
|
if (messages.length === 0) return;
|
|
23058
23310
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23106,7 +23358,7 @@ var HistoryService = class _HistoryService {
|
|
|
23106
23358
|
if (!this.currentConversationId) return 0;
|
|
23107
23359
|
}
|
|
23108
23360
|
const sessionId = this.currentConversationId;
|
|
23109
|
-
const filePath =
|
|
23361
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23110
23362
|
const messages = parseJsonl(filePath);
|
|
23111
23363
|
if (messages.length === 0) return 0;
|
|
23112
23364
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -24027,7 +24279,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
24027
24279
|
}
|
|
24028
24280
|
|
|
24029
24281
|
// src/commands/pair-auto.ts
|
|
24030
|
-
var
|
|
24282
|
+
var fs39 = __toESM(require("fs"));
|
|
24031
24283
|
var os30 = __toESM(require("os"));
|
|
24032
24284
|
var import_crypto7 = require("crypto");
|
|
24033
24285
|
|
|
@@ -24223,12 +24475,12 @@ function readTokenFromArgs(args2) {
|
|
|
24223
24475
|
}
|
|
24224
24476
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24225
24477
|
if (fileFlag) {
|
|
24226
|
-
const
|
|
24478
|
+
const path53 = fileFlag.slice("--token-file=".length);
|
|
24227
24479
|
try {
|
|
24228
|
-
const content =
|
|
24229
|
-
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`);
|
|
24230
24482
|
try {
|
|
24231
|
-
|
|
24483
|
+
fs39.unlinkSync(path53);
|
|
24232
24484
|
} catch {
|
|
24233
24485
|
}
|
|
24234
24486
|
return content;
|
|
@@ -24346,6 +24598,8 @@ async function pairAuto(args2) {
|
|
|
24346
24598
|
codespaceName: process.env.CODESPACE_NAME ?? void 0
|
|
24347
24599
|
});
|
|
24348
24600
|
console.log(` Paired with ${claimed.user.name} (${claimed.user.plan})`);
|
|
24601
|
+
void provisionProjectDependencies(process.cwd()).catch(() => {
|
|
24602
|
+
});
|
|
24349
24603
|
if (process.env.CODEAM_SKIP_AGENT_LAUNCH === "true") {
|
|
24350
24604
|
capture("pair_auto_skipped_launch", {
|
|
24351
24605
|
sessionId: claimed.sessionId,
|
|
@@ -24494,7 +24748,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24494
24748
|
var import_child_process22 = require("child_process");
|
|
24495
24749
|
var import_util4 = require("util");
|
|
24496
24750
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24497
|
-
var
|
|
24751
|
+
var path47 = __toESM(require("path"));
|
|
24498
24752
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24499
24753
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24500
24754
|
function resetStdinForChild() {
|
|
@@ -24983,7 +25237,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24983
25237
|
});
|
|
24984
25238
|
}
|
|
24985
25239
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24986
|
-
const remoteDir =
|
|
25240
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
24987
25241
|
const parts = [
|
|
24988
25242
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
24989
25243
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25053,7 +25307,7 @@ function shellQuote(s) {
|
|
|
25053
25307
|
// src/services/providers/gitpod.ts
|
|
25054
25308
|
var import_child_process23 = require("child_process");
|
|
25055
25309
|
var import_util5 = require("util");
|
|
25056
|
-
var
|
|
25310
|
+
var path48 = __toESM(require("path"));
|
|
25057
25311
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25058
25312
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25059
25313
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25293,7 +25547,7 @@ var GitpodProvider = class {
|
|
|
25293
25547
|
});
|
|
25294
25548
|
}
|
|
25295
25549
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25296
|
-
const remoteDir =
|
|
25550
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25297
25551
|
const parts = [
|
|
25298
25552
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25299
25553
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25329,7 +25583,7 @@ function shellQuote2(s) {
|
|
|
25329
25583
|
// src/services/providers/gitlab-workspaces.ts
|
|
25330
25584
|
var import_child_process24 = require("child_process");
|
|
25331
25585
|
var import_util6 = require("util");
|
|
25332
|
-
var
|
|
25586
|
+
var path49 = __toESM(require("path"));
|
|
25333
25587
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25334
25588
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25335
25589
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25589,7 +25843,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25589
25843
|
}
|
|
25590
25844
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25591
25845
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25592
|
-
const remoteDir =
|
|
25846
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25593
25847
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25594
25848
|
if (options.mode != null) {
|
|
25595
25849
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25657,7 +25911,7 @@ function shellQuote3(s) {
|
|
|
25657
25911
|
// src/services/providers/railway.ts
|
|
25658
25912
|
var import_child_process25 = require("child_process");
|
|
25659
25913
|
var import_util7 = require("util");
|
|
25660
|
-
var
|
|
25914
|
+
var path50 = __toESM(require("path"));
|
|
25661
25915
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25662
25916
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25663
25917
|
function resetStdinForChild4() {
|
|
@@ -25893,7 +26147,7 @@ var RailwayProvider = class {
|
|
|
25893
26147
|
if (!projectId || !serviceId) {
|
|
25894
26148
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25895
26149
|
}
|
|
25896
|
-
const remoteDir =
|
|
26150
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25897
26151
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25898
26152
|
if (options.mode != null) {
|
|
25899
26153
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26436,8 +26690,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26436
26690
|
var import_node_dns = require("dns");
|
|
26437
26691
|
var import_node_util4 = require("util");
|
|
26438
26692
|
var import_node_crypto8 = require("crypto");
|
|
26439
|
-
var
|
|
26440
|
-
var
|
|
26693
|
+
var fs40 = __toESM(require("fs"));
|
|
26694
|
+
var path51 = __toESM(require("path"));
|
|
26441
26695
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26442
26696
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26443
26697
|
async function checkDns(apiBase) {
|
|
@@ -26493,13 +26747,13 @@ async function checkHealth(apiBase) {
|
|
|
26493
26747
|
}
|
|
26494
26748
|
}
|
|
26495
26749
|
function checkConfigDir() {
|
|
26496
|
-
const dir =
|
|
26750
|
+
const dir = path51.join(require("os").homedir(), ".codeam");
|
|
26497
26751
|
try {
|
|
26498
|
-
|
|
26499
|
-
const probe =
|
|
26500
|
-
|
|
26501
|
-
const read =
|
|
26502
|
-
|
|
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);
|
|
26503
26757
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26504
26758
|
return {
|
|
26505
26759
|
id: "config-dir",
|
|
@@ -26563,7 +26817,7 @@ function checkNodePty() {
|
|
|
26563
26817
|
detail: "not required on this platform"
|
|
26564
26818
|
};
|
|
26565
26819
|
}
|
|
26566
|
-
const vendoredPath =
|
|
26820
|
+
const vendoredPath = path51.join(__dirname, "vendor", "node-pty");
|
|
26567
26821
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26568
26822
|
try {
|
|
26569
26823
|
require(target);
|
|
@@ -26605,7 +26859,7 @@ function checkChokidar() {
|
|
|
26605
26859
|
}
|
|
26606
26860
|
async function doctor(args2 = []) {
|
|
26607
26861
|
const json = args2.includes("--json");
|
|
26608
|
-
const cliVersion = true ? "2.
|
|
26862
|
+
const cliVersion = true ? "2.39.0" : "0.0.0-dev";
|
|
26609
26863
|
const apiBase = resolveApiBaseUrl();
|
|
26610
26864
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26611
26865
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26804,7 +27058,7 @@ async function completion(args2) {
|
|
|
26804
27058
|
// src/commands/version.ts
|
|
26805
27059
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26806
27060
|
function version2() {
|
|
26807
|
-
const v = true ? "2.
|
|
27061
|
+
const v = true ? "2.39.0" : "unknown";
|
|
26808
27062
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26809
27063
|
}
|
|
26810
27064
|
|
|
@@ -26932,9 +27186,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26932
27186
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26933
27187
|
|
|
26934
27188
|
// src/lib/updateNotifier.ts
|
|
26935
|
-
var
|
|
27189
|
+
var fs41 = __toESM(require("fs"));
|
|
26936
27190
|
var os31 = __toESM(require("os"));
|
|
26937
|
-
var
|
|
27191
|
+
var path52 = __toESM(require("path"));
|
|
26938
27192
|
var https8 = __toESM(require("https"));
|
|
26939
27193
|
var import_node_child_process12 = require("child_process");
|
|
26940
27194
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26943,12 +27197,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26943
27197
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26944
27198
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26945
27199
|
function cachePath() {
|
|
26946
|
-
const dir =
|
|
26947
|
-
return
|
|
27200
|
+
const dir = path52.join(os31.homedir(), ".codeam");
|
|
27201
|
+
return path52.join(dir, "update-check.json");
|
|
26948
27202
|
}
|
|
26949
27203
|
function readCache() {
|
|
26950
27204
|
try {
|
|
26951
|
-
const raw =
|
|
27205
|
+
const raw = fs41.readFileSync(cachePath(), "utf8");
|
|
26952
27206
|
const parsed = JSON.parse(raw);
|
|
26953
27207
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26954
27208
|
return parsed;
|
|
@@ -26959,10 +27213,10 @@ function readCache() {
|
|
|
26959
27213
|
function writeCache(cache) {
|
|
26960
27214
|
try {
|
|
26961
27215
|
const file = cachePath();
|
|
26962
|
-
|
|
27216
|
+
fs41.mkdirSync(path52.dirname(file), { recursive: true });
|
|
26963
27217
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
26964
|
-
|
|
26965
|
-
|
|
27218
|
+
fs41.writeFileSync(tmp, JSON.stringify(cache));
|
|
27219
|
+
fs41.renameSync(tmp, file);
|
|
26966
27220
|
} catch {
|
|
26967
27221
|
}
|
|
26968
27222
|
}
|
|
@@ -27036,8 +27290,8 @@ function isLinkedInstall() {
|
|
|
27036
27290
|
timeout: 2e3
|
|
27037
27291
|
}).trim();
|
|
27038
27292
|
if (!root) return false;
|
|
27039
|
-
const pkgPath =
|
|
27040
|
-
return
|
|
27293
|
+
const pkgPath = path52.join(root, PKG_NAME);
|
|
27294
|
+
return fs41.lstatSync(pkgPath).isSymbolicLink();
|
|
27041
27295
|
} catch {
|
|
27042
27296
|
return false;
|
|
27043
27297
|
}
|
|
@@ -27073,7 +27327,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27073
27327
|
return;
|
|
27074
27328
|
}
|
|
27075
27329
|
try {
|
|
27076
|
-
|
|
27330
|
+
fs41.unlinkSync(cachePath());
|
|
27077
27331
|
} catch {
|
|
27078
27332
|
}
|
|
27079
27333
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27090,7 +27344,7 @@ function checkForUpdates() {
|
|
|
27090
27344
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27091
27345
|
if (process.env.CI) return;
|
|
27092
27346
|
if (!process.stdout.isTTY) return;
|
|
27093
|
-
const current = true ? "2.
|
|
27347
|
+
const current = true ? "2.39.0" : null;
|
|
27094
27348
|
if (!current) return;
|
|
27095
27349
|
const cache = readCache();
|
|
27096
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",
|