codeam-cli 2.33.0 → 2.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/index.js +366 -295
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.33.0] — 2026-06-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Beads wire types (ingest payload + action)
|
|
12
|
+
- **cli:** Bundle @beads/bd + cross-OS adapter, installer & projectKey
|
|
13
|
+
- **cli:** Beads bootstrap + issues.jsonl watcher -> backend
|
|
14
|
+
- **cli:** Apply queued beads actions as native bd commands
|
|
15
|
+
- **cli:** Gated beads orchestrator + barrel exports
|
|
16
|
+
- **cli:** Wire always-on beads into the live start + command-relay path
|
|
17
|
+
|
|
7
18
|
## [2.32.10] — 2026-06-09
|
|
8
19
|
|
|
9
20
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.
|
|
501
|
+
version: "2.34.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",
|
|
@@ -852,6 +852,28 @@ async function postPreviewEvent(input) {
|
|
|
852
852
|
};
|
|
853
853
|
}
|
|
854
854
|
}
|
|
855
|
+
async function postBeadsProvisioning(input) {
|
|
856
|
+
try {
|
|
857
|
+
await _transport.postJsonAuthed(
|
|
858
|
+
`${API_BASE}/api/beads/provisioning`,
|
|
859
|
+
{
|
|
860
|
+
sessionId: input.sessionId,
|
|
861
|
+
pluginId: input.pluginId,
|
|
862
|
+
status: input.status,
|
|
863
|
+
...input.projectKey ? { projectKey: input.projectKey } : {}
|
|
864
|
+
},
|
|
865
|
+
input.pluginAuthToken
|
|
866
|
+
);
|
|
867
|
+
return { ok: true };
|
|
868
|
+
} catch (err) {
|
|
869
|
+
const e = err;
|
|
870
|
+
return {
|
|
871
|
+
ok: false,
|
|
872
|
+
status: typeof e.statusCode === "number" ? e.statusCode : 0,
|
|
873
|
+
message: e.message || "unknown"
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
}
|
|
855
877
|
async function _postJsonAuthed(url, body, pluginAuthToken) {
|
|
856
878
|
return new Promise((resolve7, reject) => {
|
|
857
879
|
const data = JSON.stringify(body);
|
|
@@ -1162,8 +1184,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1162
1184
|
return decodedFile;
|
|
1163
1185
|
};
|
|
1164
1186
|
}
|
|
1165
|
-
function normalizeWindowsPath(
|
|
1166
|
-
return
|
|
1187
|
+
function normalizeWindowsPath(path50) {
|
|
1188
|
+
return path50.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1167
1189
|
}
|
|
1168
1190
|
|
|
1169
1191
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3643,9 +3665,9 @@ async function addSourceContext(frames) {
|
|
|
3643
3665
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3644
3666
|
return frames;
|
|
3645
3667
|
}
|
|
3646
|
-
function getContextLinesFromFile(
|
|
3668
|
+
function getContextLinesFromFile(path50, ranges, output) {
|
|
3647
3669
|
return new Promise((resolve7) => {
|
|
3648
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3670
|
+
const stream = (0, import_node_fs.createReadStream)(path50);
|
|
3649
3671
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3650
3672
|
input: stream
|
|
3651
3673
|
});
|
|
@@ -3660,7 +3682,7 @@ function getContextLinesFromFile(path49, ranges, output) {
|
|
|
3660
3682
|
let rangeStart = range[0];
|
|
3661
3683
|
let rangeEnd = range[1];
|
|
3662
3684
|
function onStreamError() {
|
|
3663
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3685
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path50, 1);
|
|
3664
3686
|
lineReaded.close();
|
|
3665
3687
|
lineReaded.removeAllListeners();
|
|
3666
3688
|
destroyStreamAndResolve();
|
|
@@ -3721,8 +3743,8 @@ function clearLineContext(frame) {
|
|
|
3721
3743
|
delete frame.context_line;
|
|
3722
3744
|
delete frame.post_context;
|
|
3723
3745
|
}
|
|
3724
|
-
function shouldSkipContextLinesForFile(
|
|
3725
|
-
return
|
|
3746
|
+
function shouldSkipContextLinesForFile(path50) {
|
|
3747
|
+
return path50.startsWith("node:") || path50.endsWith(".min.js") || path50.endsWith(".min.cjs") || path50.endsWith(".min.mjs") || path50.startsWith("data:");
|
|
3726
3748
|
}
|
|
3727
3749
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3728
3750
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5876,7 +5898,7 @@ function readAnonId() {
|
|
|
5876
5898
|
}
|
|
5877
5899
|
function superProperties() {
|
|
5878
5900
|
return {
|
|
5879
|
-
cliVersion: true ? "2.
|
|
5901
|
+
cliVersion: true ? "2.34.0" : "0.0.0-dev",
|
|
5880
5902
|
nodeVersion: process.version,
|
|
5881
5903
|
platform: process.platform,
|
|
5882
5904
|
arch: process.arch,
|
|
@@ -9948,13 +9970,13 @@ function detectStartupBanner(lines) {
|
|
|
9948
9970
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9949
9971
|
if (metaIdx - artStart < 2) return null;
|
|
9950
9972
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9951
|
-
const
|
|
9973
|
+
const path50 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9952
9974
|
return {
|
|
9953
9975
|
title: "",
|
|
9954
9976
|
subtitle: lines[metaIdx].trim(),
|
|
9955
|
-
path:
|
|
9977
|
+
path: path50,
|
|
9956
9978
|
startIdx: artStart,
|
|
9957
|
-
endIdx: metaIdx + (
|
|
9979
|
+
endIdx: metaIdx + (path50 ? 1 : 0)
|
|
9958
9980
|
};
|
|
9959
9981
|
}
|
|
9960
9982
|
|
|
@@ -11290,11 +11312,11 @@ function parseReview(stdout) {
|
|
|
11290
11312
|
for (const line of lines) {
|
|
11291
11313
|
const m = line.match(HUNK_LINE_RE);
|
|
11292
11314
|
if (!m) continue;
|
|
11293
|
-
const [,
|
|
11294
|
-
if (!
|
|
11315
|
+
const [, path50, lineNo, sevToken, message] = m;
|
|
11316
|
+
if (!path50 || !lineNo || !message) continue;
|
|
11295
11317
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11296
11318
|
hunks.push({
|
|
11297
|
-
path:
|
|
11319
|
+
path: path50.trim(),
|
|
11298
11320
|
line: Number(lineNo),
|
|
11299
11321
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11300
11322
|
message: cleanedMessage
|
|
@@ -15688,9 +15710,9 @@ function extractSelectPrompt(text) {
|
|
|
15688
15710
|
}
|
|
15689
15711
|
|
|
15690
15712
|
// src/commands/start/handlers.ts
|
|
15691
|
-
var
|
|
15713
|
+
var fs32 = __toESM(require("fs"));
|
|
15692
15714
|
var os25 = __toESM(require("os"));
|
|
15693
|
-
var
|
|
15715
|
+
var path39 = __toESM(require("path"));
|
|
15694
15716
|
var import_crypto3 = require("crypto");
|
|
15695
15717
|
var import_child_process15 = require("child_process");
|
|
15696
15718
|
|
|
@@ -17282,10 +17304,12 @@ var BdAdapter = class {
|
|
|
17282
17304
|
return this.resolveBinary() !== null;
|
|
17283
17305
|
}
|
|
17284
17306
|
/**
|
|
17285
|
-
* Run an arbitrary bd subcommand
|
|
17286
|
-
*
|
|
17287
|
-
*
|
|
17288
|
-
*
|
|
17307
|
+
* Run an arbitrary bd subcommand against the home brain. `BEADS_DIR` is set
|
|
17308
|
+
* to the configured `beadsDir` (tests) or `~/.beads` (the verified embedded
|
|
17309
|
+
* home brain) so every command resolves to the same single graph regardless
|
|
17310
|
+
* of the process cwd. Returns the raw result; callers decide how to interpret
|
|
17311
|
+
* exit codes — note bd exits 0 even for some error states (e.g. "no beads
|
|
17312
|
+
* database found"), so JSON-parsing callers must also inspect the payload.
|
|
17289
17313
|
*/
|
|
17290
17314
|
async run(args2) {
|
|
17291
17315
|
const binary = this.resolveBinary();
|
|
@@ -17293,14 +17317,9 @@ var BdAdapter = class {
|
|
|
17293
17317
|
return { code: -1, stdout: "", stderr: "bd binary not resolved" };
|
|
17294
17318
|
}
|
|
17295
17319
|
const env = { ...process.env };
|
|
17296
|
-
|
|
17297
|
-
|
|
17298
|
-
|
|
17299
|
-
} else if (!finalArgs.includes("--global")) {
|
|
17300
|
-
finalArgs.push("--global");
|
|
17301
|
-
}
|
|
17302
|
-
log.trace("beads", `bd ${finalArgs.join(" ")}`);
|
|
17303
|
-
return _spawnSeam.run(binary, finalArgs, { cwd: this.opts.cwd, env });
|
|
17320
|
+
env.BEADS_DIR = this.opts.beadsDir ?? defaultBeadsHomeDir();
|
|
17321
|
+
log.trace("beads", `bd ${args2.join(" ")} (BEADS_DIR=${env.BEADS_DIR})`);
|
|
17322
|
+
return _spawnSeam.run(binary, args2, { cwd: this.opts.cwd, env });
|
|
17304
17323
|
}
|
|
17305
17324
|
/**
|
|
17306
17325
|
* `bd ready --json` → typed issue array. `bd list --json` shares the shape,
|
|
@@ -17372,92 +17391,179 @@ function defaultBeadsHomeDir() {
|
|
|
17372
17391
|
return path35.join(os24.homedir(), ".beads");
|
|
17373
17392
|
}
|
|
17374
17393
|
|
|
17375
|
-
// src/beads/
|
|
17376
|
-
var
|
|
17394
|
+
// src/beads/provisioner.ts
|
|
17395
|
+
var fs30 = __toESM(require("fs"));
|
|
17396
|
+
var path36 = __toESM(require("path"));
|
|
17397
|
+
|
|
17398
|
+
// src/beads/install-bd.ts
|
|
17399
|
+
var import_child_process13 = require("child_process");
|
|
17400
|
+
var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
|
|
17401
|
+
var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
|
|
17402
|
+
function resolveInstallStrategy(platform2) {
|
|
17403
|
+
if (platform2 === "win32") {
|
|
17404
|
+
return {
|
|
17405
|
+
command: "powershell.exe",
|
|
17406
|
+
args: [
|
|
17407
|
+
"-NoProfile",
|
|
17408
|
+
"-NonInteractive",
|
|
17409
|
+
"-ExecutionPolicy",
|
|
17410
|
+
"Bypass",
|
|
17411
|
+
"-Command",
|
|
17412
|
+
`irm ${INSTALL_PS1_URL} | iex`
|
|
17413
|
+
],
|
|
17414
|
+
description: `PowerShell: irm ${INSTALL_PS1_URL} | iex (requires Go 1.24+ and Git for Windows on PATH)`
|
|
17415
|
+
};
|
|
17416
|
+
}
|
|
17417
|
+
return {
|
|
17418
|
+
command: "bash",
|
|
17419
|
+
args: ["-c", `curl -fsSL ${INSTALL_SH_URL} | bash`],
|
|
17420
|
+
description: `curl -fsSL ${INSTALL_SH_URL} | bash`
|
|
17421
|
+
};
|
|
17422
|
+
}
|
|
17423
|
+
var _installSpawnSeam = {
|
|
17424
|
+
run: _defaultInstallSpawn
|
|
17425
|
+
};
|
|
17426
|
+
function _defaultInstallSpawn(strategy) {
|
|
17427
|
+
return new Promise((resolve7) => {
|
|
17428
|
+
let proc;
|
|
17429
|
+
try {
|
|
17430
|
+
proc = (0, import_child_process13.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
17431
|
+
} catch (err) {
|
|
17432
|
+
resolve7({ ok: false, code: -1, stderr: err.message });
|
|
17433
|
+
return;
|
|
17434
|
+
}
|
|
17435
|
+
let stderr = "";
|
|
17436
|
+
proc.stderr?.on("data", (c2) => {
|
|
17437
|
+
stderr += c2.toString();
|
|
17438
|
+
});
|
|
17439
|
+
proc.on("error", (err) => resolve7({ ok: false, code: -1, stderr: err.message }));
|
|
17440
|
+
proc.on(
|
|
17441
|
+
"close",
|
|
17442
|
+
(code) => resolve7({ ok: code === 0, code: code ?? -1, stderr })
|
|
17443
|
+
);
|
|
17444
|
+
});
|
|
17445
|
+
}
|
|
17446
|
+
async function installBd(platform2 = process.platform) {
|
|
17447
|
+
const strategy = resolveInstallStrategy(platform2);
|
|
17448
|
+
log.info("beads", `installing bd via ${strategy.description}`);
|
|
17449
|
+
const result = await _installSpawnSeam.run(strategy);
|
|
17450
|
+
if (!result.ok) {
|
|
17451
|
+
log.warn(
|
|
17452
|
+
"beads",
|
|
17453
|
+
`bd install failed (code=${result.code}): ${result.stderr.slice(0, 200)}`
|
|
17454
|
+
);
|
|
17455
|
+
}
|
|
17456
|
+
return result;
|
|
17457
|
+
}
|
|
17458
|
+
|
|
17459
|
+
// src/beads/provisioner.ts
|
|
17460
|
+
var AGENT_SETUP_RECIPE = {
|
|
17377
17461
|
claude: "claude",
|
|
17378
17462
|
codex: "codex",
|
|
17463
|
+
copilot: "copilot",
|
|
17379
17464
|
cursor: "cursor",
|
|
17380
|
-
gemini: "gemini",
|
|
17381
17465
|
aider: "aider",
|
|
17382
|
-
|
|
17466
|
+
gemini: "gemini",
|
|
17467
|
+
coderabbit: null
|
|
17468
|
+
};
|
|
17469
|
+
var _provisionSeam = {
|
|
17470
|
+
install: installBd,
|
|
17471
|
+
homeBrainInitialized
|
|
17383
17472
|
};
|
|
17384
|
-
|
|
17473
|
+
function homeBrainInitialized(beadsDir) {
|
|
17474
|
+
try {
|
|
17475
|
+
return fs30.statSync(path36.join(beadsDir, "embeddeddolt")).isDirectory();
|
|
17476
|
+
} catch {
|
|
17477
|
+
return false;
|
|
17478
|
+
}
|
|
17479
|
+
}
|
|
17480
|
+
async function provisionBeads(opts = {}) {
|
|
17385
17481
|
const bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
17482
|
+
const beadsDir = opts.beadsDir ?? defaultBeadsHomeDir();
|
|
17386
17483
|
const result = {
|
|
17387
17484
|
bdAvailable: false,
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
|
|
17485
|
+
initialized: false,
|
|
17486
|
+
exportEnabled: false,
|
|
17487
|
+
agentsWired: []
|
|
17391
17488
|
};
|
|
17392
17489
|
if (!bd.isAvailable()) {
|
|
17393
|
-
log.
|
|
17394
|
-
|
|
17490
|
+
log.info("beads", "bd binary missing \u2014 running OS installer fallback");
|
|
17491
|
+
const install = await _provisionSeam.install();
|
|
17492
|
+
if (!install.ok) {
|
|
17493
|
+
log.warn("beads", `bd install failed (code=${install.code}) \u2014 beads disabled this run`);
|
|
17494
|
+
return result;
|
|
17495
|
+
}
|
|
17395
17496
|
}
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
if (!result.serverUp) {
|
|
17399
|
-
log.warn("beads", "dolt sql-server not up after start \u2014 skipping wiring this run");
|
|
17497
|
+
if (!bd.isAvailable()) {
|
|
17498
|
+
log.warn("beads", "bd still unavailable after install \u2014 beads disabled this run");
|
|
17400
17499
|
return result;
|
|
17401
17500
|
}
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17405
|
-
|
|
17406
|
-
|
|
17501
|
+
result.bdAvailable = true;
|
|
17502
|
+
if (_provisionSeam.homeBrainInitialized(beadsDir)) {
|
|
17503
|
+
log.trace("beads", `home brain already initialized at ${beadsDir}`);
|
|
17504
|
+
result.initialized = true;
|
|
17505
|
+
} else {
|
|
17506
|
+
log.info("beads", `initializing home brain at ${beadsDir}`);
|
|
17507
|
+
const init = await bd.run(["init", "--skip-agents", "--skip-hooks", "--non-interactive"]);
|
|
17508
|
+
if (init.code !== 0) {
|
|
17509
|
+
log.warn("beads", `bd init failed (code=${init.code}): ${init.stderr.slice(0, 200)}`);
|
|
17510
|
+
return result;
|
|
17407
17511
|
}
|
|
17408
|
-
|
|
17409
|
-
if (applied) result.agentsConfigured.push(agent);
|
|
17512
|
+
result.initialized = true;
|
|
17410
17513
|
}
|
|
17411
|
-
|
|
17514
|
+
const exp = await bd.run(["config", "set", "export.auto", "true"]);
|
|
17515
|
+
result.exportEnabled = exp.code === 0;
|
|
17516
|
+
result.agentsWired = await setupAgents(bd, opts.agents ?? []);
|
|
17412
17517
|
log.info(
|
|
17413
17518
|
"beads",
|
|
17414
|
-
`
|
|
17519
|
+
`provision done initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
|
|
17415
17520
|
);
|
|
17416
17521
|
return result;
|
|
17417
17522
|
}
|
|
17418
|
-
async function
|
|
17419
|
-
const
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
|
|
17423
|
-
|
|
17424
|
-
|
|
17425
|
-
|
|
17426
|
-
|
|
17427
|
-
|
|
17428
|
-
|
|
17523
|
+
async function setupAgents(bd, agents) {
|
|
17524
|
+
const wired = [];
|
|
17525
|
+
for (const recipe of dedupeRecipes(agents)) {
|
|
17526
|
+
try {
|
|
17527
|
+
const check = await bd.run(["setup", recipe, "--global", "--check"]);
|
|
17528
|
+
if (check.code === 0) {
|
|
17529
|
+
log.trace("beads", `bd setup ${recipe} --global already installed \u2014 skipping`);
|
|
17530
|
+
wired.push(recipe);
|
|
17531
|
+
continue;
|
|
17532
|
+
}
|
|
17533
|
+
log.info("beads", `wiring agent natively: bd setup ${recipe} --global`);
|
|
17534
|
+
const setup = await bd.run(["setup", recipe, "--global"]);
|
|
17535
|
+
if (setup.code === 0) {
|
|
17536
|
+
wired.push(recipe);
|
|
17537
|
+
} else {
|
|
17538
|
+
log.warn(
|
|
17539
|
+
"beads",
|
|
17540
|
+
`bd setup ${recipe} --global failed (code=${setup.code}): ${setup.stderr.slice(0, 200)} \u2014 non-fatal, agent runs without native bd wiring`
|
|
17541
|
+
);
|
|
17542
|
+
}
|
|
17543
|
+
} catch (err) {
|
|
17544
|
+
log.warn("beads", `bd setup ${recipe} --global threw (non-fatal)`, err);
|
|
17545
|
+
}
|
|
17429
17546
|
}
|
|
17430
|
-
|
|
17431
|
-
return recheck.code === 0;
|
|
17547
|
+
return wired;
|
|
17432
17548
|
}
|
|
17433
|
-
|
|
17434
|
-
const
|
|
17435
|
-
|
|
17436
|
-
|
|
17437
|
-
|
|
17438
|
-
}
|
|
17439
|
-
const setup = await bd.run(["setup", recipe]);
|
|
17440
|
-
if (setup.code !== 0) {
|
|
17441
|
-
log.warn("beads", `bd setup ${recipe} failed (code=${setup.code})`);
|
|
17442
|
-
return false;
|
|
17549
|
+
function dedupeRecipes(agents) {
|
|
17550
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17551
|
+
for (const agent of agents) {
|
|
17552
|
+
const recipe = AGENT_SETUP_RECIPE[agent];
|
|
17553
|
+
if (recipe) seen.add(recipe);
|
|
17443
17554
|
}
|
|
17444
|
-
|
|
17445
|
-
return true;
|
|
17446
|
-
}
|
|
17447
|
-
async function ensureAutoExport(bd) {
|
|
17448
|
-
const res = await bd.run(["config", "set", "export.jsonl", "true"]);
|
|
17449
|
-
return res.code === 0;
|
|
17555
|
+
return [...seen];
|
|
17450
17556
|
}
|
|
17451
17557
|
|
|
17452
17558
|
// src/beads/watcher.ts
|
|
17453
17559
|
var crypto3 = __toESM(require("crypto"));
|
|
17454
|
-
var
|
|
17560
|
+
var path38 = __toESM(require("path"));
|
|
17455
17561
|
|
|
17456
17562
|
// src/beads/project-key.ts
|
|
17457
|
-
var
|
|
17563
|
+
var import_child_process14 = require("child_process");
|
|
17458
17564
|
var crypto2 = __toESM(require("crypto"));
|
|
17459
|
-
var
|
|
17460
|
-
var
|
|
17565
|
+
var fs31 = __toESM(require("fs"));
|
|
17566
|
+
var path37 = __toESM(require("path"));
|
|
17461
17567
|
function normalizeOrigin(raw) {
|
|
17462
17568
|
const trimmed = raw.trim();
|
|
17463
17569
|
if (!trimmed) return null;
|
|
@@ -17483,17 +17589,17 @@ function normalizeOrigin(raw) {
|
|
|
17483
17589
|
return `${host}/${pathPart}`;
|
|
17484
17590
|
}
|
|
17485
17591
|
function findRepoRoot(cwd) {
|
|
17486
|
-
let dir =
|
|
17592
|
+
let dir = path37.resolve(cwd);
|
|
17487
17593
|
const seen = /* @__PURE__ */ new Set();
|
|
17488
17594
|
for (let i = 0; i < 256; i++) {
|
|
17489
17595
|
if (seen.has(dir)) return null;
|
|
17490
17596
|
seen.add(dir);
|
|
17491
17597
|
try {
|
|
17492
|
-
const stat3 =
|
|
17598
|
+
const stat3 = fs31.statSync(path37.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17493
17599
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17494
17600
|
} catch {
|
|
17495
17601
|
}
|
|
17496
|
-
const parent =
|
|
17602
|
+
const parent = path37.dirname(dir);
|
|
17497
17603
|
if (parent === dir) return null;
|
|
17498
17604
|
dir = parent;
|
|
17499
17605
|
}
|
|
@@ -17501,10 +17607,10 @@ function findRepoRoot(cwd) {
|
|
|
17501
17607
|
}
|
|
17502
17608
|
var _execSeam2 = {
|
|
17503
17609
|
exec: (file, args2, opts) => {
|
|
17504
|
-
const out2 = (0,
|
|
17610
|
+
const out2 = (0, import_child_process14.execFileSync)(file, args2, opts);
|
|
17505
17611
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17506
17612
|
},
|
|
17507
|
-
realpath: (p2) =>
|
|
17613
|
+
realpath: (p2) => fs31.realpathSync(p2)
|
|
17508
17614
|
};
|
|
17509
17615
|
function readOrigin(cwd) {
|
|
17510
17616
|
try {
|
|
@@ -17533,7 +17639,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
17533
17639
|
} catch {
|
|
17534
17640
|
}
|
|
17535
17641
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17536
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
17642
|
+
return { projectKey: `path:${hash}`, projectLabel: path37.basename(real) || "project" };
|
|
17537
17643
|
}
|
|
17538
17644
|
|
|
17539
17645
|
// src/services/file-watcher/transport.ts
|
|
@@ -17601,7 +17707,7 @@ var BeadsWatcher = class {
|
|
|
17601
17707
|
constructor(opts) {
|
|
17602
17708
|
this.opts = opts;
|
|
17603
17709
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
17604
|
-
this.feedPath = opts.feedPath ??
|
|
17710
|
+
this.feedPath = opts.feedPath ?? path38.join(defaultBeadsHomeDir(), "issues.jsonl");
|
|
17605
17711
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
17606
17712
|
}
|
|
17607
17713
|
opts;
|
|
@@ -17772,85 +17878,12 @@ async function applyBeadsAction(action, deps) {
|
|
|
17772
17878
|
return { ok: true, action: action.kind, code: 0 };
|
|
17773
17879
|
}
|
|
17774
17880
|
|
|
17775
|
-
// src/beads/install-bd.ts
|
|
17776
|
-
var import_child_process14 = require("child_process");
|
|
17777
|
-
var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
|
|
17778
|
-
var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
|
|
17779
|
-
function resolveInstallStrategy(platform2) {
|
|
17780
|
-
if (platform2 === "win32") {
|
|
17781
|
-
return {
|
|
17782
|
-
command: "powershell.exe",
|
|
17783
|
-
args: [
|
|
17784
|
-
"-NoProfile",
|
|
17785
|
-
"-NonInteractive",
|
|
17786
|
-
"-ExecutionPolicy",
|
|
17787
|
-
"Bypass",
|
|
17788
|
-
"-Command",
|
|
17789
|
-
`irm ${INSTALL_PS1_URL} | iex`
|
|
17790
|
-
],
|
|
17791
|
-
description: `PowerShell: irm ${INSTALL_PS1_URL} | iex (requires Go 1.24+ and Git for Windows on PATH)`
|
|
17792
|
-
};
|
|
17793
|
-
}
|
|
17794
|
-
return {
|
|
17795
|
-
command: "bash",
|
|
17796
|
-
args: ["-c", `curl -fsSL ${INSTALL_SH_URL} | bash`],
|
|
17797
|
-
description: `curl -fsSL ${INSTALL_SH_URL} | bash`
|
|
17798
|
-
};
|
|
17799
|
-
}
|
|
17800
|
-
var _installSpawnSeam = {
|
|
17801
|
-
run: _defaultInstallSpawn
|
|
17802
|
-
};
|
|
17803
|
-
function _defaultInstallSpawn(strategy) {
|
|
17804
|
-
return new Promise((resolve7) => {
|
|
17805
|
-
let proc;
|
|
17806
|
-
try {
|
|
17807
|
-
proc = (0, import_child_process14.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
17808
|
-
} catch (err) {
|
|
17809
|
-
resolve7({ ok: false, code: -1, stderr: err.message });
|
|
17810
|
-
return;
|
|
17811
|
-
}
|
|
17812
|
-
let stderr = "";
|
|
17813
|
-
proc.stderr?.on("data", (c2) => {
|
|
17814
|
-
stderr += c2.toString();
|
|
17815
|
-
});
|
|
17816
|
-
proc.on("error", (err) => resolve7({ ok: false, code: -1, stderr: err.message }));
|
|
17817
|
-
proc.on(
|
|
17818
|
-
"close",
|
|
17819
|
-
(code) => resolve7({ ok: code === 0, code: code ?? -1, stderr })
|
|
17820
|
-
);
|
|
17821
|
-
});
|
|
17822
|
-
}
|
|
17823
|
-
async function installBd(platform2 = process.platform) {
|
|
17824
|
-
const strategy = resolveInstallStrategy(platform2);
|
|
17825
|
-
log.info("beads", `installing bd via ${strategy.description}`);
|
|
17826
|
-
const result = await _installSpawnSeam.run(strategy);
|
|
17827
|
-
if (!result.ok) {
|
|
17828
|
-
log.warn(
|
|
17829
|
-
"beads",
|
|
17830
|
-
`bd install failed (code=${result.code}): ${result.stderr.slice(0, 200)}`
|
|
17831
|
-
);
|
|
17832
|
-
}
|
|
17833
|
-
return result;
|
|
17834
|
-
}
|
|
17835
|
-
|
|
17836
17881
|
// src/beads/index.ts
|
|
17837
|
-
async function
|
|
17838
|
-
if (!opts.enabled) {
|
|
17839
|
-
log.trace("beads", "beads flag off \u2014 skipping");
|
|
17840
|
-
return null;
|
|
17841
|
-
}
|
|
17882
|
+
async function startBeads(opts) {
|
|
17842
17883
|
const adapter = new BdAdapter({ cwd: opts.cwd });
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
}
|
|
17847
|
-
if (!adapter.isAvailable()) {
|
|
17848
|
-
log.warn("beads", "bd unavailable \u2014 beads disabled for this session");
|
|
17849
|
-
return null;
|
|
17850
|
-
}
|
|
17851
|
-
const boot = await bootstrapBeads({ cwd: opts.cwd, agents: opts.agents, adapter });
|
|
17852
|
-
if (!boot.serverUp) {
|
|
17853
|
-
log.warn("beads", "beads server not up \u2014 watcher not started this run");
|
|
17884
|
+
const provision = await provisionBeads({ cwd: opts.cwd, adapter, agents: opts.agents });
|
|
17885
|
+
if (!provision.bdAvailable || !provision.initialized) {
|
|
17886
|
+
log.warn("beads", "home brain not provisioned \u2014 watcher not started this run");
|
|
17854
17887
|
return null;
|
|
17855
17888
|
}
|
|
17856
17889
|
const watcher = new BeadsWatcher({
|
|
@@ -17876,28 +17909,42 @@ function beadsKilled() {
|
|
|
17876
17909
|
const v = process.env.CODEAM_BEADS_DISABLED;
|
|
17877
17910
|
return !!v && v !== "0" && v.toLowerCase() !== "false";
|
|
17878
17911
|
}
|
|
17879
|
-
async function
|
|
17912
|
+
async function provisionBeadsForStart(ctx) {
|
|
17880
17913
|
if (beadsKilled()) {
|
|
17881
|
-
log.trace("beads", "CODEAM_BEADS_DISABLED set \u2014 beads off
|
|
17914
|
+
log.trace("beads", "CODEAM_BEADS_DISABLED set \u2014 beads off this run");
|
|
17882
17915
|
return null;
|
|
17883
17916
|
}
|
|
17884
17917
|
if (!ctx.pluginAuthToken) {
|
|
17885
|
-
log.trace("beads", "no pluginAuthToken
|
|
17918
|
+
log.trace("beads", "no pluginAuthToken \u2014 beads off");
|
|
17886
17919
|
return null;
|
|
17887
17920
|
}
|
|
17921
|
+
const pluginAuthToken = ctx.pluginAuthToken;
|
|
17922
|
+
let started = null;
|
|
17888
17923
|
try {
|
|
17889
|
-
|
|
17890
|
-
enabled: true,
|
|
17924
|
+
started = await startBeads({
|
|
17891
17925
|
sessionId: ctx.sessionId,
|
|
17892
17926
|
pluginId: ctx.pluginId,
|
|
17893
|
-
pluginAuthToken
|
|
17894
|
-
|
|
17895
|
-
|
|
17927
|
+
pluginAuthToken,
|
|
17928
|
+
cwd: ctx.cwd,
|
|
17929
|
+
agents: ctx.agents
|
|
17896
17930
|
});
|
|
17897
17931
|
} catch (err) {
|
|
17898
|
-
log.warn("beads", "
|
|
17899
|
-
|
|
17900
|
-
}
|
|
17932
|
+
log.warn("beads", "provisionBeadsForStart failed (non-fatal)", err);
|
|
17933
|
+
started = null;
|
|
17934
|
+
}
|
|
17935
|
+
const { projectKey } = deriveProjectIdentity(ctx.cwd);
|
|
17936
|
+
void postBeadsProvisioning({
|
|
17937
|
+
sessionId: ctx.sessionId,
|
|
17938
|
+
pluginId: ctx.pluginId,
|
|
17939
|
+
pluginAuthToken,
|
|
17940
|
+
status: started ? "ready" : "failed",
|
|
17941
|
+
projectKey
|
|
17942
|
+
}).then((res) => {
|
|
17943
|
+
if (!res.ok) {
|
|
17944
|
+
log.trace("beads", `provisioning signal POST non-ok (status=${res.status}) \u2014 ignoring`);
|
|
17945
|
+
}
|
|
17946
|
+
});
|
|
17947
|
+
return started;
|
|
17901
17948
|
}
|
|
17902
17949
|
var ACTION_KINDS = /* @__PURE__ */ new Set([
|
|
17903
17950
|
"claim",
|
|
@@ -17930,7 +17977,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
17930
17977
|
function cleanupAttachmentTempFiles() {
|
|
17931
17978
|
for (const p2 of pendingAttachmentFiles) {
|
|
17932
17979
|
try {
|
|
17933
|
-
|
|
17980
|
+
fs32.unlinkSync(p2);
|
|
17934
17981
|
} catch {
|
|
17935
17982
|
}
|
|
17936
17983
|
}
|
|
@@ -17939,8 +17986,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
17939
17986
|
function saveFilesTemp(files) {
|
|
17940
17987
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
17941
17988
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
17942
|
-
const tmpPath =
|
|
17943
|
-
|
|
17989
|
+
const tmpPath = path39.join(os25.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
17990
|
+
fs32.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
17944
17991
|
pendingAttachmentFiles.add(tmpPath);
|
|
17945
17992
|
return tmpPath;
|
|
17946
17993
|
});
|
|
@@ -17960,7 +18007,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
17960
18007
|
setTimeout(() => {
|
|
17961
18008
|
for (const p2 of paths) {
|
|
17962
18009
|
try {
|
|
17963
|
-
|
|
18010
|
+
fs32.unlinkSync(p2);
|
|
17964
18011
|
} catch {
|
|
17965
18012
|
}
|
|
17966
18013
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -18533,8 +18580,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
18533
18580
|
if (args2.length === 0) return detection;
|
|
18534
18581
|
const binName = args2[0];
|
|
18535
18582
|
if (binName.startsWith("-")) return detection;
|
|
18536
|
-
const binPath =
|
|
18537
|
-
if (!
|
|
18583
|
+
const binPath = path39.join(cwd, "node_modules", ".bin", binName);
|
|
18584
|
+
if (!fs32.existsSync(binPath)) return detection;
|
|
18538
18585
|
return {
|
|
18539
18586
|
...detection,
|
|
18540
18587
|
command: binPath,
|
|
@@ -18945,9 +18992,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
18945
18992
|
|
|
18946
18993
|
// src/services/file-watcher.service.ts
|
|
18947
18994
|
var import_child_process16 = require("child_process");
|
|
18948
|
-
var
|
|
18995
|
+
var fs33 = __toESM(require("fs"));
|
|
18949
18996
|
var os26 = __toESM(require("os"));
|
|
18950
|
-
var
|
|
18997
|
+
var path40 = __toESM(require("path"));
|
|
18951
18998
|
var import_ignore = __toESM(require("ignore"));
|
|
18952
18999
|
|
|
18953
19000
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19090,18 +19137,18 @@ var _findGitRootSeam = {
|
|
|
19090
19137
|
resolve: _defaultFindGitRoot
|
|
19091
19138
|
};
|
|
19092
19139
|
function _defaultFindGitRoot(startDir) {
|
|
19093
|
-
let dir =
|
|
19140
|
+
let dir = path40.resolve(startDir);
|
|
19094
19141
|
const seen = /* @__PURE__ */ new Set();
|
|
19095
19142
|
for (let i = 0; i < 256; i++) {
|
|
19096
19143
|
if (seen.has(dir)) return null;
|
|
19097
19144
|
seen.add(dir);
|
|
19098
19145
|
try {
|
|
19099
|
-
const gitPath =
|
|
19100
|
-
const stat3 =
|
|
19146
|
+
const gitPath = path40.join(dir, ".git");
|
|
19147
|
+
const stat3 = fs33.statSync(gitPath, { throwIfNoEntry: false });
|
|
19101
19148
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19102
19149
|
} catch {
|
|
19103
19150
|
}
|
|
19104
|
-
const parent =
|
|
19151
|
+
const parent = path40.dirname(dir);
|
|
19105
19152
|
if (parent === dir) return null;
|
|
19106
19153
|
dir = parent;
|
|
19107
19154
|
}
|
|
@@ -19346,7 +19393,7 @@ var FileWatcherService = class {
|
|
|
19346
19393
|
}
|
|
19347
19394
|
async emitForFile(absPath, changeType) {
|
|
19348
19395
|
if (this.stopped) return;
|
|
19349
|
-
const fileDir =
|
|
19396
|
+
const fileDir = path40.dirname(absPath);
|
|
19350
19397
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
19351
19398
|
if (gitRoot === void 0) {
|
|
19352
19399
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -19359,19 +19406,19 @@ var FileWatcherService = class {
|
|
|
19359
19406
|
);
|
|
19360
19407
|
return;
|
|
19361
19408
|
}
|
|
19362
|
-
const relPathInRepo =
|
|
19409
|
+
const relPathInRepo = path40.relative(gitRoot, absPath);
|
|
19363
19410
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
19364
19411
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
19365
19412
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
19366
19413
|
log.trace(
|
|
19367
19414
|
"fileWatcher",
|
|
19368
|
-
`${relPathInRepo} ignored by ${
|
|
19415
|
+
`${relPathInRepo} ignored by ${path40.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
19369
19416
|
);
|
|
19370
19417
|
return;
|
|
19371
19418
|
}
|
|
19372
19419
|
this.opts.onRepoDirty?.(gitRoot);
|
|
19373
|
-
const repoPath =
|
|
19374
|
-
const repoName =
|
|
19420
|
+
const repoPath = path40.relative(this.opts.workingDir, gitRoot);
|
|
19421
|
+
const repoName = path40.basename(gitRoot);
|
|
19375
19422
|
let diffText = "";
|
|
19376
19423
|
let fileStatus = "modified";
|
|
19377
19424
|
if (changeType === "unlink") {
|
|
@@ -19546,7 +19593,7 @@ var FileWatcherService = class {
|
|
|
19546
19593
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
19547
19594
|
let entries;
|
|
19548
19595
|
try {
|
|
19549
|
-
entries =
|
|
19596
|
+
entries = fs33.readdirSync(dir, { withFileTypes: true });
|
|
19550
19597
|
} catch {
|
|
19551
19598
|
return;
|
|
19552
19599
|
}
|
|
@@ -19555,16 +19602,16 @@ var FileWatcherService = class {
|
|
|
19555
19602
|
);
|
|
19556
19603
|
if (gitignoreEntry) {
|
|
19557
19604
|
try {
|
|
19558
|
-
const body =
|
|
19559
|
-
const rel =
|
|
19605
|
+
const body = fs33.readFileSync(path40.join(dir, ".gitignore"), "utf8");
|
|
19606
|
+
const rel = path40.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
19560
19607
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
19561
19608
|
const trimmed = line.trim();
|
|
19562
19609
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
19563
19610
|
if (!rel) return line;
|
|
19564
19611
|
if (trimmed.startsWith("!")) {
|
|
19565
|
-
return "!" +
|
|
19612
|
+
return "!" + path40.posix.join(rel, trimmed.slice(1));
|
|
19566
19613
|
}
|
|
19567
|
-
return
|
|
19614
|
+
return path40.posix.join(rel, trimmed);
|
|
19568
19615
|
}).join("\n");
|
|
19569
19616
|
matcher.add(prefixed);
|
|
19570
19617
|
} catch {
|
|
@@ -19573,7 +19620,7 @@ var FileWatcherService = class {
|
|
|
19573
19620
|
for (const entry of entries) {
|
|
19574
19621
|
if (!entry.isDirectory()) continue;
|
|
19575
19622
|
if (entry.name === ".git") continue;
|
|
19576
|
-
const childAbs =
|
|
19623
|
+
const childAbs = path40.join(dir, entry.name);
|
|
19577
19624
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
19578
19625
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
19579
19626
|
}
|
|
@@ -19743,7 +19790,7 @@ var import_crypto4 = require("crypto");
|
|
|
19743
19790
|
|
|
19744
19791
|
// src/services/turn-files/git-changeset.ts
|
|
19745
19792
|
var import_child_process17 = require("child_process");
|
|
19746
|
-
var
|
|
19793
|
+
var path41 = __toESM(require("path"));
|
|
19747
19794
|
async function collectRepoChangeset(opts) {
|
|
19748
19795
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
19749
19796
|
if (status2 === null) return null;
|
|
@@ -19854,7 +19901,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
19854
19901
|
});
|
|
19855
19902
|
}
|
|
19856
19903
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
19857
|
-
const
|
|
19904
|
+
const fs39 = await import("fs/promises");
|
|
19858
19905
|
const out2 = [];
|
|
19859
19906
|
await walk(workingDir, 0);
|
|
19860
19907
|
return out2;
|
|
@@ -19862,7 +19909,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
19862
19909
|
if (depth > maxDepth) return;
|
|
19863
19910
|
let entries = [];
|
|
19864
19911
|
try {
|
|
19865
|
-
const dirents = await
|
|
19912
|
+
const dirents = await fs39.readdir(dir, { withFileTypes: true });
|
|
19866
19913
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
19867
19914
|
} catch {
|
|
19868
19915
|
return;
|
|
@@ -19873,8 +19920,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
19873
19920
|
if (hasGit) {
|
|
19874
19921
|
out2.push({
|
|
19875
19922
|
repoRoot: dir,
|
|
19876
|
-
repoPath:
|
|
19877
|
-
repoName:
|
|
19923
|
+
repoPath: path41.relative(workingDir, dir),
|
|
19924
|
+
repoName: path41.basename(dir)
|
|
19878
19925
|
});
|
|
19879
19926
|
return;
|
|
19880
19927
|
}
|
|
@@ -19882,14 +19929,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
19882
19929
|
if (!entry.isDirectory) continue;
|
|
19883
19930
|
if (entry.name === "node_modules") continue;
|
|
19884
19931
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
19885
|
-
await walk(
|
|
19932
|
+
await walk(path41.join(dir, entry.name), depth + 1);
|
|
19886
19933
|
}
|
|
19887
19934
|
}
|
|
19888
19935
|
}
|
|
19889
19936
|
|
|
19890
19937
|
// src/services/turn-files/files-outbox.ts
|
|
19891
|
-
var
|
|
19892
|
-
var
|
|
19938
|
+
var fs34 = __toESM(require("fs/promises"));
|
|
19939
|
+
var path42 = __toESM(require("path"));
|
|
19893
19940
|
var import_os7 = require("os");
|
|
19894
19941
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
19895
19942
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -19922,16 +19969,16 @@ var FilesOutbox = class {
|
|
|
19922
19969
|
backoffIndex = 0;
|
|
19923
19970
|
stopped = false;
|
|
19924
19971
|
constructor(opts) {
|
|
19925
|
-
const base = opts.baseDir ??
|
|
19926
|
-
this.filePath =
|
|
19972
|
+
const base = opts.baseDir ?? path42.join(homeDir(), HOME_OUTBOX_DIR);
|
|
19973
|
+
this.filePath = path42.join(base, `${opts.sessionId}.jsonl`);
|
|
19927
19974
|
this.post = opts.post;
|
|
19928
19975
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
19929
19976
|
}
|
|
19930
19977
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
19931
19978
|
* line is durable on disk (not once the POST succeeds). */
|
|
19932
19979
|
async enqueue(entry) {
|
|
19933
|
-
await
|
|
19934
|
-
await
|
|
19980
|
+
await fs34.mkdir(path42.dirname(this.filePath), { recursive: true });
|
|
19981
|
+
await fs34.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
19935
19982
|
this.backoffIndex = 0;
|
|
19936
19983
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
19937
19984
|
}
|
|
@@ -20020,7 +20067,7 @@ var FilesOutbox = class {
|
|
|
20020
20067
|
async readAll() {
|
|
20021
20068
|
let raw = "";
|
|
20022
20069
|
try {
|
|
20023
|
-
raw = await
|
|
20070
|
+
raw = await fs34.readFile(this.filePath, "utf8");
|
|
20024
20071
|
} catch {
|
|
20025
20072
|
return [];
|
|
20026
20073
|
}
|
|
@@ -20044,12 +20091,12 @@ var FilesOutbox = class {
|
|
|
20044
20091
|
async rewrite(entries) {
|
|
20045
20092
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20046
20093
|
if (entries.length === 0) {
|
|
20047
|
-
await
|
|
20094
|
+
await fs34.unlink(this.filePath).catch(() => void 0);
|
|
20048
20095
|
return;
|
|
20049
20096
|
}
|
|
20050
20097
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20051
|
-
await
|
|
20052
|
-
await
|
|
20098
|
+
await fs34.writeFile(tmpPath, payload, "utf8");
|
|
20099
|
+
await fs34.rename(tmpPath, this.filePath);
|
|
20053
20100
|
}
|
|
20054
20101
|
};
|
|
20055
20102
|
function applyJitter(ms) {
|
|
@@ -20670,16 +20717,7 @@ async function runAcpSession(opts) {
|
|
|
20670
20717
|
}).catch((err) => {
|
|
20671
20718
|
log.warn("acpRunner", `fileWatcher.start failed: ${describeError(err)}`);
|
|
20672
20719
|
});
|
|
20673
|
-
|
|
20674
|
-
void startBeadsForSession({
|
|
20675
|
-
sessionId: opts.sessionId,
|
|
20676
|
-
pluginId: opts.pluginId,
|
|
20677
|
-
pluginAuthToken: opts.pluginAuthToken,
|
|
20678
|
-
agents: [opts.agent],
|
|
20679
|
-
cwd: opts.cwd
|
|
20680
|
-
}).then((started) => {
|
|
20681
|
-
beads = started;
|
|
20682
|
-
});
|
|
20720
|
+
const getBeads = opts.getBeads ?? (() => null);
|
|
20683
20721
|
const relay = new CommandRelayService(
|
|
20684
20722
|
opts.pluginId,
|
|
20685
20723
|
async (cmd) => {
|
|
@@ -20694,7 +20732,7 @@ async function runAcpSession(opts) {
|
|
|
20694
20732
|
history,
|
|
20695
20733
|
initialize.agentCapabilities,
|
|
20696
20734
|
turnFiles,
|
|
20697
|
-
|
|
20735
|
+
getBeads
|
|
20698
20736
|
);
|
|
20699
20737
|
},
|
|
20700
20738
|
{ id: opts.agent, name: opts.agent, displayName: opts.agent }
|
|
@@ -20705,7 +20743,6 @@ async function runAcpSession(opts) {
|
|
|
20705
20743
|
relay.stop();
|
|
20706
20744
|
void fileWatcher.stop();
|
|
20707
20745
|
turnFiles.stop();
|
|
20708
|
-
void beads?.watcher.stop();
|
|
20709
20746
|
closeAllTerminals();
|
|
20710
20747
|
await client2.stop();
|
|
20711
20748
|
process.exit(0);
|
|
@@ -21813,8 +21850,8 @@ var OutputService = class _OutputService {
|
|
|
21813
21850
|
};
|
|
21814
21851
|
|
|
21815
21852
|
// src/services/history.service.ts
|
|
21816
|
-
var
|
|
21817
|
-
var
|
|
21853
|
+
var fs35 = __toESM(require("fs"));
|
|
21854
|
+
var path43 = __toESM(require("path"));
|
|
21818
21855
|
var os27 = __toESM(require("os"));
|
|
21819
21856
|
var https7 = __toESM(require("https"));
|
|
21820
21857
|
var http7 = __toESM(require("http"));
|
|
@@ -21842,7 +21879,7 @@ function parseJsonl(filePath) {
|
|
|
21842
21879
|
const messages = [];
|
|
21843
21880
|
let raw;
|
|
21844
21881
|
try {
|
|
21845
|
-
raw =
|
|
21882
|
+
raw = fs35.readFileSync(filePath, "utf8");
|
|
21846
21883
|
} catch (err) {
|
|
21847
21884
|
if (err.code !== "ENOENT") {
|
|
21848
21885
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -21977,7 +22014,7 @@ var HistoryService = class _HistoryService {
|
|
|
21977
22014
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
21978
22015
|
}
|
|
21979
22016
|
get projectDir() {
|
|
21980
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
22017
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path43.join(os27.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
21981
22018
|
}
|
|
21982
22019
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
21983
22020
|
setCurrentConversationId(id) {
|
|
@@ -21989,7 +22026,7 @@ var HistoryService = class _HistoryService {
|
|
|
21989
22026
|
/** Return the current message count in the active conversation. */
|
|
21990
22027
|
getCurrentMessageCount() {
|
|
21991
22028
|
if (!this.currentConversationId) return 0;
|
|
21992
|
-
const filePath =
|
|
22029
|
+
const filePath = path43.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
21993
22030
|
return parseJsonl(filePath).length;
|
|
21994
22031
|
}
|
|
21995
22032
|
/**
|
|
@@ -22000,7 +22037,7 @@ var HistoryService = class _HistoryService {
|
|
|
22000
22037
|
const deadline = Date.now() + timeoutMs;
|
|
22001
22038
|
while (Date.now() < deadline) {
|
|
22002
22039
|
if (!this.currentConversationId) return null;
|
|
22003
|
-
const filePath =
|
|
22040
|
+
const filePath = path43.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22004
22041
|
const messages = parseJsonl(filePath);
|
|
22005
22042
|
if (messages.length > previousCount) {
|
|
22006
22043
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22026,16 +22063,16 @@ var HistoryService = class _HistoryService {
|
|
|
22026
22063
|
const dir = this.projectDir;
|
|
22027
22064
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22028
22065
|
try {
|
|
22029
|
-
const files =
|
|
22066
|
+
const files = fs35.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22030
22067
|
try {
|
|
22031
|
-
const stat3 =
|
|
22068
|
+
const stat3 = fs35.statSync(path43.join(dir, e.name));
|
|
22032
22069
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22033
22070
|
} catch {
|
|
22034
22071
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22035
22072
|
}
|
|
22036
22073
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22037
22074
|
if (files.length > 0) {
|
|
22038
|
-
this.currentConversationId =
|
|
22075
|
+
this.currentConversationId = path43.basename(files[0].name, ".jsonl");
|
|
22039
22076
|
}
|
|
22040
22077
|
} catch {
|
|
22041
22078
|
}
|
|
@@ -22069,13 +22106,13 @@ var HistoryService = class _HistoryService {
|
|
|
22069
22106
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22070
22107
|
let entries;
|
|
22071
22108
|
try {
|
|
22072
|
-
entries =
|
|
22109
|
+
entries = fs35.readdirSync(dir, { withFileTypes: true });
|
|
22073
22110
|
} catch {
|
|
22074
22111
|
return null;
|
|
22075
22112
|
}
|
|
22076
22113
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22077
22114
|
try {
|
|
22078
|
-
const stat3 =
|
|
22115
|
+
const stat3 = fs35.statSync(path43.join(dir, e.name));
|
|
22079
22116
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22080
22117
|
} catch {
|
|
22081
22118
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22084,12 +22121,12 @@ var HistoryService = class _HistoryService {
|
|
|
22084
22121
|
if (files.length === 0) return null;
|
|
22085
22122
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22086
22123
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22087
|
-
return this.extractUsageFromFile(
|
|
22124
|
+
return this.extractUsageFromFile(path43.join(dir, targetFile));
|
|
22088
22125
|
}
|
|
22089
22126
|
extractUsageFromFile(filePath) {
|
|
22090
22127
|
let raw;
|
|
22091
22128
|
try {
|
|
22092
|
-
raw =
|
|
22129
|
+
raw = fs35.readFileSync(filePath, "utf8");
|
|
22093
22130
|
} catch {
|
|
22094
22131
|
return null;
|
|
22095
22132
|
}
|
|
@@ -22134,9 +22171,9 @@ var HistoryService = class _HistoryService {
|
|
|
22134
22171
|
let totalCost = 0;
|
|
22135
22172
|
let files;
|
|
22136
22173
|
try {
|
|
22137
|
-
files =
|
|
22174
|
+
files = fs35.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22138
22175
|
try {
|
|
22139
|
-
return
|
|
22176
|
+
return fs35.statSync(path43.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22140
22177
|
} catch {
|
|
22141
22178
|
return false;
|
|
22142
22179
|
}
|
|
@@ -22147,7 +22184,7 @@ var HistoryService = class _HistoryService {
|
|
|
22147
22184
|
for (const file of files) {
|
|
22148
22185
|
let raw;
|
|
22149
22186
|
try {
|
|
22150
|
-
raw =
|
|
22187
|
+
raw = fs35.readFileSync(path43.join(projectDir, file), "utf8");
|
|
22151
22188
|
} catch {
|
|
22152
22189
|
continue;
|
|
22153
22190
|
}
|
|
@@ -22211,7 +22248,7 @@ var HistoryService = class _HistoryService {
|
|
|
22211
22248
|
* showing an empty conversation.
|
|
22212
22249
|
*/
|
|
22213
22250
|
async loadConversation(sessionId) {
|
|
22214
|
-
const filePath =
|
|
22251
|
+
const filePath = path43.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22215
22252
|
const messages = parseJsonl(filePath);
|
|
22216
22253
|
if (messages.length === 0) return;
|
|
22217
22254
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -22265,7 +22302,7 @@ var HistoryService = class _HistoryService {
|
|
|
22265
22302
|
if (!this.currentConversationId) return 0;
|
|
22266
22303
|
}
|
|
22267
22304
|
const sessionId = this.currentConversationId;
|
|
22268
|
-
const filePath =
|
|
22305
|
+
const filePath = path43.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22269
22306
|
const messages = parseJsonl(filePath);
|
|
22270
22307
|
if (messages.length === 0) return 0;
|
|
22271
22308
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -22787,6 +22824,20 @@ async function start(requestedAgent) {
|
|
|
22787
22824
|
"pluginAuth",
|
|
22788
22825
|
`boot triple sessionId=${session.id} pluginId=${pluginId} tokenLen=${tokenForLog.length} tokenHead=${tokenForLog.slice(0, 12)} tokenTail=${tokenForLog.slice(-8)} mintedEqualsCached=${refreshed === session.pluginAuthToken}`
|
|
22789
22826
|
);
|
|
22827
|
+
let beads = null;
|
|
22828
|
+
const getBeads = () => beads;
|
|
22829
|
+
const beadsReady = provisionBeadsForStart({
|
|
22830
|
+
sessionId: session.id,
|
|
22831
|
+
pluginId,
|
|
22832
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
22833
|
+
cwd,
|
|
22834
|
+
// Wire this session's agent natively via `bd setup <recipe> --global` so
|
|
22835
|
+
// the agent actually uses bd (D12 — REVISED). Covers BOTH ACP and PTY.
|
|
22836
|
+
agents: [session.agent]
|
|
22837
|
+
}).then((started) => {
|
|
22838
|
+
beads = started;
|
|
22839
|
+
return started;
|
|
22840
|
+
});
|
|
22790
22841
|
const acpDisabled = process.env.CODEAM_ACP_DISABLED === "1";
|
|
22791
22842
|
if (!acpDisabled && session.pluginAuthToken) {
|
|
22792
22843
|
const adapter = getAcpAdapter(session.agent);
|
|
@@ -22797,7 +22848,8 @@ async function start(requestedAgent) {
|
|
|
22797
22848
|
pluginId,
|
|
22798
22849
|
pluginAuthToken: session.pluginAuthToken,
|
|
22799
22850
|
adapter,
|
|
22800
|
-
cwd
|
|
22851
|
+
cwd,
|
|
22852
|
+
getBeads
|
|
22801
22853
|
});
|
|
22802
22854
|
return;
|
|
22803
22855
|
}
|
|
@@ -22859,7 +22911,6 @@ async function start(requestedAgent) {
|
|
|
22859
22911
|
dirtyTracker: dirtyTracker ?? void 0
|
|
22860
22912
|
}) : null;
|
|
22861
22913
|
let streamingEmitter = null;
|
|
22862
|
-
let beads = null;
|
|
22863
22914
|
const agent = new AgentService(
|
|
22864
22915
|
runtime,
|
|
22865
22916
|
{
|
|
@@ -22910,14 +22961,7 @@ async function start(requestedAgent) {
|
|
|
22910
22961
|
await dispatchCommand(ctx, cmd);
|
|
22911
22962
|
}, runtime.meta);
|
|
22912
22963
|
ctx.relay = relay;
|
|
22913
|
-
void
|
|
22914
|
-
sessionId: session.id,
|
|
22915
|
-
pluginId,
|
|
22916
|
-
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
22917
|
-
agents: [session.agent],
|
|
22918
|
-
cwd
|
|
22919
|
-
}).then((started) => {
|
|
22920
|
-
beads = started;
|
|
22964
|
+
void beadsReady.then((started) => {
|
|
22921
22965
|
ctx.beads = started;
|
|
22922
22966
|
});
|
|
22923
22967
|
registerTerminalHandlers({
|
|
@@ -23175,7 +23219,7 @@ async function autoLinkAfterPair(opts) {
|
|
|
23175
23219
|
}
|
|
23176
23220
|
|
|
23177
23221
|
// src/commands/pair-auto.ts
|
|
23178
|
-
var
|
|
23222
|
+
var fs36 = __toESM(require("fs"));
|
|
23179
23223
|
var os28 = __toESM(require("os"));
|
|
23180
23224
|
var import_crypto7 = require("crypto");
|
|
23181
23225
|
|
|
@@ -23236,6 +23280,15 @@ async function startInfraOnly(agentId) {
|
|
|
23236
23280
|
pluginId,
|
|
23237
23281
|
pluginAuthToken: session.pluginAuthToken
|
|
23238
23282
|
}) : null;
|
|
23283
|
+
let beads = null;
|
|
23284
|
+
void provisionBeadsForStart({
|
|
23285
|
+
sessionId: session.id,
|
|
23286
|
+
pluginId,
|
|
23287
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
23288
|
+
cwd
|
|
23289
|
+
}).then((started) => {
|
|
23290
|
+
beads = started;
|
|
23291
|
+
});
|
|
23239
23292
|
let relayRef = null;
|
|
23240
23293
|
const ctx = {
|
|
23241
23294
|
// Agent-touching fields are not used by any of the commands
|
|
@@ -23257,6 +23310,23 @@ async function startInfraOnly(agentId) {
|
|
|
23257
23310
|
const relay = new CommandRelayService(
|
|
23258
23311
|
pluginId,
|
|
23259
23312
|
async (cmd) => {
|
|
23313
|
+
if (cmd.type === "beads_action") {
|
|
23314
|
+
if (!beads) {
|
|
23315
|
+
log.trace("infra-only", "beads_action received but beads not running \u2014 dropping");
|
|
23316
|
+
return;
|
|
23317
|
+
}
|
|
23318
|
+
const action = beadsActionFromPayload(cmd.payload);
|
|
23319
|
+
if (!action) {
|
|
23320
|
+
log.warn("infra-only", "malformed beads_action payload \u2014 dropping");
|
|
23321
|
+
return;
|
|
23322
|
+
}
|
|
23323
|
+
try {
|
|
23324
|
+
await handleBeadsActionCommand(action, beads);
|
|
23325
|
+
} catch (err) {
|
|
23326
|
+
log.warn("infra-only", "handleBeadsActionCommand failed (non-fatal)", err);
|
|
23327
|
+
}
|
|
23328
|
+
return;
|
|
23329
|
+
}
|
|
23260
23330
|
if (!INFRA_ONLY_COMMAND_TYPES.has(cmd.type)) {
|
|
23261
23331
|
log.trace("infra-only", `dropping agent-only command type=${cmd.type}`);
|
|
23262
23332
|
return;
|
|
@@ -23317,6 +23387,7 @@ async function startInfraOnly(agentId) {
|
|
|
23317
23387
|
} catch {
|
|
23318
23388
|
}
|
|
23319
23389
|
void fileWatcher?.stop();
|
|
23390
|
+
void beads?.watcher.stop();
|
|
23320
23391
|
closeAllTerminals();
|
|
23321
23392
|
cleanupAttachmentTempFiles();
|
|
23322
23393
|
process.exit(0);
|
|
@@ -23344,12 +23415,12 @@ function readTokenFromArgs(args2) {
|
|
|
23344
23415
|
}
|
|
23345
23416
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
23346
23417
|
if (fileFlag) {
|
|
23347
|
-
const
|
|
23418
|
+
const path50 = fileFlag.slice("--token-file=".length);
|
|
23348
23419
|
try {
|
|
23349
|
-
const content =
|
|
23350
|
-
if (content.length === 0) fail(`--token-file ${
|
|
23420
|
+
const content = fs36.readFileSync(path50, "utf8").trim();
|
|
23421
|
+
if (content.length === 0) fail(`--token-file ${path50} is empty`);
|
|
23351
23422
|
try {
|
|
23352
|
-
|
|
23423
|
+
fs36.unlinkSync(path50);
|
|
23353
23424
|
} catch {
|
|
23354
23425
|
}
|
|
23355
23426
|
return content;
|
|
@@ -23615,7 +23686,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
23615
23686
|
var import_child_process19 = require("child_process");
|
|
23616
23687
|
var import_util4 = require("util");
|
|
23617
23688
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
23618
|
-
var
|
|
23689
|
+
var path44 = __toESM(require("path"));
|
|
23619
23690
|
var execFileP5 = (0, import_util4.promisify)(import_child_process19.execFile);
|
|
23620
23691
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
23621
23692
|
function resetStdinForChild() {
|
|
@@ -24104,7 +24175,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24104
24175
|
});
|
|
24105
24176
|
}
|
|
24106
24177
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24107
|
-
const remoteDir =
|
|
24178
|
+
const remoteDir = path44.posix.dirname(remotePath);
|
|
24108
24179
|
const parts = [
|
|
24109
24180
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
24110
24181
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -24174,7 +24245,7 @@ function shellQuote(s) {
|
|
|
24174
24245
|
// src/services/providers/gitpod.ts
|
|
24175
24246
|
var import_child_process20 = require("child_process");
|
|
24176
24247
|
var import_util5 = require("util");
|
|
24177
|
-
var
|
|
24248
|
+
var path45 = __toESM(require("path"));
|
|
24178
24249
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
24179
24250
|
var execFileP6 = (0, import_util5.promisify)(import_child_process20.execFile);
|
|
24180
24251
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -24414,7 +24485,7 @@ var GitpodProvider = class {
|
|
|
24414
24485
|
});
|
|
24415
24486
|
}
|
|
24416
24487
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24417
|
-
const remoteDir =
|
|
24488
|
+
const remoteDir = path45.posix.dirname(remotePath);
|
|
24418
24489
|
const parts = [
|
|
24419
24490
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
24420
24491
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -24450,7 +24521,7 @@ function shellQuote2(s) {
|
|
|
24450
24521
|
// src/services/providers/gitlab-workspaces.ts
|
|
24451
24522
|
var import_child_process21 = require("child_process");
|
|
24452
24523
|
var import_util6 = require("util");
|
|
24453
|
-
var
|
|
24524
|
+
var path46 = __toESM(require("path"));
|
|
24454
24525
|
var execFileP7 = (0, import_util6.promisify)(import_child_process21.execFile);
|
|
24455
24526
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
24456
24527
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -24710,7 +24781,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
24710
24781
|
}
|
|
24711
24782
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24712
24783
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
24713
|
-
const remoteDir =
|
|
24784
|
+
const remoteDir = path46.posix.dirname(remotePath);
|
|
24714
24785
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
24715
24786
|
if (options.mode != null) {
|
|
24716
24787
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -24778,7 +24849,7 @@ function shellQuote3(s) {
|
|
|
24778
24849
|
// src/services/providers/railway.ts
|
|
24779
24850
|
var import_child_process22 = require("child_process");
|
|
24780
24851
|
var import_util7 = require("util");
|
|
24781
|
-
var
|
|
24852
|
+
var path47 = __toESM(require("path"));
|
|
24782
24853
|
var execFileP8 = (0, import_util7.promisify)(import_child_process22.execFile);
|
|
24783
24854
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
24784
24855
|
function resetStdinForChild4() {
|
|
@@ -25014,7 +25085,7 @@ var RailwayProvider = class {
|
|
|
25014
25085
|
if (!projectId || !serviceId) {
|
|
25015
25086
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25016
25087
|
}
|
|
25017
|
-
const remoteDir =
|
|
25088
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25018
25089
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25019
25090
|
if (options.mode != null) {
|
|
25020
25091
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -25557,8 +25628,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
25557
25628
|
var import_node_dns = require("dns");
|
|
25558
25629
|
var import_node_util4 = require("util");
|
|
25559
25630
|
var import_node_crypto8 = require("crypto");
|
|
25560
|
-
var
|
|
25561
|
-
var
|
|
25631
|
+
var fs37 = __toESM(require("fs"));
|
|
25632
|
+
var path48 = __toESM(require("path"));
|
|
25562
25633
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
25563
25634
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
25564
25635
|
async function checkDns(apiBase) {
|
|
@@ -25614,13 +25685,13 @@ async function checkHealth(apiBase) {
|
|
|
25614
25685
|
}
|
|
25615
25686
|
}
|
|
25616
25687
|
function checkConfigDir() {
|
|
25617
|
-
const dir =
|
|
25688
|
+
const dir = path48.join(require("os").homedir(), ".codeam");
|
|
25618
25689
|
try {
|
|
25619
|
-
|
|
25620
|
-
const probe =
|
|
25621
|
-
|
|
25622
|
-
const read =
|
|
25623
|
-
|
|
25690
|
+
fs37.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
25691
|
+
const probe = path48.join(dir, ".doctor-probe");
|
|
25692
|
+
fs37.writeFileSync(probe, "ok", { mode: 384 });
|
|
25693
|
+
const read = fs37.readFileSync(probe, "utf8");
|
|
25694
|
+
fs37.unlinkSync(probe);
|
|
25624
25695
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
25625
25696
|
return {
|
|
25626
25697
|
id: "config-dir",
|
|
@@ -25684,7 +25755,7 @@ function checkNodePty() {
|
|
|
25684
25755
|
detail: "not required on this platform"
|
|
25685
25756
|
};
|
|
25686
25757
|
}
|
|
25687
|
-
const vendoredPath =
|
|
25758
|
+
const vendoredPath = path48.join(__dirname, "vendor", "node-pty");
|
|
25688
25759
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
25689
25760
|
try {
|
|
25690
25761
|
require(target);
|
|
@@ -25726,7 +25797,7 @@ function checkChokidar() {
|
|
|
25726
25797
|
}
|
|
25727
25798
|
async function doctor(args2 = []) {
|
|
25728
25799
|
const json = args2.includes("--json");
|
|
25729
|
-
const cliVersion = true ? "2.
|
|
25800
|
+
const cliVersion = true ? "2.34.0" : "0.0.0-dev";
|
|
25730
25801
|
const apiBase = resolveApiBaseUrl();
|
|
25731
25802
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
25732
25803
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -25925,7 +25996,7 @@ async function completion(args2) {
|
|
|
25925
25996
|
// src/commands/version.ts
|
|
25926
25997
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
25927
25998
|
function version2() {
|
|
25928
|
-
const v = true ? "2.
|
|
25999
|
+
const v = true ? "2.34.0" : "unknown";
|
|
25929
26000
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
25930
26001
|
}
|
|
25931
26002
|
|
|
@@ -26053,9 +26124,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26053
26124
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26054
26125
|
|
|
26055
26126
|
// src/lib/updateNotifier.ts
|
|
26056
|
-
var
|
|
26127
|
+
var fs38 = __toESM(require("fs"));
|
|
26057
26128
|
var os29 = __toESM(require("os"));
|
|
26058
|
-
var
|
|
26129
|
+
var path49 = __toESM(require("path"));
|
|
26059
26130
|
var https8 = __toESM(require("https"));
|
|
26060
26131
|
var import_node_child_process12 = require("child_process");
|
|
26061
26132
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26064,12 +26135,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26064
26135
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26065
26136
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26066
26137
|
function cachePath() {
|
|
26067
|
-
const dir =
|
|
26068
|
-
return
|
|
26138
|
+
const dir = path49.join(os29.homedir(), ".codeam");
|
|
26139
|
+
return path49.join(dir, "update-check.json");
|
|
26069
26140
|
}
|
|
26070
26141
|
function readCache() {
|
|
26071
26142
|
try {
|
|
26072
|
-
const raw =
|
|
26143
|
+
const raw = fs38.readFileSync(cachePath(), "utf8");
|
|
26073
26144
|
const parsed = JSON.parse(raw);
|
|
26074
26145
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26075
26146
|
return parsed;
|
|
@@ -26080,10 +26151,10 @@ function readCache() {
|
|
|
26080
26151
|
function writeCache(cache) {
|
|
26081
26152
|
try {
|
|
26082
26153
|
const file = cachePath();
|
|
26083
|
-
|
|
26154
|
+
fs38.mkdirSync(path49.dirname(file), { recursive: true });
|
|
26084
26155
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
26085
|
-
|
|
26086
|
-
|
|
26156
|
+
fs38.writeFileSync(tmp, JSON.stringify(cache));
|
|
26157
|
+
fs38.renameSync(tmp, file);
|
|
26087
26158
|
} catch {
|
|
26088
26159
|
}
|
|
26089
26160
|
}
|
|
@@ -26157,8 +26228,8 @@ function isLinkedInstall() {
|
|
|
26157
26228
|
timeout: 2e3
|
|
26158
26229
|
}).trim();
|
|
26159
26230
|
if (!root) return false;
|
|
26160
|
-
const pkgPath =
|
|
26161
|
-
return
|
|
26231
|
+
const pkgPath = path49.join(root, PKG_NAME);
|
|
26232
|
+
return fs38.lstatSync(pkgPath).isSymbolicLink();
|
|
26162
26233
|
} catch {
|
|
26163
26234
|
return false;
|
|
26164
26235
|
}
|
|
@@ -26194,7 +26265,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
26194
26265
|
return;
|
|
26195
26266
|
}
|
|
26196
26267
|
try {
|
|
26197
|
-
|
|
26268
|
+
fs38.unlinkSync(cachePath());
|
|
26198
26269
|
} catch {
|
|
26199
26270
|
}
|
|
26200
26271
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -26211,7 +26282,7 @@ function checkForUpdates() {
|
|
|
26211
26282
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
26212
26283
|
if (process.env.CI) return;
|
|
26213
26284
|
if (!process.stdout.isTTY) return;
|
|
26214
|
-
const current = true ? "2.
|
|
26285
|
+
const current = true ? "2.34.0" : null;
|
|
26215
26286
|
if (!current) return;
|
|
26216
26287
|
const cache = readCache();
|
|
26217
26288
|
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.34.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",
|